This article outlines the steps required for the canonical bridge upgrade.
1. Smart Contract
- Discussion Phase:
- Does the design involve only a single chain or both chains?
| // executeAffirmation.js | |
| // | |
| // Relays Ethereum -> Gnosis Chain Omnibridge messages by calling | |
| // executeAffirmation() on the AMB home bridge as a bridge validator. | |
| // | |
| // Direction note: this is the *opposite* of callExecuteSignature.js / | |
| // claimAll.js. Those handle GC -> ETH, where validators sign on GC and anyone | |
| // submits the collected signatures on ETH. Here the user request originates on | |
| // ETH (UserRequestForAffirmation on the foreign AMB) and each validator | |
| // independently confirms it on GC with executeAffirmation(bytes). There is no |
| // Sign Omnibridge (AMB) messages with a validator private key. | |
| // | |
| // Usage: | |
| // node manual_sign_omni.js <private-key> | |
| // | |
| // Reads: omnibridge_tx_to_sign.csv (columns: Tx Hash, Message, Origin) | |
| // Writes: omnibridge_tx_signed.csv (adds a Signature column) | |
| // | |
| // Each Message is a raw hex payload. Bridge validators sign it with the | |
| // EIP-191 personal_sign scheme (\x19Ethereum Signed Message:\n<len> prefix |
| {"token":[{ | |
| "bridge_type": "omni", | |
| "foreign_address": "0x6810e776880C02933D47DB1b9fc05908e5386b96", | |
| "origin_chain_id": "1", | |
| "address": "0x9C58BAcC331c9aa871AFD802DB6379a98e80CEdb", | |
| "decimals": "18", | |
| "symbol": "GNO" | |
| }, | |
| { | |
| "bridge_type": "omni", |
| import { createChainConfig, createChainForkConfig } from "@lodestar/config"; | |
| import { mainnetChainConfig } from "@lodestar/config/networks"; | |
| const _targetSlot = 11698097; // slot after Pectra | |
| const rootPath = ["block_roots"]; | |
| const forkConfig = createChainForkConfig(createChainConfig(mainnetChainConfig)); | |
| const BLOCK_ROOTS_INDEX = forkConfig | |
| .getForkTypes(_targetSlot) |
| import { | |
| createPublicClient, | |
| createWalletClient, | |
| http, | |
| parseAbiItem, | |
| decodeEventLog, | |
| } from "viem"; | |
| import { privateKeyToAccount } from "viem/accounts"; | |
| import { gnosis, mainnet } from "viem/chains"; |
| import { | |
| createClient, | |
| getClient, | |
| convertViemChainToRelayChain, | |
| MAINNET_RELAY_API, | |
| adaptViemWallet, | |
| } from "@reservoir0x/relay-sdk"; | |
| import { createWalletClient, http, parseUnits, publicActions } from "viem"; | |
| import { arbitrum, base } from "viem/chains"; | |
| import { privateKeyToAccount } from "viem/accounts"; |
| import { http, createWalletClient, parseAbiItem, publicActions } from "viem"; | |
| import { gnosis, sepolia } from "viem/chains"; | |
| import { privateKeyToAccount } from "viem/accounts"; | |
| const main = async () => { | |
| console.log("Start event listener"); | |
| // Configuration | |
| const sourceChain = sepolia; | |
| const destinationChain = gnosis; |
| import { http, createWalletClient, parseAbiItem, publicActions } from "viem"; | |
| import { gnosisChiado, sepolia } from "viem/chains"; | |
| import { privateKeyToAccount } from "viem/accounts"; | |
| const main = async () => { | |
| console.log("Start event listener"); | |
| // Configuration | |
| const sourceChain = sepolia; | |
| const destinationChain = gnosisChiado; |
| require("log-timestamp"); | |
| import { HyperClient, MessageStatusWithMeta } from "@polytope-labs/hyperclient"; | |
| import { config } from "dotenv"; | |
| import { | |
| createPublicClient, | |
| createWalletClient, | |
| decodeFunctionData, | |
| getContract, | |
| http, |