From 8db95a2dca6cbe0c0480abf5532375f2840f71b2 Mon Sep 17 00:00:00 2001 From: Ori Pomerantz Date: Thu, 13 Feb 2025 17:18:17 -0600 Subject: [PATCH 1/6] fixing errors --- .../interop/tutorials/message-passing.mdx | 111 ++++++++++-------- public/tutorials/app_v2.mts | 75 ++++++++++++ 2 files changed, 134 insertions(+), 52 deletions(-) create mode 100644 public/tutorials/app_v2.mts diff --git a/pages/stack/interop/tutorials/message-passing.mdx b/pages/stack/interop/tutorials/message-passing.mdx index 007326985..7b74cea76 100644 --- a/pages/stack/interop/tutorials/message-passing.mdx +++ b/pages/stack/interop/tutorials/message-passing.mdx @@ -93,19 +93,26 @@ For development purposes, we'll first use autorelay mode to handle message execu ### Setting up test networks + + + Do *not* attempt to run these steps with the [devnet](../tools/devnet). + At this point we are relying on the autorelay functionality of Supersim. + The devnet does not have this, you have to send the executing message yourself, as explained [here](#implement-manual-message-relaying). + + 1. In the directory where Supersim is installed, start it with autorelay. ```sh - supersim + ./supersim --interop.autorelay ``` Supersim creates three `anvil` blockchains: - \| Role | ChainID | RPC URL | - \| -------\* | ------: | ---------------------------------------------\* | - \| L1 | 900 | [http://127.0.0.1:8545](http://127.0.0.1:8545) | - \| OPChainA | 901 | [http://127.0.0.1:9545](http://127.0.0.1:9545) | - \| OPChainB | 902 | [http://127.0.0.1:9546](http://127.0.0.1:9546) | + | Role | ChainID | RPC URL | + | -------- | ------: | --------------------------------------------- | + | L1 | 900 | [http://127.0.0.1:8545](http://127.0.0.1:8545) | + | OPChainA | 901 | [http://127.0.0.1:9545](http://127.0.0.1:9545) | + | OPChainB | 902 | [http://127.0.0.1:9546](http://127.0.0.1:9546) | 2. In a separate shell, store the configuration in environment variables. @@ -141,8 +148,8 @@ For development purposes, we'll first use autorelay mode to handle message execu 2. In `src/Greeter.sol` put this file. This is a variation on [Hardhat's Greeter contract](https://github.com/matter-labs/hardhat-zksync/blob/main/examples/upgradable-example/contracts/Greeter.sol). - ```solidity file=/public/tutorials/Greeter.sol#L1-L20 hash=b3c5550bcc2cc4272125388ef23a67e7 - ``` + ```solidity file=/public/tutorials/Greeter.sol#L1-L20 hash=b3c5550bcc2cc4272125388ef23a67e7 + ``` 3. Deploy the `Greeter` contract to Chain B and store the resulting contract address in the `GREETER_B_ADDR` environment variable. @@ -441,10 +448,10 @@ In production we will not have this, we need to create our own executing message 2. Create or replace `src/app.mts` with this code. - ```solidity file=/public/tutorials/app.mts#L1-L51 hash=8f6f776884b8e37ae613f7aea8cd6a3b - ``` + ```solidity file=/public/tutorials/app.mts#L1-L51 hash=8f6f776884b8e37ae613f7aea8cd6a3b + ``` - 3. Run the program, see that a greeting from chain A is related to chain B. + 3. Run the program, see that a greeting from chain A is relayed to chain B. ```sh npm start @@ -490,50 +497,50 @@ In production we will not have this, we need to create our own executing message 1. Replace `src/app.mts` with: - ```js file=/public/tutorials/app.mts#L1-L51 hash=8f6f776884b8e37ae613f7aea8cd6a3b - ``` + ```typescript file=/public/tutorials/app_v2.mts hash=4811b7946a82b2815c103da8a65c1334 + ``` -
- Explanation +
+ Explanation - 1. **Import Required Libraries** + 1. **Import Required Libraries** - * Imports functions from `viem` for wallet creation, HTTP transport, and contract interactions. - * Imports `@eth-optimism/viem` utilities for handling OP-Stack-specific actions and interoperability. - * Loads ABI definitions from `Greeter.json` and `GreetingSender.json` for contract interactions. + * Imports functions from `viem` for wallet creation, HTTP transport, and contract interactions. + * Imports `@eth-optimism/viem` utilities for handling OP-Stack-specific actions and interoperability. + * Loads ABI definitions from `Greeter.json` and `GreetingSender.json` for contract interactions. - 2. **Initialize Wallet Clients** + 2. **Initialize Wallet Clients** - * Uses `privateKeyToAccount` to generate an account from an environment variable. - * Creates `walletA` for chain `supersimL2A` and `walletB` for chain `supersimL2B`, extending them with Viem's public and OP-Stack-specific actions. + * Uses `privateKeyToAccount` to generate an account from an environment variable. + * Creates `walletA` for chain `supersimL2A` and `walletB` for chain `supersimL2B`, extending them with Viem's public and OP-Stack-specific actions. - 3. **Get Contract Instances** + 3. **Get Contract Instances** - * Retrieves contract instances for `greeter` on `walletB` and `greetingSender` on `walletA` using `getContract`. - * The addresses are taken from environment variables, and the clients are set to the respective wallets. + * Retrieves contract instances for `greeter` on `walletB` and `greetingSender` on `walletA` using `getContract`. + * The addresses are taken from environment variables, and the clients are set to the respective wallets. - 4. **Direct Greeting on Chain B** + 4. **Direct Greeting on Chain B** - * Calls `setGreeting` on `greeter` to store a greeting directly on chain B. - * Waits for the transaction to be confirmed using `waitForTransactionReceipt`. - * Reads and logs the greeting stored on chain B. + * Calls `setGreeting` on `greeter` to store a greeting directly on chain B. + * Waits for the transaction to be confirmed using `waitForTransactionReceipt`. + * Reads and logs the greeting stored on chain B. - 5. **Cross-Chain Greeting via Chain A** + 5. **Cross-Chain Greeting via Chain A** - * Calls `setGreeting` on `greetingSender` to send a greeting through chain A. - * Waits for the transaction receipt on chain A. + * Calls `setGreeting` on `greetingSender` to send a greeting through chain A. + * Waits for the transaction receipt on chain A. - 6. **Retrieve and Relay the Cross-Chain Message** + 6. **Retrieve and Relay the Cross-Chain Message** - * Extracts the message from the transaction receipt using `createInteropSentL2ToL2Messages`. - * Relays the message to chain B using `walletB.interop.relayMessage`. - * Waits for confirmation of the relay transaction. + * Extracts the message from the transaction receipt using `createInteropSentL2ToL2Messages`. + * Relays the message to chain B using `walletB.interop.relayMessage`. + * Waits for confirmation of the relay transaction. - 7. **Verify the Updated Greeting on Chain B** + 7. **Verify the Updated Greeting on Chain B** - * Reads the greeting from `greeter` after the relay process. - * Logs the updated greeting, showing that it was successfully relayed from chain A to chain B. -
+ * Reads the greeting from `greeter` after the relay process. + * Logs the updated greeting, showing that it was successfully relayed from chain A to chain B. +
2. Rerun the JavaScript program, and see that the message is relayed. @@ -546,22 +553,22 @@ In production we will not have this, we need to create our own executing message The same contracts are deployed on [the devnet](../tools/devnet). You can relay messages in exactly the same way you'd do it on Supersim. - \| Contract | Network | Address | - \| ---------------\* | -------------------------------------------\* | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\* | - \| `Greeter` | [Devnet 1](../tools/devnet#interop-devnet-1) | [`0x1A183FCf61053B7dcd2322BbE766f7E1946d3718`](https://sid.testnet.routescan.io/address/0x1A183FCf61053B7dcd2322BbE766f7E1946d3718) | - \| `GreetingSender` | [Devnet 0](../tools/devnet#interop-devnet-1) | [`0x9De9f84a4EB3616B44CF1d68cD1A9098Df6cB25f`](https://sid.testnet.routescan.io/address/0x9De9f84a4EB3616B44CF1d68cD1A9098Df6cB25f/contract/420120000/readContract?chainid=420120000) | + | Contract | Network | Address | + | --------------- | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | + | `Greeter` | [Devnet 1](../tools/devnet#interop-devnet-1) | [`0x1A183FCf61053B7dcd2322BbE766f7E1946d3718`](https://sid.testnet.routescan.io/address/0x1A183FCf61053B7dcd2322BbE766f7E1946d3718) | + | `GreetingSender` | [Devnet 0](../tools/devnet#interop-devnet-1) | [`0x9De9f84a4EB3616B44CF1d68cD1A9098Df6cB25f`](https://sid.testnet.routescan.io/address/0x9De9f84a4EB3616B44CF1d68cD1A9098Df6cB25f/contract/420120000/readContract?chainid=420120000) | - To modify the program to relay messagez on devnet, follow these steps: + To modify the program to relay messages on devnet, follow these steps: 1. In `src/app.mts`, replace these lines to update the chains and contract addresses. - \| Line number | New content | - \| ----------: | -------------------------------------------------------------------------\* | - \| 10 | `import { interopAlpha0, interopAlpha1 } from '@eth-optimism/viem/chains'` | - \| 24 | ` chain: interopAlpha0,` | - \| 32 | ` chain: interopAlpha1,` | - \| 40 | ` address: "0x1A183FCf61053B7dcd2322BbE766f7E1946d3718",` | - \| 46 | ` address: "0x9De9f84a4EB3616B44CF1d68cD1A9098Df6cB25f",` | + | Line number | New content | + | ----------: | ------------------------------------------------------------------------- | + | 10 | `import { interopAlpha0, interopAlpha1 } from '@eth-optimism/viem/chains'` | + | 24 | ` chain: interopAlpha0,` | + | 32 | ` chain: interopAlpha1,` | + | 40 | ` address: "0x1A183FCf61053B7dcd2322BbE766f7E1946d3718",` | + | 46 | ` address: "0x9De9f84a4EB3616B44CF1d68cD1A9098Df6cB25f",` | 2. Set `PRIV_KEY` to the private key of an address that has Sepolia ETH on the two chains. diff --git a/public/tutorials/app_v2.mts b/public/tutorials/app_v2.mts new file mode 100644 index 000000000..3327aa60e --- /dev/null +++ b/public/tutorials/app_v2.mts @@ -0,0 +1,75 @@ +import { + createWalletClient, + http, + defineChain, + publicActions, + getContract, + Address, +} from 'viem' +import { privateKeyToAccount } from 'viem/accounts' +import { supersimL2A, supersimL2B } from '@eth-optimism/viem/chains' + +import { + walletActionsL2, + publicActionsL2, + createInteropSentL2ToL2Messages, +} from '@eth-optimism/viem' + +import greeterData from './Greeter.json' +import greetingSenderData from './GreetingSender.json' + +const account = privateKeyToAccount(process.env.PRIV_KEY as `0x${string}`) + +const walletA = createWalletClient({ + chain: supersimL2A, + transport: http(), + account +}).extend(publicActions) + .extend(publicActionsL2()) + .extend(walletActionsL2()) + +const walletB = createWalletClient({ + chain: supersimL2B, + transport: http(), + account +}).extend(publicActions) + .extend(publicActionsL2()) + .extend(walletActionsL2()) + +const greeter = getContract({ + address: process.env.GREETER_B_ADDR as Address, + abi: greeterData.abi, + client: walletB +}) + +const greetingSender = getContract({ + address: process.env.GREETER_A_ADDR as Address, + abi: greetingSenderData.abi, + client: walletA +}) + +const txnBHash = await greeter.write.setGreeting( + ["Greeting directly to chain B"]) +await walletB.waitForTransactionReceipt({hash: txnBHash}) + +const greeting1 = await greeter.read.greet() +console.log(`Chain B Greeting: ${greeting1}`) + +const txnAHash = await greetingSender.write.setGreeting( + ["Greeting through chain A"]) +const receiptA = await walletA.waitForTransactionReceipt({hash: txnAHash}) + +const sentMessage = + (await createInteropSentL2ToL2Messages(walletA, { receipt: receiptA })) + .sentMessages[0] +const relayMsgTxnHash = await walletB.interop.relayMessage({ + sentMessageId: sentMessage.id, + sentMessagePayload: sentMessage.payload, + }) + +const receiptRelay = await walletB.waitForTransactionReceipt( + {hash: relayMsgTxnHash}) + +const greeting2 = await greeter.read.greet() +console.log(`Chain A Greeting: ${greeting2}`) + From d80015f5da49566257eeaaa0bdf480e5fff4edb8 Mon Sep 17 00:00:00 2001 From: Ori Pomerantz Date: Thu, 13 Feb 2025 17:25:21 -0600 Subject: [PATCH 2/6] Changed the warning --- pages/stack/interop/tutorials/message-passing.mdx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pages/stack/interop/tutorials/message-passing.mdx b/pages/stack/interop/tutorials/message-passing.mdx index 7b74cea76..79fb7e860 100644 --- a/pages/stack/interop/tutorials/message-passing.mdx +++ b/pages/stack/interop/tutorials/message-passing.mdx @@ -95,9 +95,7 @@ For development purposes, we'll first use autorelay mode to handle message execu - Do *not* attempt to run these steps with the [devnet](../tools/devnet). - At this point we are relying on the autorelay functionality of Supersim. - The devnet does not have this, you have to send the executing message yourself, as explained [here](#implement-manual-message-relaying). + If you attempt to run these steps with the [devnet](../tools/devnet), you *must* Send the executing message yourself, as explained [here](#implement-manual-message-relaying). 1. In the directory where Supersim is installed, start it with autorelay. From 4f87f79f9fc0815f1335d4be6db43b9aefdab9b9 Mon Sep 17 00:00:00 2001 From: Ori Pomerantz Date: Thu, 13 Feb 2025 17:30:37 -0600 Subject: [PATCH 3/6] Fixed type of code --- pages/stack/interop/tutorials/message-passing.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/stack/interop/tutorials/message-passing.mdx b/pages/stack/interop/tutorials/message-passing.mdx index 79fb7e860..6b54bdca0 100644 --- a/pages/stack/interop/tutorials/message-passing.mdx +++ b/pages/stack/interop/tutorials/message-passing.mdx @@ -446,7 +446,7 @@ In production we will not have this, we need to create our own executing message 2. Create or replace `src/app.mts` with this code. - ```solidity file=/public/tutorials/app.mts#L1-L51 hash=8f6f776884b8e37ae613f7aea8cd6a3b + ```typescript file=/public/tutorials/app.mts#L1-L51 hash=8f6f776884b8e37ae613f7aea8cd6a3b ``` 3. Run the program, see that a greeting from chain A is relayed to chain B. From c56fe2ea298913f188a7d212f6d59019731314b6 Mon Sep 17 00:00:00 2001 From: Ori Pomerantz Date: Fri, 14 Feb 2025 08:07:23 -0600 Subject: [PATCH 4/6] Update message-passing.mdx --- pages/stack/interop/tutorials/message-passing.mdx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pages/stack/interop/tutorials/message-passing.mdx b/pages/stack/interop/tutorials/message-passing.mdx index 6b54bdca0..7e750b00f 100644 --- a/pages/stack/interop/tutorials/message-passing.mdx +++ b/pages/stack/interop/tutorials/message-passing.mdx @@ -562,11 +562,11 @@ In production we will not have this, we need to create our own executing message | Line number | New content | | ----------: | ------------------------------------------------------------------------- | - | 10 | `import { interopAlpha0, interopAlpha1 } from '@eth-optimism/viem/chains'` | - | 24 | ` chain: interopAlpha0,` | - | 32 | ` chain: interopAlpha1,` | - | 40 | ` address: "0x1A183FCf61053B7dcd2322BbE766f7E1946d3718",` | - | 46 | ` address: "0x9De9f84a4EB3616B44CF1d68cD1A9098Df6cB25f",` | + | 9 | `import { interopAlpha0, interopAlpha1 } from '@eth-optimism/viem/chains'` | + | 23 | ` chain: interopAlpha0,` | + | 31 | ` chain: interopAlpha1,` | + | 39 | ` address: "0x1A183FCf61053B7dcd2322BbE766f7E1946d3718",` | + | 45 | ` address: "0x9De9f84a4EB3616B44CF1d68cD1A9098Df6cB25f",` | 2. Set `PRIV_KEY` to the private key of an address that has Sepolia ETH on the two chains. From 1a9c8824554f5d4e4f7da5d10d7e188f342aede6 Mon Sep 17 00:00:00 2001 From: Ori Pomerantz Date: Fri, 14 Feb 2025 08:08:30 -0600 Subject: [PATCH 5/6] Update app_v2.mts --- public/tutorials/app_v2.mts | 1 - 1 file changed, 1 deletion(-) diff --git a/public/tutorials/app_v2.mts b/public/tutorials/app_v2.mts index 3327aa60e..cc42adab7 100644 --- a/public/tutorials/app_v2.mts +++ b/public/tutorials/app_v2.mts @@ -1,7 +1,6 @@ import { createWalletClient, http, - defineChain, publicActions, getContract, Address, From bb9aa215af3857ed5f4213092b441642484e1583 Mon Sep 17 00:00:00 2001 From: Ori Pomerantz Date: Fri, 14 Feb 2025 08:57:05 -0600 Subject: [PATCH 6/6] @krofax comments --- pages/stack/interop/tutorials/message-passing.mdx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/pages/stack/interop/tutorials/message-passing.mdx b/pages/stack/interop/tutorials/message-passing.mdx index 7e750b00f..9ffbdd62e 100644 --- a/pages/stack/interop/tutorials/message-passing.mdx +++ b/pages/stack/interop/tutorials/message-passing.mdx @@ -495,7 +495,7 @@ In production we will not have this, we need to create our own executing message 1. Replace `src/app.mts` with: - ```typescript file=/public/tutorials/app_v2.mts hash=4811b7946a82b2815c103da8a65c1334 + ```typescript file=/public/tutorials/app_v2.mts hash=a7b0f60aa6f1e48fc9994178ed3d5498 ```
@@ -568,12 +568,21 @@ In production we will not have this, we need to create our own executing message | 39 | ` address: "0x1A183FCf61053B7dcd2322BbE766f7E1946d3718",` | | 45 | ` address: "0x9De9f84a4EB3616B44CF1d68cD1A9098Df6cB25f",` | - 2. Set `PRIV_KEY` to the private key of an address that has Sepolia ETH on the two chains. + 2. Set `PRIV_KEY` to the private key of an address that has [Sepolia ETH](https://cloud.google.com/application/web3/faucet/ethereum/sepolia). ```sh export PRIV_KEY=0x ``` + 3. Send ETH to the two L2 blockchains. + + ```sh + cast send --rpc-url https://endpoints.omniatech.io/v1/eth/sepolia/public --private-key $PRIV_KEY --value 0.001ether 0x7385d89d38ab79984e7c84fab9ce5e6f4815468a + cast send --rpc-url https://endpoints.omniatech.io/v1/eth/sepolia/public --private-key $PRIV_KEY --value 0.001ether 0x7385d89d38ab79984e7c84fab9ce5e6f4815468a + ``` + + Wait a few minutes until you can see the ETH [on your explorer](https://sid.testnet.routescan.io/). + 3. Rerun the test. ```sh