├── .changeset ├── README.md └── config.json ├── .circleci └── config.yml ├── .dockerignore ├── .github └── CODEOWNERS ├── .gitignore ├── .gitmodules ├── .nvmrc ├── .prettierignore ├── .prettierrc.js ├── .vscode ├── extensions.json └── settings.json ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── README.md ├── apps ├── autorelayer-interop │ ├── CHANGELOG.md │ ├── README.md │ ├── eslint.config.js │ ├── package.json │ ├── src │ │ ├── app.ts │ │ ├── index.ts │ │ ├── relayer.ts │ │ └── utils │ │ │ └── jsonFetchParams.ts │ └── tsconfig.json ├── ponder-interop │ ├── .npmignore │ ├── CHANGELOG.md │ ├── README.md │ ├── docker-compose.yml │ ├── eslint.config.js │ ├── package.json │ ├── ponder-env.d.ts │ ├── ponder.config.alphanet.ts │ ├── ponder.config.devnet.ts │ ├── ponder.config.supersim.ts │ ├── ponder.config.ts │ ├── ponder.schema.ts │ ├── setup-local-db.sql │ ├── src │ │ ├── api │ │ │ └── index.ts │ │ ├── createPonderConfig.ts │ │ ├── index.ts │ │ └── utils │ │ │ └── hashMessageIdentifier.ts │ └── tsconfig.json ├── sponsored-sender │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── src │ │ ├── api.ts │ │ ├── app.ts │ │ ├── index.ts │ │ ├── jsonrpc │ │ │ ├── handler.ts │ │ │ ├── types.ts │ │ │ └── utils.ts │ │ └── sender │ │ │ └── senderJsonRpcHandler.ts │ └── tsconfig.json └── superchain-playground │ ├── CHANGELOG.md │ ├── README.md │ ├── components.json │ ├── eslint.config.js │ ├── index.html │ ├── package.json │ ├── postcss.config.js │ ├── public │ └── favicon.svg │ ├── src │ ├── App.tsx │ ├── AppRouter.tsx │ ├── Providers.tsx │ ├── components │ │ ├── BridgeCard.tsx │ │ ├── ConnectWalletButton.tsx │ │ ├── ConstructionAlert.tsx │ │ ├── DecodedMessageData.tsx │ │ ├── L2ChainPicker.tsx │ │ ├── NavBar.tsx │ │ ├── NetworkPicker.tsx │ │ ├── RemainingTimeDisplay.tsx │ │ ├── SelectNetwork.tsx │ │ ├── SideNav.tsx │ │ ├── SupportedNetworks.tsx │ │ ├── WalletAddressInput.tsx │ │ └── ui │ │ │ ├── accordion.tsx │ │ │ ├── alert.tsx │ │ │ ├── avatar.tsx │ │ │ ├── badge.tsx │ │ │ ├── button.tsx │ │ │ ├── calendar.tsx │ │ │ ├── card.tsx │ │ │ ├── checkbox.tsx │ │ │ ├── chip.tsx │ │ │ ├── collapsible.tsx │ │ │ ├── command.tsx │ │ │ ├── dialog.tsx │ │ │ ├── dropdown-menu.tsx │ │ │ ├── input.tsx │ │ │ ├── label.tsx │ │ │ ├── popover.tsx │ │ │ ├── radio-group.tsx │ │ │ ├── scroll-area.tsx │ │ │ ├── select.tsx │ │ │ ├── separator.tsx │ │ │ ├── sheet.tsx │ │ │ ├── sidebar.tsx │ │ │ ├── skeleton.tsx │ │ │ ├── switch.tsx │ │ │ ├── table.tsx │ │ │ ├── tabs.tsx │ │ │ ├── toast.tsx │ │ │ ├── toaster.tsx │ │ │ ├── tooltip.tsx │ │ │ └── use-toast.ts │ ├── connectors │ │ └── devAccount.ts │ ├── constants │ │ ├── L1CrossDomainMessengerAbi.ts │ │ ├── l1StandardBridgeAbi.ts │ │ ├── multicall3Abi.ts │ │ ├── predeployByContractAddress.ts │ │ └── superchainTokenBridgeAbi.ts │ ├── envVars.ts │ ├── hooks │ │ ├── use-mobile.tsx │ │ ├── use-toast.ts │ │ ├── useBuildProveWithdrawal.ts │ │ ├── useGetL2Output.ts │ │ ├── useGetTimeToFinalize.ts │ │ ├── useGetTimeToProve.ts │ │ ├── useGetWithdrawalStatus.ts │ │ ├── useInvalidateGetWithdrawalStatus.ts │ │ ├── useTokenInfo.ts │ │ └── useWithdrawalMessage.ts │ ├── index.css │ ├── layouts │ │ └── NavBarLayout.tsx │ ├── lib │ │ ├── encodeL2ToL2CrossDomainSentMessageEvent.ts │ │ ├── getL2ToL2CrossDomainMessageHash.ts │ │ ├── truncateHash.ts │ │ ├── utils.ts │ │ └── wagmi.ts │ ├── main.tsx │ ├── pages │ │ ├── BridgePage.tsx │ │ ├── ChainsPage.tsx │ │ ├── ConfigPage.tsx │ │ ├── L2ToL1RelayerPage.tsx │ │ ├── MainPage.tsx │ │ ├── SuperchainETHBridgePage.tsx │ │ ├── SuperchainMessageRelayer.tsx │ │ └── SuperchainTokenBridgePage.tsx │ ├── stores │ │ ├── useConfig.ts │ │ ├── useRecentAddressStore.ts │ │ └── useTransactionStore.ts │ ├── types │ │ └── L2ToL2CrossDomainMessage.ts │ ├── utils │ │ ├── formatDuration.ts │ │ └── truncateDecimal.ts │ ├── vite-env.d.ts │ └── withdrawal-status │ │ ├── Finalized.tsx │ │ ├── ReadyToFinalize.tsx │ │ ├── ReadyToProve.tsx │ │ ├── WaitingToFinalize.tsx │ │ └── WaitingToProve.tsx │ ├── tailwind.config.js │ ├── tsconfig.json │ └── vite.config.ts ├── eslint.config.js ├── lib └── .gitignore ├── mise.toml ├── nx.json ├── package.json ├── packages ├── supersim │ ├── .gitignore │ ├── CHANGELOG.md │ ├── README.md │ ├── eslint.config.js │ ├── install.js │ └── package.json ├── utils-app │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── src │ │ ├── App.ts │ │ └── middleware.ts │ └── tsconfig.json ├── viem │ ├── .gitignore │ ├── CHANGELOG.md │ ├── README.md │ ├── docs │ │ ├── README.md │ │ ├── actions │ │ │ └── interop │ │ │ │ ├── README.md │ │ │ │ ├── functions │ │ │ │ ├── buildExecutingMessage.md │ │ │ │ ├── estimateRelayCrossDomainMessageGas.md │ │ │ │ ├── estimateSendCrossDomainMessageGas.md │ │ │ │ ├── estimateSendETHGas.md │ │ │ │ ├── estimateSendSuperchainERC20Gas.md │ │ │ │ ├── getCrossDomainMessageStatus.md │ │ │ │ ├── getCrossDomainMessages.md │ │ │ │ ├── relayCrossDomainMessage.md │ │ │ │ ├── sendCrossDomainMessage.md │ │ │ │ ├── sendETH.md │ │ │ │ ├── sendSuperchainERC20.md │ │ │ │ ├── simulateRelayCrossDomainMessage.md │ │ │ │ ├── simulateSendCrossDomainMessage.md │ │ │ │ ├── simulateSendETH.md │ │ │ │ └── simulateSendSuperchainERC20.md │ │ │ │ └── type-aliases │ │ │ │ ├── BuildExecutingMessageParameters.md │ │ │ │ ├── BuildExecutingMessageReturnType.md │ │ │ │ ├── GetCrossDomainMessageStatusParameters.md │ │ │ │ ├── GetCrossDomainMessageStatusReturnType.md │ │ │ │ ├── GetCrossDomainMessagesParameters.md │ │ │ │ ├── GetCrossDomainMessagesReturnType.md │ │ │ │ ├── RelayCrossDomainMessageContractReturnType.md │ │ │ │ ├── RelayCrossDomainMessageErrorType.md │ │ │ │ ├── RelayCrossDomainMessageParameters.md │ │ │ │ ├── RelayCrossDomainMessageReturnType.md │ │ │ │ ├── SendCrossDomainMessageContractReturnType.md │ │ │ │ ├── SendCrossDomainMessageErrorType.md │ │ │ │ ├── SendCrossDomainMessageParameters.md │ │ │ │ ├── SendCrossDomainMessageReturnType.md │ │ │ │ ├── SendETHContractReturnType.md │ │ │ │ ├── SendETHErrorType.md │ │ │ │ ├── SendETHParameters.md │ │ │ │ ├── SendSuperchainERC20ContractReturnType.md │ │ │ │ ├── SendSuperchainERC20ErrorType.md │ │ │ │ ├── SendSuperchainERC20Parameters.md │ │ │ │ └── SendSuperchainERC20ReturnType.md │ │ ├── chains │ │ │ ├── README.md │ │ │ └── variables │ │ │ │ ├── arenaZ.md │ │ │ │ ├── arenaZSepolia.md │ │ │ │ ├── automata.md │ │ │ │ ├── base.md │ │ │ │ ├── baseSepolia.md │ │ │ │ ├── cyber.md │ │ │ │ ├── cyberSepolia.md │ │ │ │ ├── ethernity.md │ │ │ │ ├── ethernitySepolia.md │ │ │ │ ├── funki.md │ │ │ │ ├── funkiSepolia.md │ │ │ │ ├── ink.md │ │ │ │ ├── inkSepolia.md │ │ │ │ ├── interopAlpha0.md │ │ │ │ ├── interopAlpha1.md │ │ │ │ ├── interopAlphaChains.md │ │ │ │ ├── interopRcAlpha0.md │ │ │ │ ├── interopRcAlpha1.md │ │ │ │ ├── interopRcAlphaChains.md │ │ │ │ ├── lisk.md │ │ │ │ ├── liskSepolia.md │ │ │ │ ├── lyra.md │ │ │ │ ├── mainnetChains.md │ │ │ │ ├── metal.md │ │ │ │ ├── metalSepolia.md │ │ │ │ ├── minatoSepolia.md │ │ │ │ ├── mode.md │ │ │ │ ├── modeSepolia.md │ │ │ │ ├── op.md │ │ │ │ ├── opSepolia.md │ │ │ │ ├── orderly.md │ │ │ │ ├── race.md │ │ │ │ ├── raceSepolia.md │ │ │ │ ├── redstone.md │ │ │ │ ├── sepoliaChains.md │ │ │ │ ├── shape.md │ │ │ │ ├── shapeSepolia.md │ │ │ │ ├── sseed.md │ │ │ │ ├── supersimChains.md │ │ │ │ ├── supersimL1.md │ │ │ │ ├── supersimL2A.md │ │ │ │ ├── supersimL2B.md │ │ │ │ ├── supersimL2C.md │ │ │ │ ├── supersimL2D.md │ │ │ │ ├── supersimL2E.md │ │ │ │ ├── swan.md │ │ │ │ ├── swell.md │ │ │ │ ├── tbn.md │ │ │ │ ├── tbnSepolia.md │ │ │ │ ├── unichainSepolia.md │ │ │ │ ├── worldchain.md │ │ │ │ ├── worldchainSepolia.md │ │ │ │ ├── zora.md │ │ │ │ └── zoraSepolia.md │ │ └── index │ │ │ ├── README.md │ │ │ ├── type-aliases │ │ │ └── MessageIdentifier.md │ │ │ └── variables │ │ │ ├── contracts.md │ │ │ ├── crossDomainMessengerAbi.md │ │ │ ├── crossL2InboxAbi.md │ │ │ ├── l2ToL2CrossDomainMessengerAbi.md │ │ │ ├── optimismMintableERC20Abi.md │ │ │ ├── optimismMintableERC20FactoryAbi.md │ │ │ ├── standardBridgeAbi.md │ │ │ ├── superchainERC20Abi.md │ │ │ ├── superchainETHBridgeAbi.md │ │ │ └── superchainTokenBridgeAbi.md │ ├── eslint.config.js │ ├── package.json │ ├── scripts │ │ ├── abidocgen.ts │ │ ├── abigen.ts │ │ ├── chaingen.ts │ │ └── templates │ │ │ ├── abis.eta │ │ │ └── chains.eta │ ├── src │ │ ├── abis.ts │ │ ├── actions │ │ │ ├── depositCrossDomainMessage.spec.ts │ │ │ ├── depositCrossDomainMessage.ts │ │ │ ├── depositERC20.spec.ts │ │ │ ├── depositERC20.ts │ │ │ ├── index.ts │ │ │ ├── interop │ │ │ │ ├── buildExecutingMessage.ts │ │ │ │ ├── getCrossDomainMessageStatus.ts │ │ │ │ ├── getCrossDomainMessages.ts │ │ │ │ ├── index.ts │ │ │ │ ├── relayCrossDomainMessage.spec.ts │ │ │ │ ├── relayCrossDomainMessage.ts │ │ │ │ ├── sendCrossDomainMessage.spec.ts │ │ │ │ ├── sendCrossDomainMessage.ts │ │ │ │ ├── sendETH.spec.ts │ │ │ │ ├── sendETH.ts │ │ │ │ ├── sendSuperchainERC20.spec.ts │ │ │ │ └── sendSuperchainERC20.ts │ │ │ ├── withdrawCrossDomainMessage.spec.ts │ │ │ ├── withdrawCrossDomainMessage.ts │ │ │ ├── withdrawOptimismERC20.spec.ts │ │ │ └── withdrawOptimismERC20.ts │ │ ├── addressSet.ts │ │ ├── chains │ │ │ ├── chains.ts │ │ │ ├── index.ts │ │ │ ├── interopAlpha.ts │ │ │ ├── interopAlphaAddresses.ts │ │ │ ├── interopRcAlpha.ts │ │ │ ├── interopRcAlphaAddresses.ts │ │ │ ├── mainnet.ts │ │ │ ├── networks.ts │ │ │ ├── sepolia.ts │ │ │ ├── supersim.ts │ │ │ ├── supersimAddresses.ts │ │ │ └── types.ts │ │ ├── contracts.ts │ │ ├── core │ │ │ └── baseWriteAction.ts │ │ ├── decorators │ │ │ ├── publicL2.ts │ │ │ └── walletL2.ts │ │ ├── index.ts │ │ ├── test │ │ │ ├── clients.ts │ │ │ ├── globalSetup.ts │ │ │ ├── setupTicTacToe.ts │ │ │ ├── startSupersim.ts │ │ │ ├── supERC20.ts │ │ │ └── testConstants.ts │ │ ├── types │ │ │ ├── interop │ │ │ │ ├── cdm.ts │ │ │ │ ├── executingMessage.ts │ │ │ │ └── index.ts │ │ │ └── utils.ts │ │ └── utils │ │ │ └── interop │ │ │ ├── encodeAccessList.spec.ts │ │ │ ├── encodeAccessList.ts │ │ │ ├── encodeMessagePayload.ts │ │ │ ├── extractSentMessageLogs.ts │ │ │ ├── hashCrossDomainMessage.ts │ │ │ └── index.ts │ ├── tsconfig.json │ ├── typedoc.json │ └── vitest.config.ts └── wagmi │ ├── .gitignore │ ├── CHANGELOG.md │ ├── README.md │ ├── docs │ ├── useRelayL2ToL2Message.md │ └── useSendL2ToL2Message.md │ ├── eslint.config.js │ ├── package.json │ ├── src │ ├── hooks │ │ ├── useCrossChainSendETH.ts │ │ ├── useRelayL2ToL2Message.ts │ │ ├── useSendL2ToL2Message.ts │ │ └── useSendSuperchainERC20.ts │ └── index.ts │ └── tsconfig.json ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── scripts └── update-supersim-version.ts └── tsconfig.base.json /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json", 3 | "changelog": [ 4 | "@changesets/changelog-github", 5 | { 6 | "repo": "ethereum-optimism/ecosystem" 7 | } 8 | ], 9 | "commit": false, 10 | "fixed": [], 11 | "linked": [], 12 | "access": "public", 13 | "baseBranch": "main", 14 | "updateInternalDependencies": "patch", 15 | "privatePackages": { 16 | "version": true, 17 | "tag": true 18 | }, 19 | "ignore": [], 20 | "___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": { 21 | "onlyUpdatePeerDependentsWhenOutOfRange": true 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | node_modules 3 | /.pnp 4 | packages/*/.env 5 | app/*/.env 6 | .npmrc 7 | 8 | # testing 9 | /coverage 10 | 11 | # build artifacts 12 | **/build/ 13 | **/dist/ 14 | **/tsconfig.tsbuildinfo 15 | .nx 16 | 17 | # misc 18 | .DS_Store 19 | .env 20 | .env.local 21 | .env.development.local 22 | .env.test.local 23 | .env.production.local 24 | 25 | npm-debug.log* 26 | 27 | # ponder 28 | **/.ponder 29 | **/generated 30 | 31 | # cert files 32 | *.crt 33 | *.pem 34 | *.key -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Default owners 2 | * @ethereum-optimism/ecosystem 3 | 4 | /docs @ethereum-optimism/ecosystem @zainbacchus 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | **/node_modules 3 | /.pnp 4 | packages/*/.env 5 | app/*/.env 6 | .npmrc 7 | 8 | # testing 9 | /coverage 10 | 11 | # build artifacts 12 | **/build/ 13 | **/dist/ 14 | **/tsconfig.tsbuildinfo 15 | .nx 16 | 17 | # misc 18 | .DS_Store 19 | .env 20 | .env.local 21 | .env.development.local 22 | .env.test.local 23 | .env.production.local 24 | 25 | npm-debug.log* 26 | 27 | # ponder 28 | **/.ponder 29 | **/generated 30 | 31 | # cert files 32 | *.crt 33 | *.pem 34 | *.key -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/superchain-registry"] 2 | path = lib/superchain-registry 3 | url = https://github.com/ethereum-optimism/superchain-registry 4 | [submodule "lib/optimism"] 5 | path = lib/optimism 6 | url = https://github.com/ethereum-optimism/optimism 7 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 18.18.1 -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | **/build/ 2 | **/dist/ 3 | **/types/ 4 | **/node_modules/ 5 | **/ponder-env.d.ts 6 | 7 | 8 | /.nx/cache -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | tabWidth: 2, 3 | useTabs: false, 4 | trailingComma: 'all', 5 | semi: false, 6 | singleQuote: true, 7 | arrowParens: 'always', 8 | } 9 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations. 3 | // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp 4 | 5 | // List of extensions which should be recommended for users of this workspace. 6 | "recommendations": [ 7 | "ms-azuretools.vscode-docker", 8 | "dbaeumer.vscode-eslint", 9 | "esbenp.prettier-vscode", 10 | "JuanBlanco.solidity" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "npm.packageManager": "pnpm", 3 | "typescript.updateImportsOnFileMove.enabled": "always", 4 | "javascript.updateImportsOnFileMove.enabled": "always", 5 | "editor.formatOnSaveMode": "file", 6 | "editor.tabCompletion": "on", 7 | "editor.tabSize": 2, 8 | "editor.formatOnSave": true, 9 | "editor.inlineSuggest.enabled": true, 10 | "editor.codeActionsOnSave": { 11 | "source.fixAll": "explicit" 12 | }, 13 | "files.eol": "\n", 14 | "eslint.lintTask.enable": true, 15 | "eslint.enable": true, 16 | "eslint.debug": true, 17 | "[typescript]": { 18 | "editor.defaultFormatter": "esbenp.prettier-vscode" 19 | }, 20 | "eslint.nodePath": "./node_modules/eslint/bin/", 21 | "eslint.format.enable": true, 22 | "eslint.workingDirectories": [{ "mode": "auto" }], 23 | "editorconfig.generateAuto": false, 24 | "files.trimTrailingWhitespace": true 25 | } 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | (The MIT License) 2 | 3 | Copyright 2020-2024 Optimism 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /apps/autorelayer-interop/README.md: -------------------------------------------------------------------------------- 1 | # AutoRelayer 2 | 3 | A simple autorelayer to use between interoperable networks. This relies on a stateful api to return a list of pending messages between the set of interoperable chains. The [ponder-interop](../ponder-interop/README.md) app implements the expected API service, indexing all interopable messages from the [L2ToL2CrossDomainMessenger](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/L2ToL2CrossDomainMessenger.sol). 4 | 5 | ## Configuration 6 | 7 | Configured entirely with environment variables 8 | 9 | ``` 10 | AUTORELAYER_LOOP_INTERVAL_MS= // default 6s 11 | AUTORELAYER_PONDER_API_URL= // default http://localhost:42069 12 | ``` 13 | 14 | There's two methods of tx submission, local & sponsored endpoint. Only one can be used 15 | 16 | - Local: Set a private key for tx submission 17 | - Sponsored Endpoint: Single url tx sponsored endpoint. See the [README](../sponsored-sender/README.md) for local implementation of this. 18 | 19 | ``` 20 | AUTORELAYER_PRIVATE_KEY=0x 21 | AUTORELAYER_SPONSORED_ENDPOINT= 22 | ``` 23 | -------------------------------------------------------------------------------- /apps/autorelayer-interop/eslint.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'eslint/config'; 2 | 3 | import rootConfig from '../../eslint.config.js'; 4 | 5 | // Create a new configuration that extends the root configuration 6 | export default defineConfig([{ 7 | ...rootConfig, 8 | rules: { 9 | ...rootConfig.rules, 10 | '@typescript-eslint/no-unused-vars': [ 11 | 'error', 12 | { varsIgnorePattern: '_', argsIgnorePattern: '_' }, 13 | ], 14 | }, 15 | }]); 16 | -------------------------------------------------------------------------------- /apps/autorelayer-interop/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@eth-optimism/autorelayer-interop", 3 | "repository": { 4 | "type": "git", 5 | "url": "https://github.com/ethereum-optimism/ecosystem.git", 6 | "directory": "apps/autorelayer-interop" 7 | }, 8 | "homepage": "https://github.com/ethereum-optimism/ecosystem/tree/main/apps/autorelayer-interop#readme", 9 | "bugs": { 10 | "url": "https://github.com/ethereum-optimism/ecosystem/issues" 11 | }, 12 | "version": "0.0.14", 13 | "type": "module", 14 | "files": [ 15 | "dist" 16 | ], 17 | "main": "./dist/app.js", 18 | "types": "./dist/app.d.ts", 19 | "exports": { 20 | ".": { 21 | "types": "./dist/app.d.ts", 22 | "import": "./dist/app.js" 23 | } 24 | }, 25 | "scripts": { 26 | "build": "pnpm clean && tsc && resolve-tspaths", 27 | "clean": "rm -rf dist tsconfig.tsbuildinfo", 28 | "lint": "eslint \"**/*.{ts,tsx}\" && pnpm prettier --check \"**/*.{ts,tsx}\" --ignore-path \"../../.prettierignore\"", 29 | "lint:fix": "eslint \"**/*.{ts,tsx}\" --fix && pnpm prettier \"**/*.{ts,tsx}\" --write --loglevel=warn --ignore-path \"../../.prettierignore\"", 30 | "dev": "tsx src/index.ts", 31 | "start": "node dist/index.js", 32 | "typecheck": "tsc" 33 | }, 34 | "dependencies": { 35 | "commander": "^13.1.0", 36 | "viem": "2.17.9", 37 | "@eth-optimism/utils-app": "workspace:*", 38 | "@eth-optimism/viem": "workspace:*" 39 | }, 40 | "peerDependencies": { 41 | "pino": "^9.6.0", 42 | "pino-pretty": "^13.0.0" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /apps/autorelayer-interop/src/index.ts: -------------------------------------------------------------------------------- 1 | import { RelayerApp } from '@/app.js' 2 | 3 | await new RelayerApp().run() 4 | -------------------------------------------------------------------------------- /apps/autorelayer-interop/src/utils/jsonFetchParams.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fetch params for JSON requests. 3 | */ 4 | export const jsonFetchParams = { 5 | method: 'GET', 6 | headers: { 'Content-Type': 'application/json' }, 7 | } as const 8 | -------------------------------------------------------------------------------- /apps/autorelayer-interop/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "include": ["src"], 4 | "compilerOptions": { 5 | "rootDir": "src", 6 | "baseUrl": ".", 7 | "paths": { 8 | "@/*": ["./src/*"] 9 | }, 10 | "target": "es2021", 11 | "lib": ["esnext"], 12 | "strict": true, 13 | "composite": true, 14 | "outDir": "dist", 15 | "moduleResolution": "NodeNext", 16 | "module": "NodeNext", 17 | "sourceMap": true, 18 | "declaration": true, 19 | "declarationMap": true, 20 | "emitDeclarationOnly": false, 21 | "noEmit": false 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /apps/ponder-interop/.npmignore: -------------------------------------------------------------------------------- 1 | # Ignore everything 2 | * 3 | 4 | # ponder.schema.js is the only file we want to include in the npm package 5 | !dist/ponder.schema.js 6 | !dist/ponder.schema.d.ts -------------------------------------------------------------------------------- /apps/ponder-interop/README.md: -------------------------------------------------------------------------------- 1 | # Ponder Interop 2 | 3 | A [Ponder](https://ponder.sh) indexer for op-stack interop contracts. Exposes a http api, leveraged in services such as the [autorelayer](../autorelayer-interop/README.md). 4 | 5 | See ponder [documentation](https://ponder.sh/docs/getting-started/new-project) on how ponder works. 6 | 7 | ## Configuration 8 | 9 | Ponder configuration is available in 3 settings. 10 | 11 | 1. `pnpm dev:alphanet`. Spins up a dev instance indexing the interop alpha networks 12 | 2. `pnpm dev:devnet`. Spins up a dev instances indexing the interop devnet networks. 13 | 3. `pnpm dev:supersim`. Spins up a dev instances indexing 2 local supersim instances. Chains 901 & 902 14 | 4. `pnpm dev`. Spins up a dev instance bootstrapped from chains specified from env, `PONDER_INTEROP_ENDPOINT_=` 15 | -------------------------------------------------------------------------------- /apps/ponder-interop/docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | postgres: 3 | profiles: 4 | - dependencies 5 | image: postgres:latest 6 | environment: 7 | - POSTGRES_HOST_AUTH_METHOD=trust 8 | healthcheck: 9 | test: 10 | [ 11 | 'CMD-SHELL', 12 | 'pg_isready -q -U local-db-user -d ponder-interop', 13 | ] 14 | interval: 5s 15 | timeout: 10s 16 | retries: 3 17 | start_period: 2s 18 | ports: 19 | - 5432:5432 20 | volumes: 21 | - ./setup-local-db.sql:/docker-entrypoint-initdb.d/setup-local-db.sql 22 | 23 | ponder-interop: 24 | profiles: 25 | - app 26 | build: 27 | context: ../../ 28 | dockerfile: Dockerfile 29 | target: ponder-interop 30 | args: 31 | - DOCKER_TARGET=ponder-interop 32 | env_file: .env 33 | environment: 34 | - DATABASE_URL=postgresql://local-db-user:@postgres:5432/ponder-interop 35 | volumes: 36 | - ../../certs/extra-ca-certificates.crt:/usr/local/share/ca-certificates/extra-ca-certificates.crt 37 | healthcheck: 38 | test: wget localhost:42069/health -q -O - > /dev/null 2>&1 39 | ports: 40 | - 42069:42069 41 | depends_on: 42 | postgres: 43 | condition: service_healthy 44 | 45 | volumes: 46 | db: 47 | -------------------------------------------------------------------------------- /apps/ponder-interop/eslint.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'eslint/config'; 2 | 3 | import rootConfig from '../../eslint.config.js'; 4 | 5 | // Create a new configuration that extends the root configuration 6 | export default defineConfig([{ 7 | ...rootConfig, 8 | ignores: [...rootConfig.ignores, 'ponder-env.d.ts'], 9 | }]); -------------------------------------------------------------------------------- /apps/ponder-interop/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@eth-optimism/ponder-interop", 3 | "repository": { 4 | "type": "git", 5 | "url": "https://github.com/ethereum-optimism/ecosystem.git", 6 | "directory": "apps/ponder-interop" 7 | }, 8 | "homepage": "https://github.com/ethereum-optimism/ecosystem/tree/main/apps/ponder-interop#readme", 9 | "bugs": { 10 | "url": "https://github.com/ethereum-optimism/ecosystem/issues" 11 | }, 12 | "version": "0.0.12", 13 | "type": "module", 14 | "main": "./dist/ponder.schema.js", 15 | "types": "./dist/ponder.schema.d.ts", 16 | "exports": { 17 | ".": { 18 | "types": "./dist/ponder.schema.d.ts", 19 | "import": "./dist/ponder.schema.js" 20 | } 21 | }, 22 | "scripts": { 23 | "build": "tsc && resolve-tspaths", 24 | "clean": "rm -rf dist", 25 | "dev": "ponder dev", 26 | "dev:devnet": "pnpm dev --config ponder.config.devnet.ts", 27 | "dev:alphanet": "pnpm dev --config ponder.config.alphanet.ts", 28 | "dev:supersim": "pnpm dev --config ponder.config.supersim.ts", 29 | "docker:services:up": "docker compose --profile dependencies up -d", 30 | "docker:up": "docker compose --profile dependencies --profile app up -d", 31 | "docker:down": "docker compose down", 32 | "start": "ponder start", 33 | "start:devnet": "ponder start --config ponder.config.devnet.ts", 34 | "start:alphanet": "ponder start --config ponder.config.alphanet.ts", 35 | "db": "ponder db", 36 | "codegen": "ponder codegen", 37 | "lint": "eslint \"**/*.{ts,tsx}\" && pnpm prettier --check \"**/*.{ts,tsx}\" --ignore-path \"../../.prettierignore\"", 38 | "lint:fix": "eslint \"**/*.{ts,tsx}\" --fix && pnpm prettier \"**/*.{ts,tsx}\" --write --loglevel=warn --ignore-path \"../../.prettierignore\"", 39 | "typecheck": "tsc --noEmit --emitDeclarationOnly false" 40 | }, 41 | "dependencies": { 42 | "@eth-optimism/viem": "workspace:*", 43 | "drizzle-orm": "0.39.3", 44 | "hono": "^4.5.0", 45 | "ponder": "^0.10.6", 46 | "viem": "^2.17.9", 47 | "zod": "^3.24.2", 48 | "zod-validation-error": "^3.4.0" 49 | } 50 | } -------------------------------------------------------------------------------- /apps/ponder-interop/ponder-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module "ponder:internal" { 4 | const config: typeof import("./ponder.config.ts"); 5 | const schema: typeof import("./ponder.schema.ts"); 6 | } 7 | 8 | declare module "ponder:schema" { 9 | export * from "./ponder.schema.ts"; 10 | } 11 | 12 | // This file enables type checking and editor autocomplete for this Ponder project. 13 | // After upgrading, you may find that changes have been made to this file. 14 | // If this happens, please commit the changes. Do not manually edit this file. 15 | // See https://ponder.sh/docs/getting-started/installation#typescript for more information. 16 | -------------------------------------------------------------------------------- /apps/ponder-interop/ponder.config.alphanet.ts: -------------------------------------------------------------------------------- 1 | import { interopRcAlpha0, interopRcAlpha1 } from '@eth-optimism/viem/chains' 2 | import { http } from 'viem' 3 | 4 | import type { Endpoints } from '@/createPonderConfig.js' 5 | import { createPonderConfig } from '@/createPonderConfig.js' 6 | 7 | const endpoints: Endpoints = { 8 | interopRcAlpha0: { 9 | chainId: interopRcAlpha0.id, 10 | transport: http(interopRcAlpha0.rpcUrls.default.http[0]), 11 | }, 12 | interopRcAlpha1: { 13 | chainId: interopRcAlpha1.id, 14 | transport: http(interopRcAlpha1.rpcUrls.default.http[0]), 15 | }, 16 | } 17 | 18 | export default createPonderConfig(endpoints) 19 | -------------------------------------------------------------------------------- /apps/ponder-interop/ponder.config.devnet.ts: -------------------------------------------------------------------------------- 1 | import { interopAlpha0, interopAlpha1 } from '@eth-optimism/viem/chains' 2 | import { http } from 'viem' 3 | 4 | import type { Endpoints } from '@/createPonderConfig.js' 5 | import { createPonderConfig } from '@/createPonderConfig.js' 6 | 7 | const endpoints: Endpoints = { 8 | interopAlpha0: { 9 | chainId: interopAlpha0.id, 10 | transport: http(interopAlpha0.rpcUrls.default.http[0]), 11 | }, 12 | interopAlpha1: { 13 | chainId: interopAlpha1.id, 14 | transport: http(interopAlpha1.rpcUrls.default.http[0]), 15 | }, 16 | } 17 | 18 | export default createPonderConfig(endpoints) 19 | -------------------------------------------------------------------------------- /apps/ponder-interop/ponder.config.supersim.ts: -------------------------------------------------------------------------------- 1 | import { supersimL2A, supersimL2B } from '@eth-optimism/viem/chains' 2 | import { http } from 'viem' 3 | 4 | import type { Endpoints } from '@/createPonderConfig.js' 5 | import { createPonderConfig } from '@/createPonderConfig.js' 6 | 7 | const endpoints: Endpoints = { 8 | supersimL2A: { 9 | chainId: supersimL2A.id, 10 | transport: http(supersimL2A.rpcUrls.default.http[0]), 11 | disableCache: true, 12 | }, 13 | supersimL2B: { 14 | chainId: supersimL2B.id, 15 | transport: http(supersimL2B.rpcUrls.default.http[0]), 16 | disableCache: true, 17 | }, 18 | } 19 | 20 | export default createPonderConfig(endpoints) 21 | -------------------------------------------------------------------------------- /apps/ponder-interop/ponder.config.ts: -------------------------------------------------------------------------------- 1 | import type { Transport } from 'viem' 2 | import { http } from 'viem' 3 | import { z } from 'zod' 4 | 5 | import { createPonderConfig } from '@/createPonderConfig.js' 6 | 7 | // Parse Endpoints from Environment 8 | const endpoints: Record = {} 9 | for (const [key, value] of Object.entries(process.env)) { 10 | if (!key.startsWith('PONDER_INTEROP_ENDPOINT_') || value === undefined) { 11 | continue 12 | } 13 | 14 | const chainIdStr = key.replace('PONDER_INTEROP_ENDPOINT_', '') 15 | const chainIdSchema = z.string().regex(/^\d+$/) 16 | const chainIdResult = chainIdSchema.safeParse(chainIdStr) 17 | if (!chainIdResult.success) { 18 | throw new Error( 19 | `invalid chain id for ${key}. Use format PONDER_INTEROP_ENDPOINT_=: ${chainIdStr}`, 20 | ) 21 | } 22 | 23 | const urlSchema = z.string().url() 24 | const result = urlSchema.safeParse(value) 25 | if (!result.success) { 26 | throw new Error(`invalid endpoint url for ${key}: ${value}`) 27 | } 28 | 29 | endpoints[chainIdStr] = { 30 | chainId: parseInt(chainIdStr), 31 | transport: http(value), 32 | } 33 | } 34 | 35 | if (Object.keys(endpoints).length === 0) { 36 | throw new Error( 37 | 'No endpoints in environment found. Please set `PONDER_INTEROP_ENDPOINT_=` urls for each chain to index.', 38 | ) 39 | } 40 | 41 | export default createPonderConfig(endpoints) 42 | -------------------------------------------------------------------------------- /apps/ponder-interop/ponder.schema.ts: -------------------------------------------------------------------------------- 1 | // Hack to resolve https://github.com/ponder-sh/ponder/issues/1722 2 | import 'drizzle-orm/pg-core' 3 | 4 | import { index, onchainTable } from 'ponder' 5 | 6 | export const sentMessages = onchainTable( 7 | 'l2_to_l2_cdm_sent_messages', 8 | (t) => ({ 9 | // unique identifier 10 | messageIdentifierHash: t.hex().primaryKey(), 11 | 12 | // parsed message fields 13 | messageHash: t.hex().notNull(), 14 | source: t.bigint().notNull(), 15 | destination: t.bigint().notNull(), 16 | nonce: t.bigint().notNull(), 17 | sender: t.hex().notNull(), 18 | target: t.hex().notNull(), 19 | message: t.hex().notNull(), 20 | 21 | // log fields 22 | logIndex: t.bigint().notNull(), 23 | logPayload: t.hex().notNull(), 24 | 25 | // general fields 26 | timestamp: t.bigint().notNull(), 27 | blockNumber: t.bigint().notNull(), 28 | transactionHash: t.hex().notNull(), 29 | txOrigin: t.hex().notNull(), 30 | }), 31 | (table) => ({ 32 | messageHashIdx: index().on(table.messageHash), 33 | }), 34 | ) 35 | 36 | export const relayedMessages = onchainTable( 37 | 'l2_to_l2_cdm_relayed_messages', 38 | (t) => ({ 39 | // unique identifier 40 | messageHash: t.hex().primaryKey(), 41 | 42 | // Some unique metadata on the relaying side 43 | relayer: t.hex().notNull(), 44 | 45 | // log fields 46 | logIndex: t.bigint().notNull(), 47 | logPayload: t.hex().notNull(), 48 | 49 | // general fields 50 | timestamp: t.bigint().notNull(), 51 | blockNumber: t.bigint().notNull(), 52 | transactionHash: t.hex().notNull(), 53 | }), 54 | ) 55 | -------------------------------------------------------------------------------- /apps/ponder-interop/setup-local-db.sql: -------------------------------------------------------------------------------- 1 | CREATE USER "local-db-user"; 2 | 3 | CREATE ROLE read_only; 4 | CREATE ROLE read_write; 5 | 6 | GRANT read_write TO postgres; 7 | GRANT read_write TO "local-db-user"; 8 | 9 | CREATE DATABASE "ponder-interop"; 10 | 11 | \c "ponder-interop" 12 | 13 | -- read_only 14 | GRANT CONNECT ON DATABASE "ponder-interop" TO read_only; 15 | 16 | GRANT USAGE ON SCHEMA public TO read_only; 17 | 18 | GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; 19 | 20 | ALTER DEFAULT PRIVILEGES GRANT SELECT ON TABLES TO read_only; 21 | 22 | -- read_write 23 | GRANT CREATE, CONNECT ON DATABASE "ponder-interop" TO read_write; 24 | 25 | GRANT USAGE, CREATE ON SCHEMA public TO read_write; 26 | 27 | GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO read_write; 28 | 29 | ALTER DEFAULT PRIVILEGES GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO read_write; 30 | 31 | GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO read_write; 32 | 33 | ALTER DEFAULT PRIVILEGES GRANT USAGE ON SEQUENCES TO read_write; 34 | 35 | ALTER DEFAULT PRIVILEGES FOR ROLE read_write GRANT SELECT ON TABLES TO read_only; -------------------------------------------------------------------------------- /apps/ponder-interop/src/createPonderConfig.ts: -------------------------------------------------------------------------------- 1 | import { 2 | contracts as addrs, 3 | l2ToL2CrossDomainMessengerAbi, 4 | } from '@eth-optimism/viem' 5 | import { createConfig } from 'ponder' 6 | import type { Transport } from 'viem' 7 | 8 | export type Endpoint = { 9 | chainId: number 10 | transport: Transport 11 | disableCache?: boolean 12 | } 13 | 14 | /** 15 | * A map of name to {@link Endpoint} 16 | */ 17 | export type Endpoints = Record 18 | 19 | /** 20 | * Create a Ponder config for interop 21 | * @param endpoints - Interoperable endpoints to index -- {@link Endpoints} 22 | * @returns Ponder configuration 23 | */ 24 | export function createPonderConfig(endpoints: Endpoints) { 25 | if (Object.keys(endpoints).length === 0) { 26 | throw new Error('no endpoints provided') 27 | } 28 | 29 | // relevant interop contracts 30 | const contracts = { 31 | L2ToL2CDM: { 32 | abi: l2ToL2CrossDomainMessengerAbi, 33 | startBlock: 1, 34 | network: Object.fromEntries( 35 | Object.keys(endpoints).map((key) => [ 36 | key, 37 | { address: addrs.l2ToL2CrossDomainMessenger.address }, 38 | ]), 39 | ), 40 | }, 41 | } 42 | 43 | return createConfig({ 44 | ordering: 'multichain', 45 | networks: endpoints, 46 | contracts, 47 | }) 48 | } 49 | -------------------------------------------------------------------------------- /apps/ponder-interop/src/utils/hashMessageIdentifier.ts: -------------------------------------------------------------------------------- 1 | import type { MessageIdentifier } from '@eth-optimism/viem' 2 | import type { Hash } from 'viem' 3 | import { encodeAbiParameters, keccak256, parseAbiParameters } from 'viem' 4 | 5 | /** 6 | * Hash an L2 to L2 cross domain message identifier 7 | * @param message {@link MessageIdentifier} 8 | * @returns Hash of the cross domain message identifier 9 | */ 10 | export function hashMessageIdentifier(message: MessageIdentifier): Hash { 11 | const encoded = encodeAbiParameters( 12 | parseAbiParameters('address,uint256,uint256,uint256,uint256'), 13 | [ 14 | message.origin, 15 | message.blockNumber, 16 | message.logIndex, 17 | message.timestamp, 18 | message.chainId, 19 | ], 20 | ) 21 | 22 | return keccak256(encoded) 23 | } 24 | -------------------------------------------------------------------------------- /apps/ponder-interop/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "declaration": true, 5 | // Type checking 6 | "strict": true, 7 | "noUncheckedIndexedAccess": true, 8 | 9 | // Interop constraints 10 | "verbatimModuleSyntax": false, 11 | "esModuleInterop": true, 12 | "isolatedModules": true, 13 | "allowSyntheticDefaultImports": true, 14 | "resolveJsonModule": true, 15 | 16 | // Paths 17 | "paths": { 18 | "@/*": ["./src/*"] 19 | }, 20 | 21 | // Language and environment 22 | "moduleResolution": "bundler", 23 | "module": "ESNext", 24 | "lib": ["ES2022"], 25 | "target": "ES2022", 26 | "outDir": "dist", 27 | 28 | // Skip type checking for node modules 29 | "skipLibCheck": true 30 | }, 31 | "include": ["./**/*.ts"], 32 | "exclude": ["node_modules"] 33 | } 34 | -------------------------------------------------------------------------------- /apps/sponsored-sender/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @eth-optimism/sponsored-sender 2 | 3 | ## 0.0.7 4 | 5 | ### Patch Changes 6 | 7 | - Updated dependencies [[`1ef3b6b`](https://github.com/ethereum-optimism/ecosystem/commit/1ef3b6b777619ec85a5f6848f8eca8491279268e)]: 8 | - @eth-optimism/utils-app@0.0.6 9 | 10 | ## 0.0.6 11 | 12 | ### Patch Changes 13 | 14 | - Updated dependencies [[`1e7472f`](https://github.com/ethereum-optimism/ecosystem/commit/1e7472f0582288583b5e6807892025f12172092a), [`40a535f`](https://github.com/ethereum-optimism/ecosystem/commit/40a535fb51f751cf0db265b4c26fb2f1badf6f46)]: 15 | - @eth-optimism/viem@0.4.9 16 | - @eth-optimism/utils-app@0.0.5 17 | 18 | ## 0.0.5 19 | 20 | ### Patch Changes 21 | 22 | - Updated dependencies [[`03b307c`](https://github.com/ethereum-optimism/ecosystem/commit/03b307c9744beb834746182f402bc8f1705c8ea4)]: 23 | - @eth-optimism/utils-app@0.0.4 24 | 25 | ## 0.0.4 26 | 27 | ### Patch Changes 28 | 29 | - Updated dependencies [[`c9dbca4`](https://github.com/ethereum-optimism/ecosystem/commit/c9dbca401eed763eb20b05437e3e460cdaadd711)]: 30 | - @eth-optimism/viem@0.4.8 31 | 32 | ## 0.0.3 33 | 34 | ### Patch Changes 35 | 36 | - Updated dependencies [[`4a7f3be`](https://github.com/ethereum-optimism/ecosystem/commit/4a7f3be47fd7ebef846341c499588bdcb2a00773)]: 37 | - @eth-optimism/utils-app@0.0.3 38 | 39 | ## 0.0.2 40 | 41 | ### Patch Changes 42 | 43 | - Updated dependencies [[`8b58cc7`](https://github.com/ethereum-optimism/ecosystem/commit/8b58cc7e852d066561f1e680fca5d29a2dd318b1)]: 44 | - @eth-optimism/utils-app@0.0.2 45 | -------------------------------------------------------------------------------- /apps/sponsored-sender/README.md: -------------------------------------------------------------------------------- 1 | # Sponsored Sender 2 | 3 | A simple json-rpc proxy service implementation to faciliate sponsored transactions to different chains. The json-rpc endpoint is available per chain at the `/${chainId}` route. The methods implemented under each route. 4 | 5 | - `eth_chainId` simply mirrors back the same chain id in the route 6 | - `eth_account` the senders used to relay transactions 7 | - `eth_sendTransaction` signs the unsigned payload and submits with the configured sender account 8 | 9 | This service is not meant for production use. Primarily useful for local testing for services that require the existence of a single sponsored endpoint URL. 10 | 11 | ## Configuration 12 | 13 | Configured entirely with environment variables 14 | 15 | ``` 16 | SPONSORED_SENDER_PRIVATE_KEY=0x 17 | SPONSORED_SENDER_ENDPOINTS=http://localhost:9545,http://localhost:9546 18 | ``` 19 | -------------------------------------------------------------------------------- /apps/sponsored-sender/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@eth-optimism/sponsored-sender", 3 | "version": "0.0.7", 4 | "private": true, 5 | "type": "module", 6 | "files": [ 7 | "dist" 8 | ], 9 | "scripts": { 10 | "build": "tsc && resolve-tspaths", 11 | "lint": "eslint \"**/*.{ts,tsx}\" && pnpm prettier --check \"**/*.{ts,tsx}\" --ignore-path \"../../.prettierignore\"", 12 | "lint:fix": "eslint \"**/*.{ts,tsx}\" --fix && pnpm prettier \"**/*.{ts,tsx}\" --write --loglevel=warn --ignore-path \"../../.prettierignore\"", 13 | "dev": "tsx src/index.ts", 14 | "start": "node dist/index.js", 15 | "typecheck": "tsc" 16 | }, 17 | "dependencies": { 18 | "abitype": "^1.0.8", 19 | "commander": "^13.1.0", 20 | "@hono/node-server": "^1.14.0", 21 | "viem": "^2.17.9", 22 | "@eth-optimism/viem": "workspace:*", 23 | "@eth-optimism/utils-app": "workspace:*", 24 | "hono": "^4.5.0", 25 | "zod": "^3.24.2", 26 | "zod-validation-error": "^3.4.0" 27 | }, 28 | "peerDependencies": { 29 | "pino": "^9.6.0", 30 | "pino-pretty": "^13.0.0" 31 | } 32 | } -------------------------------------------------------------------------------- /apps/sponsored-sender/src/api.ts: -------------------------------------------------------------------------------- 1 | import { Hono } from 'hono' 2 | import type { pino } from 'pino' 3 | import { z } from 'zod' 4 | 5 | import type { JsonRpcHandler } from '@/jsonrpc/handler.js' 6 | import type { JsonRpcResponse } from '@/jsonrpc/types.js' 7 | import { parseRequestBody } from '@/jsonrpc/utils.js' 8 | 9 | const sponsoredEndpointSchema = z.object({ 10 | chainId: z.coerce.number().int().positive(), 11 | }) 12 | 13 | /** 14 | * Create a Hono API Router that routes JSON RPC requests to the correct 15 | * handler based on the chain ID. 16 | * @param handlers - A map of chain IDs to JSON RPC handlers. 17 | * @returns A Hono API Router. 18 | */ 19 | export function createApiRouter( 20 | log: pino.Logger, 21 | handlers: Record, 22 | ): Hono { 23 | const api = new Hono() 24 | 25 | // global middleware 26 | api.use(async (c, next) => { 27 | const { req } = c 28 | const now = Date.now() 29 | await next() 30 | const ms = Date.now() - now 31 | log.info(`${req.method} ${req.path} - ${ms}ms`) 32 | }) 33 | 34 | // route json rpc requests based on chainId 35 | api.post('/:chainId', async (c) => { 36 | if (c.req.header('Content-Type') !== 'application/json') { 37 | return c.json({ error: 'Content-Type must be application/json' }, 400) 38 | } 39 | 40 | const params = c.req.param() 41 | const result = sponsoredEndpointSchema.safeParse(params) 42 | if (!result.success) { 43 | return c.json({ error: result.error.format() }, 400) 44 | } 45 | 46 | const chainId = result.data.chainId 47 | const handler = chainId in handlers ? handlers[chainId] : null 48 | if (!handler) { 49 | return c.json({ error: 'unregistered chain id' }, 400) 50 | } 51 | 52 | const body = await c.req.json() 53 | const bodyResult = parseRequestBody(body) 54 | if (bodyResult.error) { 55 | const resp = { 56 | jsonrpc: '2.0', 57 | id: null, 58 | error: { code: -32600, message: 'Invalid Request' }, 59 | } satisfies JsonRpcResponse 60 | 61 | return c.json(resp) 62 | } 63 | 64 | const response = await handler.handle(bodyResult.data) 65 | return c.json(response) 66 | }) 67 | 68 | return api 69 | } 70 | -------------------------------------------------------------------------------- /apps/sponsored-sender/src/index.ts: -------------------------------------------------------------------------------- 1 | import { SponsoredSenderApp } from '@/app.js' 2 | 3 | await new SponsoredSenderApp().run() 4 | -------------------------------------------------------------------------------- /apps/sponsored-sender/src/jsonrpc/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * The error object in a JSON RPC response. 3 | */ 4 | export type JsonRpcError = { 5 | error: { 6 | code: number 7 | message: string 8 | } 9 | } 10 | 11 | /** 12 | * The result object in a JSON RPC response. 13 | */ 14 | export type JsonRpcResult = { 15 | result: unknown 16 | } 17 | 18 | /** 19 | * The response object in a JSON RPC response. 20 | */ 21 | export type JsonRpcResponse = { 22 | jsonrpc: '2.0' 23 | id: number | string | null 24 | } & (JsonRpcError | JsonRpcResult) 25 | 26 | /** 27 | * The request object in a JSON RPC request. 28 | */ 29 | export type JsonRpcRequest = { 30 | jsonrpc: '2.0' 31 | id: number | string 32 | method: string 33 | params?: unknown 34 | } 35 | -------------------------------------------------------------------------------- /apps/sponsored-sender/src/jsonrpc/utils.ts: -------------------------------------------------------------------------------- 1 | import { z } from 'zod' 2 | 3 | import type { JsonRpcRequest } from '@/jsonrpc/types.js' 4 | 5 | type ParseRequestBodyResult = { 6 | data: JsonRpcRequest | JsonRpcRequest[] 7 | error?: Error 8 | } 9 | 10 | const JsonRpcRequestZodSchema = z 11 | .object({ 12 | jsonrpc: z.literal('2.0'), 13 | id: z.union([z.number().int(), z.string()]), 14 | method: z.string(), 15 | params: z.unknown().optional(), 16 | }) 17 | .strict() 18 | 19 | /** 20 | * Parse out the json rpcs out of the request body. 21 | * @param body - The request body. 22 | * @returns A single json rpc request or an array of json rpc requests - {@link JsonRpcRequest} 23 | */ 24 | export function parseRequestBody(body: unknown): ParseRequestBodyResult { 25 | const result = JsonRpcRequestZodSchema.safeParse(body) 26 | if (result.success) { 27 | return { data: result.data } 28 | } 29 | 30 | return { data: [], error: result.error } 31 | } 32 | -------------------------------------------------------------------------------- /apps/sponsored-sender/src/sender/senderJsonRpcHandler.ts: -------------------------------------------------------------------------------- 1 | import { Address as zodAddress } from 'abitype/zod' 2 | import type { Hex, PublicClient } from 'viem' 3 | import { isHex } from 'viem' 4 | import type { Account } from 'viem/accounts' 5 | import { sendTransaction } from 'viem/actions' 6 | import { z } from 'zod' 7 | 8 | import { JsonRpcHandler } from '@/jsonrpc/handler.js' 9 | 10 | const zodHex = z.string().refine((val): val is Hex => isHex(val), { 11 | message: 'invalid hex string', 12 | }) 13 | 14 | const zodTx = z.object( 15 | { 16 | to: zodAddress, 17 | data: zodHex, 18 | value: z.bigint().optional(), 19 | }, 20 | { 21 | message: 'invalid transaction', 22 | }, 23 | ) 24 | 25 | /** 26 | * Create a JSON RPC handler that sponsors `eth_sendTransaction` requests. Also 27 | * supports `eth_chainId` and `eth_accounts` for contextual information. 28 | * @param sender - The sponsored sender's account. 29 | * @param client - The client. 30 | * @returns A JSON RPC handler. 31 | */ 32 | export function senderJsonRpcHandler( 33 | sender: Account, 34 | client: PublicClient, 35 | ): JsonRpcHandler { 36 | const handler = new JsonRpcHandler() 37 | 38 | handler.method('eth_chainId', z.undefined(), async () => { 39 | return client.getChainId() 40 | }) 41 | 42 | handler.method('eth_accounts', z.undefined(), async () => { 43 | return [sender.address] 44 | }) 45 | 46 | handler.method('eth_sendTransaction', z.tuple([zodTx]), async (params) => { 47 | const request = params[0] 48 | return sendTransaction(client, { 49 | account: sender, 50 | chain: client.chain, 51 | to: request.to, 52 | data: request.data, 53 | value: request.value, 54 | }) 55 | }) 56 | 57 | return handler 58 | } 59 | -------------------------------------------------------------------------------- /apps/sponsored-sender/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "include": ["src"], 4 | "compilerOptions": { 5 | "rootDir": "src", 6 | "baseUrl": ".", 7 | "paths": { 8 | "@/*": ["./src/*"] 9 | }, 10 | "target": "es2021", 11 | "lib": ["esnext"], 12 | "strict": true, 13 | "composite": true, 14 | "outDir": "dist", 15 | "moduleResolution": "NodeNext", 16 | "module": "NodeNext", 17 | "sourceMap": true 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /apps/superchain-playground/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @eth-optimism/superchain-playground 2 | 3 | ## 0.0.2 4 | 5 | ### Patch Changes 6 | 7 | - Updated dependencies [[`1e7472f`](https://github.com/ethereum-optimism/ecosystem/commit/1e7472f0582288583b5e6807892025f12172092a)]: 8 | - @eth-optimism/viem@0.4.9 9 | - @eth-optimism/wagmi@0.1.8 10 | -------------------------------------------------------------------------------- /apps/superchain-playground/README.md: -------------------------------------------------------------------------------- 1 | # Superchain Playground 2 | 3 | Implementation of the [superchain playground](https://playground.optimism.io). This site contains **non-production** reference and demo components for the various op-stack features 4 | 5 | ```bash 6 | $ pnpm i 7 | $ VITE_WALLET_CONNECT_PROJECT_ID=foobarbaz pnpm dev 8 | ``` 9 | 10 | ## Configuration 11 | 12 | If using [wallet connect](https://walletconnect.network/) to connect to the playground, ensure a valid wallet connect is set in the environment 13 | 14 | ```bash 15 | $ export VITE_WALLET_CONNECT_PROJECT_ID= 16 | ``` 17 | 18 | > The default dev account provided is the first pre-funded private key available in supersim 19 | -------------------------------------------------------------------------------- /apps/superchain-playground/components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "default", 4 | "rsc": false, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "tailwind.config.js", 8 | "css": "src/index.css", 9 | "baseColor": "slate", 10 | "cssVariables": true 11 | }, 12 | "aliases": { 13 | "components": "@/components", 14 | "utils": "@/lib/utils" 15 | } 16 | } -------------------------------------------------------------------------------- /apps/superchain-playground/eslint.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'eslint/config'; 2 | 3 | import rootConfig from '../../eslint.config.js'; 4 | 5 | // Create a new configuration that extends the root configuration 6 | export default defineConfig([{ 7 | ...rootConfig, 8 | ignores: [...rootConfig.ignores, '**/dist/**'], 9 | rules: { 10 | ...rootConfig.rules, 11 | '@typescript-eslint/no-console': ['off'], 12 | }, 13 | }]); 14 | -------------------------------------------------------------------------------- /apps/superchain-playground/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Superchain Playground 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /apps/superchain-playground/postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { AppRoutes } from '@/AppRouter' 2 | import { Toaster } from '@/components/ui/toaster' 3 | import { Providers } from '@/Providers' 4 | 5 | function App() { 6 | return ( 7 | 8 | 9 | 10 | 11 | ) 12 | } 13 | 14 | export default App 15 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/AppRouter.tsx: -------------------------------------------------------------------------------- 1 | import { createBrowserRouter, Navigate, RouterProvider } from 'react-router-dom' 2 | 3 | import { NavBarLayout } from '@/layouts/NavBarLayout' 4 | import { BridgePage } from '@/pages/BridgePage' 5 | import { ChainsPage } from '@/pages/ChainsPage' 6 | import { ConfigPage } from '@/pages/ConfigPage' 7 | import { L2ToL1RelayerPage } from '@/pages/L2ToL1RelayerPage' 8 | import { SuperchainETHBridgePage } from '@/pages/SuperchainETHBridgePage' 9 | import { SuperchainMessageRelayer } from '@/pages/SuperchainMessageRelayer' 10 | import { SuperchainTokenBridgePage } from '@/pages/SuperchainTokenBridgePage' 11 | 12 | const router = createBrowserRouter([ 13 | { 14 | element: , 15 | children: [ 16 | { 17 | path: '/', 18 | element: , 19 | }, 20 | { 21 | path: '/bridge', 22 | element: , 23 | }, 24 | { 25 | path: '/chains', 26 | element: , 27 | }, 28 | { 29 | path: '/l2-to-l1-relayer', 30 | element: , 31 | }, 32 | { 33 | path: '/superchain-eth-bridge', 34 | element: , 35 | }, 36 | { 37 | path: '/superchain-token-bridge', 38 | element: , 39 | }, 40 | { 41 | path: '/superchain-message-relayer', 42 | element: , 43 | }, 44 | { 45 | path: '/config', 46 | element: , 47 | }, 48 | ], 49 | }, 50 | ]) 51 | 52 | export const AppRoutes = () => { 53 | return 54 | } 55 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/Providers.tsx: -------------------------------------------------------------------------------- 1 | import { RainbowKitProvider } from '@rainbow-me/rainbowkit' 2 | import { QueryClient, QueryClientProvider } from '@tanstack/react-query' 3 | import { WagmiProvider } from 'wagmi' 4 | 5 | import { config } from '@/lib/wagmi' 6 | 7 | const queryClient = new QueryClient() 8 | 9 | export const Providers = ({ children }: { children: React.ReactNode }) => { 10 | return ( 11 | 12 | 13 | {children} 14 | 15 | 16 | ) 17 | } 18 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/components/ConstructionAlert.tsx: -------------------------------------------------------------------------------- 1 | import { HardHat } from 'lucide-react' 2 | 3 | import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert' 4 | 5 | export const ConstructionAlert = () => { 6 | return ( 7 | 8 | 9 | Under construction 10 | 11 | This page is still a work in progress. 12 | 13 | 14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/components/L2ChainPicker.tsx: -------------------------------------------------------------------------------- 1 | import { networks } from '@eth-optimism/viem/chains' 2 | 3 | import { Label } from '@/components/ui/label' 4 | import { 5 | Select, 6 | SelectContent, 7 | SelectItem, 8 | SelectTrigger, 9 | SelectValue, 10 | } from '@/components/ui/select' 11 | import { useConfig } from '@/stores/useConfig' 12 | 13 | interface ChainPickerProps { 14 | label?: string 15 | chainId: number | undefined 16 | onChange: (chainId: number) => void 17 | placeholder?: string 18 | } 19 | 20 | export const L2ChainPicker = ({ 21 | label, 22 | chainId, 23 | onChange, 24 | placeholder = 'Select Chain', 25 | }: ChainPickerProps) => { 26 | const { networkName } = useConfig() 27 | const network = networks[networkName] 28 | 29 | return ( 30 |
31 | {label && } 32 | 47 |
48 | ) 49 | } 50 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/components/NavBar.tsx: -------------------------------------------------------------------------------- 1 | import { ConnectWalletButton } from '@/components/ConnectWalletButton' 2 | import { SidebarTrigger, useSidebar } from '@/components/ui/sidebar' 3 | 4 | export const NavBar = () => { 5 | const { isMobile } = useSidebar() 6 | return ( 7 |
8 | {isMobile ? :
} 9 |
10 | 11 |
12 |
13 | ) 14 | } 15 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/components/NetworkPicker.tsx: -------------------------------------------------------------------------------- 1 | import type { NetworkName } from '@eth-optimism/viem/chains' 2 | 3 | import { 4 | Select, 5 | SelectContent, 6 | SelectItem, 7 | SelectTrigger, 8 | SelectValue, 9 | } from '@/components/ui/select' 10 | import { useConfig } from '@/stores/useConfig' 11 | 12 | interface NetworkPickerProps { 13 | networks: NetworkName[] 14 | } 15 | 16 | export const NetworkPicker = ({ networks }: NetworkPickerProps) => { 17 | const { networkName, setNetworkName } = useConfig() 18 | 19 | return ( 20 |
21 | 22 | 37 |
38 | ) 39 | } 40 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/components/RemainingTimeDisplay.tsx: -------------------------------------------------------------------------------- 1 | import { formatDuration } from '@/utils/formatDuration' 2 | 3 | export const RemainingTimeDisplay = ({ seconds }: { seconds: number }) => { 4 | const formattedTime = formatDuration(seconds) 5 | 6 | return
{formattedTime}
7 | } 8 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/components/SelectNetwork.tsx: -------------------------------------------------------------------------------- 1 | import type { NetworkName } from '@eth-optimism/viem/chains' 2 | import { networks } from '@eth-optimism/viem/chains' 3 | 4 | import { 5 | Select, 6 | SelectContent, 7 | SelectItem, 8 | SelectTrigger, 9 | SelectValue, 10 | } from '@/components/ui/select' 11 | import { useConfig } from '@/stores/useConfig' 12 | 13 | export const SelectNetwork = () => { 14 | const { networkName, setNetworkName } = useConfig() 15 | 16 | return ( 17 | 41 | ) 42 | } 43 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/components/SupportedNetworks.tsx: -------------------------------------------------------------------------------- 1 | import type { NetworkName } from '@eth-optimism/viem/chains' 2 | import { AlertTriangle } from 'lucide-react' 3 | import type { ReactNode } from 'react' 4 | 5 | import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert' 6 | import { useConfig } from '@/stores/useConfig' 7 | 8 | import { NetworkPicker } from './NetworkPicker' 9 | 10 | interface SupportedNetworksProps { 11 | networks: NetworkName[] 12 | children: ReactNode 13 | } 14 | 15 | export const SupportedNetworks = ({ 16 | networks, 17 | children, 18 | }: SupportedNetworksProps) => { 19 | const { networkName } = useConfig() 20 | if (networks.includes(networkName)) { 21 | return <>{children} 22 | } 23 | 24 | return ( 25 | 26 |
27 | 28 |
29 | Unsupported Network 30 | 31 | Select a supported network to continue 32 | 33 |
34 |
35 |
36 | 37 |
38 |
39 | ) 40 | } 41 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/components/ui/accordion.tsx: -------------------------------------------------------------------------------- 1 | import * as AccordionPrimitive from '@radix-ui/react-accordion' 2 | import { ChevronDown } from 'lucide-react' 3 | import * as React from 'react' 4 | 5 | import { cn } from '@/lib/utils' 6 | 7 | const Accordion = AccordionPrimitive.Root 8 | 9 | const AccordionItem = React.forwardRef< 10 | React.ElementRef, 11 | React.ComponentPropsWithoutRef 12 | >(({ className, ...props }, ref) => ( 13 | 18 | )) 19 | AccordionItem.displayName = 'AccordionItem' 20 | 21 | const AccordionTrigger = React.forwardRef< 22 | React.ElementRef, 23 | React.ComponentPropsWithoutRef 24 | >(({ className, children, ...props }, ref) => ( 25 | 26 | svg]:rotate-180', 30 | className, 31 | )} 32 | {...props} 33 | > 34 | {children} 35 | 36 | 37 | 38 | )) 39 | AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName 40 | 41 | const AccordionContent = React.forwardRef< 42 | React.ElementRef, 43 | React.ComponentPropsWithoutRef 44 | >(({ className, children, ...props }, ref) => ( 45 | 53 |
{children}
54 |
55 | )) 56 | AccordionContent.displayName = AccordionPrimitive.Content.displayName 57 | 58 | export { Accordion, AccordionContent, AccordionItem, AccordionTrigger } 59 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/components/ui/alert.tsx: -------------------------------------------------------------------------------- 1 | import { cva, type VariantProps } from 'class-variance-authority' 2 | import * as React from 'react' 3 | 4 | import { cn } from '@/lib/utils' 5 | 6 | const alertVariants = cva( 7 | 'relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground', 8 | { 9 | variants: { 10 | variant: { 11 | default: 'bg-background text-foreground', 12 | destructive: 13 | 'border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive', 14 | }, 15 | }, 16 | defaultVariants: { 17 | variant: 'default', 18 | }, 19 | }, 20 | ) 21 | 22 | const Alert = React.forwardRef< 23 | HTMLDivElement, 24 | React.HTMLAttributes & VariantProps 25 | >(({ className, variant, ...props }, ref) => ( 26 |
32 | )) 33 | Alert.displayName = 'Alert' 34 | 35 | const AlertTitle = React.forwardRef< 36 | HTMLParagraphElement, 37 | React.HTMLAttributes 38 | >(({ className, ...props }, ref) => ( 39 |
44 | )) 45 | AlertTitle.displayName = 'AlertTitle' 46 | 47 | const AlertDescription = React.forwardRef< 48 | HTMLParagraphElement, 49 | React.HTMLAttributes 50 | >(({ className, ...props }, ref) => ( 51 |
56 | )) 57 | AlertDescription.displayName = 'AlertDescription' 58 | 59 | export { Alert, AlertDescription, AlertTitle } 60 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/components/ui/avatar.tsx: -------------------------------------------------------------------------------- 1 | import * as AvatarPrimitive from '@radix-ui/react-avatar' 2 | import * as React from 'react' 3 | 4 | import { cn } from '@/lib/utils' 5 | 6 | const Avatar = React.forwardRef< 7 | React.ElementRef, 8 | React.ComponentPropsWithoutRef 9 | >(({ className, ...props }, ref) => ( 10 | 18 | )) 19 | Avatar.displayName = AvatarPrimitive.Root.displayName 20 | 21 | const AvatarImage = React.forwardRef< 22 | React.ElementRef, 23 | React.ComponentPropsWithoutRef 24 | >(({ className, ...props }, ref) => ( 25 | 30 | )) 31 | AvatarImage.displayName = AvatarPrimitive.Image.displayName 32 | 33 | const AvatarFallback = React.forwardRef< 34 | React.ElementRef, 35 | React.ComponentPropsWithoutRef 36 | >(({ className, ...props }, ref) => ( 37 | 45 | )) 46 | AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName 47 | 48 | export { Avatar, AvatarFallback, AvatarImage } 49 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/components/ui/badge.tsx: -------------------------------------------------------------------------------- 1 | import { cva, type VariantProps } from 'class-variance-authority' 2 | import * as React from 'react' 3 | 4 | import { cn } from '@/lib/utils' 5 | 6 | const badgeVariants = cva( 7 | 'inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2', 8 | { 9 | variants: { 10 | variant: { 11 | default: 12 | 'border-transparent bg-primary text-primary-foreground hover:bg-primary/80', 13 | secondary: 14 | 'border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80', 15 | destructive: 16 | 'border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80', 17 | outline: 'text-foreground', 18 | }, 19 | }, 20 | defaultVariants: { 21 | variant: 'default', 22 | }, 23 | }, 24 | ) 25 | 26 | export interface BadgeProps 27 | extends React.HTMLAttributes, 28 | VariantProps {} 29 | 30 | function Badge({ className, variant, ...props }: BadgeProps) { 31 | return ( 32 |
33 | ) 34 | } 35 | 36 | export { Badge, badgeVariants } 37 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/components/ui/button.tsx: -------------------------------------------------------------------------------- 1 | import { Slot } from '@radix-ui/react-slot' 2 | import { cva, type VariantProps } from 'class-variance-authority' 3 | import * as React from 'react' 4 | 5 | import { cn } from '@/lib/utils' 6 | 7 | const buttonVariants = cva( 8 | 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0', 9 | { 10 | variants: { 11 | variant: { 12 | default: 'bg-primary text-primary-foreground hover:bg-primary/90', 13 | destructive: 14 | 'bg-destructive text-destructive-foreground hover:bg-destructive/90', 15 | outline: 16 | 'border border-input bg-background hover:bg-accent hover:text-accent-foreground', 17 | secondary: 18 | 'bg-secondary text-secondary-foreground hover:bg-secondary/80', 19 | ghost: 'hover:bg-accent hover:text-accent-foreground', 20 | link: 'text-primary underline-offset-4 hover:underline', 21 | }, 22 | size: { 23 | default: 'h-10 px-4 py-2', 24 | sm: 'h-9 rounded-md px-3', 25 | lg: 'h-11 rounded-md px-8', 26 | icon: 'h-10 w-10', 27 | }, 28 | }, 29 | defaultVariants: { 30 | variant: 'default', 31 | size: 'default', 32 | }, 33 | }, 34 | ) 35 | 36 | export interface ButtonProps 37 | extends React.ButtonHTMLAttributes, 38 | VariantProps { 39 | asChild?: boolean 40 | } 41 | 42 | const Button = React.forwardRef( 43 | ({ className, variant, size, asChild = false, ...props }, ref) => { 44 | const Comp = asChild ? Slot : 'button' 45 | return ( 46 | 51 | ) 52 | }, 53 | ) 54 | Button.displayName = 'Button' 55 | 56 | export { Button, buttonVariants } 57 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/components/ui/card.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | import { cn } from '@/lib/utils' 4 | 5 | const Card = React.forwardRef< 6 | HTMLDivElement, 7 | React.HTMLAttributes 8 | >(({ className, ...props }, ref) => ( 9 |
17 | )) 18 | Card.displayName = 'Card' 19 | 20 | const CardHeader = React.forwardRef< 21 | HTMLDivElement, 22 | React.HTMLAttributes 23 | >(({ className, ...props }, ref) => ( 24 |
29 | )) 30 | CardHeader.displayName = 'CardHeader' 31 | 32 | const CardTitle = React.forwardRef< 33 | HTMLParagraphElement, 34 | React.HTMLAttributes 35 | >(({ className, ...props }, ref) => ( 36 |

44 | )) 45 | CardTitle.displayName = 'CardTitle' 46 | 47 | const CardDescription = React.forwardRef< 48 | HTMLParagraphElement, 49 | React.HTMLAttributes 50 | >(({ className, ...props }, ref) => ( 51 |

56 | )) 57 | CardDescription.displayName = 'CardDescription' 58 | 59 | const CardContent = React.forwardRef< 60 | HTMLDivElement, 61 | React.HTMLAttributes 62 | >(({ className, ...props }, ref) => ( 63 |

64 | )) 65 | CardContent.displayName = 'CardContent' 66 | 67 | const CardFooter = React.forwardRef< 68 | HTMLDivElement, 69 | React.HTMLAttributes 70 | >(({ className, ...props }, ref) => ( 71 |
76 | )) 77 | CardFooter.displayName = 'CardFooter' 78 | 79 | export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } 80 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/components/ui/checkbox.tsx: -------------------------------------------------------------------------------- 1 | import * as CheckboxPrimitive from '@radix-ui/react-checkbox' 2 | import { Check } from 'lucide-react' 3 | import * as React from 'react' 4 | 5 | import { cn } from '@/lib/utils' 6 | 7 | const Checkbox = React.forwardRef< 8 | React.ElementRef, 9 | React.ComponentPropsWithoutRef 10 | >(({ className, ...props }, ref) => ( 11 | 19 | 22 | 23 | 24 | 25 | )) 26 | Checkbox.displayName = CheckboxPrimitive.Root.displayName 27 | 28 | export { Checkbox } 29 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/components/ui/chip.tsx: -------------------------------------------------------------------------------- 1 | import { cva, type VariantProps } from 'class-variance-authority' 2 | import * as React from 'react' 3 | 4 | import { cn } from '@/lib/utils' 5 | 6 | export const chipVariants = cva( 7 | 'inline-flex select-none rounded-full font-semibold ', 8 | { 9 | variants: { 10 | variant: { 11 | default: 'bg-primary text-primary-foreground hover:bg-primary/90', 12 | success: 'bg-blue-600 text-white hover:bg-600/90', 13 | progress: 'bg-emerald-600 text-white hover:bg-emerald-600/90', 14 | error: 15 | 'bg-destructive text-destructive-foreground hover:bg-destructive/9', 16 | }, 17 | size: { 18 | default: 'py-1 px-4 text-md', 19 | }, 20 | }, 21 | defaultVariants: { 22 | variant: 'default', 23 | size: 'default', 24 | }, 25 | }, 26 | ) 27 | 28 | export interface ChipProps 29 | extends React.ButtonHTMLAttributes, 30 | VariantProps {} 31 | 32 | export const Chip = React.forwardRef( 33 | ({ className, variant, size, ...props }, ref) => { 34 | return ( 35 |
40 | ) 41 | }, 42 | ) 43 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/components/ui/collapsible.tsx: -------------------------------------------------------------------------------- 1 | import * as CollapsiblePrimitive from '@radix-ui/react-collapsible' 2 | 3 | const Collapsible = CollapsiblePrimitive.Root 4 | 5 | const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger 6 | 7 | const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent 8 | 9 | export { Collapsible, CollapsibleContent, CollapsibleTrigger } 10 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/components/ui/input.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | import { cn } from '@/lib/utils' 4 | 5 | const Input = React.forwardRef>( 6 | ({ className, type, ...props }, ref) => { 7 | return ( 8 | 17 | ) 18 | }, 19 | ) 20 | Input.displayName = 'Input' 21 | 22 | export { Input } 23 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/components/ui/label.tsx: -------------------------------------------------------------------------------- 1 | import * as LabelPrimitive from '@radix-ui/react-label' 2 | import { cva, type VariantProps } from 'class-variance-authority' 3 | import * as React from 'react' 4 | 5 | import { cn } from '@/lib/utils' 6 | 7 | const labelVariants = cva( 8 | 'text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70', 9 | ) 10 | 11 | const Label = React.forwardRef< 12 | React.ElementRef, 13 | React.ComponentPropsWithoutRef & 14 | VariantProps 15 | >(({ className, ...props }, ref) => ( 16 | 21 | )) 22 | Label.displayName = LabelPrimitive.Root.displayName 23 | 24 | export { Label } 25 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/components/ui/popover.tsx: -------------------------------------------------------------------------------- 1 | import * as PopoverPrimitive from '@radix-ui/react-popover' 2 | import * as React from 'react' 3 | 4 | import { cn } from '@/lib/utils' 5 | 6 | const Popover = PopoverPrimitive.Root 7 | 8 | const PopoverTrigger = PopoverPrimitive.Trigger 9 | 10 | const PopoverContent = React.forwardRef< 11 | React.ElementRef, 12 | React.ComponentPropsWithoutRef 13 | >(({ className, align = 'center', sideOffset = 4, ...props }, ref) => ( 14 | 15 | 25 | 26 | )) 27 | PopoverContent.displayName = PopoverPrimitive.Content.displayName 28 | 29 | export { Popover, PopoverContent, PopoverTrigger } 30 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/components/ui/radio-group.tsx: -------------------------------------------------------------------------------- 1 | import * as RadioGroupPrimitive from '@radix-ui/react-radio-group' 2 | import { Circle } from 'lucide-react' 3 | import * as React from 'react' 4 | 5 | import { cn } from '@/lib/utils' 6 | 7 | const RadioGroup = React.forwardRef< 8 | React.ElementRef, 9 | React.ComponentPropsWithoutRef 10 | >(({ className, ...props }, ref) => { 11 | return ( 12 | 17 | ) 18 | }) 19 | RadioGroup.displayName = RadioGroupPrimitive.Root.displayName 20 | 21 | const RadioGroupItem = React.forwardRef< 22 | React.ElementRef, 23 | React.ComponentPropsWithoutRef 24 | >(({ className, ...props }, ref) => { 25 | return ( 26 | 34 | 35 | 36 | 37 | 38 | ) 39 | }) 40 | RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName 41 | 42 | export { RadioGroup, RadioGroupItem } 43 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/components/ui/scroll-area.tsx: -------------------------------------------------------------------------------- 1 | import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area' 2 | import * as React from 'react' 3 | 4 | import { cn } from '@/lib/utils' 5 | 6 | const ScrollArea = React.forwardRef< 7 | React.ElementRef, 8 | React.ComponentPropsWithoutRef 9 | >(({ className, children, ...props }, ref) => ( 10 | 15 | 16 | {children} 17 | 18 | 19 | 20 | 21 | )) 22 | ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName 23 | 24 | const ScrollBar = React.forwardRef< 25 | React.ElementRef, 26 | React.ComponentPropsWithoutRef 27 | >(({ className, orientation = 'vertical', ...props }, ref) => ( 28 | 41 | 42 | 43 | )) 44 | ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName 45 | 46 | export { ScrollArea, ScrollBar } 47 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/components/ui/separator.tsx: -------------------------------------------------------------------------------- 1 | import * as SeparatorPrimitive from '@radix-ui/react-separator' 2 | import * as React from 'react' 3 | 4 | import { cn } from '@/lib/utils' 5 | 6 | const Separator = React.forwardRef< 7 | React.ElementRef, 8 | React.ComponentPropsWithoutRef 9 | >( 10 | ( 11 | { className, orientation = 'horizontal', decorative = true, ...props }, 12 | ref, 13 | ) => ( 14 | 25 | ), 26 | ) 27 | Separator.displayName = SeparatorPrimitive.Root.displayName 28 | 29 | export { Separator } 30 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/components/ui/skeleton.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from '@/lib/utils' 2 | 3 | function Skeleton({ 4 | className, 5 | ...props 6 | }: React.HTMLAttributes) { 7 | return ( 8 |
12 | ) 13 | } 14 | 15 | export { Skeleton } 16 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/components/ui/switch.tsx: -------------------------------------------------------------------------------- 1 | import * as SwitchPrimitives from '@radix-ui/react-switch' 2 | import * as React from 'react' 3 | 4 | import { cn } from '@/lib/utils' 5 | 6 | const Switch = React.forwardRef< 7 | React.ElementRef, 8 | React.ComponentPropsWithoutRef 9 | >(({ className, ...props }, ref) => ( 10 | 18 | 23 | 24 | )) 25 | Switch.displayName = SwitchPrimitives.Root.displayName 26 | 27 | export { Switch } 28 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/components/ui/tabs.tsx: -------------------------------------------------------------------------------- 1 | import * as TabsPrimitive from '@radix-ui/react-tabs' 2 | import * as React from 'react' 3 | 4 | import { cn } from '@/lib/utils' 5 | 6 | const Tabs = TabsPrimitive.Root 7 | 8 | const TabsList = React.forwardRef< 9 | React.ElementRef, 10 | React.ComponentPropsWithoutRef 11 | >(({ className, ...props }, ref) => ( 12 | 20 | )) 21 | TabsList.displayName = TabsPrimitive.List.displayName 22 | 23 | const TabsTrigger = React.forwardRef< 24 | React.ElementRef, 25 | React.ComponentPropsWithoutRef 26 | >(({ className, ...props }, ref) => ( 27 | 35 | )) 36 | TabsTrigger.displayName = TabsPrimitive.Trigger.displayName 37 | 38 | const TabsContent = React.forwardRef< 39 | React.ElementRef, 40 | React.ComponentPropsWithoutRef 41 | >(({ className, ...props }, ref) => ( 42 | 50 | )) 51 | TabsContent.displayName = TabsPrimitive.Content.displayName 52 | 53 | export { Tabs, TabsContent, TabsList, TabsTrigger } 54 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/components/ui/toaster.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | Toast, 3 | ToastClose, 4 | ToastDescription, 5 | ToastProvider, 6 | ToastTitle, 7 | ToastViewport, 8 | } from '@/components/ui/toast' 9 | import { useToast } from '@/components/ui/use-toast' 10 | 11 | export function Toaster() { 12 | const { toasts } = useToast() 13 | 14 | return ( 15 | 16 | {toasts.map(function ({ id, title, description, action, ...props }) { 17 | return ( 18 | 19 |
20 | {title && {title}} 21 | {description && ( 22 | {description} 23 | )} 24 |
25 | {action} 26 | 27 |
28 | ) 29 | })} 30 | 31 |
32 | ) 33 | } 34 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/components/ui/tooltip.tsx: -------------------------------------------------------------------------------- 1 | import * as TooltipPrimitive from '@radix-ui/react-tooltip' 2 | import * as React from 'react' 3 | 4 | import { cn } from '@/lib/utils' 5 | 6 | const TooltipProvider = TooltipPrimitive.Provider 7 | 8 | const Tooltip = TooltipPrimitive.Root 9 | 10 | const TooltipTrigger = TooltipPrimitive.Trigger 11 | 12 | const TooltipContent = React.forwardRef< 13 | React.ElementRef, 14 | React.ComponentPropsWithoutRef 15 | >(({ className, sideOffset = 4, ...props }, ref) => ( 16 | 25 | )) 26 | TooltipContent.displayName = TooltipPrimitive.Content.displayName 27 | 28 | export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } 29 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/constants/predeployByContractAddress.ts: -------------------------------------------------------------------------------- 1 | import { contracts } from '@eth-optimism/viem' 2 | import type { Abi, Address } from 'viem' 3 | 4 | import { superchainTokenBridgeAbi } from '@/constants/superchainTokenBridgeAbi' 5 | 6 | export const predeployByContractAddress: Record< 7 | Address, 8 | { abi: Abi; name: string } 9 | > = { 10 | [contracts.superchainTokenBridge.address]: { 11 | abi: superchainTokenBridgeAbi, 12 | name: 'SuperchainTokenBridge', 13 | }, 14 | } 15 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/envVars.ts: -------------------------------------------------------------------------------- 1 | import type { Address } from 'viem' 2 | import { z } from 'zod' 3 | 4 | const envVarSchema = z.object({ 5 | VITE_WALLET_CONNECT_PROJECT_ID: z.string().transform((x) => x as Address), 6 | }) 7 | 8 | export const envVars = envVarSchema.parse(import.meta.env) 9 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/hooks/use-mobile.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | const MOBILE_BREAKPOINT = 768 4 | 5 | export function useIsMobile() { 6 | const [isMobile, setIsMobile] = React.useState(undefined) 7 | 8 | React.useEffect(() => { 9 | const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`) 10 | const onChange = () => { 11 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT) 12 | } 13 | mql.addEventListener('change', onChange) 14 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT) 15 | return () => mql.removeEventListener('change', onChange) 16 | }, []) 17 | 18 | return !!isMobile 19 | } 20 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/hooks/useBuildProveWithdrawal.ts: -------------------------------------------------------------------------------- 1 | import { useQuery } from '@tanstack/react-query' 2 | import type { Chain } from 'viem' 3 | import type { 4 | GetL2OutputReturnType, 5 | GetWithdrawalsReturnType, 6 | } from 'viem/op-stack' 7 | import { publicActionsL2 } from 'viem/op-stack' 8 | import { usePublicClient } from 'wagmi' 9 | 10 | export const useBuildProveWithdrawal = ({ 11 | withdrawal, 12 | output, 13 | l2Chain, 14 | }: { 15 | withdrawal?: GetWithdrawalsReturnType[number] 16 | output?: GetL2OutputReturnType 17 | l2Chain: Chain 18 | }) => { 19 | const publicClientL2 = usePublicClient({ chainId: l2Chain.id }) 20 | return useQuery({ 21 | enabled: !!publicClientL2 && !!withdrawal && !!output, 22 | queryKey: [ 23 | 'build-prove-withdrawal', 24 | l2Chain.id, 25 | withdrawal?.withdrawalHash, 26 | output?.l2BlockNumber.toString(), 27 | ], 28 | queryFn: async () => { 29 | if (!publicClientL2 || !withdrawal || !output) { 30 | return 31 | } 32 | return await publicClientL2 33 | .extend(publicActionsL2()) 34 | .buildProveWithdrawal({ 35 | output, 36 | withdrawal, 37 | }) 38 | }, 39 | }) 40 | } 41 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/hooks/useGetL2Output.ts: -------------------------------------------------------------------------------- 1 | import { useQuery } from '@tanstack/react-query' 2 | import type { Chain } from 'viem' 3 | import { publicActionsL1 } from 'viem/op-stack' 4 | import { usePublicClient } from 'wagmi' 5 | 6 | export const useGetL2Output = ({ 7 | l2BlockNumber, 8 | l2Chain, 9 | }: { 10 | l2BlockNumber?: bigint 11 | l2Chain: Chain 12 | }) => { 13 | const publicClientL1 = usePublicClient({ chainId: l2Chain.sourceId! }) 14 | return useQuery({ 15 | enabled: !!publicClientL1 && !!l2BlockNumber, 16 | queryKey: ['get-l2-output', l2Chain.id, l2BlockNumber?.toString()], 17 | queryFn: async () => { 18 | if (!publicClientL1 || l2BlockNumber === undefined) { 19 | return 20 | } 21 | return await publicClientL1.extend(publicActionsL1()).getL2Output({ 22 | l2BlockNumber, 23 | targetChain: l2Chain as any, 24 | }) 25 | }, 26 | }) 27 | } 28 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/hooks/useGetTimeToFinalize.ts: -------------------------------------------------------------------------------- 1 | import { useQuery } from '@tanstack/react-query' 2 | import type { Chain, Hash } from 'viem' 3 | import { publicActionsL1 } from 'viem/op-stack' 4 | import { usePublicClient, useTransactionReceipt } from 'wagmi' 5 | 6 | import { useWithdrawalMessage } from '@/hooks/useWithdrawalMessage' 7 | 8 | export const useGetTimeToFinalize = ({ 9 | transactionHash, 10 | l2Chain, 11 | }: { 12 | transactionHash: Hash 13 | l2Chain: Chain 14 | }) => { 15 | const { data: receipt } = useTransactionReceipt({ 16 | hash: transactionHash, 17 | chainId: l2Chain.id, 18 | }) 19 | 20 | const l1PublicClient = usePublicClient({ chainId: l2Chain.sourceId! }) 21 | 22 | const withdrawal = useWithdrawalMessage(receipt) 23 | 24 | return useQuery({ 25 | enabled: !!receipt && !!l1PublicClient, 26 | queryKey: ['get-time-to-finalize', l2Chain.id, transactionHash], 27 | queryFn: async () => { 28 | if (!receipt || !l1PublicClient || !withdrawal) return 29 | 30 | return await l1PublicClient.extend(publicActionsL1()).getTimeToFinalize({ 31 | withdrawalHash: withdrawal.withdrawalHash, 32 | targetChain: l2Chain as any, 33 | }) 34 | }, 35 | refetchInterval: 5 * 1000, 36 | }) 37 | } 38 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/hooks/useGetTimeToProve.ts: -------------------------------------------------------------------------------- 1 | import { useQuery } from '@tanstack/react-query' 2 | import type { Chain, Hash } from 'viem' 3 | import { publicActionsL1 } from 'viem/op-stack' 4 | import { usePublicClient, useTransactionReceipt } from 'wagmi' 5 | 6 | export const useGetTimeToProve = ({ 7 | transactionHash, 8 | l2Chain, 9 | }: { 10 | transactionHash: Hash 11 | l2Chain: Chain 12 | }) => { 13 | const { data: receipt } = useTransactionReceipt({ 14 | hash: transactionHash, 15 | chainId: l2Chain.id, 16 | }) 17 | 18 | const l1PublicClient = usePublicClient({ chainId: l2Chain.sourceId! }) 19 | 20 | return useQuery({ 21 | enabled: !!receipt && !!l1PublicClient, 22 | queryKey: ['get-time-to-prove', l2Chain.id, transactionHash], 23 | queryFn: async () => { 24 | if (!receipt || !l1PublicClient) return 25 | 26 | return await l1PublicClient.extend(publicActionsL1()).getTimeToProve({ 27 | receipt, 28 | targetChain: l2Chain as any, 29 | }) 30 | }, 31 | refetchInterval: 6 * 1000, 32 | }) 33 | } 34 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/hooks/useGetWithdrawalStatus.ts: -------------------------------------------------------------------------------- 1 | import { useQuery } from '@tanstack/react-query' 2 | import type { Chain, TransactionReceipt } from 'viem' 3 | import { publicActionsL1 } from 'viem/op-stack' 4 | import { usePublicClient } from 'wagmi' 5 | 6 | export const useGetWithdrawalStatus = ({ 7 | transactionReceipt, 8 | l2Chain, 9 | }: { 10 | transactionReceipt?: TransactionReceipt 11 | l2Chain: Chain 12 | }) => { 13 | const l1PublicClient = usePublicClient({ chainId: l2Chain.sourceId! }) 14 | 15 | return useQuery({ 16 | enabled: !!transactionReceipt && l1PublicClient !== undefined, 17 | queryKey: [ 18 | 'get-withdrawal-status', 19 | l2Chain.id, 20 | transactionReceipt?.transactionHash, 21 | ], 22 | queryFn: async () => { 23 | if (!transactionReceipt || !l1PublicClient) { 24 | return 25 | } 26 | 27 | const withdrawalStatus = await l1PublicClient 28 | .extend(publicActionsL1()) 29 | .getWithdrawalStatus({ 30 | receipt: transactionReceipt, 31 | targetChain: l2Chain as any, 32 | }) 33 | 34 | return withdrawalStatus 35 | }, 36 | 37 | refetchInterval: 6 * 1000, 38 | }) 39 | } 40 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/hooks/useInvalidateGetWithdrawalStatus.ts: -------------------------------------------------------------------------------- 1 | import { useQueryClient } from '@tanstack/react-query' 2 | 3 | export const useInvalidateGetWithdrawalStatus = () => { 4 | const queryClient = useQueryClient() 5 | return { 6 | invalidate: (chainPairId: string, transactionHash: string) => { 7 | queryClient.invalidateQueries({ 8 | queryKey: ['get-withdrawal-status', chainPairId, transactionHash], 9 | }) 10 | }, 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/hooks/useTokenInfo.ts: -------------------------------------------------------------------------------- 1 | import type { Address } from 'viem' 2 | import { erc20Abi } from 'viem' 3 | import { useReadContracts } from 'wagmi' 4 | 5 | export const useTokenInfo = ({ 6 | address, 7 | chainId, 8 | }: { 9 | address: Address 10 | chainId: number 11 | }) => { 12 | const result = useReadContracts({ 13 | contracts: [ 14 | { 15 | address, 16 | abi: erc20Abi, 17 | functionName: 'symbol', 18 | chainId, 19 | }, 20 | { 21 | address, 22 | abi: erc20Abi, 23 | functionName: 'decimals', 24 | chainId, 25 | }, 26 | { 27 | address, 28 | abi: erc20Abi, 29 | functionName: 'name', 30 | chainId, 31 | }, 32 | ], 33 | }) 34 | const [symbol, decimals, name] = result.data || [] 35 | 36 | return { 37 | isLoading: result.isLoading, 38 | symbol: symbol?.result, 39 | decimals: decimals?.result, 40 | name: name?.result, 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/hooks/useWithdrawalMessage.ts: -------------------------------------------------------------------------------- 1 | import type { TransactionReceipt } from 'viem' 2 | import { getWithdrawals } from 'viem/op-stack' 3 | 4 | export const useWithdrawalMessage = (receipt?: TransactionReceipt) => { 5 | return receipt ? getWithdrawals(receipt)[0] : undefined 6 | } 7 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/layouts/NavBarLayout.tsx: -------------------------------------------------------------------------------- 1 | import { Outlet } from 'react-router-dom' 2 | 3 | import { NavBar } from '@/components/NavBar' 4 | import { SideNav } from '@/components/SideNav' 5 | import { SidebarProvider } from '@/components/ui/sidebar' 6 | 7 | export const NavBarLayout = () => { 8 | return ( 9 | 10 |
11 |
12 | 13 |
14 | 15 |
16 | 17 |
18 |
19 |
20 |
21 |
22 | ) 23 | } 24 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/lib/encodeL2ToL2CrossDomainSentMessageEvent.ts: -------------------------------------------------------------------------------- 1 | import { l2ToL2CrossDomainMessengerAbi } from '@eth-optimism/viem' 2 | import { 3 | encodeAbiParameters, 4 | encodeEventTopics, 5 | encodePacked, 6 | toHex, 7 | } from 'viem' 8 | 9 | import type { L2ToL2CrossDomainMessage } from '@/types/L2ToL2CrossDomainMessage' 10 | 11 | export const encodeL2ToL2CrossDomainSentMessageEvent = ( 12 | message: L2ToL2CrossDomainMessage, 13 | ) => { 14 | const topics = encodeEventTopics({ 15 | abi: l2ToL2CrossDomainMessengerAbi, 16 | eventName: 'SentMessage', 17 | args: { 18 | destination: message.destination, 19 | target: message.target, 20 | messageNonce: message.messageNonce, 21 | }, 22 | }) 23 | 24 | const data = encodeAbiParameters( 25 | [{ type: 'address' }, { type: 'bytes' }], 26 | [message.sender, message.message], 27 | ) 28 | 29 | if (topics === null || !Array.isArray(topics)) { 30 | throw new Error('Failed to encode event topics') 31 | } 32 | 33 | // TODO: MAYBE is a bug in viem? but prob not. either way when messageNonce is 0n, the topic is null 34 | if (topics[3] === null) { 35 | topics[3] = toHex(message.messageNonce, { size: 32 }) 36 | } 37 | 38 | return encodePacked( 39 | ['bytes32[]', 'bytes'], 40 | [topics as Array<`0x${string}`>, data], 41 | ) 42 | } 43 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/lib/getL2ToL2CrossDomainMessageHash.ts: -------------------------------------------------------------------------------- 1 | import type { Hex } from 'viem' 2 | import { encodeAbiParameters, keccak256 } from 'viem' 3 | 4 | import type { L2ToL2CrossDomainMessage } from '@/types/L2ToL2CrossDomainMessage' 5 | 6 | /** 7 | * Generates a unique hash for cross L2 messages. This hash is used to identify 8 | * the message and ensure it is not relayed more than once. 9 | * @param messageParams Object containing all parameters for the cross-domain message. 10 | * @returns Hash of the encoded message parameters, used to uniquely identify the message. 11 | */ 12 | export function getL2ToL2CrossDomainMessageHash( 13 | messageParams: L2ToL2CrossDomainMessage, 14 | source: bigint, 15 | ): Hex { 16 | const { destination, messageNonce, sender, target, message } = messageParams 17 | 18 | const encodedParams = encodeAbiParameters( 19 | [ 20 | { type: 'uint256' }, 21 | { type: 'uint256' }, 22 | { type: 'uint256' }, 23 | { type: 'address' }, 24 | { type: 'address' }, 25 | { type: 'bytes' }, 26 | ], 27 | [destination, source, messageNonce, sender, target, message], 28 | ) 29 | 30 | return keccak256(encodedParams) 31 | } 32 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/lib/truncateHash.ts: -------------------------------------------------------------------------------- 1 | import type { Hex } from 'viem' 2 | 3 | export const truncateHash = (address: Hex) => { 4 | return `${address.slice(0, 10)}...${address.slice(-6)}` 5 | } 6 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { type ClassValue, clsx } from 'clsx' 2 | import { twMerge } from 'tailwind-merge' 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)) 6 | } 7 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/lib/wagmi.ts: -------------------------------------------------------------------------------- 1 | import '@rainbow-me/rainbowkit/styles.css' 2 | 3 | import { networks } from '@eth-optimism/viem/chains' 4 | import type { Chain } from 'viem' 5 | import { privateKeyToAccount } from 'viem/accounts' 6 | import { createConfig, http } from 'wagmi' 7 | import { metaMask, walletConnect } from 'wagmi/connectors' 8 | 9 | import { devAccount } from '@/connectors/devAccount' 10 | import { envVars } from '@/envVars' 11 | 12 | export const defaultDevAccount = privateKeyToAccount( 13 | '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80', 14 | ) 15 | 16 | const ns = Object.values(networks) 17 | 18 | const sourceChains = ns.map((n) => n.sourceChain) 19 | const chains = ns.flatMap((n) => n.chains) 20 | const allChains = [...sourceChains, ...chains] as const 21 | 22 | const transports = Object.fromEntries( 23 | allChains.map((chain) => { 24 | return [chain.id, http(chain.rpcUrls.default.http[0])] 25 | }), 26 | ) 27 | 28 | export const config = createConfig({ 29 | chains: allChains as readonly [Chain, ...Chain[]], 30 | transports, 31 | connectors: [ 32 | devAccount(defaultDevAccount), 33 | walletConnect({ projectId: envVars.VITE_WALLET_CONNECT_PROJECT_ID || '' }), 34 | metaMask(), 35 | ], 36 | }) 37 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/main.tsx: -------------------------------------------------------------------------------- 1 | import './index.css' 2 | 3 | import React from 'react' 4 | import ReactDOM from 'react-dom/client' 5 | 6 | import App from '@/App' 7 | 8 | ReactDOM.createRoot(document.getElementById('root')!).render( 9 | 10 | 11 | , 12 | ) 13 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/pages/BridgePage.tsx: -------------------------------------------------------------------------------- 1 | import type { NetworkName } from '@eth-optimism/viem/chains' 2 | import { networks } from '@eth-optimism/viem/chains' 3 | 4 | import { BridgeCard } from '@/components/BridgeCard' 5 | import { SupportedNetworks } from '@/components/SupportedNetworks' 6 | import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs' 7 | import { useConfig } from '@/stores/useConfig' 8 | 9 | const supportedNetworkNames: NetworkName[] = [ 10 | 'sepolia', 11 | 'interop-alpha', 12 | 'supersim', 13 | ] 14 | 15 | export const BridgePage = () => { 16 | const { networkName, setNetworkName } = useConfig() 17 | const supportedNetworks = supportedNetworkNames.map((name) => networks[name]) 18 | 19 | return ( 20 |
21 | 22 | 23 | 24 | {supportedNetworks.map((network) => ( 25 | setNetworkName(network.name)} 27 | className="flex-1 relative" 28 | key={network.name} 29 | value={network.name} 30 | > 31 | {network.name} 32 | 33 | ))} 34 | 35 | 36 | {supportedNetworks.map((network) => { 37 | return ( 38 | 39 | 40 | 41 | ) 42 | })} 43 | 44 | 45 |
46 | ) 47 | } 48 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/pages/MainPage.tsx: -------------------------------------------------------------------------------- 1 | export const MainPage = () => { 2 | return ( 3 |
4 | Hello world main page 5 |
6 |
7 | ) 8 | } 9 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/stores/useConfig.ts: -------------------------------------------------------------------------------- 1 | import type { NetworkName } from '@eth-optimism/viem/chains' 2 | import { create } from 'zustand' 3 | import { persist } from 'zustand/middleware' 4 | 5 | type Config = { 6 | networkName: NetworkName 7 | setNetworkName: (networkName: NetworkName) => void 8 | 9 | rpcOverrideByChainId: Record 10 | setRpcOverrideByChainId: (chainId: number, rpcUrl: string) => void 11 | } 12 | 13 | export const useConfig = create()( 14 | persist( 15 | (set, get) => ({ 16 | networkName: 'sepolia', // Default to Sepolia 17 | setNetworkName: (networkName: NetworkName) => { 18 | set({ networkName }) 19 | }, 20 | 21 | rpcOverrideByChainId: {}, 22 | setRpcOverrideByChainId: (chainId: number, rpcUrl: string) => { 23 | set({ 24 | rpcOverrideByChainId: { 25 | ...get().rpcOverrideByChainId, 26 | [chainId]: rpcUrl, 27 | }, 28 | }) 29 | }, 30 | }), 31 | { 32 | name: 'superchain-tools-storage', 33 | }, 34 | ), 35 | ) 36 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/stores/useRecentAddressStore.ts: -------------------------------------------------------------------------------- 1 | import type { Address } from 'viem' 2 | import { create } from 'zustand' 3 | 4 | type AddressEntry = { 5 | address: Address 6 | } 7 | 8 | type AddressRecord = Record 9 | 10 | type RecentAddressStore = { 11 | addressEntryByAddress: AddressRecord 12 | addAddress: (address: Address) => void 13 | } 14 | 15 | export const useRecentAddressStore = create((set) => ({ 16 | addressEntryByAddress: { 17 | '0xAaA2b0D6295b91505500B7630e9E36a461ceAd1b': { 18 | address: '0xAaA2b0D6295b91505500B7630e9E36a461ceAd1b', 19 | }, 20 | }, 21 | 22 | addAddress: (address: Address) => { 23 | set((state) => ({ 24 | addressEntryByAddress: { 25 | [address]: { address }, 26 | ...state.addressEntryByAddress, 27 | }, 28 | })) 29 | }, 30 | })) 31 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/stores/useTransactionStore.ts: -------------------------------------------------------------------------------- 1 | import type { Hash } from 'viem' 2 | import { create } from 'zustand' 3 | import { persist } from 'zustand/middleware' 4 | 5 | type TransactionEntry = { 6 | chainId: number 7 | hash: Hash 8 | } 9 | 10 | type TransactionStore = { 11 | transactionEntryByHash: Record 12 | 13 | addTransaction: (entry: TransactionEntry) => void 14 | } 15 | 16 | export const useTransactionStore = create()( 17 | persist( 18 | (set) => ({ 19 | transactionEntryByHash: {}, 20 | 21 | addTransaction: (entry: TransactionEntry) => { 22 | set((state) => ({ 23 | transactionEntryByHash: { 24 | [entry.hash]: entry, 25 | ...state.transactionEntryByHash, 26 | }, 27 | })) 28 | }, 29 | }), 30 | { 31 | name: 'superchain-tools-transaction-store', 32 | }, 33 | ), 34 | ) 35 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/types/L2ToL2CrossDomainMessage.ts: -------------------------------------------------------------------------------- 1 | import type { Address, Hex } from "viem"; 2 | 3 | export type L2ToL2CrossDomainMessage = { 4 | destination: bigint; 5 | messageNonce: bigint; 6 | sender: Address; 7 | target: Address; 8 | message: Hex; 9 | }; 10 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/utils/formatDuration.ts: -------------------------------------------------------------------------------- 1 | export function formatDuration(totalSeconds: number): string { 2 | if (totalSeconds < 60) { 3 | return `${totalSeconds} seconds` 4 | } 5 | 6 | const hours = Math.floor(totalSeconds / 3600) 7 | const minutes = Math.floor((totalSeconds % 3600) / 60) 8 | const seconds = totalSeconds % 60 9 | 10 | const parts = [] 11 | 12 | if (hours > 0) { 13 | parts.push(`${hours} ${hours === 1 ? 'hour' : 'hours'}`) 14 | } 15 | if (minutes > 0) { 16 | parts.push(`${minutes} ${minutes === 1 ? 'minute' : 'minutes'}`) 17 | } 18 | if (seconds > 0) { 19 | parts.push(`${seconds} ${seconds === 1 ? 'second' : 'seconds'}`) 20 | } 21 | 22 | return parts.join(' ') 23 | } 24 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/utils/truncateDecimal.ts: -------------------------------------------------------------------------------- 1 | export const truncateDecimal = ( 2 | decimalString: string, 3 | maxLengthAfterDecimal = 5, 4 | ): string => { 5 | if (decimalString.includes('.')) { 6 | const parts = decimalString.split('.') 7 | const integerPart = parts[0]! 8 | const decimalPart = parts[1]! 9 | .substring(0, maxLengthAfterDecimal) 10 | .replace(/0+$/, '') 11 | 12 | return decimalPart ? `${integerPart}.${decimalPart}` : integerPart 13 | } 14 | 15 | return decimalString 16 | } 17 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | // types/mdx.d.ts 4 | declare module '*.mdx' { 5 | let MDXComponent: (props) => JSX.Element 6 | export default MDXComponent 7 | } 8 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/withdrawal-status/Finalized.tsx: -------------------------------------------------------------------------------- 1 | export const Finalized = () => { 2 | return
Transaction is finalized
3 | } 4 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/withdrawal-status/WaitingToFinalize.tsx: -------------------------------------------------------------------------------- 1 | import { Clock, Loader2 } from 'lucide-react' 2 | import type { Chain, Hash } from 'viem' 3 | 4 | import { RemainingTimeDisplay } from '@/components/RemainingTimeDisplay' 5 | import { Card, CardContent } from '@/components/ui/card' 6 | import { Skeleton } from '@/components/ui/skeleton' 7 | import { useGetTimeToFinalize } from '@/hooks/useGetTimeToFinalize' 8 | 9 | const EstimatedRemainingTime = ({ 10 | transactionHash, 11 | l2Chain, 12 | }: { 13 | transactionHash: Hash 14 | l2Chain: Chain 15 | }) => { 16 | const { data, isLoading } = useGetTimeToFinalize({ 17 | transactionHash, 18 | l2Chain, 19 | }) 20 | 21 | if (isLoading) { 22 | return ( 23 |
24 | 25 | 26 |
27 | ) 28 | } 29 | 30 | if (!data) return null 31 | 32 | return ( 33 |
34 |
35 | 36 | Estimated remaining time 37 |
38 | 39 |
40 | ) 41 | } 42 | 43 | export const WaitingToFinalize = ({ 44 | transactionHash, 45 | l2Chain, 46 | }: { 47 | transactionHash: Hash 48 | l2Chain: Chain 49 | }) => { 50 | return ( 51 | 52 | 53 |
54 | 55 | Waiting to finalize... 56 |
57 | 61 |
62 |
63 | ) 64 | } 65 | -------------------------------------------------------------------------------- /apps/superchain-playground/src/withdrawal-status/WaitingToProve.tsx: -------------------------------------------------------------------------------- 1 | import { Clock } from 'lucide-react' 2 | import type { Chain, Hash } from 'viem' 3 | 4 | import { RemainingTimeDisplay } from '@/components/RemainingTimeDisplay' 5 | import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' 6 | import { Skeleton } from '@/components/ui/skeleton' 7 | import { useGetTimeToProve } from '@/hooks/useGetTimeToProve' 8 | 9 | const EstimatedRemainingTime = ({ 10 | transactionHash, 11 | l2Chain, 12 | }: { 13 | transactionHash: Hash 14 | l2Chain: Chain 15 | }) => { 16 | const { data, isLoading } = useGetTimeToProve({ 17 | transactionHash, 18 | l2Chain, 19 | }) 20 | 21 | if (!data || isLoading) { 22 | return ( 23 |
24 | 25 | 26 |
27 | ) 28 | } 29 | 30 | return ( 31 |
32 |
33 | Estimated remaining time 34 |
35 | 36 |
37 | ) 38 | } 39 | 40 | export const WaitingToProve = ({ 41 | transactionHash, 42 | l2Chain, 43 | }: { 44 | transactionHash: Hash 45 | l2Chain: Chain 46 | }) => { 47 | return ( 48 | 49 | 50 | 51 | 52 | Waiting to prove 53 | 54 | 55 | 56 | 60 | 61 | 62 | ) 63 | } 64 | -------------------------------------------------------------------------------- /apps/superchain-playground/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "declaration": true, 5 | // Type checking 6 | "strict": true, 7 | "noUncheckedIndexedAccess": true, 8 | 9 | // Interop constraints 10 | "verbatimModuleSyntax": false, 11 | "esModuleInterop": true, 12 | "isolatedModules": true, 13 | "allowSyntheticDefaultImports": true, 14 | "resolveJsonModule": true, 15 | 16 | // Paths 17 | "paths": { 18 | "@/*": ["./src/*"] 19 | }, 20 | 21 | // Language and environment 22 | "moduleResolution": "bundler", 23 | "module": "ESNext", 24 | "lib": ["ES2022", "DOM", "DOM.Iterable"], 25 | "target": "ES2022", 26 | "outDir": "dist", 27 | "noEmit": true, 28 | "jsx": "react-jsx", 29 | 30 | // Skip type checking for node modules 31 | "skipLibCheck": true 32 | }, 33 | "include": ["./**/*.ts", "./**/*.tsx"], 34 | "exclude": ["node_modules"] 35 | } 36 | -------------------------------------------------------------------------------- /apps/superchain-playground/vite.config.ts: -------------------------------------------------------------------------------- 1 | import react from '@vitejs/plugin-react' 2 | import path from 'path' 3 | import { defineConfig } from 'vite' 4 | 5 | export default defineConfig({ 6 | plugins: [react({ include: /\.(jsx|js|tsx|ts)$/ })], 7 | resolve: { 8 | alias: { 9 | '@': path.resolve(__dirname, './src'), 10 | }, 11 | }, 12 | }) 13 | -------------------------------------------------------------------------------- /lib/.gitignore: -------------------------------------------------------------------------------- 1 | forge-artifacts -------------------------------------------------------------------------------- /mise.toml: -------------------------------------------------------------------------------- 1 | [tools] 2 | node = "18.18.1" 3 | 4 | "ubi:ethereum-optimism/supersim"="0.1.0-alpha.49" 5 | 6 | # Foundry dependencies 7 | # Foundry is a special case because it supplies multiple binaries at the same 8 | # GitHub release, so we need to use the aliasing trick to get mise to not error 9 | # The git ref here should be on the `stable` branch. 10 | forge = "nightly-0dd4d3153764f4706c2c9857675e42dec64155a7" 11 | cast = "nightly-0dd4d3153764f4706c2c9857675e42dec64155a7" 12 | anvil = "nightly-0dd4d3153764f4706c2c9857675e42dec64155a7" 13 | 14 | [alias] 15 | forge = "ubi:foundry-rs/foundry[exe=forge]" 16 | cast = "ubi:foundry-rs/foundry[exe=cast]" 17 | anvil = "ubi:foundry-rs/foundry[exe=anvil]" 18 | 19 | [hooks] 20 | # Enabling corepack will install the `pnpm` package manager specified in package.json 21 | postinstall = "npx corepack enable" 22 | 23 | [settings] 24 | # Needs to be enabled for hooks to work 25 | experimental = true -------------------------------------------------------------------------------- /nx.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/nx/schemas/nx-schema.json", 3 | "neverConnectToCloud": true, 4 | "targetDefaults": { 5 | "dev": { 6 | "cache": true, 7 | "dependsOn": ["^build"] 8 | }, 9 | "generate": { 10 | "cache": true, 11 | "dependsOn": ["ecosystem:fetch:artifacts"] 12 | }, 13 | "build": { 14 | "cache": true, 15 | "dependsOn": ["^build", "^build:types"] 16 | }, 17 | "build:types": { 18 | "cache": true, 19 | "dependsOn": ["^build:types", "^build"] 20 | }, 21 | "typecheck": { 22 | "dependsOn": ["^build:types"] 23 | }, 24 | "lint": { 25 | "cache": true 26 | }, 27 | "e2e": { 28 | "cache": true 29 | } 30 | }, 31 | "namedInputs": { 32 | "default": ["{projectRoot}/**/*", "sharedGlobals"], 33 | "sharedGlobals": [ 34 | "{workspaceRoot}/.prettierrc.js", 35 | "{workspaceRoot}/.prettierignore", 36 | "{workspaceRoot}/tsconfig.base.json", 37 | "{workspaceRoot}/eslint.config.js", 38 | "{workspaceRoot}/nx.json", 39 | "{workspaceRoot}/mise.toml" 40 | ], 41 | "production": ["default"] 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /packages/supersim/.gitignore: -------------------------------------------------------------------------------- 1 | bin -------------------------------------------------------------------------------- /packages/supersim/README.md: -------------------------------------------------------------------------------- 1 | # Supersim 2 | 3 | Supersim is a lightweight tool to simulate the Superchain locally (with a single L1 and multiple OP-Stack L2s). 4 | 5 | For more detailed documentation please refer to the [supersim repo](https://github.com/ethereum-optimism/supersim) 6 | 7 | # Installation 8 | 9 | **npm** 10 | ``` 11 | npx supersim 12 | ``` 13 | 14 | **pnpm** 15 | ``` 16 | pnpm dlx supersim 17 | ``` 18 | 19 | **yarn** 20 | ``` 21 | yarn dlx supersim 22 | ``` -------------------------------------------------------------------------------- /packages/supersim/eslint.config.js: -------------------------------------------------------------------------------- 1 | const rootConfig = require('../../eslint.config.js'); 2 | 3 | // Create a new configuration that extends the root configuration 4 | module.exports = [rootConfig]; -------------------------------------------------------------------------------- /packages/supersim/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "supersim", 3 | "version": "0.1.0-alpha.49", 4 | "description": "Supersim is a lightweight tool to simulate the Superchain locally", 5 | "license": "MIT", 6 | "author": "Optimism PBC", 7 | "keywords": [ 8 | "optimism", 9 | "ethereum", 10 | "supersim", 11 | "superchain" 12 | ], 13 | "engines": { 14 | "node": ">=18.0.0" 15 | }, 16 | "bin": { 17 | "supersim": "./bin/supersim" 18 | }, 19 | "scripts": { 20 | "lint": "eslint install.js && pnpm prettier --check install.js --ignore-path \"../../.prettierignore\"", 21 | "lint:fix": "eslint install.js --fix --quiet && pnpm prettier install.js --write --loglevel=warn --ignore-path \"../../.prettierignore\"", 22 | "postinstall": "node install.js" 23 | }, 24 | "dependencies": { 25 | "follow-redirects": "^1.15.9" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/utils-app/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @eth-optimism/utils-app 2 | 3 | ## 0.0.6 4 | 5 | ### Patch Changes 6 | 7 | - [#830](https://github.com/ethereum-optimism/ecosystem/pull/830) [`1ef3b6b`](https://github.com/ethereum-optimism/ecosystem/commit/1ef3b6b777619ec85a5f6848f8eca8491279268e) Thanks [@tremarkley](https://github.com/tremarkley)! - fix: start admin api server after preMain hook 8 | 9 | ## 0.0.5 10 | 11 | ### Patch Changes 12 | 13 | - [#829](https://github.com/ethereum-optimism/ecosystem/pull/829) [`40a535f`](https://github.com/ethereum-optimism/ecosystem/commit/40a535fb51f751cf0db265b4c26fb2f1badf6f46) Thanks [@tremarkley](https://github.com/tremarkley)! - Add initializeAdminApi hook 14 | 15 | ## 0.0.4 16 | 17 | ### Patch Changes 18 | 19 | - [#790](https://github.com/ethereum-optimism/ecosystem/pull/790) [`03b307c`](https://github.com/ethereum-optimism/ecosystem/commit/03b307c9744beb834746182f402bc8f1705c8ea4) Thanks [@hamdiallam](https://github.com/hamdiallam)! - support spinning up a default admin server for every App 20 | 21 | ## 0.0.3 22 | 23 | ### Patch Changes 24 | 25 | - [#770](https://github.com/ethereum-optimism/ecosystem/pull/770) [`4a7f3be`](https://github.com/ethereum-optimism/ecosystem/commit/4a7f3be47fd7ebef846341c499588bdcb2a00773) Thanks [@tremarkley](https://github.com/tremarkley)! - initialize autorelayer-interop package 26 | 27 | ## 0.0.2 28 | 29 | ### Patch Changes 30 | 31 | - [#764](https://github.com/ethereum-optimism/ecosystem/pull/764) [`8b58cc7`](https://github.com/ethereum-optimism/ecosystem/commit/8b58cc7e852d066561f1e680fca5d29a2dd318b1) Thanks [@tremarkley](https://github.com/tremarkley)! - Update package config for publishing 32 | -------------------------------------------------------------------------------- /packages/utils-app/README.md: -------------------------------------------------------------------------------- 1 | # Utils-App 2 | 3 | A general framework for creating typescript applications. 4 | 5 | - Handles application lifecycle 6 | - Metrics server configuration 7 | - CLI configuration 8 | 9 | ## Configuration 10 | 11 | A set of default options are provided to every instance of `App`. 12 | 13 | ```bash 14 | --log-level Set log level (choices: "debug", "info", "warn", "error", "silent", default: "debug", env: LOG_LEVEL) 15 | --admin-enabled Enable admin API server (default: false, env: ADMIN_ENABLED) 16 | --admin-port Port for admin API (default: "9000", env: ADMIN_PORT) 17 | --metrics-enabled Enable metrics collection (default: false, env: METRICS_ENABLED) 18 | --metrics-port Port for metrics server (default: "7300", env: METRICS_PORT) 19 | ``` 20 | 21 | - The [Hono](https://hono.dev/docs/getting-started/nodejs) admin api, logger, and all [commander options](https://www.npmjs.com/package/commander) are available as properties on `App`. 22 | 23 | - An overridable method on `App` is available, `protected additionalOptions(): []Options`, used to specify any additional cli options needed. 24 | 25 | - If enabled, the metrics server emits metrics under the `/metrics` path. 26 | 27 | ## Lifecycle 28 | 29 | The application lifecycle follows 30 | 31 | 1. preMain(): _validate options and admin api registration prior to running app_ 32 | 2. main(): _implementation of app logic_ 33 | 3. shutdown() : _triggered on interruption or executed after the return of main_ 34 | - _This MUST cause the resolution of the main promise in order for graceful shutdown. After the 5th interruption, the process is forcefully exited._ 35 | -------------------------------------------------------------------------------- /packages/utils-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@eth-optimism/utils-app", 3 | "repository": { 4 | "type": "git", 5 | "url": "https://github.com/ethereum-optimism/ecosystem.git", 6 | "directory": "packages/utils-app" 7 | }, 8 | "homepage": "https://github.com/ethereum-optimism/ecosystem/tree/main/packages/utils-app#readme", 9 | "bugs": { 10 | "url": "https://github.com/ethereum-optimism/ecosystem/issues" 11 | }, 12 | "version": "0.0.6", 13 | "type": "module", 14 | "main": "./dist/App.js", 15 | "module": "./dist/App.js", 16 | "types": "./dist/App.d.ts", 17 | "files": [ 18 | "dist/*" 19 | ], 20 | "exports": { 21 | ".": { 22 | "types": "./dist/App.d.ts", 23 | "import": "./dist/App.js" 24 | } 25 | }, 26 | "scripts": { 27 | "build": "tsc && resolve-tspaths", 28 | "lint": "eslint \"**/*.{ts,tsx}\" && pnpm prettier --check \"**/*.{ts,tsx}\" --ignore-path \"../../.prettierignore\"", 29 | "lint:fix": "eslint \"**/*.{ts,tsx}\" --fix && pnpm prettier \"**/*.{ts,tsx}\" --write --loglevel=warn --ignore-path \"../../.prettierignore\"", 30 | "typecheck": "tsc" 31 | }, 32 | "peerDependencies": { 33 | "@hono/node-server": "^1.14.0", 34 | "hono": "^4.5.0", 35 | "commander": "^13.1.0", 36 | "pino": "^9.6.0", 37 | "pino-pretty": "^13.0.0", 38 | "prom-client": "^15.1.0" 39 | } 40 | } -------------------------------------------------------------------------------- /packages/utils-app/src/middleware.ts: -------------------------------------------------------------------------------- 1 | import { createMiddleware } from 'hono/factory' 2 | import type { Logger } from 'pino' 3 | 4 | /** 5 | * Middleware to log requests to the server. 6 | * @param log - the logger. 7 | * @returns Hono middleware function. 8 | */ 9 | export function requestLoggingMiddleware(log: Logger) { 10 | return createMiddleware(async (c, next) => { 11 | const { req } = c 12 | const now = Date.now() 13 | await next() 14 | const ms = Date.now() - now 15 | log.info(`${req.method} ${req.path} - ${ms}ms`) 16 | }) 17 | } 18 | -------------------------------------------------------------------------------- /packages/utils-app/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "include": ["src"], 4 | "compilerOptions": { 5 | "rootDir": "src", 6 | "baseUrl": ".", 7 | "paths": { 8 | "@/*": ["./src/*"] 9 | }, 10 | "target": "es2021", 11 | "lib": ["esnext"], 12 | "strict": true, 13 | "composite": true, 14 | "outDir": "dist", 15 | "moduleResolution": "NodeNext", 16 | "module": "NodeNext", 17 | "sourceMap": true 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/viem/.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | src/test/*.txt -------------------------------------------------------------------------------- /packages/viem/README.md: -------------------------------------------------------------------------------- 1 | # @eth-optimism/viem 2 | 3 | This package is a TypeScript extension for Viem that provides actions and utilities for working with OP stack chains. The goal of this package is to upstream as many actions and utilities as possible directly into Viem. You can view this as a playground for new features that haven't hit mainnet yet or more experimental features in the OP stack. 4 | 5 | ### Documentation 6 | 7 | - [SDK Reference](./docs/README.md) 8 | 9 | ### Code Snippets 10 | 11 | - [Interop](./docs/actions/interop/README.md) 12 | 13 | ### Running Tests 14 | 15 | Before you can run the unit tests you'll need [supersim](https://github.com/ethereum-optimism/supersim) installed. Once you have supersim installed you can run `pnpm nx run @eth-optimism/viem:test` from the root of the monorepo to get the tests running. 16 | -------------------------------------------------------------------------------- /packages/viem/docs/README.md: -------------------------------------------------------------------------------- 1 | **@eth-optimism/viem** • **Docs** 2 | 3 | *** 4 | 5 | # @eth-optimism/viem 6 | 7 | ## Modules 8 | 9 | - [actions/interop](actions/interop/README.md) 10 | - [chains](chains/README.md) 11 | - [index](index/README.md) 12 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/functions/buildExecutingMessage.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / buildExecutingMessage 6 | 7 | # buildExecutingMessage() 8 | 9 | > **buildExecutingMessage**\<`TChain`, `TAccount`\>(`client`, `params`): `Promise`\<[`BuildExecutingMessageReturnType`](../type-aliases/BuildExecutingMessageReturnType.md)\> 10 | 11 | Build an executing message from a log 12 | 13 | ## Type Parameters 14 | 15 | • **TChain** *extends* `undefined` \| `Chain` 16 | 17 | • **TAccount** *extends* `undefined` \| `Account` 18 | 19 | ## Parameters 20 | 21 | • **client**: `Client`\<`Transport`, `TChain`, `TAccount`\> 22 | 23 | client to the chain that emitted the log 24 | 25 | • **params**: [`BuildExecutingMessageParameters`](../type-aliases/BuildExecutingMessageParameters.md) 26 | 27 | [BuildExecutingMessageParameters](../type-aliases/BuildExecutingMessageParameters.md) 28 | 29 | ## Returns 30 | 31 | `Promise`\<[`BuildExecutingMessageReturnType`](../type-aliases/BuildExecutingMessageReturnType.md)\> 32 | 33 | - [BuildExecutingMessageReturnType](../type-aliases/BuildExecutingMessageReturnType.md) 34 | 35 | ## Example 36 | 37 | ```ts 38 | import { createPublicClient } from 'viem' 39 | import { http } from 'viem/transports' 40 | import { op } from '@eth-optimism/viem/chains' 41 | 42 | const publicClientOp = createPublicClient({ chain: op, transport: http() }) 43 | const receipt = await publicClientOp.getTransactionReceipt({ hash: '0x...' }) 44 | const params = await buildExecutingMessage(publicClientOp, { log: receipt.logs[0] }) 45 | ``` 46 | 47 | ## Defined in 48 | 49 | [packages/viem/src/actions/interop/buildExecutingMessage.ts:58](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/buildExecutingMessage.ts#L58) 50 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/functions/estimateRelayCrossDomainMessageGas.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / estimateRelayCrossDomainMessageGas 6 | 7 | # estimateRelayCrossDomainMessageGas() 8 | 9 | > **estimateRelayCrossDomainMessageGas**\<`TChain`, `TAccount`, `TChainOverride`\>(`client`, `parameters`): `Promise`\<`bigint`\> 10 | 11 | Estimates gas for [relayCrossDomainMessage](relayCrossDomainMessage.md) 12 | 13 | ## Type Parameters 14 | 15 | • **TChain** *extends* `undefined` \| `Chain` 16 | 17 | • **TAccount** *extends* `undefined` \| `Account` 18 | 19 | • **TChainOverride** *extends* `undefined` \| `Chain` = `undefined` 20 | 21 | ## Parameters 22 | 23 | • **client**: `Client`\<`Transport`, `TChain`, `TAccount`\> 24 | 25 | L2 Client 26 | 27 | • **parameters**: [`RelayCrossDomainMessageParameters`](../type-aliases/RelayCrossDomainMessageParameters.md)\<`TChain`, `TAccount`, `TChainOverride`, `DeriveChain`\<`TChain`, `TChainOverride`\>\> 28 | 29 | [RelayCrossDomainMessageParameters](../type-aliases/RelayCrossDomainMessageParameters.md) 30 | 31 | ## Returns 32 | 33 | `Promise`\<`bigint`\> 34 | 35 | estimated gas value. 36 | 37 | ## Defined in 38 | 39 | [packages/viem/src/actions/interop/relayCrossDomainMessage.ts:120](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/relayCrossDomainMessage.ts#L120) 40 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/functions/estimateSendCrossDomainMessageGas.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / estimateSendCrossDomainMessageGas 6 | 7 | # estimateSendCrossDomainMessageGas() 8 | 9 | > **estimateSendCrossDomainMessageGas**\<`TChain`, `TAccount`, `TChainOverride`\>(`client`, `parameters`): `Promise`\<`bigint`\> 10 | 11 | Estimates gas for sendMessage 12 | 13 | ## Type Parameters 14 | 15 | • **TChain** *extends* `undefined` \| `Chain` 16 | 17 | • **TAccount** *extends* `undefined` \| `Account` 18 | 19 | • **TChainOverride** *extends* `undefined` \| `Chain` = `undefined` 20 | 21 | ## Parameters 22 | 23 | • **client**: `Client`\<`Transport`, `TChain`, `TAccount`\> 24 | 25 | L2 Client 26 | 27 | • **parameters**: [`SendCrossDomainMessageParameters`](../type-aliases/SendCrossDomainMessageParameters.md)\<`TChain`, `TAccount`, `TChainOverride`, `DeriveChain`\<`TChain`, `TChainOverride`\>\> 28 | 29 | [SendCrossDomainMessageParameters](../type-aliases/SendCrossDomainMessageParameters.md) 30 | 31 | ## Returns 32 | 33 | `Promise`\<`bigint`\> 34 | 35 | estimated gas value. 36 | 37 | ## Defined in 38 | 39 | [packages/viem/src/actions/interop/sendCrossDomainMessage.ts:106](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/sendCrossDomainMessage.ts#L106) 40 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/functions/estimateSendETHGas.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / estimateSendETHGas 6 | 7 | # estimateSendETHGas() 8 | 9 | > **estimateSendETHGas**\<`TChain`, `TAccount`, `TChainOverride`\>(`client`, `parameters`): `Promise`\<`bigint`\> 10 | 11 | Estimates gas for [sendETH](sendETH.md) 12 | 13 | ## Type Parameters 14 | 15 | • **TChain** *extends* `undefined` \| `Chain` 16 | 17 | • **TAccount** *extends* `undefined` \| `Account` 18 | 19 | • **TChainOverride** *extends* `undefined` \| `Chain` = `undefined` 20 | 21 | ## Parameters 22 | 23 | • **client**: `Client`\<`Transport`, `TChain`, `TAccount`\> 24 | 25 | L2 Client 26 | 27 | • **parameters**: [`SendETHParameters`](../type-aliases/SendETHParameters.md)\<`TChain`, `TAccount`, `TChainOverride`, `DeriveChain`\<`TChain`, `TChainOverride`\>\> 28 | 29 | [SendETHParameters](../type-aliases/SendETHParameters.md) 30 | 31 | ## Returns 32 | 33 | `Promise`\<`bigint`\> 34 | 35 | estimated gas value. 36 | 37 | ## Defined in 38 | 39 | [packages/viem/src/actions/interop/sendETH.ts:96](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/sendETH.ts#L96) 40 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/functions/estimateSendSuperchainERC20Gas.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / estimateSendSuperchainERC20Gas 6 | 7 | # estimateSendSuperchainERC20Gas() 8 | 9 | > **estimateSendSuperchainERC20Gas**\<`TChain`, `TAccount`, `TChainOverride`\>(`client`, `parameters`): `Promise`\<`bigint`\> 10 | 11 | Estimates gas for [sendSuperchainERC20](sendSuperchainERC20.md) 12 | 13 | ## Type Parameters 14 | 15 | • **TChain** *extends* `undefined` \| `Chain` 16 | 17 | • **TAccount** *extends* `undefined` \| `Account` 18 | 19 | • **TChainOverride** *extends* `undefined` \| `Chain` = `undefined` 20 | 21 | ## Parameters 22 | 23 | • **client**: `Client`\<`Transport`, `TChain`, `TAccount`\> 24 | 25 | L2 Client 26 | 27 | • **parameters**: [`SendSuperchainERC20Parameters`](../type-aliases/SendSuperchainERC20Parameters.md)\<`TChain`, `TAccount`, `TChainOverride`, `DeriveChain`\<`TChain`, `TChainOverride`\>\> 28 | 29 | [SendSuperchainERC20Parameters](../type-aliases/SendSuperchainERC20Parameters.md) 30 | 31 | ## Returns 32 | 33 | `Promise`\<`bigint`\> 34 | 35 | estimated gas value. 36 | 37 | ## Defined in 38 | 39 | [packages/viem/src/actions/interop/sendSuperchainERC20.ts:106](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/sendSuperchainERC20.ts#L106) 40 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/functions/getCrossDomainMessageStatus.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / getCrossDomainMessageStatus 6 | 7 | # getCrossDomainMessageStatus() 8 | 9 | > **getCrossDomainMessageStatus**\<`TChain`, `TAccount`\>(`client`, `parameters`): `Promise`\<[`GetCrossDomainMessageStatusReturnType`](../type-aliases/GetCrossDomainMessageStatusReturnType.md)\> 10 | 11 | Get the status of a cross domain message 12 | 13 | ## Type Parameters 14 | 15 | • **TChain** *extends* `undefined` \| `Chain` 16 | 17 | • **TAccount** *extends* `undefined` \| `Account` 18 | 19 | ## Parameters 20 | 21 | • **client**: `Client`\<`Transport`, `TChain`, `TAccount`\> 22 | 23 | The client to use 24 | 25 | • **parameters**: [`GetCrossDomainMessageStatusParameters`](../type-aliases/GetCrossDomainMessageStatusParameters.md) 26 | 27 | [GetCrossDomainMessageStatusParameters](../type-aliases/GetCrossDomainMessageStatusParameters.md) 28 | 29 | ## Returns 30 | 31 | `Promise`\<[`GetCrossDomainMessageStatusReturnType`](../type-aliases/GetCrossDomainMessageStatusReturnType.md)\> 32 | 33 | status -[GetCrossDomainMessageStatusReturnType](../type-aliases/GetCrossDomainMessageStatusReturnType.md) 34 | 35 | ## Example 36 | 37 | ```ts 38 | import { createPublicClient } from 'viem' 39 | import { op, unichain } from '@eth-optimism/viem/chains' 40 | 41 | const publicClientOp = createPublicClient({ chain: op, transport: http() }) 42 | const publicClientUnichain = createPublicClient({ chain: unichain, transport: http() }) 43 | 44 | const receipt = await publicClientOp.getTransactionReceipt({ hash: '0x...' }) 45 | const messages = await getCrossDomainMessages(publicClientOp, { logs: receipt.logs }) 46 | 47 | const message = messages.filter((message) => message.destination === unichain.id)[0] 48 | const status = await getCrossDomainMessageStatus(publicClientUnichain, { message }) 49 | ``` 50 | 51 | ## Defined in 52 | 53 | [packages/viem/src/actions/interop/getCrossDomainMessageStatus.ts:53](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/getCrossDomainMessageStatus.ts#L53) 54 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/functions/getCrossDomainMessages.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / getCrossDomainMessages 6 | 7 | # getCrossDomainMessages() 8 | 9 | > **getCrossDomainMessages**\<`TChain`, `TAccount`\>(`client`, `parameters`): `Promise`\<[`GetCrossDomainMessagesReturnType`](../type-aliases/GetCrossDomainMessagesReturnType.md)\> 10 | 11 | Get all cross domain messages from a set of logs 12 | 13 | ## Type Parameters 14 | 15 | • **TChain** *extends* `undefined` \| `Chain` 16 | 17 | • **TAccount** *extends* `undefined` \| `Account` 18 | 19 | ## Parameters 20 | 21 | • **client**: `Client`\<`Transport`, `TChain`, `TAccount`\> 22 | 23 | The client to use 24 | 25 | • **parameters**: [`GetCrossDomainMessagesParameters`](../type-aliases/GetCrossDomainMessagesParameters.md) 26 | 27 | [GetCrossDomainMessagesParameters](../type-aliases/GetCrossDomainMessagesParameters.md) 28 | 29 | ## Returns 30 | 31 | `Promise`\<[`GetCrossDomainMessagesReturnType`](../type-aliases/GetCrossDomainMessagesReturnType.md)\> 32 | 33 | cross domain messages - [GetCrossDomainMessagesReturnType](../type-aliases/GetCrossDomainMessagesReturnType.md) 34 | 35 | ## Example 36 | 37 | ```ts 38 | import { createPublicClient } from 'viem' 39 | import { http } from 'viem/transports' 40 | import { op } from '@eth-optimism/viem/chains' 41 | import { getCrossDomainMessages } from '@eth-optimism/viem/actions/interop' 42 | 43 | const publicClientOp = createPublicClient({ chain: op, transport: http() }) 44 | const receipt = await publicClientOp.getTransactionReceipt({ hash: '0x...' }) 45 | const messages = await getCrossDomainMessages(publicClientOp, { logs: receipt.logs }) 46 | ``` 47 | 48 | ## Defined in 49 | 50 | [packages/viem/src/actions/interop/getCrossDomainMessages.ts:33](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/getCrossDomainMessages.ts#L33) 51 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/functions/sendCrossDomainMessage.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / sendCrossDomainMessage 6 | 7 | # sendCrossDomainMessage() 8 | 9 | > **sendCrossDomainMessage**\<`chain`, `account`, `chainOverride`\>(`client`, `parameters`): `Promise`\<[`SendCrossDomainMessageReturnType`](../type-aliases/SendCrossDomainMessageReturnType.md)\> 10 | 11 | Initiates the intent of sending a L2 to L2 message. Used in the interop flow. 12 | 13 | ## Type Parameters 14 | 15 | • **chain** *extends* `undefined` \| `Chain` 16 | 17 | • **account** *extends* `undefined` \| `Account` 18 | 19 | • **chainOverride** *extends* `undefined` \| `Chain` = `undefined` 20 | 21 | ## Parameters 22 | 23 | • **client**: `Client`\<`Transport`, `chain`, `account`\> 24 | 25 | L2 Client 26 | 27 | • **parameters**: [`SendCrossDomainMessageParameters`](../type-aliases/SendCrossDomainMessageParameters.md)\<`chain`, `account`, `chainOverride`, `DeriveChain`\<`chain`, `chainOverride`\>\> 28 | 29 | [SendCrossDomainMessageParameters](../type-aliases/SendCrossDomainMessageParameters.md) 30 | 31 | ## Returns 32 | 33 | `Promise`\<[`SendCrossDomainMessageReturnType`](../type-aliases/SendCrossDomainMessageReturnType.md)\> 34 | 35 | transaction hash - [SendCrossDomainMessageReturnType](../type-aliases/SendCrossDomainMessageReturnType.md) 36 | 37 | ## Defined in 38 | 39 | [packages/viem/src/actions/interop/sendCrossDomainMessage.ts:77](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/sendCrossDomainMessage.ts#L77) 40 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/functions/sendETH.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / sendETH 6 | 7 | # sendETH() 8 | 9 | > **sendETH**\<`chain`, `account`, `chainOverride`\>(`client`, `parameters`): `Promise`\<[`SendETHContractReturnType`](../type-aliases/SendETHContractReturnType.md)\> 10 | 11 | Sends ETH to the specified recipient on the destination chain 12 | 13 | ## Type Parameters 14 | 15 | • **chain** *extends* `undefined` \| `Chain` 16 | 17 | • **account** *extends* `undefined` \| `Account` 18 | 19 | • **chainOverride** *extends* `undefined` \| `Chain` = `undefined` 20 | 21 | ## Parameters 22 | 23 | • **client**: `Client`\<`Transport`, `chain`, `account`\> 24 | 25 | L2 Client 26 | 27 | • **parameters**: [`SendETHParameters`](../type-aliases/SendETHParameters.md)\<`chain`, `account`, `chainOverride`, `DeriveChain`\<`chain`, `chainOverride`\>\> 28 | 29 | [SendETHParameters](../type-aliases/SendETHParameters.md) 30 | 31 | ## Returns 32 | 33 | `Promise`\<[`SendETHContractReturnType`](../type-aliases/SendETHContractReturnType.md)\> 34 | 35 | transaction hash - [SendETHContractReturnType](../type-aliases/SendETHContractReturnType.md) 36 | 37 | ## Defined in 38 | 39 | [packages/viem/src/actions/interop/sendETH.ts:67](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/sendETH.ts#L67) 40 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/functions/sendSuperchainERC20.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / sendSuperchainERC20 6 | 7 | # sendSuperchainERC20() 8 | 9 | > **sendSuperchainERC20**\<`chain`, `account`, `chainOverride`\>(`client`, `parameters`): `Promise`\<[`SendSuperchainERC20ReturnType`](../type-aliases/SendSuperchainERC20ReturnType.md)\> 10 | 11 | Sends tokens to a target address on another chain. Used in the interop flow. 12 | 13 | ## Type Parameters 14 | 15 | • **chain** *extends* `undefined` \| `Chain` 16 | 17 | • **account** *extends* `undefined` \| `Account` 18 | 19 | • **chainOverride** *extends* `undefined` \| `Chain` = `undefined` 20 | 21 | ## Parameters 22 | 23 | • **client**: `Client`\<`Transport`, `chain`, `account`\> 24 | 25 | L2 Client 26 | 27 | • **parameters**: [`SendSuperchainERC20Parameters`](../type-aliases/SendSuperchainERC20Parameters.md)\<`chain`, `account`, `chainOverride`, `DeriveChain`\<`chain`, `chainOverride`\>\> 28 | 29 | [SendSuperchainERC20Parameters](../type-aliases/SendSuperchainERC20Parameters.md) 30 | 31 | ## Returns 32 | 33 | `Promise`\<[`SendSuperchainERC20ReturnType`](../type-aliases/SendSuperchainERC20ReturnType.md)\> 34 | 35 | transaction hash - [SendSuperchainERC20ReturnType](../type-aliases/SendSuperchainERC20ReturnType.md) 36 | 37 | ## Defined in 38 | 39 | [packages/viem/src/actions/interop/sendSuperchainERC20.ts:77](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/sendSuperchainERC20.ts#L77) 40 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/functions/simulateRelayCrossDomainMessage.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / simulateRelayCrossDomainMessage 6 | 7 | # simulateRelayCrossDomainMessage() 8 | 9 | > **simulateRelayCrossDomainMessage**\<`TChain`, `TAccount`, `TChainOverride`\>(`client`, `parameters`): `Promise`\<[`RelayCrossDomainMessageContractReturnType`](../type-aliases/RelayCrossDomainMessageContractReturnType.md)\> 10 | 11 | Simulate contract call for [relayCrossDomainMessage](relayCrossDomainMessage.md) 12 | 13 | ## Type Parameters 14 | 15 | • **TChain** *extends* `undefined` \| `Chain` 16 | 17 | • **TAccount** *extends* `undefined` \| `Account` 18 | 19 | • **TChainOverride** *extends* `undefined` \| `Chain` = `undefined` 20 | 21 | ## Parameters 22 | 23 | • **client**: `Client`\<`Transport`, `TChain`, `TAccount`\> 24 | 25 | L2 Client 26 | 27 | • **parameters**: [`RelayCrossDomainMessageParameters`](../type-aliases/RelayCrossDomainMessageParameters.md)\<`TChain`, `TAccount`, `TChainOverride`, `DeriveChain`\<`TChain`, `TChainOverride`\>\> 28 | 29 | [RelayCrossDomainMessageParameters](../type-aliases/RelayCrossDomainMessageParameters.md) 30 | 31 | ## Returns 32 | 33 | `Promise`\<[`RelayCrossDomainMessageContractReturnType`](../type-aliases/RelayCrossDomainMessageContractReturnType.md)\> 34 | 35 | contract return value - [RelayCrossDomainMessageContractReturnType](../type-aliases/RelayCrossDomainMessageContractReturnType.md) 36 | 37 | ## Defined in 38 | 39 | [packages/viem/src/actions/interop/relayCrossDomainMessage.ts:150](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/relayCrossDomainMessage.ts#L150) 40 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/functions/simulateSendCrossDomainMessage.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / simulateSendCrossDomainMessage 6 | 7 | # simulateSendCrossDomainMessage() 8 | 9 | > **simulateSendCrossDomainMessage**\<`TChain`, `TAccount`, `TChainOverride`\>(`client`, `parameters`): `Promise`\<[`SendCrossDomainMessageContractReturnType`](../type-aliases/SendCrossDomainMessageContractReturnType.md)\> 10 | 11 | Simulate contract call for sendMessage 12 | 13 | ## Type Parameters 14 | 15 | • **TChain** *extends* `undefined` \| `Chain` 16 | 17 | • **TAccount** *extends* `undefined` \| `Account` 18 | 19 | • **TChainOverride** *extends* `undefined` \| `Chain` = `undefined` 20 | 21 | ## Parameters 22 | 23 | • **client**: `Client`\<`Transport`, `TChain`, `TAccount`\> 24 | 25 | L2 Client 26 | 27 | • **parameters**: [`SendCrossDomainMessageParameters`](../type-aliases/SendCrossDomainMessageParameters.md)\<`TChain`, `TAccount`, `TChainOverride`, `DeriveChain`\<`TChain`, `TChainOverride`\>\> 28 | 29 | [SendCrossDomainMessageParameters](../type-aliases/SendCrossDomainMessageParameters.md) 30 | 31 | ## Returns 32 | 33 | `Promise`\<[`SendCrossDomainMessageContractReturnType`](../type-aliases/SendCrossDomainMessageContractReturnType.md)\> 34 | 35 | contract return value - [SendCrossDomainMessageContractReturnType](../type-aliases/SendCrossDomainMessageContractReturnType.md) 36 | 37 | ## Defined in 38 | 39 | [packages/viem/src/actions/interop/sendCrossDomainMessage.ts:136](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/sendCrossDomainMessage.ts#L136) 40 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/functions/simulateSendETH.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / simulateSendETH 6 | 7 | # simulateSendETH() 8 | 9 | > **simulateSendETH**\<`TChain`, `TAccount`, `TChainOverride`\>(`client`, `parameters`): `Promise`\<[`SendETHContractReturnType`](../type-aliases/SendETHContractReturnType.md)\> 10 | 11 | Simulate contract call for [sendETH](sendETH.md) 12 | 13 | ## Type Parameters 14 | 15 | • **TChain** *extends* `undefined` \| `Chain` 16 | 17 | • **TAccount** *extends* `undefined` \| `Account` 18 | 19 | • **TChainOverride** *extends* `undefined` \| `Chain` = `undefined` 20 | 21 | ## Parameters 22 | 23 | • **client**: `Client`\<`Transport`, `TChain`, `TAccount`\> 24 | 25 | L2 Client 26 | 27 | • **parameters**: [`SendETHParameters`](../type-aliases/SendETHParameters.md)\<`TChain`, `TAccount`, `TChainOverride`, `DeriveChain`\<`TChain`, `TChainOverride`\>\> 28 | 29 | [SendETHParameters](../type-aliases/SendETHParameters.md) 30 | 31 | ## Returns 32 | 33 | `Promise`\<[`SendETHContractReturnType`](../type-aliases/SendETHContractReturnType.md)\> 34 | 35 | contract return value - [SendETHContractReturnType](../type-aliases/SendETHContractReturnType.md) 36 | 37 | ## Defined in 38 | 39 | [packages/viem/src/actions/interop/sendETH.ts:122](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/sendETH.ts#L122) 40 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/functions/simulateSendSuperchainERC20.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / simulateSendSuperchainERC20 6 | 7 | # simulateSendSuperchainERC20() 8 | 9 | > **simulateSendSuperchainERC20**\<`TChain`, `TAccount`, `TChainOverride`\>(`client`, `parameters`): `Promise`\<[`SendSuperchainERC20ContractReturnType`](../type-aliases/SendSuperchainERC20ContractReturnType.md)\> 10 | 11 | Simulate contract call for [sendSuperchainERC20](sendSuperchainERC20.md) 12 | 13 | ## Type Parameters 14 | 15 | • **TChain** *extends* `undefined` \| `Chain` 16 | 17 | • **TAccount** *extends* `undefined` \| `Account` 18 | 19 | • **TChainOverride** *extends* `undefined` \| `Chain` = `undefined` 20 | 21 | ## Parameters 22 | 23 | • **client**: `Client`\<`Transport`, `TChain`, `TAccount`\> 24 | 25 | L2 Client 26 | 27 | • **parameters**: [`SendSuperchainERC20Parameters`](../type-aliases/SendSuperchainERC20Parameters.md)\<`TChain`, `TAccount`, `TChainOverride`, `DeriveChain`\<`TChain`, `TChainOverride`\>\> 28 | 29 | [SendSuperchainERC20Parameters](../type-aliases/SendSuperchainERC20Parameters.md) 30 | 31 | ## Returns 32 | 33 | `Promise`\<[`SendSuperchainERC20ContractReturnType`](../type-aliases/SendSuperchainERC20ContractReturnType.md)\> 34 | 35 | contract return value - [SendSuperchainERC20ContractReturnType](../type-aliases/SendSuperchainERC20ContractReturnType.md) 36 | 37 | ## Defined in 38 | 39 | [packages/viem/src/actions/interop/sendSuperchainERC20.ts:132](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/sendSuperchainERC20.ts#L132) 40 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/type-aliases/BuildExecutingMessageParameters.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / BuildExecutingMessageParameters 6 | 7 | # BuildExecutingMessageParameters 8 | 9 | > **BuildExecutingMessageParameters**: `object` 10 | 11 | ## Type declaration 12 | 13 | ### log 14 | 15 | > **log**: `Log` 16 | 17 | ## Defined in 18 | 19 | [packages/viem/src/actions/interop/buildExecutingMessage.ts:15](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/buildExecutingMessage.ts#L15) 20 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/type-aliases/BuildExecutingMessageReturnType.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / BuildExecutingMessageReturnType 6 | 7 | # BuildExecutingMessageReturnType 8 | 9 | > **BuildExecutingMessageReturnType**: `object` 10 | 11 | ## Type declaration 12 | 13 | ### accessList 14 | 15 | > **accessList**: `AccessList` 16 | 17 | ### id 18 | 19 | > **id**: [`MessageIdentifier`](../../../index/type-aliases/MessageIdentifier.md) 20 | 21 | ### payload 22 | 23 | > **payload**: `MessagePayload` 24 | 25 | ## Defined in 26 | 27 | [packages/viem/src/actions/interop/buildExecutingMessage.ts:20](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/buildExecutingMessage.ts#L20) 28 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/type-aliases/GetCrossDomainMessageStatusParameters.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / GetCrossDomainMessageStatusParameters 6 | 7 | # GetCrossDomainMessageStatusParameters 8 | 9 | > **GetCrossDomainMessageStatusParameters**: `object` 10 | 11 | ## Type declaration 12 | 13 | ### message 14 | 15 | > **message**: `CrossDomainMessage` 16 | 17 | ## Defined in 18 | 19 | [packages/viem/src/actions/interop/getCrossDomainMessageStatus.ts:13](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/getCrossDomainMessageStatus.ts#L13) 20 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/type-aliases/GetCrossDomainMessageStatusReturnType.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / GetCrossDomainMessageStatusReturnType 6 | 7 | # GetCrossDomainMessageStatusReturnType 8 | 9 | > **GetCrossDomainMessageStatusReturnType**: `"ready-to-relay"` \| `"relayed"` 10 | 11 | ## Defined in 12 | 13 | [packages/viem/src/actions/interop/getCrossDomainMessageStatus.ts:20](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/getCrossDomainMessageStatus.ts#L20) 14 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/type-aliases/GetCrossDomainMessagesParameters.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / GetCrossDomainMessagesParameters 6 | 7 | # GetCrossDomainMessagesParameters 8 | 9 | > **GetCrossDomainMessagesParameters**: `object` 10 | 11 | ## Type declaration 12 | 13 | ### logs 14 | 15 | > **logs**: `Log`[] 16 | 17 | ## Defined in 18 | 19 | [packages/viem/src/actions/interop/getCrossDomainMessages.ts:10](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/getCrossDomainMessages.ts#L10) 20 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/type-aliases/GetCrossDomainMessagesReturnType.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / GetCrossDomainMessagesReturnType 6 | 7 | # GetCrossDomainMessagesReturnType 8 | 9 | > **GetCrossDomainMessagesReturnType**: `CrossDomainMessage`[] 10 | 11 | ## Defined in 12 | 13 | [packages/viem/src/actions/interop/getCrossDomainMessages.ts:15](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/getCrossDomainMessages.ts#L15) 14 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/type-aliases/RelayCrossDomainMessageContractReturnType.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / RelayCrossDomainMessageContractReturnType 6 | 7 | # RelayCrossDomainMessageContractReturnType 8 | 9 | > **RelayCrossDomainMessageContractReturnType**: `ContractFunctionReturnType`\<*typeof* [`l2ToL2CrossDomainMessengerAbi`](../../../index/variables/l2ToL2CrossDomainMessengerAbi.md), `"payable"`, `"relayMessage"`\> 10 | 11 | ## Defined in 12 | 13 | [packages/viem/src/actions/interop/relayCrossDomainMessage.ts:50](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/relayCrossDomainMessage.ts#L50) 14 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/type-aliases/RelayCrossDomainMessageErrorType.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / RelayCrossDomainMessageErrorType 6 | 7 | # RelayCrossDomainMessageErrorType 8 | 9 | > **RelayCrossDomainMessageErrorType**: `EstimateContractGasErrorType` \| `WriteContractErrorType` \| `ErrorType` 10 | 11 | ## Defined in 12 | 13 | [packages/viem/src/actions/interop/relayCrossDomainMessage.ts:60](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/relayCrossDomainMessage.ts#L60) 14 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/type-aliases/RelayCrossDomainMessageParameters.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / RelayCrossDomainMessageParameters 6 | 7 | # RelayCrossDomainMessageParameters\ 8 | 9 | > **RelayCrossDomainMessageParameters**\<`TChain`, `TAccount`, `TChainOverride`, `TDerivedChain`\>: `BaseWriteContractActionParameters`\<`TChain`, `TAccount`, `TChainOverride`, `TDerivedChain`\> & [`BuildExecutingMessageReturnType`](BuildExecutingMessageReturnType.md) 10 | 11 | ## Type Parameters 12 | 13 | • **TChain** *extends* `Chain` \| `undefined` = `Chain` \| `undefined` 14 | 15 | • **TAccount** *extends* `Account` \| `undefined` = `Account` \| `undefined` 16 | 17 | • **TChainOverride** *extends* `Chain` \| `undefined` = `Chain` \| `undefined` 18 | 19 | • **TDerivedChain** *extends* `Chain` \| `undefined` = `DeriveChain`\<`TChain`, `TChainOverride`\> 20 | 21 | ## Defined in 22 | 23 | [packages/viem/src/actions/interop/relayCrossDomainMessage.ts:28](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/relayCrossDomainMessage.ts#L28) 24 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/type-aliases/RelayCrossDomainMessageReturnType.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / RelayCrossDomainMessageReturnType 6 | 7 | # RelayCrossDomainMessageReturnType 8 | 9 | > **RelayCrossDomainMessageReturnType**: `Hash` 10 | 11 | ## Defined in 12 | 13 | [packages/viem/src/actions/interop/relayCrossDomainMessage.ts:45](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/relayCrossDomainMessage.ts#L45) 14 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/type-aliases/SendCrossDomainMessageContractReturnType.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / SendCrossDomainMessageContractReturnType 6 | 7 | # SendCrossDomainMessageContractReturnType 8 | 9 | > **SendCrossDomainMessageContractReturnType**: `ContractFunctionReturnType`\<*typeof* [`l2ToL2CrossDomainMessengerAbi`](../../../index/variables/l2ToL2CrossDomainMessengerAbi.md), `"nonpayable"`, `"sendMessage"`\> 10 | 11 | ## Defined in 12 | 13 | [packages/viem/src/actions/interop/sendCrossDomainMessage.ts:55](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/sendCrossDomainMessage.ts#L55) 14 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/type-aliases/SendCrossDomainMessageErrorType.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / SendCrossDomainMessageErrorType 6 | 7 | # SendCrossDomainMessageErrorType 8 | 9 | > **SendCrossDomainMessageErrorType**: `EstimateContractGasErrorType` \| `WriteContractErrorType` \| `ErrorType` 10 | 11 | ## Defined in 12 | 13 | [packages/viem/src/actions/interop/sendCrossDomainMessage.ts:65](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/sendCrossDomainMessage.ts#L65) 14 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/type-aliases/SendCrossDomainMessageParameters.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / SendCrossDomainMessageParameters 6 | 7 | # SendCrossDomainMessageParameters\ 8 | 9 | > **SendCrossDomainMessageParameters**\<`TChain`, `TAccount`, `TChainOverride`, `TDerivedChain`\>: `BaseWriteContractActionParameters`\<`TChain`, `TAccount`, `TChainOverride`, `TDerivedChain`\> & `object` 10 | 11 | ## Type declaration 12 | 13 | ### destinationChainId 14 | 15 | > **destinationChainId**: `number` 16 | 17 | Chain ID of the destination chain. 18 | 19 | ### message 20 | 21 | > **message**: `Hex` 22 | 23 | Message payload to call target with. 24 | 25 | ### target 26 | 27 | > **target**: `Address` 28 | 29 | Target contract or wallet address. 30 | 31 | ## Type Parameters 32 | 33 | • **TChain** *extends* `Chain` \| `undefined` = `Chain` \| `undefined` 34 | 35 | • **TAccount** *extends* `Account` \| `undefined` = `Account` \| `undefined` 36 | 37 | • **TChainOverride** *extends* `Chain` \| `undefined` = `Chain` \| `undefined` 38 | 39 | • **TDerivedChain** *extends* `Chain` \| `undefined` = `DeriveChain`\<`TChain`, `TChainOverride`\> 40 | 41 | ## Defined in 42 | 43 | [packages/viem/src/actions/interop/sendCrossDomainMessage.ts:28](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/sendCrossDomainMessage.ts#L28) 44 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/type-aliases/SendCrossDomainMessageReturnType.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / SendCrossDomainMessageReturnType 6 | 7 | # SendCrossDomainMessageReturnType 8 | 9 | > **SendCrossDomainMessageReturnType**: `Hash` 10 | 11 | ## Defined in 12 | 13 | [packages/viem/src/actions/interop/sendCrossDomainMessage.ts:50](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/sendCrossDomainMessage.ts#L50) 14 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/type-aliases/SendETHContractReturnType.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / SendETHContractReturnType 6 | 7 | # SendETHContractReturnType 8 | 9 | > **SendETHContractReturnType**: `ContractFunctionReturnType`\<*typeof* [`superchainETHBridgeAbi`](../../../index/variables/superchainETHBridgeAbi.md), `"payable"`, `"sendETH"`\> 10 | 11 | ## Defined in 12 | 13 | [packages/viem/src/actions/interop/sendETH.ts:46](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/sendETH.ts#L46) 14 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/type-aliases/SendETHErrorType.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / SendETHErrorType 6 | 7 | # SendETHErrorType 8 | 9 | > **SendETHErrorType**: `EstimateContractGasErrorType` \| `WriteContractErrorType` \| `ErrorType` 10 | 11 | ## Defined in 12 | 13 | [packages/viem/src/actions/interop/sendETH.ts:55](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/sendETH.ts#L55) 14 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/type-aliases/SendETHParameters.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / SendETHParameters 6 | 7 | # SendETHParameters\ 8 | 9 | > **SendETHParameters**\<`TChain`, `TAccount`, `TChainOverride`, `TDerivedChain`\>: `BaseWriteContractActionParameters`\<`TChain`, `TAccount`, `TChainOverride`, `TDerivedChain`\> & `object` 10 | 11 | ## Type declaration 12 | 13 | ### chainId 14 | 15 | > **chainId**: `number` 16 | 17 | Chain ID of the destination chain. 18 | 19 | ### to 20 | 21 | > **to**: `Address` 22 | 23 | Address to send ETH to. 24 | 25 | ## Type Parameters 26 | 27 | • **TChain** *extends* `Chain` \| `undefined` = `Chain` \| `undefined` 28 | 29 | • **TAccount** *extends* `Account` \| `undefined` = `Account` \| `undefined` 30 | 31 | • **TChainOverride** *extends* `Chain` \| `undefined` = `Chain` \| `undefined` 32 | 33 | • **TDerivedChain** *extends* `Chain` \| `undefined` = `DeriveChain`\<`TChain`, `TChainOverride`\> 34 | 35 | ## Defined in 36 | 37 | [packages/viem/src/actions/interop/sendETH.ts:26](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/sendETH.ts#L26) 38 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/type-aliases/SendSuperchainERC20ContractReturnType.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / SendSuperchainERC20ContractReturnType 6 | 7 | # SendSuperchainERC20ContractReturnType 8 | 9 | > **SendSuperchainERC20ContractReturnType**: `ContractFunctionReturnType`\<*typeof* [`superchainTokenBridgeAbi`](../../../index/variables/superchainTokenBridgeAbi.md), `"nonpayable"`, `"sendERC20"`\> 10 | 11 | ## Defined in 12 | 13 | [packages/viem/src/actions/interop/sendSuperchainERC20.ts:56](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/sendSuperchainERC20.ts#L56) 14 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/type-aliases/SendSuperchainERC20ErrorType.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / SendSuperchainERC20ErrorType 6 | 7 | # SendSuperchainERC20ErrorType 8 | 9 | > **SendSuperchainERC20ErrorType**: `EstimateContractGasErrorType` \| `WriteContractErrorType` \| `ErrorType` 10 | 11 | ## Defined in 12 | 13 | [packages/viem/src/actions/interop/sendSuperchainERC20.ts:65](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/sendSuperchainERC20.ts#L65) 14 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/type-aliases/SendSuperchainERC20Parameters.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / SendSuperchainERC20Parameters 6 | 7 | # SendSuperchainERC20Parameters\ 8 | 9 | > **SendSuperchainERC20Parameters**\<`TChain`, `TAccount`, `TChainOverride`, `TDerivedChain`\>: `BaseWriteContractActionParameters`\<`TChain`, `TAccount`, `TChainOverride`, `TDerivedChain`\> & `object` 10 | 11 | ## Type declaration 12 | 13 | ### amount 14 | 15 | > **amount**: `bigint` 16 | 17 | Amount of tokens to send. 18 | 19 | ### chainId 20 | 21 | > **chainId**: `number` 22 | 23 | Chain ID of the destination chain. 24 | 25 | ### to 26 | 27 | > **to**: `Address` 28 | 29 | Address to send tokens to. 30 | 31 | ### tokenAddress 32 | 33 | > **tokenAddress**: `Address` 34 | 35 | Token to send. 36 | 37 | ## Type Parameters 38 | 39 | • **TChain** *extends* `Chain` \| `undefined` = `Chain` \| `undefined` 40 | 41 | • **TAccount** *extends* `Account` \| `undefined` = `Account` \| `undefined` 42 | 43 | • **TChainOverride** *extends* `Chain` \| `undefined` = `Chain` \| `undefined` 44 | 45 | • **TDerivedChain** *extends* `Chain` \| `undefined` = `DeriveChain`\<`TChain`, `TChainOverride`\> 46 | 47 | ## Defined in 48 | 49 | [packages/viem/src/actions/interop/sendSuperchainERC20.ts:27](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/sendSuperchainERC20.ts#L27) 50 | -------------------------------------------------------------------------------- /packages/viem/docs/actions/interop/type-aliases/SendSuperchainERC20ReturnType.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../../README.md) / [actions/interop](../README.md) / SendSuperchainERC20ReturnType 6 | 7 | # SendSuperchainERC20ReturnType 8 | 9 | > **SendSuperchainERC20ReturnType**: `Hash` 10 | 11 | ## Defined in 12 | 13 | [packages/viem/src/actions/interop/sendSuperchainERC20.ts:51](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/actions/interop/sendSuperchainERC20.ts#L51) 14 | -------------------------------------------------------------------------------- /packages/viem/docs/chains/variables/interopAlphaChains.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../README.md) / [chains](../README.md) / interopAlphaChains 6 | 7 | # interopAlphaChains 8 | 9 | > `const` **interopAlphaChains**: (`object` \| `object`)[] 10 | 11 | ## Defined in 12 | 13 | [packages/viem/src/chains/interopAlpha.ts:83](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/chains/interopAlpha.ts#L83) 14 | -------------------------------------------------------------------------------- /packages/viem/docs/chains/variables/interopRcAlphaChains.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../README.md) / [chains](../README.md) / interopRcAlphaChains 6 | 7 | # interopRcAlphaChains 8 | 9 | > `const` **interopRcAlphaChains**: (`object` \| `object`)[] 10 | 11 | ## Defined in 12 | 13 | [packages/viem/src/chains/interopRcAlpha.ts:69](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/chains/interopRcAlpha.ts#L69) 14 | -------------------------------------------------------------------------------- /packages/viem/docs/chains/variables/mainnetChains.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../README.md) / [chains](../README.md) / mainnetChains 6 | 7 | # mainnetChains 8 | 9 | > `const` **mainnetChains**: (`object` \| `object` \| `object` \| `object` \| `object` \| `object` \| `object` \| `object` \| `object` \| `object` \| `object` \| `object` \| `object` \| `object` \| `object` \| `object` \| `object` \| `object` \| `object` \| `object` \| `object` \| `object`)[] 10 | 11 | ## Defined in 12 | 13 | [packages/viem/src/chains/mainnet.ts:1363](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/chains/mainnet.ts#L1363) 14 | -------------------------------------------------------------------------------- /packages/viem/docs/chains/variables/sepoliaChains.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../README.md) / [chains](../README.md) / sepoliaChains 6 | 7 | # sepoliaChains 8 | 9 | > `const` **sepoliaChains**: (`object` \| `object` \| `object` \| `object` \| `object` \| `object` \| `object` \| `object` \| `object` \| `object` \| `object` \| `object` \| `object` \| `object` \| `object` \| `object` \| `object`)[] 10 | 11 | ## Defined in 12 | 13 | [packages/viem/src/chains/sepolia.ts:1053](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/chains/sepolia.ts#L1053) 14 | -------------------------------------------------------------------------------- /packages/viem/docs/chains/variables/supersimChains.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../README.md) / [chains](../README.md) / supersimChains 6 | 7 | # supersimChains 8 | 9 | > `const` **supersimChains**: (`object` \| `object` \| `object` \| `object` \| `object`)[] 10 | 11 | ## Defined in 12 | 13 | [packages/viem/src/chains/supersim.ts:142](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/chains/supersim.ts#L142) 14 | -------------------------------------------------------------------------------- /packages/viem/docs/index/README.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../README.md) / index 6 | 7 | # index 8 | 9 | ## Index 10 | 11 | ### ABI 12 | 13 | - [crossDomainMessengerAbi](variables/crossDomainMessengerAbi.md) 14 | - [crossL2InboxAbi](variables/crossL2InboxAbi.md) 15 | - [l2ToL2CrossDomainMessengerAbi](variables/l2ToL2CrossDomainMessengerAbi.md) 16 | - [optimismMintableERC20Abi](variables/optimismMintableERC20Abi.md) 17 | - [optimismMintableERC20FactoryAbi](variables/optimismMintableERC20FactoryAbi.md) 18 | - [standardBridgeAbi](variables/standardBridgeAbi.md) 19 | - [superchainERC20Abi](variables/superchainERC20Abi.md) 20 | - [superchainETHBridgeAbi](variables/superchainETHBridgeAbi.md) 21 | - [superchainTokenBridgeAbi](variables/superchainTokenBridgeAbi.md) 22 | 23 | ### Predeploy Addresses 24 | 25 | - [contracts](variables/contracts.md) 26 | 27 | ### Types 28 | 29 | - [MessageIdentifier](type-aliases/MessageIdentifier.md) 30 | -------------------------------------------------------------------------------- /packages/viem/docs/index/type-aliases/MessageIdentifier.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../README.md) / [index](../README.md) / MessageIdentifier 6 | 7 | # MessageIdentifier 8 | 9 | > **MessageIdentifier**: `object` 10 | 11 | Spec for [`MessageIdentifier`](https://github.com/ethereum-optimism/specs/blob/main/specs/interop/messaging.md#message-identifier). 12 | 13 | ## Type declaration 14 | 15 | ### blockNumber 16 | 17 | > **blockNumber**: `bigint` 18 | 19 | Block number in which the log was emitted 20 | 21 | ### chainId 22 | 23 | > **chainId**: `bigint` 24 | 25 | The chain that emitted the log 26 | 27 | ### logIndex 28 | 29 | > **logIndex**: `bigint` 30 | 31 | The index of the log in the array of all logs emitted in the block 32 | 33 | ### origin 34 | 35 | > **origin**: `Address` 36 | 37 | Account that emits log 38 | 39 | ### timestamp 40 | 41 | > **timestamp**: `bigint` 42 | 43 | The timestamp that the log was emitted. Used to enforce the timestamp invariant 44 | 45 | ## Defined in 46 | 47 | [packages/viem/src/types/interop/executingMessage.ts:7](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/types/interop/executingMessage.ts#L7) 48 | -------------------------------------------------------------------------------- /packages/viem/docs/index/variables/crossDomainMessengerAbi.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../README.md) / [index](../README.md) / crossDomainMessengerAbi 6 | 7 | # crossDomainMessengerAbi 8 | 9 | > `const` **crossDomainMessengerAbi**: readonly [`object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`] 10 | 11 | ABI for the OP Stack contract `CrossDomainMessenger` 12 | 13 | ## Defined in 14 | 15 | [packages/viem/src/abis.ts:7](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/abis.ts#L7) 16 | -------------------------------------------------------------------------------- /packages/viem/docs/index/variables/crossL2InboxAbi.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../README.md) / [index](../README.md) / crossL2InboxAbi 6 | 7 | # crossL2InboxAbi 8 | 9 | > `const` **crossL2InboxAbi**: readonly [`object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`] 10 | 11 | ABI for the OP Stack contract `CrossL2Inbox` 12 | 13 | ## Defined in 14 | 15 | [packages/viem/src/abis.ts:440](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/abis.ts#L440) 16 | -------------------------------------------------------------------------------- /packages/viem/docs/index/variables/l2ToL2CrossDomainMessengerAbi.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../README.md) / [index](../README.md) / l2ToL2CrossDomainMessengerAbi 6 | 7 | # l2ToL2CrossDomainMessengerAbi 8 | 9 | > `const` **l2ToL2CrossDomainMessengerAbi**: readonly [`object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`] 10 | 11 | ABI for the OP Stack contract `L2ToL2CrossDomainMessenger` 12 | 13 | ## Defined in 14 | 15 | [packages/viem/src/abis.ts:627](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/abis.ts#L627) 16 | -------------------------------------------------------------------------------- /packages/viem/docs/index/variables/optimismMintableERC20Abi.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../README.md) / [index](../README.md) / optimismMintableERC20Abi 6 | 7 | # optimismMintableERC20Abi 8 | 9 | > `const` **optimismMintableERC20Abi**: readonly [`object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`] 10 | 11 | ABI for the OP Stack contract `OptimismMintableERC20` 12 | 13 | ## Defined in 14 | 15 | [packages/viem/src/abis.ts:918](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/abis.ts#L918) 16 | -------------------------------------------------------------------------------- /packages/viem/docs/index/variables/optimismMintableERC20FactoryAbi.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../README.md) / [index](../README.md) / optimismMintableERC20FactoryAbi 6 | 7 | # optimismMintableERC20FactoryAbi 8 | 9 | > `const` **optimismMintableERC20FactoryAbi**: readonly [`object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`] 10 | 11 | ABI for the OP Stack contract `OptimismMintableERC20Factory` 12 | 13 | ## Defined in 14 | 15 | [packages/viem/src/abis.ts:1498](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/abis.ts#L1498) 16 | -------------------------------------------------------------------------------- /packages/viem/docs/index/variables/standardBridgeAbi.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../README.md) / [index](../README.md) / standardBridgeAbi 6 | 7 | # standardBridgeAbi 8 | 9 | > `const` **standardBridgeAbi**: readonly [`object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`] 10 | 11 | ABI for the OP Stack contract `StandardBridge` 12 | 13 | ## Defined in 14 | 15 | [packages/viem/src/abis.ts:1730](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/abis.ts#L1730) 16 | -------------------------------------------------------------------------------- /packages/viem/docs/index/variables/superchainERC20Abi.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../README.md) / [index](../README.md) / superchainERC20Abi 6 | 7 | # superchainERC20Abi 8 | 9 | > `const` **superchainERC20Abi**: readonly [`object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`] 10 | 11 | ABI for the OP Stack contract `SuperchainERC20` 12 | 13 | ## Defined in 14 | 15 | [packages/viem/src/abis.ts:2169](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/abis.ts#L2169) 16 | -------------------------------------------------------------------------------- /packages/viem/docs/index/variables/superchainETHBridgeAbi.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../README.md) / [index](../README.md) / superchainETHBridgeAbi 6 | 7 | # superchainETHBridgeAbi 8 | 9 | > `const` **superchainETHBridgeAbi**: readonly [`object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`] 10 | 11 | ABI for the OP Stack contract `SuperchainETHBridge` 12 | 13 | ## Defined in 14 | 15 | [packages/viem/src/abis.ts:2636](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/abis.ts#L2636) 16 | -------------------------------------------------------------------------------- /packages/viem/docs/index/variables/superchainTokenBridgeAbi.md: -------------------------------------------------------------------------------- 1 | [**@eth-optimism/viem**](../../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [@eth-optimism/viem](../../README.md) / [index](../README.md) / superchainTokenBridgeAbi 6 | 7 | # superchainTokenBridgeAbi 8 | 9 | > `const` **superchainTokenBridgeAbi**: readonly [`object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`, `object`] 10 | 11 | ABI for the OP Stack contract `SuperchainTokenBridge` 12 | 13 | ## Defined in 14 | 15 | [packages/viem/src/abis.ts:2780](https://github.com/ethereum-optimism/ecosystem/blob/11bb27f871c202b93ad6dc93c86c82f0c754075f/packages/viem/src/abis.ts#L2780) 16 | -------------------------------------------------------------------------------- /packages/viem/eslint.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'eslint/config'; 2 | 3 | import rootConfig from '../../eslint.config.js'; 4 | 5 | // Create a new configuration that extends the root configuration 6 | export default defineConfig([{ 7 | ...rootConfig, 8 | ignores: [...rootConfig.ignores, '**/dist/**'], 9 | rules: { 10 | ...rootConfig.rules, 11 | '@typescript-eslint/no-unused-vars': [ 12 | 'error', 13 | { varsIgnorePattern: '_', argsIgnorePattern: '_' }, 14 | ], 15 | }, 16 | }]); 17 | -------------------------------------------------------------------------------- /packages/viem/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@eth-optimism/viem", 3 | "repository": { 4 | "type": "git", 5 | "url": "https://github.com/ethereum-optimism/ecosystem.git", 6 | "directory": "packages/viem" 7 | }, 8 | "homepage": "https://github.com/ethereum-optimism/ecosystem/tree/main/packages/viem#readme", 9 | "bugs": { 10 | "url": "https://github.com/ethereum-optimism/ecosystem/issues" 11 | }, 12 | "type": "module", 13 | "version": "0.4.9", 14 | "main": "dist/index.js", 15 | "types": "dist/index.d.ts", 16 | "files": [ 17 | "dist/*", 18 | "src/*" 19 | ], 20 | "exports": { 21 | ".": "./dist/index.js", 22 | "./actions": "./dist/actions/index.js", 23 | "./actions/interop": "./dist/actions/interop/index.js", 24 | "./chains": "./dist/chains/index.js", 25 | "./types/interop": "./dist/types/interop/index.js", 26 | "./utils/interop": "./dist/utils/interop/index.js" 27 | }, 28 | "scripts": { 29 | "build": "tsc && resolve-tspaths", 30 | "clean": "rm -rf build types tsconfig.tsbuildinfo", 31 | "docs": "typedoc", 32 | "gen:abis": "pnpm dlx tsx ./scripts/abigen", 33 | "gen:chains": "pnpm dlx tsx ./scripts/chaingen", 34 | "gen:abi-docs": "pnpm dlx tsx ./scripts/abidocgen", 35 | "lint": "eslint \"**/*.{ts,tsx}\" && pnpm prettier --check \"**/*.{ts,tsx}\" --ignore-path \"../../.prettierignore\"", 36 | "lint:fix": "eslint \"**/*.{ts,tsx}\" --fix && pnpm prettier \"**/*.{ts,tsx}\" --write --loglevel=warn --ignore-path \"../../.prettierignore\"", 37 | "test": "vitest --run", 38 | "typecheck": "tsc --noEmit --emitDeclarationOnly false" 39 | }, 40 | "devDependencies": { 41 | "dotenv": "16.5.0", 42 | "viem": "^2.17.9" 43 | }, 44 | "peerDependencies": { 45 | "viem": "^2.17.9" 46 | } 47 | } -------------------------------------------------------------------------------- /packages/viem/scripts/templates/abis.eta: -------------------------------------------------------------------------------- 1 | // DO NOT MODIFY THIS FILE IS AUTOGENERATED 2 | 3 | <% it.contracts.forEach(function (contract) { %> 4 | /** 5 | * ABI for the OP Stack contract `<%= contract.name %>` 6 | * @category ABI 7 | */ 8 | export const <%= contract.exportName %>Abi = <%~ it.prettyPrintJSON(contract.abi) %> as const 9 | <% }) %> 10 | -------------------------------------------------------------------------------- /packages/viem/scripts/templates/chains.eta: -------------------------------------------------------------------------------- 1 | // DO NOT MODIFY THIS FILE IS AUTOGENERATED 2 | import { defineChain } from 'viem' 3 | import * as viemChains from 'viem/chains' 4 | import { chainConfig } from 'viem/op-stack' 5 | 6 | import type { Network } from '@/chains/types.js' 7 | 8 | <%- it.chainDefs.forEach(function(chainDef){ %> 9 | /** 10 | * Chain Definition for <%= chainDef.chainName %> 11 | */ 12 | export const <%= chainDef.exportName %> = /*#__PURE__*/ defineChain({ 13 | ...chainConfig, 14 | name: '<%= chainDef.chainName %>', 15 | id: <%= chainDef.chainId %>, 16 | sourceId: <%= chainDef.sourceChainId %>, 17 | nativeCurrency: { 18 | name: '<%= chainDef.nativeCurrency.name %>', 19 | symbol: '<%= chainDef.nativeCurrency.symbol %>', 20 | decimals: <%= chainDef.nativeCurrency.decimals %>, 21 | }, 22 | rpcUrls: { 23 | default: { 24 | http: ['<%= chainDef.rpc %>'], 25 | }, 26 | }, 27 | blockExplorers: { 28 | default: { 29 | name: '<%= chainDef.chainName %> Explorer', 30 | url: '<%= chainDef.explorer %>', 31 | }, 32 | }, 33 | contracts: { 34 | ...chainConfig.contracts, 35 | <%_ Object.entries(chainDef.l1Addresses).forEach(function([name, address]){ %> 36 | <%= name %>: { 37 | <%= chainDef.sourceChainId %>: { 38 | address: '<%= address %>', 39 | }, 40 | }, 41 | <%_ }) %> 42 | }, 43 | }) 44 | <% }) -%> 45 | 46 | export const <%= it.network %>Chains = [ 47 | <%_ it.chainDefs.forEach(function(chainDef){ %> 48 | <%= chainDef.exportName %>, 49 | <%_ }) %> 50 | ] 51 | 52 | export const <%= it.network %>Network: Network = { 53 | name: '<%= it.network %>', 54 | sourceChain: <%= it.sourceChainImport %>, 55 | chains: <%= it.network %>Chains, 56 | } 57 | -------------------------------------------------------------------------------- /packages/viem/src/actions/index.ts: -------------------------------------------------------------------------------- 1 | export type { 2 | DepositCrossDomainMessageParameters, 3 | DepositCrossDomainMessageReturnType, 4 | } from '@/actions/depositCrossDomainMessage.js' 5 | export { 6 | depositCrossDomainMessage, 7 | estimateDepositCrossDomainMessageGas, 8 | simulateDepositCrossDomainMessage, 9 | } from '@/actions/depositCrossDomainMessage.js' 10 | export type { 11 | DepositERC20Parameters, 12 | DepositERC20ReturnType, 13 | } from '@/actions/depositERC20.js' 14 | export { 15 | depositERC20, 16 | estimateDepositERC20Gas, 17 | simulateDepositERC20, 18 | } from '@/actions/depositERC20.js' 19 | export type { 20 | WithdrawCrossDomainMessageParameters, 21 | WithdrawCrossDomainMessageReturnType, 22 | } from '@/actions/withdrawCrossDomainMessage.js' 23 | export { 24 | estimateWithdrawCrossDomainMessageGas, 25 | simulateWithdrawCrossDomainMessage, 26 | withdrawCrossDomainMessage, 27 | } from '@/actions/withdrawCrossDomainMessage.js' 28 | export type { 29 | WithdrawOptimismERC20Parameters, 30 | WithdrawOptimismERC20ReturnType, 31 | } from '@/actions/withdrawOptimismERC20.js' 32 | export { 33 | estimateWithdrawOptimismERC20Gas, 34 | simulateWithdrawOptimismERC20, 35 | withdrawOptimismERC20, 36 | } from '@/actions/withdrawOptimismERC20.js' 37 | -------------------------------------------------------------------------------- /packages/viem/src/actions/interop/getCrossDomainMessages.ts: -------------------------------------------------------------------------------- 1 | import type { Account, Chain, Client, Log, Transport } from 'viem' 2 | import { getChainId } from 'viem/actions' 3 | 4 | import type { CrossDomainMessage } from '@/types/interop/cdm.js' 5 | import { extractSentMessageLogs } from '@/utils/interop/extractSentMessageLogs.js' 6 | 7 | /** 8 | * @category Types 9 | */ 10 | export type GetCrossDomainMessagesParameters = { logs: Log[] } 11 | 12 | /** 13 | * @category Types 14 | */ 15 | export type GetCrossDomainMessagesReturnType = CrossDomainMessage[] 16 | 17 | /** 18 | * Get all cross domain messages from a set of logs 19 | * @category Actions 20 | * @param client - The client to use 21 | * @param parameters - {@link GetCrossDomainMessagesParameters} 22 | * @returns cross domain messages - {@link GetCrossDomainMessagesReturnType} 23 | * @example 24 | * import { createPublicClient } from 'viem' 25 | * import { http } from 'viem/transports' 26 | * import { op } from '@eth-optimism/viem/chains' 27 | * import { getCrossDomainMessages } from '@eth-optimism/viem/actions/interop' 28 | * 29 | * const publicClientOp = createPublicClient({ chain: op, transport: http() }) 30 | * const receipt = await publicClientOp.getTransactionReceipt({ hash: '0x...' }) 31 | * const messages = await getCrossDomainMessages(publicClientOp, { logs: receipt.logs }) 32 | */ 33 | export async function getCrossDomainMessages< 34 | TChain extends Chain | undefined, 35 | TAccount extends Account | undefined, 36 | >( 37 | client: Client, 38 | parameters: GetCrossDomainMessagesParameters, 39 | ): Promise { 40 | const { logs } = parameters 41 | 42 | const chainId = await getChainId(client) 43 | const sentMessages = extractSentMessageLogs({ logs }) 44 | 45 | return sentMessages.map((log) => { 46 | return { 47 | source: BigInt(chainId), 48 | destination: log.args.destination, 49 | nonce: log.args.messageNonce, 50 | sender: log.args.sender, 51 | target: log.args.target, 52 | message: log.args.message, 53 | log, 54 | } satisfies CrossDomainMessage 55 | }) 56 | } 57 | -------------------------------------------------------------------------------- /packages/viem/src/addressSet.ts: -------------------------------------------------------------------------------- 1 | import type { Address } from 'viem' 2 | 3 | export type AddressSet = { 4 | OpChainProxyAdmin: Address 5 | AddressManager: Address 6 | L1ERC721BridgeProxy: Address 7 | SystemConfigProxy: Address 8 | OptimismMintableERC20FactoryProxy: Address 9 | L1StandardBridgeProxy: Address 10 | L1CrossDomainMessengerProxy: Address 11 | OptimismPortalProxy: Address 12 | DisputeGameFactoryProxy: Address 13 | AnchorStateRegistryProxy: Address 14 | FaultDisputeGame: Address 15 | PermissionedDisputeGame: Address 16 | DelayedWETHPermissionedGameProxy: Address 17 | DelayedWETHPermissionlessGameProxy: Address 18 | } 19 | 20 | export const addressesToViemContractConstant = ( 21 | addressSet: AddressSet, 22 | sourceId: number, 23 | ) => { 24 | return { 25 | opChainProxyAdmin: addressForChain(addressSet.OpChainProxyAdmin, sourceId), 26 | addressManager: addressForChain(addressSet.AddressManager, sourceId), 27 | l1Erc721BridgeProxy: addressForChain( 28 | addressSet.L1ERC721BridgeProxy, 29 | sourceId, 30 | ), 31 | systemConfig: addressForChain(addressSet.SystemConfigProxy, sourceId), 32 | optimismMintableErc20FactoryProxy: addressForChain( 33 | addressSet.OptimismMintableERC20FactoryProxy, 34 | sourceId, 35 | ), 36 | l1StandardBridge: addressForChain( 37 | addressSet.L1StandardBridgeProxy, 38 | sourceId, 39 | ), 40 | l1CrossDomainMessenger: addressForChain( 41 | addressSet.L1CrossDomainMessengerProxy, 42 | sourceId, 43 | ), 44 | optimismPortal: addressForChain(addressSet.OptimismPortalProxy, sourceId), 45 | disputeGameFactory: addressForChain( 46 | addressSet.DisputeGameFactoryProxy, 47 | sourceId, 48 | ), 49 | anchorStateRegistry: addressForChain( 50 | addressSet.AnchorStateRegistryProxy, 51 | sourceId, 52 | ), 53 | faultDisputeGame: addressForChain(addressSet.FaultDisputeGame, sourceId), 54 | permissionedDisputeGame: addressForChain( 55 | addressSet.PermissionedDisputeGame, 56 | sourceId, 57 | ), 58 | } as const 59 | } 60 | 61 | const addressForChain = (address: Address, chainId: number) => { 62 | return { 63 | [chainId]: { address }, 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /packages/viem/src/chains/chains.ts: -------------------------------------------------------------------------------- 1 | import type { Chain } from 'viem' 2 | 3 | import { networks } from '@/chains/networks.js' 4 | 5 | /** 6 | * Map of all viem chains by ID 7 | */ 8 | export const chainById = Object.values(networks) 9 | .flatMap((network) => network.chains) 10 | .reduce((acc, chain) => { 11 | acc[chain.id] = chain 12 | return acc 13 | }, {} as Record) 14 | -------------------------------------------------------------------------------- /packages/viem/src/chains/index.ts: -------------------------------------------------------------------------------- 1 | // Generated Chains 2 | export * from '@/chains/mainnet.js' 3 | export * from '@/chains/sepolia.js' 4 | 5 | // Manually Defined Chains 6 | export * from '@/chains/interopAlpha.js' 7 | export * from '@/chains/interopRcAlpha.js' 8 | export * from '@/chains/supersim.js' 9 | 10 | // Useful Utilities 11 | export * from '@/chains/chains.js' 12 | export * from '@/chains/networks.js' 13 | export * from '@/chains/types.js' 14 | -------------------------------------------------------------------------------- /packages/viem/src/chains/interopRcAlpha.ts: -------------------------------------------------------------------------------- 1 | import { defineChain } from 'viem' 2 | import { sepolia } from 'viem/chains' 3 | import { chainConfig } from 'viem/op-stack' 4 | 5 | import { addressesToViemContractConstant } from '@/addressSet.js' 6 | import { 7 | interopRcAlpha0Addresses, 8 | interopRcAlpha1Addresses, 9 | } from '@/chains/interopRcAlphaAddresses.js' 10 | import type { Network } from '@/chains/types.js' 11 | 12 | const sourceId = sepolia.id 13 | 14 | /** 15 | * L2 chain A definition for interop-rc-alpha-0 16 | * @category interop-rc-alpha 17 | */ 18 | export const interopRcAlpha0 = defineChain({ 19 | ...chainConfig, 20 | id: 420120003, 21 | name: 'Interop RC Alpha 0', 22 | rpcUrls: { 23 | default: { 24 | http: ['https://interop-rc-alpha-0.optimism.io'], 25 | }, 26 | }, 27 | blockExplorers: { 28 | default: { 29 | name: 'Interop RC Alpha 0 Block Explorer', 30 | url: '', 31 | }, 32 | }, 33 | nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 }, 34 | sourceId, 35 | testnet: true, 36 | contracts: { 37 | ...chainConfig.contracts, 38 | ...addressesToViemContractConstant(interopRcAlpha0Addresses, sourceId), 39 | }, 40 | }) 41 | 42 | /** 43 | * L2 chain A definition for interop-rc-alpha-1 44 | * @category interop-rc-alpha 45 | */ 46 | export const interopRcAlpha1 = defineChain({ 47 | ...chainConfig, 48 | id: 420120004, 49 | name: 'Interop RC Alpha 1', 50 | rpcUrls: { 51 | default: { 52 | http: ['https://interop-rc-alpha-1.optimism.io'], 53 | }, 54 | }, 55 | blockExplorers: { 56 | default: { 57 | name: 'Interop RC Alpha 0 Block Explorer', 58 | url: '', 59 | }, 60 | }, 61 | nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 }, 62 | sourceId, 63 | testnet: true, 64 | contracts: { 65 | ...chainConfig.contracts, 66 | ...addressesToViemContractConstant(interopRcAlpha1Addresses, sourceId), 67 | }, 68 | }) 69 | 70 | export const interopRcAlphaChains = [interopRcAlpha0, interopRcAlpha1] 71 | 72 | export const interopRcAlphaNetwork: Network = { 73 | name: 'interop-rc-alpha', 74 | sourceChain: sepolia, 75 | chains: interopRcAlphaChains, 76 | } 77 | -------------------------------------------------------------------------------- /packages/viem/src/chains/networks.ts: -------------------------------------------------------------------------------- 1 | import { interopAlphaNetwork } from '@/chains/interopAlpha.js' 2 | import { interopRcAlphaNetwork } from '@/chains/interopRcAlpha.js' 3 | import { mainnetNetwork } from '@/chains/mainnet.js' 4 | import { sepoliaNetwork } from '@/chains/sepolia.js' 5 | import { supersimNetwork } from '@/chains/supersim.js' 6 | import type { Network, NetworkName } from '@/chains/types.js' 7 | 8 | /** 9 | * Map of all unique networks configurations 10 | * @dev Multiple networks can share the same source chain. 11 | * @dev Chains can be apart of multiple networks. 12 | */ 13 | export const networks: Record = { 14 | mainnet: mainnetNetwork, 15 | sepolia: sepoliaNetwork, 16 | supersim: supersimNetwork, 17 | 'interop-alpha': interopAlphaNetwork, 18 | 'interop-rc-alpha': interopRcAlphaNetwork, 19 | } 20 | -------------------------------------------------------------------------------- /packages/viem/src/chains/types.ts: -------------------------------------------------------------------------------- 1 | import type { Chain } from 'viem' 2 | 3 | /** 4 | * Names of all available networks 5 | */ 6 | export type NetworkName = 7 | | 'mainnet' 8 | | 'sepolia' 9 | | 'interop-alpha' 10 | | 'interop-rc-alpha' 11 | | 'supersim' 12 | 13 | /** 14 | * Configuration for a network 15 | */ 16 | export type Network = { 17 | name: NetworkName 18 | sourceChain: Chain 19 | chains: Chain[] 20 | } 21 | -------------------------------------------------------------------------------- /packages/viem/src/contracts.ts: -------------------------------------------------------------------------------- 1 | import type { Chain } from 'viem' 2 | import { chainConfig } from 'viem/op-stack' 3 | 4 | /** 5 | * OP Stack Predeploy Addresses 6 | * @category Predeploy Addresses 7 | */ 8 | export const contracts = { 9 | ...chainConfig.contracts, 10 | crossL2Inbox: { 11 | address: '0x4200000000000000000000000000000000000022', 12 | }, 13 | l2ToL2CrossDomainMessenger: { 14 | address: '0x4200000000000000000000000000000000000023', 15 | }, 16 | optimismMintableERC20Factory: { 17 | address: '0x4200000000000000000000000000000000000012', 18 | }, 19 | superchainTokenBridge: { 20 | address: '0x4200000000000000000000000000000000000028', 21 | }, 22 | superchainETHBridge: { 23 | address: '0x4200000000000000000000000000000000000024', 24 | }, 25 | weth: { 26 | address: '0x4200000000000000000000000000000000000006', 27 | }, 28 | } as const satisfies Chain['contracts'] 29 | -------------------------------------------------------------------------------- /packages/viem/src/index.ts: -------------------------------------------------------------------------------- 1 | // types 2 | export type { MessageIdentifier } from '@/types/interop/executingMessage.js' 3 | 4 | // contracts 5 | export { contracts } from '@/contracts.js' 6 | 7 | // abis (TEMPORARY) 8 | export * from '@/abis.js' 9 | 10 | // utils 11 | // fix 12 | 13 | // decorators 14 | export { publicActionsL2 } from '@/decorators/publicL2.js' 15 | export { walletActionsL2 } from '@/decorators/walletL2.js' 16 | -------------------------------------------------------------------------------- /packages/viem/src/test/clients.ts: -------------------------------------------------------------------------------- 1 | import { 2 | createPublicClient, 3 | createTestClient, 4 | createWalletClient, 5 | http, 6 | } from 'viem' 7 | import { privateKeyToAccount } from 'viem/accounts' 8 | 9 | import { supersimL2A, supersimL2B } from '@/chains/supersim.js' 10 | import { publicActionsL2 } from '@/decorators/publicL2.js' 11 | import { walletActionsL2 } from '@/decorators/walletL2.js' 12 | 13 | // anvil account: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 14 | export const testAccount = privateKeyToAccount( 15 | '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80', 16 | ) 17 | 18 | /** Chain A **/ 19 | 20 | export const publicClientA = createPublicClient({ 21 | chain: supersimL2A, 22 | transport: http(supersimL2A.rpcUrls.default.http[0]), 23 | }).extend(publicActionsL2()) 24 | 25 | export const walletClientA = createWalletClient({ 26 | account: testAccount, 27 | chain: supersimL2A, 28 | transport: http(supersimL2A.rpcUrls.default.http[0]), 29 | }).extend(walletActionsL2()) 30 | 31 | export const testClientA = createTestClient({ 32 | chain: supersimL2A, 33 | mode: 'anvil', 34 | transport: http(supersimL2A.rpcUrls.default.http[0]), 35 | }) 36 | 37 | /** Chain B **/ 38 | 39 | export const publicClientB = createPublicClient({ 40 | chain: supersimL2B, 41 | transport: http(supersimL2B.rpcUrls.default.http[0]), 42 | }).extend(publicActionsL2()) 43 | 44 | export const walletClientB = createWalletClient({ 45 | account: testAccount, 46 | chain: supersimL2B, 47 | transport: http(supersimL2B.rpcUrls.default.http[0]), 48 | }).extend(walletActionsL2()) 49 | 50 | export const testClientB = createTestClient({ 51 | chain: supersimL2A, 52 | mode: 'anvil', 53 | transport: http(supersimL2B.rpcUrls.default.http[0]), 54 | }) 55 | -------------------------------------------------------------------------------- /packages/viem/src/test/globalSetup.ts: -------------------------------------------------------------------------------- 1 | import { setupTicTacToe } from '@/test/setupTicTacToe.js' 2 | 3 | import { startSupersim } from './startSupersim.js' 4 | 5 | async function main() { 6 | let shutdown 7 | 8 | try { 9 | shutdown = await startSupersim() 10 | await setupTicTacToe() 11 | } catch (e) { 12 | process.exit(1) 13 | } 14 | 15 | return () => { 16 | shutdown() 17 | } 18 | } 19 | 20 | export default main 21 | -------------------------------------------------------------------------------- /packages/viem/src/test/startSupersim.ts: -------------------------------------------------------------------------------- 1 | import { spawn } from 'child_process' 2 | import fs from 'fs' 3 | import path from 'path' 4 | 5 | export type SupersimParameters = { 6 | l1Port?: number 7 | l2StartingPort?: number 8 | } 9 | 10 | export type SupersimReturnArg = Promise<() => void> 11 | 12 | const READY_TEXT = 'supersim is ready' 13 | const STD_OUT_PATH = path.resolve(__dirname, './stdout.txt') 14 | const STD_ERR_PATH = path.resolve(__dirname, './stderr.txt') 15 | 16 | export async function startSupersim( 17 | params?: SupersimParameters, 18 | ): SupersimReturnArg { 19 | const args = [] as string[] 20 | 21 | if (params?.l1Port) { 22 | args.push(`--l1.port ${params.l1Port}`) 23 | } 24 | 25 | if (params?.l2StartingPort) { 26 | args.push(` --l2.starting.port ${params.l2StartingPort}`) 27 | } 28 | 29 | fs.writeFileSync(STD_OUT_PATH, '') 30 | fs.writeFileSync(STD_ERR_PATH, '') 31 | 32 | const supersimProcess = spawn('supersim', args, { shell: true }) 33 | 34 | const cleanup = () => { 35 | if (!supersimProcess.killed) { 36 | supersimProcess.kill() 37 | } 38 | } 39 | 40 | return new Promise((resolve, reject) => { 41 | supersimProcess.stdout.on('data', (data) => { 42 | const blob: string = data.toString() 43 | 44 | fs.appendFileSync(STD_OUT_PATH, blob.replace(/\\n/g, '\n')) 45 | 46 | if (blob.includes(READY_TEXT)) { 47 | resolve(cleanup) 48 | } 49 | }) 50 | 51 | supersimProcess.stderr.on('data', (data) => { 52 | const blob: string = data.toString() 53 | fs.appendFileSync(STD_ERR_PATH, blob.replace(/\\n/g, '\n')) 54 | reject(blob) 55 | }) 56 | }) 57 | } 58 | -------------------------------------------------------------------------------- /packages/viem/src/test/supERC20.ts: -------------------------------------------------------------------------------- 1 | export const SUPERSIM_SUPERC20_ADDRESS = 2 | '0x420beeF000000000000000000000000000000001' 3 | -------------------------------------------------------------------------------- /packages/viem/src/test/testConstants.ts: -------------------------------------------------------------------------------- 1 | // Hardcoded since we don't have a good way to pull the L1 contracts for supersim yet. 2 | export const supersimL2AL1StandardBridgeAddress = 3 | '0xFD840Ec94235a8884881a68BB93d0110C9955604' 4 | 5 | // Hardcoded since we don't have a good way to pull the L1 contracts for supersim yet. 6 | export const supersimL2AL1CrossDomainMessengerAddress = 7 | '0x1D9234B7E5e720ef9022A64DB5e39E99708dC229' 8 | -------------------------------------------------------------------------------- /packages/viem/src/types/interop/cdm.ts: -------------------------------------------------------------------------------- 1 | import type { Address, Hex, Log } from 'viem' 2 | 3 | export type CrossDomainMessage = { 4 | source: bigint 5 | destination: bigint 6 | nonce: bigint 7 | sender: Address 8 | target: Address 9 | message: Hex 10 | 11 | /** Log that was the source of the message */ 12 | log: Log 13 | } 14 | -------------------------------------------------------------------------------- /packages/viem/src/types/interop/executingMessage.ts: -------------------------------------------------------------------------------- 1 | import type { Address, Hex } from 'viem' 2 | 3 | /** 4 | * Spec for [`MessageIdentifier`](https://github.com/ethereum-optimism/specs/blob/main/specs/interop/messaging.md#message-identifier). 5 | * @category Types 6 | */ 7 | export type MessageIdentifier = { 8 | /** Account that emits log */ 9 | origin: Address 10 | /** Block number in which the log was emitted */ 11 | blockNumber: bigint 12 | /** The index of the log in the array of all logs emitted in the block */ 13 | logIndex: bigint 14 | /** The timestamp that the log was emitted. Used to enforce the timestamp invariant */ 15 | timestamp: bigint 16 | /** The chain that emitted the log */ 17 | chainId: bigint 18 | } 19 | 20 | /** 21 | * Spec for [`MessagePayload`](https://github.com/ethereum-optimism/specs/blob/main/specs/interop/messaging.md#message-payload). 22 | * @category Types 23 | */ 24 | export type MessagePayload = Hex 25 | -------------------------------------------------------------------------------- /packages/viem/src/types/interop/index.ts: -------------------------------------------------------------------------------- 1 | export type { CrossDomainMessage } from '@/types/interop/cdm.js' 2 | export type { 3 | MessageIdentifier, 4 | MessagePayload, 5 | } from '@/types/interop/executingMessage.js' 6 | -------------------------------------------------------------------------------- /packages/viem/src/types/utils.ts: -------------------------------------------------------------------------------- 1 | import type { Account, Address, Chain, ChainContract } from 'viem' 2 | 3 | export type Prettify = { 4 | [K in keyof T]: T[K] 5 | } & {} 6 | 7 | export type UnionEvaluate = type extends object ? Prettify : type 8 | 9 | export type IsUndefined = [undefined] extends [T] ? true : false 10 | export type ErrorType = Error & { name: name } 11 | 12 | export type GetAccountParameter< 13 | account extends Account | undefined = Account | undefined, 14 | accountOverride extends Account | Address | undefined = Account | Address, 15 | required extends boolean = true, 16 | > = IsUndefined extends true 17 | ? required extends true 18 | ? { account: accountOverride | Account | Address } 19 | : { account?: accountOverride | Account | Address | undefined } 20 | : { account?: accountOverride | Account | Address | undefined } 21 | 22 | export type GetContractAddressParameter< 23 | chain extends Chain | undefined, 24 | contractName extends string, 25 | > = 26 | | (chain extends Chain 27 | ? Prettify< 28 | { 29 | targetChain: Prettify> 30 | } & { 31 | [_ in `${contractName}Address`]?: undefined 32 | } 33 | > 34 | : never) 35 | | Prettify< 36 | { 37 | targetChain?: undefined 38 | } & { 39 | [_ in `${contractName}Address`]: Address 40 | } 41 | > 42 | 43 | export type TargetChain< 44 | chain extends Chain = Chain, 45 | contractName extends string = string, 46 | > = { 47 | /** Required Properties of `Chain` */ 48 | id: chain['id'] 49 | name: chain['name'] 50 | nativeCurrency: chain['nativeCurrency'] 51 | rpcUrls: chain['rpcUrls'] 52 | 53 | /** Enforce the specific contract */ 54 | contracts: { 55 | [_ in contractName]: { [_ in chain['id']]: ChainContract } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /packages/viem/src/utils/interop/encodeMessagePayload.ts: -------------------------------------------------------------------------------- 1 | import type { Log } from 'viem' 2 | import { concat } from 'viem' 3 | 4 | import type { MessagePayload } from '@/types/interop/executingMessage.js' 5 | 6 | /** 7 | * @description Create an executing message payload from a log 8 | * @category Utils 9 | * @param log - The log to create the payload from 10 | * @returns The payload of the executing message 11 | */ 12 | export function encodeMessagePayload(log: Log): MessagePayload { 13 | return concat([...log.topics, log.data]) 14 | } 15 | -------------------------------------------------------------------------------- /packages/viem/src/utils/interop/extractSentMessageLogs.ts: -------------------------------------------------------------------------------- 1 | import type { Log } from 'viem' 2 | import { parseEventLogs } from 'viem' 3 | 4 | import { l2ToL2CrossDomainMessengerAbi } from '@/abis.js' 5 | 6 | export type ExtractSentMessageLogsParameters = { logs: Log[] } 7 | export type ExtractSentMessageLogsReturnType = Array< 8 | Log< 9 | bigint, 10 | number, 11 | false, 12 | undefined, 13 | true, 14 | typeof l2ToL2CrossDomainMessengerAbi, 15 | 'SentMessage' 16 | > 17 | > 18 | 19 | /** 20 | * @description Extract all L2ToL2CrossDomainMessenger SentMessage logs from a receipt 21 | * @category Utils 22 | * @param params - {@link ExtractSentMessageLogsParameters} 23 | * @returns - {@link ExtractSentMessageLogsReturnType} 24 | */ 25 | export function extractSentMessageLogs( 26 | params: ExtractSentMessageLogsParameters, 27 | ): ExtractSentMessageLogsReturnType { 28 | return parseEventLogs({ 29 | abi: l2ToL2CrossDomainMessengerAbi, 30 | eventName: 'SentMessage', 31 | logs: params.logs, 32 | }) 33 | } 34 | -------------------------------------------------------------------------------- /packages/viem/src/utils/interop/hashCrossDomainMessage.ts: -------------------------------------------------------------------------------- 1 | import type { Hash } from 'viem' 2 | import { encodeAbiParameters, keccak256, parseAbiParameters } from 'viem' 3 | 4 | import type { CrossDomainMessage } from '@/types/interop/cdm.js' 5 | 6 | /** 7 | * Hash an L2 to L2 cross domain message 8 | * @category Utils 9 | * @param message {@link CrossDomainMessage} 10 | * @returns Hash of the cross domain message 11 | */ 12 | export function hashCrossDomainMessage(message: CrossDomainMessage): Hash { 13 | const encoded = encodeAbiParameters( 14 | parseAbiParameters('uint256,uint256,uint256,address,address,bytes'), 15 | [ 16 | message.destination, 17 | message.source, 18 | message.nonce, 19 | message.sender, 20 | message.target, 21 | message.message, 22 | ], 23 | ) 24 | 25 | return keccak256(encoded) 26 | } 27 | -------------------------------------------------------------------------------- /packages/viem/src/utils/interop/index.ts: -------------------------------------------------------------------------------- 1 | export { encodeAccessList } from '@/utils/interop/encodeAccessList.js' 2 | export { encodeMessagePayload } from '@/utils/interop/encodeMessagePayload.js' 3 | export { extractSentMessageLogs } from '@/utils/interop/extractSentMessageLogs.js' 4 | export { hashCrossDomainMessage } from '@/utils/interop/hashCrossDomainMessage.js' 5 | -------------------------------------------------------------------------------- /packages/viem/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "include": ["src"], 4 | "compilerOptions": { 5 | "rootDir": "src", 6 | "baseUrl": ".", 7 | "paths": { 8 | "@/*": ["./src/*"] 9 | }, 10 | "target": "es2021", 11 | "lib": ["esnext"], 12 | "strict": true, 13 | "composite": true, 14 | "outDir": "dist", 15 | "moduleResolution": "NodeNext", 16 | "module": "NodeNext", 17 | "sourceMap": true 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/viem/typedoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://typedoc.org/schema.json", 3 | "out": "./docs", 4 | "plugin": ["typedoc-plugin-markdown"], 5 | "entryPoints": ["./src/index.ts", "./src/actions/interop/index.ts", "./src/chains/index.ts"], 6 | "exclude": [ 7 | "**/*.spec.ts", 8 | "./src/decorators/**", 9 | "./src/test/**" 10 | ], 11 | "readme": "none", 12 | "excludeInternal": true, 13 | "textContentMappings": { 14 | "title.memberPage": "{name}", 15 | } 16 | } -------------------------------------------------------------------------------- /packages/viem/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import path from 'path' 2 | import { defineConfig } from 'vitest/config' 3 | 4 | export default defineConfig({ 5 | resolve: { 6 | alias: { 7 | '@': path.resolve(__dirname, './src'), 8 | }, 9 | }, 10 | test: { 11 | testTimeout: 30_000, 12 | globalSetup: ['./src/test/globalSetup.ts'], 13 | fileParallelism: false, 14 | }, 15 | }) 16 | -------------------------------------------------------------------------------- /packages/wagmi/.gitignore: -------------------------------------------------------------------------------- 1 | dist -------------------------------------------------------------------------------- /packages/wagmi/README.md: -------------------------------------------------------------------------------- 1 | # @eth-optimism/wagmi 2 | 3 | This package is a TypeScript extension for Wagmi that provides actions and utilities for working with OP stack chains. 4 | 5 | ## Documentation 6 | 7 | ### Hooks 8 | 9 | * [`useSendL2ToL2Message`](https://github.com/ethereum-optimism/ecosystem/tree/main/packages/wagmi/docs/useSendL2ToL2Message.md) 10 | * [`useExecuteL2ToL2Message`](https://github.com/ethereum-optimism/ecosystem/tree/main/packages/wagmi/docs/useExecuteL2ToL2Message.md) 11 | -------------------------------------------------------------------------------- /packages/wagmi/docs/useRelayL2ToL2Message.md: -------------------------------------------------------------------------------- 1 | # useRelayL2ToL2Message 2 | 3 | Relays an cross domain messenger from the L2ToL2CrossDomainMessenger 4 | 5 | ## Usage 6 | 7 | ```ts [example.ts] 8 | const { 9 | relayMessage, 10 | isError, 11 | isPending, 12 | } = useRelayL2ToL2Message() 13 | 14 | const hash = await relayMessage({ 15 | account: address, 16 | sentMessageId: id, 17 | sentMessagePayload: payload, 18 | chain: destinationChain, 19 | }) 20 | ``` 21 | 22 | ## Returns 23 | 24 | ### `relayMessage` 25 | 26 | - **Type:** `(params: RelayL2ToL2MessageParameters) => Promise<`0x${string}`>` 27 | 28 | Call this function with the [RelayL2ToL2MessageParameters](https://github.com/ethereum-optimism/ecosystem/blob/main/packages/viem/docs/actions/relayL2ToL2Message.md#parameters) to execute a cross chain message 29 | 30 | ### `isError` 31 | 32 | - **Type:** `boolean` 33 | 34 | This will be true if there was an error attempting the cross chain message 35 | 36 | ### `isPending` 37 | 38 | - **Type:** `boolean` 39 | 40 | This will be true while the request is in flight 41 | 42 | ### `isSuccess` 43 | 44 | - **Type:** `boolean` 45 | 46 | This will be true after the request has returned successfully 47 | 48 | -------------------------------------------------------------------------------- /packages/wagmi/docs/useSendL2ToL2Message.md: -------------------------------------------------------------------------------- 1 | # useSendL2ToL2Message 2 | 3 | Initiates an L2 to L2 message. Used in the interop flow. 4 | 5 | ## Usage 6 | 7 | ```ts [example.ts] 8 | const { 9 | sendMessage, 10 | isError, 11 | isPending, 12 | } = useSendL2ToL2Message() 13 | 14 | const hash = await sendMessage({ 15 | account: address, 16 | destinationChainId: optimism.id, 17 | target: contractAddress, 18 | message: encodedMessage, 19 | chain: originChain, 20 | }) 21 | ``` 22 | 23 | ## Returns 24 | 25 | ### `sendMessage` 26 | 27 | - **Type:** `(params: SendL2ToL2MessageParameters) => Promise<`0x${string}`>` 28 | 29 | Call this function with the [SendL2ToL2MessageParameters](https://github.com/ethereum-optimism/ecosystem/blob/main/packages/viem/docs/actions/sendL2ToL2Message.md#parameters) to initiate a cross chain message 30 | 31 | ### `isError` 32 | 33 | - **Type:** `boolean` 34 | 35 | This will be true if there was an error attempting the cross chain message 36 | 37 | ### `isPending` 38 | 39 | - **Type:** `boolean` 40 | 41 | This will be true while the request is in flight 42 | 43 | ### `isSuccess` 44 | 45 | - **Type:** `boolean` 46 | 47 | This will be true after the request has returned successfully 48 | 49 | -------------------------------------------------------------------------------- /packages/wagmi/eslint.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'eslint/config'; 2 | 3 | import rootConfig from '../../eslint.config.js'; 4 | 5 | // Create a new configuration that extends the root configuration 6 | export default defineConfig([{ 7 | ...rootConfig, 8 | ignores: [...rootConfig.ignores, '**/dist/**'], 9 | }]); 10 | -------------------------------------------------------------------------------- /packages/wagmi/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@eth-optimism/wagmi", 3 | "description": "OP extensions for wagmi", 4 | "type": "module", 5 | "version": "0.1.8", 6 | "main": "dist/index.js", 7 | "types": "dist/index.d.ts", 8 | "files": [ 9 | "dist/*", 10 | "src/*" 11 | ], 12 | "scripts": { 13 | "clean": "rm -rf build types tsconfig.tsbuildinfo", 14 | "build": "tsc && resolve-tspaths", 15 | "lint": "eslint \"**/*.{ts,tsx}\" && pnpm prettier --check \"**/*.{ts,tsx}\" --ignore-path \"../../.prettierignore\"", 16 | "lint:fix": "eslint \"**/*.{ts,tsx}\" --fix && pnpm prettier \"**/*.{ts,tsx}\" --write --loglevel=warn --ignore-path \"../../.prettierignore\"", 17 | "test": "vitest --passWithNoTests --run", 18 | "typecheck": "tsc --noEmit --emitDeclarationOnly false" 19 | }, 20 | "devDependencies": { 21 | "@eth-optimism/viem": "workspace:*", 22 | "@tanstack/react-query": "^5", 23 | "react": "^18", 24 | "viem": "^2.17.9", 25 | "wagmi": "^2.12" 26 | }, 27 | "peerDependencies": { 28 | "@eth-optimism/viem": "workspace:*", 29 | "@tanstack/react-query": "^5", 30 | "react": "^18", 31 | "viem": "^2.17.9", 32 | "wagmi": "^2.12" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/wagmi/src/hooks/useCrossChainSendETH.ts: -------------------------------------------------------------------------------- 1 | import { contracts, superchainETHBridgeAbi } from '@eth-optimism/viem' 2 | import type { SendETHParameters } from '@eth-optimism/viem/actions/interop' 3 | import { useCallback } from 'react' 4 | import { useConfig, useWriteContract } from 'wagmi' 5 | 6 | export const useCrossChainSendETH = () => { 7 | const config = useConfig() 8 | const { writeContractAsync, isError, isPending, isSuccess } = 9 | useWriteContract({ config }) 10 | 11 | const crossChainSendETH = useCallback( 12 | (params: SendETHParameters) => { 13 | const { to, chainId, value } = params 14 | 15 | return writeContractAsync({ 16 | abi: superchainETHBridgeAbi, 17 | address: contracts.superchainETHBridge.address, 18 | value, 19 | functionName: 'sendETH', 20 | args: [to, BigInt(chainId)], 21 | }) 22 | }, 23 | [writeContractAsync], 24 | ) 25 | 26 | return { crossChainSendETH, isError, isPending, isSuccess } 27 | } 28 | -------------------------------------------------------------------------------- /packages/wagmi/src/hooks/useRelayL2ToL2Message.ts: -------------------------------------------------------------------------------- 1 | import { contracts, l2ToL2CrossDomainMessengerAbi } from '@eth-optimism/viem' 2 | import type { RelayCrossDomainMessageParameters } from '@eth-optimism/viem/actions/interop' 3 | import { useCallback } from 'react' 4 | import { useConfig, useWriteContract } from 'wagmi' 5 | 6 | export const useRelayL2ToL2Message = () => { 7 | const config = useConfig() 8 | const { writeContractAsync, isError, isPending, isSuccess } = 9 | useWriteContract({ config }) 10 | 11 | const relayMessage = useCallback( 12 | (params: RelayCrossDomainMessageParameters) => { 13 | const { 14 | id, 15 | payload, 16 | nonce, 17 | maxFeePerGas, 18 | maxPriorityFeePerGas, 19 | chain, 20 | gas, 21 | } = params 22 | 23 | return writeContractAsync({ 24 | abi: l2ToL2CrossDomainMessengerAbi, 25 | address: contracts.l2ToL2CrossDomainMessenger.address, 26 | functionName: 'relayMessage', 27 | args: [id, payload], 28 | chain, 29 | gas: gas ? gas : undefined, 30 | nonce, 31 | maxFeePerGas, 32 | maxPriorityFeePerGas, 33 | }) 34 | }, 35 | [writeContractAsync], 36 | ) 37 | 38 | return { relayMessage, isError, isPending, isSuccess } 39 | } 40 | -------------------------------------------------------------------------------- /packages/wagmi/src/hooks/useSendL2ToL2Message.ts: -------------------------------------------------------------------------------- 1 | import { contracts, l2ToL2CrossDomainMessengerAbi } from '@eth-optimism/viem' 2 | import type { SendCrossDomainMessageParameters } from '@eth-optimism/viem/actions/interop' 3 | import { useCallback } from 'react' 4 | import { useConfig, useWriteContract } from 'wagmi' 5 | 6 | export const useSendL2ToL2Message = () => { 7 | const config = useConfig() 8 | const { writeContractAsync, isError, isPending, isSuccess } = 9 | useWriteContract({ config }) 10 | 11 | const sendMessage = useCallback( 12 | (params: SendCrossDomainMessageParameters) => { 13 | const { destinationChainId, target, message } = params 14 | 15 | return writeContractAsync({ 16 | abi: l2ToL2CrossDomainMessengerAbi, 17 | address: contracts.l2ToL2CrossDomainMessenger.address, 18 | functionName: 'sendMessage', 19 | args: [BigInt(destinationChainId), target, message], 20 | }) 21 | }, 22 | [writeContractAsync], 23 | ) 24 | 25 | return { sendMessage, isError, isPending, isSuccess } 26 | } 27 | -------------------------------------------------------------------------------- /packages/wagmi/src/hooks/useSendSuperchainERC20.ts: -------------------------------------------------------------------------------- 1 | import { contracts, superchainTokenBridgeAbi } from '@eth-optimism/viem' 2 | import type { SendSuperchainERC20Parameters } from '@eth-optimism/viem/actions/interop' 3 | import { useCallback } from 'react' 4 | import { useConfig, useWriteContract } from 'wagmi' 5 | 6 | export const useSendSuperchainERC20 = () => { 7 | const config = useConfig() 8 | 9 | const { writeContractAsync, isError, isPending, isSuccess } = 10 | useWriteContract({ config }) 11 | 12 | const sendSuperchainERC20 = useCallback( 13 | (params: SendSuperchainERC20Parameters) => { 14 | const { tokenAddress, to, amount, chainId } = params 15 | 16 | return writeContractAsync({ 17 | abi: superchainTokenBridgeAbi, 18 | address: contracts.superchainTokenBridge.address, 19 | functionName: 'sendERC20', 20 | args: [tokenAddress, to, amount, BigInt(chainId)], 21 | }) 22 | }, 23 | [writeContractAsync], 24 | ) 25 | 26 | return { sendSuperchainERC20, isError, isPending, isSuccess } 27 | } 28 | -------------------------------------------------------------------------------- /packages/wagmi/src/index.ts: -------------------------------------------------------------------------------- 1 | // hooks 2 | export { useCrossChainSendETH } from '@/hooks/useCrossChainSendETH.js' 3 | export { useRelayL2ToL2Message } from '@/hooks/useRelayL2ToL2Message.js' 4 | export { useSendL2ToL2Message } from '@/hooks/useSendL2ToL2Message.js' 5 | export { useSendSuperchainERC20 } from '@/hooks/useSendSuperchainERC20.js' 6 | -------------------------------------------------------------------------------- /packages/wagmi/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "include": ["src"], 4 | "compilerOptions": { 5 | "rootDir": "src", 6 | "baseUrl": ".", 7 | "paths": { 8 | "@/*": ["./src/*"] 9 | }, 10 | "target": "es2021", 11 | "lib": ["esnext"], 12 | "strict": true, 13 | "composite": true, 14 | "outDir": "dist", 15 | "moduleResolution": "NodeNext", 16 | "module": "NodeNext", 17 | "sourceMap": true 18 | } 19 | } -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - 'apps/*' 3 | - 'packages/*' 4 | -------------------------------------------------------------------------------- /tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "declaration": true, 5 | "useUnknownInCatchVariables": false, 6 | "allowJs": true, 7 | "skipLibCheck": true, 8 | "esModuleInterop": true, 9 | "allowSyntheticDefaultImports": true, 10 | "strict": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "noFallthroughCasesInSwitch": true, 13 | "moduleResolution": "node", 14 | "resolveJsonModule": true, 15 | "isolatedModules": true 16 | } 17 | } 18 | --------------------------------------------------------------------------------