Conversation
6673509 to
13c5831
Compare
critesjosh
left a comment
There was a problem hiding this comment.
Wdyt about adding tests?
Also, It seems like there are some missing steps (e.g. compiling contracts, both solidity and aztec)
|
|
||
| Before starting, make sure you have the Aztec local network running at version #include_aztec_version. Check out [the local network guide](../../../getting_started_on_local_network.md) for setup instructions. | ||
|
|
||
| ## What You'll Build |
There was a problem hiding this comment.
It would be good to add a prerequisites section somewhere near the top.
This quickly gets into a bit of Aztec jargon (l2-l1 messages, portals, governance concepts) and it would be nice for readers to know where to go to learn more about these topics. Maybe just add links in-line as these concepts are introduced
There was a problem hiding this comment.
If the intention is to have readers write the code as they go along, I think it should be more clear. There should be a "project setup" section that helps readers set up their project so they know what tools they will be using and where to put the files as they encounter them.
|
|
||
| Both messages must be consumed on L1 before the swap executes. This two-message pattern prevents anyone from stealing funds or changing swap parameters. | ||
|
|
||
| ### Why Two Messages? |
There was a problem hiding this comment.
this section is redundant with the lines just above. consider consolidating them
| The public swap transfers tokens from the sender to the contract, exits them to L1 via the bridge, and sends a swap intent message: | ||
|
|
||
| :::note Authorization Witnesses | ||
| Aztec uses **authorization witnesses** (authwit) instead of the ERC20 approve/transferFrom pattern. The contract computes the hash of the exact action it wants to perform, sets that hash as authorized, then immediately performs the action. This gives fine-grained control - the authorization is for a specific action, not a blanket approval. Since we authorize and spend in the same transaction, replay attacks are impossible. |
There was a problem hiding this comment.
maybe add a link to the authwit page
| IInbox public inbox; | ||
| uint256 public rollupVersion; | ||
|
|
||
| function initialize( |
There was a problem hiding this comment.
Should we add a comment that there is no access control on this, but there should be for a real prod contract?
| uint256[2] calldata _leafIndices, | ||
| bytes32[][2] calldata _paths | ||
| ) external returns (bytes32, uint256) { | ||
| IERC20 inputAsset = ExampleTokenPortal(_inputTokenPortal).underlying(); |
| )); | ||
|
|
||
| // Approve bridge to burn this contract's funds and exit to L1 Uniswap Portal | ||
| let _ = self.call_self._approve_bridge_and_exit_input_asset_to_L1( |
There was a problem hiding this comment.
maybe worth adding a note about the let _ syntax and why its used. wdyt?
| console.log(`Deposit message leaf index: ${depositLeafIndex}\n`); | ||
| // docs:end:deposit_to_l2 | ||
|
|
||
| // docs:start:mine_blocks |
There was a problem hiding this comment.
i dont think this is used in the tutorial or explained why mining 2 blocks in necessary
b3f871b to
de017ec
Compare
11fcbb0 to
3b13191
Compare
critesjosh
left a comment
There was a problem hiding this comment.
looks like the build is broken. also can you merge next into this branch once the TS execution PR (#20113) get merged in, and make sure that the TS in this PR runs
02d739d to
5527846
Compare
65d2eb1 to
6d6f329
Compare
6d6f329 to
f24e354
Compare
f24e354 to
e78ecf7
Compare
critesjosh
left a comment
There was a problem hiding this comment.
The main components of the tutorial are all here, we just need to stitch them together properly and polish it so new folks can get through this with minimal friction.
|
|
||
| ## Part 1: Token Portal (Solidity) | ||
|
|
||
| The [token portal](../../aztec-nr/framework-description/ethereum_aztec_messaging.md) handles depositing tokens from L1 to L2 and withdrawing from L2 to L1. This version hardcodes `caller_on_l1` to `address(0)` (meaning anyone can execute the withdrawal). |
There was a problem hiding this comment.
I dont see caller_on_l1 being hardcoded to 0. maybe i missing it?
There was a problem hiding this comment.
also, I think we can link to a better page, the current link is about general message passing, not about a token portal specifically, as the link indicates. maybe a linke to the aztecjs token bridge tutorial would be better?
|
|
||
| The [registry](../../aztec-nr/framework-description/ethereum_aztec_messaging.md) provides governance-updateable addresses for core Aztec contracts. Rather than hardcoding rollup addresses, portals query the registry, allowing the protocol to upgrade without redeploying all portals. | ||
|
|
||
| Each cross-chain message includes a **content hash** — a `keccak256` digest of the function selector and its parameters that uniquely identifies the message. The content hash in each function uses `abi.encodeWithSignature` to include a function selector, making each message type unique and preventing a deposit message from being confused with a withdrawal message. |
There was a problem hiding this comment.
isnt it sha256, not keccak?
| #include_code swap_private /docs/examples/contracts/example_uniswap/src/main.nr rust | ||
|
|
||
| :::note Why no recipient parameter? | ||
| In `swap_private`, the recipient is the transaction sender (implicit). This preserves privacy: revealing a recipient address to L1 would compromise the caller's identity. The output tokens are deposited privately on L2, where only the caller can claim them. |
There was a problem hiding this comment.
| In `swap_private`, the recipient is the transaction sender (implicit). This preserves privacy: revealing a recipient address to L1 would compromise the caller's identity. The output tokens are deposited privately on L2, where only the caller can claim them. | |
| In `swap_private`, the recipient is the person that provide the secret used to generate the hash for the L1 to L2 message. This preserves privacy: revealing a recipient address to L1 would compromise the caller's identity. The output tokens are deposited privately to L2, where only the secret holder can claim them. |
I think this is more accurate
| BridgeA -->|"5. L2→L1 msg"| PortalA | ||
|
|
||
| UniL1 -->|"6. Consume msg 1"| PortalA | ||
| UniL1 -->|"7. Consume msg 2"| UniL1 |
There was a problem hiding this comment.
Should this arrow point to the outbox? Its confusing that that the UniL1 box is pointing to itself
|
|
||
| #include_code consume_l1_messages_execute /docs/examples/ts/example_swap/index.ts typescript | ||
|
|
||
| Finally, claim the output DAI on L2: |
There was a problem hiding this comment.
You also start line 306 with Finally,
|
|
||
| ### Private Swap | ||
|
|
||
| The private swap is similar but uses `transfer_to_public` (private to public transfer) and [`enqueue_self`](../../aztec-nr/framework-description/calling_contracts.md) instead of `call_self`: |
There was a problem hiding this comment.
I think a brief inline explanation of why enqueue_self instead of call_self would be helpful
| Before starting this tutorial, you need: | ||
|
|
||
| 1. **Aztec local network** running at version #include_aztec_version -- see [the local network guide](../../../getting_started_on_local_network.md) for setup instructions | ||
| 2. **Foundry** installed for Solidity compilation -- see [Foundry installation](https://book.getfoundry.sh/getting-started/installation) |
There was a problem hiding this comment.
| 2. **Foundry** installed for Solidity compilation -- see [Foundry installation](https://book.getfoundry.sh/getting-started/installation) |
comes with aztec
There was a problem hiding this comment.
if you accept this, you'll also have to renumber the following items
|
|
||
| Each swap generates **two L2-to-L1 messages**, both of which must be consumed on L1 before the swap executes: | ||
|
|
||
| 1. **Token bridge exit** - Authorizes releasing input tokens from the bridge to the uniswap portal |
There was a problem hiding this comment.
| 1. **Token bridge exit** - Authorizes releasing input tokens from the bridge to the uniswap portal | |
| 1. **Token bridge exit** - Authorizes releasing input tokens from the token portal to the uniswap portal |
Since its referred to as TokenPortal.sol in the contract name above
|
|
||
| ## Project Setup | ||
|
|
||
| This tutorial uses three types of contracts (Solidity, Noir, TypeScript) spread across a project. The code is shown inline via snippets -- you do not need to type it manually. However, understanding the project layout will help you follow along. |
There was a problem hiding this comment.
You mention here that readers do not need to type this out manually. But at the end of Step 2 (Compile Solidity Contracts) has an instruction to run forge build. At that point, I was just following along, reading, so I don't have a project set up. It's not clear if I should be building a project as follow along or just reading. Since it's a tutorial, let's have readers build the project as they go, as much as possible, so we need to add some steps about how to set up the project (either clone a template repo, or specify what commands they should run to get the project set up)
d29b0fd to
d30723c
Compare
7acaa50 to
ec3dbbe
Compare
ec3dbbe to
8acd772
Compare
8acd772 to
721d77d
Compare
critesjosh
left a comment
There was a problem hiding this comment.
disabled automerge and approving with some nits
| Before starting this tutorial, you need: | ||
|
|
||
| 1. **Aztec local network** running at version #include_aztec_version -- see [the local network guide](../../../getting_started_on_local_network.md) for setup instructions | ||
| 2. **Node.js** (v18+) and a package manager (yarn or npm) |
There was a problem hiding this comment.
| 2. **Node.js** (v18+) and a package manager (yarn or npm) | |
| 2. **Node.js** (v24+) and a package manager (yarn or npm) |
I think we are recommending node 24 now? Its what we use in aztec-packages
| The example code lives in the Aztec packages repository: | ||
|
|
||
| ```bash | ||
| git clone --depth 1 --branch #include_aztec_version https://github.com/AztecProtocol/aztec-packages |
There was a problem hiding this comment.
| git clone --depth 1 --branch #include_aztec_version https://github.com/AztecProtocol/aztec-packages | |
| git clone --depth 1 --branch #include_aztec_version https://github.com/AztecProtocol/aztec-packages.git |
|
|
||
| ``` | ||
| examples/ | ||
| ├── solidity/ |
There was a problem hiding this comment.
nit: this actually comes after contracts/
| UniL1["ExampleUniswapPortal<br/>(Solidity)"] | ||
| PortalA["ExampleTokenPortal A"] | ||
| PortalB["ExampleTokenPortal B"] | ||
| ERC20A["WETH (ERC20)"] |
| User -->|"1. swap_public()"| UniL2 | ||
| UniL2 -->|"2. Transfer WETH"| TokenA | ||
| UniL2 -->|"3. Exit to L1"| BridgeA | ||
| UniL2 -->|"4. L2→L1 msg"| UniL1 |
| @aztec/stdlib@#include_aztec_version \ | ||
| @aztec/ethereum@#include_aztec_version \ | ||
| @aztec/noir-contracts.js@#include_aztec_version \ | ||
| @aztec/foundation@#include_aztec_version \ |
There was a problem hiding this comment.
looks like viem also required? its in the config.yaml
| console.log("=== PUBLIC SWAP FLOW ===\n"); | ||
| console.log("Initiating public swap on L2 (WETH -> DAI)...\n"); | ||
|
|
||
| // Force L2 block production so the authwit is included in a block before the swap |
There was a problem hiding this comment.
| // Force L2 block production so the authwit is included in a block before the swap | |
| // Force L2 block production so the claim message is included in a block before the swap |
this is for the claim message, not the authwit right?
adds uniswap tut and sample code
721d77d to
290671e
Compare
## Summary PR #21231 changed the `computeL2ToL1MembershipWitness` API signature from `(node, epoch, message)` to `(node, message, txHash)`, but the `example_swap` docs example (added in PR #20233) was written against the old API. This caused the merge-train CI to fail with `TypeError: Cannot read properties of undefined (reading 'siblingPath')` because the function received wrong arguments and returned `undefined`. ## Changes - Removed `RollupContract` import and usage (no longer needed to manually compute epoch) - Updated both `computeL2ToL1MembershipWitness` calls to use new signature: `(node, message, txHash)` - Get epoch numbers from the returned witness (`witness.epochNumber`) instead of computing manually ClaudeBox log: https://claudebox.work/s/5eb93c1235ed3384?run=2 Co-authored-by: esau <152162806+sklppy88@users.noreply.github.com>


adds uniswap tut and sample code