diff --git a/pages/stack/interop/tutorials/message-passing.mdx b/pages/stack/interop/tutorials/message-passing.mdx index 007326985..9ffbdd62e 100644 --- a/pages/stack/interop/tutorials/message-passing.mdx +++ b/pages/stack/interop/tutorials/message-passing.mdx @@ -93,19 +93,24 @@ For development purposes, we'll first use autorelay mode to handle message execu ### Setting up test networks + + + 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. ```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 +146,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 +446,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 - ``` + ```typescript 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 +495,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=a7b0f60aa6f1e48fc9994178ed3d5498 + ``` -
- 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,29 +551,38 @@ 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 | + | ----------: | ------------------------------------------------------------------------- | + | 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. + 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 diff --git a/public/tutorials/app_v2.mts b/public/tutorials/app_v2.mts new file mode 100644 index 000000000..cc42adab7 --- /dev/null +++ b/public/tutorials/app_v2.mts @@ -0,0 +1,74 @@ +import { + createWalletClient, + http, + 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}`) +