From 84c9fdbecf0b44a0897badcc12e5a9b333da4ec0 Mon Sep 17 00:00:00 2001 From: Cat McGee Date: Wed, 24 Jan 2024 14:58:35 +0600 Subject: [PATCH] chore(docs): Fix token bridge tutorial (#3935) Had a few missing links, wrong filepaths, and missing snippets --- .../token_portal/depositing_to_aztec.md | 15 +++++++++- .../dev_docs/tutorials/token_portal/setup.md | 30 +++++++------------ .../token_portal/typescript_glue_code.md | 17 ++++------- .../token_portal/withdrawing_to_l1.md | 20 ++++++++----- l1-contracts/test/portals/TokenPortal.sol | 2 +- 5 files changed, 43 insertions(+), 41 deletions(-) diff --git a/docs/docs/dev_docs/tutorials/token_portal/depositing_to_aztec.md b/docs/docs/dev_docs/tutorials/token_portal/depositing_to_aztec.md index bbb5915ff12..9452657be1f 100644 --- a/docs/docs/dev_docs/tutorials/token_portal/depositing_to_aztec.md +++ b/docs/docs/dev_docs/tutorials/token_portal/depositing_to_aztec.md @@ -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 +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: diff --git a/docs/docs/dev_docs/tutorials/token_portal/setup.md b/docs/docs/dev_docs/tutorials/token_portal/setup.md index 2c1e4472f48..3f738e02fc0 100644 --- a/docs/docs/dev_docs/tutorials/token_portal/setup.md +++ b/docs/docs/dev_docs/tutorials/token_portal/setup.md @@ -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: @@ -74,6 +75,7 @@ aztec-contracts ├── src ├── main.nr ├── token_interface.nr + ├── util.nr ``` # Create a JS hardhat project @@ -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 ``` @@ -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 ``` @@ -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 { @@ -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)" @@ -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 -``` - Finally, we will create a test file. Run this in the `src` directory.: ```bash @@ -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. diff --git a/docs/docs/dev_docs/tutorials/token_portal/typescript_glue_code.md b/docs/docs/dev_docs/tutorials/token_portal/typescript_glue_code.md index 7adc80a0154..ca4e63c1994 100644 --- a/docs/docs/dev_docs/tutorials/token_portal/typescript_glue_code.md +++ b/docs/docs/dev_docs/tutorials/token_portal/typescript_glue_code.md @@ -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 @@ -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'; +import { AccountWallet, AztecAddress, DebugLogger, EthAddress, Fr, computeAuthWitMessageHash, createDebugLogger, createPXEClient, waitForSandbox } from '@aztec/aztec.js'; +import { getSandboxAccountsWallets } from '@aztec/accounts/testing'; import { TokenContract } from '@aztec/noir-contracts/Token'; import { TokenBridgeContract } from '@aztec/noir-contracts/TokenBridge'; @@ -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, diff --git a/docs/docs/dev_docs/tutorials/token_portal/withdrawing_to_l1.md b/docs/docs/dev_docs/tutorials/token_portal/withdrawing_to_l1.md index fd2a2ea1721..8716421c10b 100644 --- a/docs/docs/dev_docs/tutorials/token_portal/withdrawing_to_l1.md +++ b/docs/docs/dev_docs/tutorials/token_portal/withdrawing_to_l1.md @@ -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 +#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. @@ -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 +} +``` -#include_code compute_note_hash_and_nullifier_placeholder /yarn-project/noir-contracts/contracts/token_bridge_contract/src/main.nr rust ## Compile code @@ -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! diff --git a/l1-contracts/test/portals/TokenPortal.sol b/l1-contracts/test/portals/TokenPortal.sol index ccd6661ea83..42119952264 100644 --- a/l1-contracts/test/portals/TokenPortal.sol +++ b/l1-contracts/test/portals/TokenPortal.sol @@ -1,4 +1,3 @@ -// docs:start:init pragma solidity >=0.8.18; import {IERC20} from "@oz/token/ERC20/IERC20.sol"; @@ -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;