Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(docs): Fix token bridge tutorial #3935

Merged
merged 9 commits into from
Jan 24, 2024
15 changes: 14 additions & 1 deletion docs/docs/dev_docs/tutorials/token_portal/depositing_to_aztec.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,20 @@ In this step, we will write our token portal contract on L1.

In `l1-contracts/contracts` in your file called `TokenPortal.sol` paste this:

#include_code init /l1-contracts/test/portals/TokenPortal.sol solidity
```solidity
critesjosh marked this conversation as resolved.
Show resolved Hide resolved
pragma solidity >=0.8.18;

import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

// Messaging
import {IRegistry} from "@aztec/l1-contracts/src/core/interfaces/messagebridge/IRegistry.sol";
import {IInbox} from "@aztec/l1-contracts/src/core/interfaces/messagebridge/IInbox.sol";
import {DataStructures} from "@aztec/l1-contracts/src/core/libraries/DataStructures.sol";
import {Hash} from "@aztec/l1-contracts/src/core/libraries/Hash.sol";

#include_code init /l1-contracts/test/portals/TokenPortal.sol raw
```

This imports relevant files including the interfaces used by the Aztec rollup. And initializes the contract with the following parameters:

Expand Down
30 changes: 10 additions & 20 deletions docs/docs/dev_docs/tutorials/token_portal/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ type = "contract"

[dependencies]
aztec = { git="https://github.com/AztecProtocol/aztec-packages/", tag="#include_aztec_version", directory="yarn-project/aztec-nr/aztec" }
token_portal_content_hash_lib = { git="https://github.com/AztecProtocol/aztec-packages/", tag="aztec-packages-v0.16.9", directory="yarn-project/noir-contracts/contracts/token_portal_content_hash_lib" }
token_portal_content_hash_lib = { git="https://github.com/AztecProtocol/aztec-packages/", tag="#include_aztec_version", directory="yarn-project/noir-contracts/contracts/token_portal_content_hash_lib" }
protocol_types = { git="https://github.com/AztecProtocol/aztec-packages/", tag="#include_aztec_version", directory="yarn-project/noir-protocol-circuits/src/crates/types"}
```

We will also be writing some helper functions that should exist elsewhere so we don't overcomplicated our contract. In `src` create two more files - one called `util.nr` and one called `token_interface` - so your dir structure should now look like this:
Expand All @@ -74,6 +75,7 @@ aztec-contracts
├── src
├── main.nr
├── token_interface.nr
├── util.nr
```

# Create a JS hardhat project
Expand All @@ -99,7 +101,7 @@ touch TokenPortal.sol
Now add dependencies that are required. These include interfaces to Aztec Inbox, Outbox and Registry smart contracts, OpenZeppelin contracts, and NomicFoundation.

```bash
yarn add @aztec/foundation @aztec/l1-contracts @openzeppelin/contracts && yarn add --dev @nomicfoundation/hardhat-network-helpers @nomicfoundation/hardhat-chai-matchers @nomiclabs/hardhat-ethers @nomiclabs/hardhat-etherscan @types/chai @types/mocha @typechain/ethers-v5 @typechain/hardhat chai hardhat-gas-reporter solidity-coverage ts-node typechain typescript
yarn add @aztec/foundation @aztec/l1-contracts @openzeppelin/contracts && yarn add --dev @nomicfoundation/hardhat-network-helpers @nomicfoundation/hardhat-chai-matchers @nomiclabs/hardhat-ethers @nomiclabs/hardhat-etherscan @types/chai @types/mocha @typechain/ethers-v5 @typechain/hardhat chai@4.0.0 hardhat-gas-reporter solidity-coverage ts-node typechain typescript

```

Expand Down Expand Up @@ -129,7 +131,7 @@ Inside the `packages` directory, run

```bash
mkdir src && cd src && yarn init -yp
yarn add @aztec/aztec.js @aztec/accounts @aztec/noir-contracts @aztec/circuit-types @aztec/foundation @aztec/l1-artifacts viem "@types/node@^20.8.2"
yarn add typescript @aztec/aztec.js @aztec/accounts @aztec/noir-contracts @aztec/types @aztec/foundation @aztec/l1-artifacts viem@1.21.4 "@types/node@^20.8.2"
yarn add -D jest @jest/globals ts-jest
```

Expand All @@ -144,7 +146,7 @@ In `package.json`, add:
}
```

Your `package.json` should look something like this:
Your `package.json` should look something like this (do not copy and paste):

```json
{
Expand All @@ -154,18 +156,11 @@ Your `package.json` should look something like this:
"license": "MIT",
"private": true,
"type": "module",
"dependencies": {
"@aztec/aztec.js": "^0.8.7",
"@aztec/foundation": "^0.8.7",
"@aztec/noir-contracts": "^0.8.7",
"@aztec/circuit-types": "^0.8.7",
"@types/node": "^20.8.2",
"ethers": "^5.7"
"dependencies": {
"dep": "version",
},
"devDependencies": {
"@jest/globals": "^29.7.0",
"jest": "^29.7.0",
"ts-jest": "^29.1.1"
"dep": "version",
},
"scripts": {
"test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest)"
Expand Down Expand Up @@ -227,12 +222,6 @@ Then create a jest config file: `jest.config.json`
}
```

You will also need to install some dependencies:

```bash
yarn add --dev typescript @types/jest ts-jest
catmcgee marked this conversation as resolved.
Show resolved Hide resolved
```

Finally, we will create a test file. Run this in the `src` directory.:

```bash
Expand All @@ -249,6 +238,7 @@ src
└── cross_chain_messaging.test.ts
├── jest.config.json
├── package.json
├── tsconfig.json
```

In the next step, we’ll start writing our L1 smart contract with some logic to deposit tokens to Aztec from L1.
17 changes: 5 additions & 12 deletions docs/docs/dev_docs/tutorials/token_portal/typescript_glue_code.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,12 @@ title: Deploy & Call Contracts with Typescript

In this step we will write a Typescript test to interact with the sandbox and call our contracts!

Go to the `src/test` directory in your `packages` dir and create a new file called `cross_chain_messaging.test.ts`:

```bash
cd src/test
touch cross_chain_messaging.test.ts
```

## Test imports and setup

We need some helper files that can keep our code clean. Inside your `src/test` directory:

```bash
mkdir fixtures && cd fixtures
cd fixtures
touch utils.ts
cd .. && mkdir shared && cd shared
touch cross_chain_test_harness.ts
Expand Down Expand Up @@ -47,8 +40,8 @@ Open `cross_chain_messaging.test.ts` and paste the initial description of the te

```typescript
import { expect, jest} from '@jest/globals'
import { AccountWallet, AztecAddress, DebugLogger, EthAddress, Fr, computeAuthWitMessageHash, createDebugLogger, createPXEClient, waitForPXE } from '@aztec/aztec.js';
import { getInitialTestAccountsWallets } from '@aztec/accounts/testing';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a heads up, I the name of this function will change back after the next release.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh. that's tomorrow then - maybe we should just keep it

import { AccountWallet, AztecAddress, DebugLogger, EthAddress, Fr, computeAuthWitMessageHash, createDebugLogger, createPXEClient, waitForSandbox } from '@aztec/aztec.js';
import { getSandboxAccountsWallets } from '@aztec/accounts/testing';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we update this code block to import code directly from the tests?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the tests themselves have a MUCH more complicated setup than the e2e code we use in the tutorials. it requires 4 extra files with a bunch of new imports. the tutorial setup code is not referenced anywhere else in the codebase

the only solutions are to overcomplicate the tutorial or manually keep an eye on ~15 lines of code. i'm happy to test every release - it's all in devrel repo anyway

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok cool, works for me!

import { TokenContract } from '@aztec/noir-contracts/Token';
import { TokenBridgeContract } from '@aztec/noir-contracts/TokenBridge';

Expand Down Expand Up @@ -80,8 +73,8 @@ describe('e2e_cross_chain_messaging', () => {
beforeEach(async () => {
logger = createDebugLogger('aztec:e2e_uniswap');
const pxe = createPXEClient(PXE_URL);
await waitForPXE(pxe);
const wallets = await getInitialTestAccountsWallets(pxe);
await waitForSandbox(pxe);
const wallets = await getSandboxAccountsWallets(pxe);

const walletClient = createWalletClient({
account: hdAccount,
Expand Down
20 changes: 13 additions & 7 deletions docs/docs/dev_docs/tutorials/token_portal/withdrawing_to_l1.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,10 @@ For both the public and private flow, we use the same mechanism to determine the
After the transaction is completed on L2, the portal must call the outbox to successfully transfer funds to the user on L1. Like with deposits, things can be complex here. For example, what happens if the transaction was done on L2 to burn tokens but can’t be withdrawn to L1? Then the funds are lost forever! How do we prevent this?

Paste this in your `TokenPortal.sol`:

#include_code token_portal_withdraw /l1-contracts/test/portals/TokenPortal.sol solidity
```solidity
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this change? Running the docs locally, this removes the link to source at the bottom of the code snippet. Is it just for the closing curly brace? If so, I agree with the change.

Do you think we should add a link to the source below the reference?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah it's just for the closing curly brace. this contract is referenced a lot throughout the rest of the include_code snippets so im not sure we should reference - might be confusing, makes it seem like it's a new contract. wdyt?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok that makes sense. If there are links to source elsewhere, not a big deal.

#include_code token_portal_withdraw /l1-contracts/test/portals/TokenPortal.sol raw
}
```

Here we reconstruct the L2 to L1 message and check that this message exists on the outbox. If so, we consume it and transfer the funds to the recipient. As part of the reconstruction, the content hash looks similar to what we did in our bridge contract on aztec where we pass the amount and recipient to the the hash. This way a malicious actor can’t change the recipient parameter to the address and withdraw funds to themselves.

Expand All @@ -53,13 +55,17 @@ We call this pattern _designed caller_ which enables a new paradigm **where we c

Before we can compile and use the contract, we need to add two additional functions.

We need a function that let's us read the token value.
We need a function that lets us read the token value. Paste this into `main.nr`:

#include_code read_token /yarn-project/noir-contracts/contracts/token_bridge_contract/src/main.nr rust

And the `compute_note_hash_and_nullifier` required on every contract.
And the `compute_note_hash_and_nullifier` required on every contract:

```rust
#include_code compute_note_hash_and_nullifier_placeholder /yarn-project/noir-contracts/contracts/token_bridge_contract/src/main.nr raw
}
critesjosh marked this conversation as resolved.
Show resolved Hide resolved
```

#include_code compute_note_hash_and_nullifier_placeholder /yarn-project/noir-contracts/contracts/token_bridge_contract/src/main.nr rust

## Compile code

Expand All @@ -75,14 +81,14 @@ npx hardhat compile
And compile your Aztec.nr contracts like this:

```bash
cd aztec-contracts/token-bridge
cd aztec-contracts/token_bridge
aztec-nargo compile
```

And generate the TypeScript interface for the contract and add it to the test dir:

```bash
aztec-cli codegen target -o ../../../src/test/fixtures --ts
aztec-cli codegen target -o ../../src/test/fixtures --ts
```

This will create a TS interface in our `src/test` folder!
Expand Down
2 changes: 1 addition & 1 deletion l1-contracts/test/portals/TokenPortal.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// docs:start:init
pragma solidity >=0.8.18;

import {IERC20} from "@oz/token/ERC20/IERC20.sol";
Expand All @@ -12,6 +11,7 @@ import {DataStructures} from "../../src/core/libraries/DataStructures.sol";
import {Hash} from "../../src/core/libraries/Hash.sol";
// docs:end:content_hash_sol_import

// docs:start:init
contract TokenPortal {
using SafeERC20 for IERC20;

Expand Down