From d05dd70c5cdc0d72ecd2d967a77bb2b63cd2ebcc Mon Sep 17 00:00:00 2001 From: Lukas Rosario <36800180+lukasrosario@users.noreply.github.com> Date: Mon, 20 Nov 2023 21:45:21 +0300 Subject: [PATCH] types / write refactor & finalize hooks --- example/components/DepositETH.tsx | 36 ++-- package.json | 13 +- pnpm-lock.yaml | 169 ++++++++++++------ src/constants/chains/base.ts | 12 ++ src/constants/chains/baseGoerli.ts | 12 ++ src/constants/chains/optimismGoerli.ts | 12 ++ src/hooks/L1/useSimulateDepositERC20.ts | 33 +++- src/hooks/L1/useSimulateDepositETH.ts | 36 ++-- ...seSimulateFinalizeWithdrawalTransaction.ts | 93 ++++++++++ .../useSimulateProveWithdrawalTransaction.ts | 123 +++++++++---- src/hooks/L1/useWriteDepositERC20.ts | 61 +++++-- src/hooks/L1/useWriteDepositETH.ts | 65 +++++-- .../useWriteFinalizeWithdrawalTransaction.ts | 104 +++++++++++ .../L1/useWriteProveWithdrawalTransaction.ts | 155 ++++++++++------ src/hooks/L2/useSimulateWithdrawERC20.ts | 36 ++-- src/hooks/L2/useSimulateWithdrawETH.ts | 37 ++-- src/hooks/L2/useWriteWithdrawERC20.ts | 30 ++-- src/hooks/L2/useWriteWithdrawETH.ts | 48 +++-- src/hooks/index.ts | 18 ++ src/hooks/useOpConfig.ts | 7 +- src/index.ts | 18 ++ .../UseSimulateOPActionBaseParameters.ts | 23 ++- .../UseSimulateOPActionBaseReturnType.ts | 5 +- src/types/UseWriteOPActionBaseParameters.ts | 22 +-- src/types/UseWriteOPActionBaseReturnType.ts | 6 +- 25 files changed, 878 insertions(+), 296 deletions(-) create mode 100644 src/constants/chains/base.ts create mode 100644 src/constants/chains/baseGoerli.ts create mode 100644 src/constants/chains/optimismGoerli.ts create mode 100644 src/hooks/L1/useSimulateFinalizeWithdrawalTransaction.ts create mode 100644 src/hooks/L1/useWriteFinalizeWithdrawalTransaction.ts diff --git a/example/components/DepositETH.tsx b/example/components/DepositETH.tsx index 018a783..f0cac77 100644 --- a/example/components/DepositETH.tsx +++ b/example/components/DepositETH.tsx @@ -7,8 +7,6 @@ import { Button } from './Button' import { InputGroup } from './InputGroup' import { Modal } from './Modal' -const portal = '0xe93c8cD0D409341205A592f8c4Ac1A5fe5585cfA' - type DepositETHModalProps = { isOpen: boolean onClose: () => void @@ -22,13 +20,14 @@ function DepositETHModal({ isOpen, onClose }: DepositETHModalProps) { args: { to: to as Address, gasLimit: 100000, + amount: parseEther(amount), }, - portal, - chainId: 5, - value: parseEther(amount), + l2ChainId: 84531, query: { enabled: false }, }) - const { data, status: writeStatus, writeDepositETHAsync } = useWriteDepositETH() + const { data: l1TxHash, l2TxHash, status: writeStatus, writeDepositETHAsync } = useWriteDepositETH({ + l2ChainId: 84531, + }) const handleClick = async () => { if (action === 'simulate') { @@ -39,10 +38,8 @@ function DepositETHModal({ isOpen, onClose }: DepositETHModalProps) { args: { to: to as Address, gasLimit: 100000, + amount: parseEther(amount), }, - portal, - chainId: 5, - value: parseEther(amount), }) } catch (e) { console.error(e) @@ -76,16 +73,29 @@ function DepositETHModal({ isOpen, onClose }: DepositETHModalProps) { Status: {writeStatus} - {data && ( + {l1TxHash && ( +
+ L1 Tx: + + {`${l1TxHash?.slice(0, 8)}...`} + +
+ )} + {l2TxHash && (
- Transaction: + L2 Tx: - {`${data?.slice(0, 8)}...`} + {`${l2TxHash?.slice(0, 8)}...`}
)} diff --git a/package.json b/package.json index 54fc1af..43c7dc7 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,8 @@ "typedoc-plugin-markdown": "^3.17.0", "typescript": "5.0.4", "vitest": "^0.34.1", - "wagmi": "alpha" + "wagmi": "beta", + "@tanstack/react-query": ">=5.0.0" }, "scripts": { "build": "pnpm run clean && pnpm run build:cjs && pnpm run build:esm && pnpm run build:types", @@ -87,19 +88,19 @@ "bench:ci": "CI=true vitest bench", "dev:docs": "pnpm -r --filter docs dev", "dev:example": "pnpm -r --filter example dev", + "dev:demo": "pnpm -r --filter demo dev", "prepare": "npx simple-git-hooks" }, "dependencies": { "@eth-optimism/contracts-ts": "^0.15.0" }, "peerDependencies": { - "@tanstack/query-core": ">=5.0.0", - "@tanstack/react-query": "beta", - "@wagmi/core": "alpha", + "@tanstack/react-query": ">=5.0.0", + "@wagmi/core": "beta", "op-viem": "1.3.0-alpha", "typescript": ">=5.0.4", - "viem": "2.0.0-alpha.17", - "wagmi": "alpha" + "viem": "2.0.0-beta.0", + "wagmi": "beta" }, "peerDependenciesMeta": { "typescript": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4199874..e277eca 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,22 +13,16 @@ importers: dependencies: '@eth-optimism/contracts-ts': specifier: ^0.15.0 - version: 0.15.0(@wagmi/core@2.0.0-alpha.10)(typescript@5.0.4)(wagmi@2.0.0-alpha.10) - '@tanstack/query-core': - specifier: '>=5.0.0' - version: 5.0.5 - '@tanstack/react-query': - specifier: beta - version: 5.0.0-beta.35(react-dom@18.2.0)(react-native@0.72.6)(react@18.2.0) + version: 0.15.0(@wagmi/core@2.0.0-beta.1)(typescript@5.0.4)(wagmi@2.0.0-beta.1) '@wagmi/core': - specifier: alpha - version: 2.0.0-alpha.10(@types/react@18.2.31)(react@18.2.0)(typescript@5.0.4)(viem@2.0.0-alpha.17) + specifier: beta + version: 2.0.0-beta.1(@types/react@18.2.31)(react@18.2.0)(typescript@5.0.4)(viem@2.0.0-beta.0) op-viem: specifier: 1.3.0-alpha - version: 1.3.0-alpha(@wagmi/core@2.0.0-alpha.10)(typescript@5.0.4)(viem@2.0.0-alpha.17)(wagmi@2.0.0-alpha.10) + version: 1.3.0-alpha(@wagmi/core@2.0.0-beta.1)(typescript@5.0.4)(viem@2.0.0-beta.0)(wagmi@2.0.0-beta.1) viem: - specifier: 2.0.0-alpha.17 - version: 2.0.0-alpha.17(typescript@5.0.4)(zod@3.22.4) + specifier: 2.0.0-beta.0 + version: 2.0.0-beta.0(typescript@5.0.4) devDependencies: '@biomejs/biome': specifier: 1.0.0 @@ -45,6 +39,9 @@ importers: '@eth-optimism/sdk': specifier: ^3.1.2 version: 3.1.4(ethers@5.7.2) + '@tanstack/react-query': + specifier: '>=5.0.0' + version: 5.8.1(react-dom@18.2.0)(react-native@0.72.6)(react@18.2.0) '@testing-library/react': specifier: ^14.0.0 version: 14.0.0(react-dom@18.2.0)(react@18.2.0) @@ -100,8 +97,60 @@ importers: specifier: ^0.34.1 version: 0.34.6(happy-dom@12.10.3) wagmi: - specifier: alpha - version: 2.0.0-alpha.10(@tanstack/react-query@5.0.0-beta.35)(@types/react@18.2.31)(react-native@0.72.6)(react@18.2.0)(typescript@5.0.4)(viem@2.0.0-alpha.17) + specifier: beta + version: 2.0.0-beta.1(@tanstack/react-query@5.8.1)(@types/react@18.2.31)(react-native@0.72.6)(react@18.2.0)(typescript@5.0.4)(viem@2.0.0-beta.0) + + demo: + dependencies: + next: + specifier: 13.5.6 + version: 13.5.6(@babel/core@7.23.2)(react-dom@18.2.0)(react@18.2.0) + op-wagmi: + specifier: workspace:* + version: link:.. + react: + specifier: ^18 + version: 18.2.0 + react-dom: + specifier: ^18 + version: 18.2.0(react@18.2.0) + devDependencies: + '@types/node': + specifier: ^20 + version: 20.8.7 + '@types/react': + specifier: ^18 + version: 18.2.31 + '@types/react-dom': + specifier: ^18 + version: 18.2.14 + autoprefixer: + specifier: ^10 + version: 10.4.16(postcss@8.4.31) + bufferutil: + specifier: ^4.0.7 + version: 4.0.8 + encoding: + specifier: ^0.1.13 + version: 0.1.13 + lokijs: + specifier: ^1.5.12 + version: 1.5.12 + pino-pretty: + specifier: ^10.2.0 + version: 10.2.3 + postcss: + specifier: ^8 + version: 8.4.31 + tailwindcss: + specifier: ^3 + version: 3.3.3 + typescript: + specifier: ^5 + version: 5.0.4 + utf-8-validate: + specifier: ^6.0.3 + version: 6.0.3 docs: devDependencies: @@ -2498,7 +2547,7 @@ packages: requiresBuild: true dev: true - /@eth-optimism/contracts-ts@0.15.0(@wagmi/core@2.0.0-alpha.10)(typescript@5.0.4)(wagmi@2.0.0-alpha.10): + /@eth-optimism/contracts-ts@0.15.0(@wagmi/core@2.0.0-beta.1)(typescript@5.0.4)(wagmi@2.0.0-beta.1): resolution: {integrity: sha512-qga3xsj+NhnxjY96TWktKAmc2DSYrdy0E+lVkS3NZ/b5w898IisoMj/Xvv3KoovBJmnk+/ENNnMX7kk+fwQdtA==} peerDependencies: '@wagmi/core': '>1.0.0' @@ -2510,11 +2559,11 @@ packages: optional: true dependencies: '@testing-library/react': 14.0.0(react-dom@18.2.0)(react@18.2.0) - '@wagmi/core': 2.0.0-alpha.10(@types/react@18.2.31)(react@18.2.0)(typescript@5.0.4)(viem@2.0.0-alpha.17) + '@wagmi/core': 2.0.0-beta.1(@types/react@18.2.31)(react@18.2.0)(typescript@5.0.4)(viem@2.0.0-beta.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) viem: 1.16.6(typescript@5.0.4) - wagmi: 2.0.0-alpha.10(@tanstack/react-query@5.0.0-beta.35)(@types/react@18.2.31)(react-native@0.72.6)(react@18.2.0)(typescript@5.0.4)(viem@2.0.0-alpha.17) + wagmi: 2.0.0-beta.1(@tanstack/react-query@5.8.1)(@types/react@18.2.31)(react-native@0.72.6)(react@18.2.0)(typescript@5.0.4)(viem@2.0.0-beta.0) transitivePeerDependencies: - bufferutil - typescript @@ -3723,7 +3772,7 @@ packages: resolution: {integrity: sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==} dependencies: '@noble/curves': 1.1.0 - '@noble/hashes': 1.3.1 + '@noble/hashes': 1.3.2 '@scure/base': 1.1.3 /@scure/bip32@1.3.2: @@ -3870,15 +3919,11 @@ packages: tslib: 2.6.2 dev: false - /@tanstack/query-core@5.0.0-beta.35: - resolution: {integrity: sha512-UDFfBR+ncev2nte+nLsNTCX9Q06rfqADhTVnp5m43IdxFoXwy1qRVg3mBkMDZp+P2JHkKlRohYvZ+bUeuIwK2Q==} - - /@tanstack/query-core@5.0.5: - resolution: {integrity: sha512-MThCETMkHDHTnFZHp71L+SqTtD5d6XHftFCVR1xRJdWM3qGrlQ2VCXaj0SKVcyJej2e1Opa2c7iknu1llxCDNQ==} - dev: false + /@tanstack/query-core@5.8.1: + resolution: {integrity: sha512-Y0enatz2zQXBAsd7XmajlCs+WaitdR7dIFkqz9Xd7HL4KV04JOigWVreYseTmNH7YFSBSC/BJ9uuNp1MAf+GfA==} - /@tanstack/react-query@5.0.0-beta.35(react-dom@18.2.0)(react-native@0.72.6)(react@18.2.0): - resolution: {integrity: sha512-9hxP/DZbGucYFaHx6Njhkrbx32lNRk4QqqkGzyQ4IPaYfJTELE7urc9LBYRwrof211cj0W76IxmpjDwZ5ljZpQ==} + /@tanstack/react-query@5.8.1(react-dom@18.2.0)(react-native@0.72.6)(react@18.2.0): + resolution: {integrity: sha512-YMagxS8iNPOLg0pK6WOjdSDlAvWKOf69udLOwQrBVmkC2SRLNLko7elo5Ro3ptlJkXvTVHidxC/h5KGi5bH1XQ==} peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 @@ -3889,8 +3934,7 @@ packages: react-native: optional: true dependencies: - '@tanstack/query-core': 5.0.0-beta.35 - client-only: 0.0.1 + '@tanstack/query-core': 5.8.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) react-native: 0.72.6(@babel/core@7.23.2)(@babel/preset-env@7.23.2)(react@18.2.0) @@ -4339,12 +4383,12 @@ packages: - utf-8-validate dev: true - /@wagmi/connectors@4.0.0-alpha.10(@types/react@18.2.31)(@wagmi/core@2.0.0-alpha.10)(react-native@0.72.6)(react@18.2.0)(typescript@5.0.4)(viem@2.0.0-alpha.17): - resolution: {integrity: sha512-daiYtIM/wGH5S+zZX4gfdX8HSEWEw4Y17eeYZrbJlI/+hXbzleggixJD7ihADnZBJDvqpCwLYumeUAAfXc5iRg==} + /@wagmi/connectors@4.0.0-beta.1(@types/react@18.2.31)(@wagmi/core@2.0.0-beta.1)(react-native@0.72.6)(react@18.2.0)(typescript@5.0.4)(viem@2.0.0-beta.0): + resolution: {integrity: sha512-CEfkQFxKhJqmW3c11JKVhr/U1QwirdKIxHGgCvR2pPij7om2MEJCZgNKMeFPlwQb+UGXCIJLvndVrpFSZqvOLA==} peerDependencies: - '@wagmi/core': 2.0.0-alpha.10 + '@wagmi/core': 2.0.0-beta.1 typescript: '>=5.0.4' - viem: 2.0.0-alpha.17 + viem: 2.0.0-beta.0 peerDependenciesMeta: typescript: optional: true @@ -4354,11 +4398,11 @@ packages: '@metamask/sdk': 0.8.0(@types/react@18.2.31)(react-native@0.72.6)(react@18.2.0) '@safe-global/safe-apps-provider': 0.18.0(typescript@5.0.4) '@safe-global/safe-apps-sdk': 8.1.0(typescript@5.0.4) - '@wagmi/core': 2.0.0-alpha.10(@types/react@18.2.31)(react@18.2.0)(typescript@5.0.4)(viem@2.0.0-alpha.17) + '@wagmi/core': 2.0.0-beta.1(@types/react@18.2.31)(react@18.2.0)(typescript@5.0.4)(viem@2.0.0-beta.0) '@walletconnect/ethereum-provider': 2.10.2(@walletconnect/modal@2.6.2) '@walletconnect/modal': 2.6.2(@types/react@18.2.31)(react@18.2.0) typescript: 5.0.4 - viem: 2.0.0-alpha.17(typescript@5.0.4)(zod@3.22.4) + viem: 2.0.0-beta.0(typescript@5.0.4) transitivePeerDependencies: - '@react-native-async-storage/async-storage' - '@types/react' @@ -4371,12 +4415,12 @@ packages: - utf-8-validate - zod - /@wagmi/core@2.0.0-alpha.10(@types/react@18.2.31)(react@18.2.0)(typescript@5.0.4)(viem@2.0.0-alpha.17): - resolution: {integrity: sha512-qIKHIoTH1BlI71sqiYPh20GCtUTK+/ORLe9mukUzqw5Zu1aIzEkxUMd4XVZu4joEPl97Gc5813dVHZLHZcTABw==} + /@wagmi/core@2.0.0-beta.1(@types/react@18.2.31)(react@18.2.0)(typescript@5.0.4)(viem@2.0.0-beta.0): + resolution: {integrity: sha512-EoKjv7axGBMiFYkTTNZscQJHgiPwgFwht33RHMeVacI00wUgslLLnAjkaAhu/blH9Dej+89wrJrpLzI1ZNf7lg==} peerDependencies: - '@tanstack/query-core': '>5.0.0-beta.28' + '@tanstack/query-core': '>=5.0.0' typescript: '>=5.0.4' - viem: 2.0.0-alpha.17 + viem: 2.0.0-beta.0 peerDependenciesMeta: '@tanstack/query-core': optional: true @@ -4386,7 +4430,7 @@ packages: eventemitter3: 5.0.1 mipd: 0.0.5(typescript@5.0.4) typescript: 5.0.4 - viem: 2.0.0-alpha.17(typescript@5.0.4)(zod@3.22.4) + viem: 2.0.0-beta.0(typescript@5.0.4) zustand: 4.4.4(@types/react@18.2.31)(react@18.2.0) transitivePeerDependencies: - '@types/react' @@ -5343,6 +5387,7 @@ packages: /client-only@0.0.1: resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + dev: false /cliui@6.0.0: resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} @@ -8271,7 +8316,7 @@ packages: mimic-fn: 4.0.0 dev: true - /op-viem@1.3.0-alpha(@wagmi/core@2.0.0-alpha.10)(typescript@5.0.4)(viem@2.0.0-alpha.17)(wagmi@2.0.0-alpha.10): + /op-viem@1.3.0-alpha(@wagmi/core@2.0.0-beta.1)(typescript@5.0.4)(viem@2.0.0-beta.0)(wagmi@2.0.0-beta.1): resolution: {integrity: sha512-pcV+8BwYUwWfixti9aRVs2A/3Y5PjUIvGDOFPm7AyHnrxwm8JHmtWnj+MRUuHJ+SujZ8picdUyu/wvCxLj2Mng==} requiresBuild: true peerDependencies: @@ -8281,9 +8326,9 @@ packages: typescript: optional: true dependencies: - '@eth-optimism/contracts-ts': 0.15.0(@wagmi/core@2.0.0-alpha.10)(typescript@5.0.4)(wagmi@2.0.0-alpha.10) + '@eth-optimism/contracts-ts': 0.15.0(@wagmi/core@2.0.0-beta.1)(typescript@5.0.4)(wagmi@2.0.0-beta.1) typescript: 5.0.4 - viem: 2.0.0-alpha.17(typescript@5.0.4)(zod@3.22.4) + viem: 2.0.0-beta.0(typescript@5.0.4) transitivePeerDependencies: - '@wagmi/core' - bufferutil @@ -10249,6 +10294,29 @@ packages: - bufferutil - utf-8-validate - zod + dev: true + + /viem@2.0.0-beta.0(typescript@5.0.4): + resolution: {integrity: sha512-KsUh16uhSvTSI/tCBuMqjCvvdVIKDI4lAFWQ4hMPofBLw9W0UEmFk8hd+e/NlNc/fI24eghHmkTYLBRancIBkg==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@adraffy/ens-normalize': 1.9.4 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@scure/bip32': 1.3.2 + '@scure/bip39': 1.2.1 + abitype: 0.10.0(typescript@5.0.4)(zod@3.22.4) + isows: 1.0.3(ws@8.13.0) + typescript: 5.0.4 + ws: 8.13.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod /vite-node@0.34.6(@types/node@20.8.7): resolution: {integrity: sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==} @@ -10496,26 +10564,27 @@ packages: typescript: 5.0.4 dev: true - /wagmi@2.0.0-alpha.10(@tanstack/react-query@5.0.0-beta.35)(@types/react@18.2.31)(react-native@0.72.6)(react@18.2.0)(typescript@5.0.4)(viem@2.0.0-alpha.17): - resolution: {integrity: sha512-SBsYn8d1gG5I3vPYsPWo0/UmdlumUHRII5Tnrw2QHx0+Zy9senqfkP5c05WXvDQjLLQdNOsV5gyVQZe2KtcEzg==} + /wagmi@2.0.0-beta.1(@tanstack/react-query@5.8.1)(@types/react@18.2.31)(react-native@0.72.6)(react@18.2.0)(typescript@5.0.4)(viem@2.0.0-beta.0): + resolution: {integrity: sha512-KSXlcdVUQ18FeH2hZNbk8NPAcMrwJrPus2zJx53CEwVK/xBj7emcN1yLJw+YrEQbHSq7kem0Wt8Gl+fobO2/wg==} peerDependencies: - '@tanstack/react-query': '>5.0.0-beta.28' + '@tanstack/react-query': '>=5.0.0' react: '>=18' typescript: '>=5.0.4' - viem: 2.0.0-alpha.17 + viem: 2.0.0-beta.0 peerDependenciesMeta: typescript: optional: true dependencies: - '@tanstack/react-query': 5.0.0-beta.35(react-dom@18.2.0)(react-native@0.72.6)(react@18.2.0) - '@wagmi/connectors': 4.0.0-alpha.10(@types/react@18.2.31)(@wagmi/core@2.0.0-alpha.10)(react-native@0.72.6)(react@18.2.0)(typescript@5.0.4)(viem@2.0.0-alpha.17) - '@wagmi/core': 2.0.0-alpha.10(@types/react@18.2.31)(react@18.2.0)(typescript@5.0.4)(viem@2.0.0-alpha.17) + '@tanstack/react-query': 5.8.1(react-dom@18.2.0)(react-native@0.72.6)(react@18.2.0) + '@wagmi/connectors': 4.0.0-beta.1(@types/react@18.2.31)(@wagmi/core@2.0.0-beta.1)(react-native@0.72.6)(react@18.2.0)(typescript@5.0.4)(viem@2.0.0-beta.0) + '@wagmi/core': 2.0.0-beta.1(@types/react@18.2.31)(react@18.2.0)(typescript@5.0.4)(viem@2.0.0-beta.0) react: 18.2.0 typescript: 5.0.4 use-sync-external-store: 1.2.0(react@18.2.0) - viem: 2.0.0-alpha.17(typescript@5.0.4)(zod@3.22.4) + viem: 2.0.0-beta.0(typescript@5.0.4) transitivePeerDependencies: - '@react-native-async-storage/async-storage' + - '@tanstack/query-core' - '@types/react' - bufferutil - encoding diff --git a/src/constants/chains/base.ts b/src/constants/chains/base.ts new file mode 100644 index 0000000..3704625 --- /dev/null +++ b/src/constants/chains/base.ts @@ -0,0 +1,12 @@ +import { baseAddresses } from 'op-viem/chains' +import type { L2Chain } from '../../types/OpConfig.js' + +export const base: L2Chain = { + chainId: 8453, + l1ChaindId: 1, + l1Addresses: baseAddresses, + l2Addresses: { + l2L1MessagePasserAddress: { address: '0x4200000000000000000000000000000000000016', chainId: 8453 }, + l2StandardBridge: { address: '0x4200000000000000000000000000000000000010', chainId: 8453 }, + }, +} as const diff --git a/src/constants/chains/baseGoerli.ts b/src/constants/chains/baseGoerli.ts new file mode 100644 index 0000000..dd24954 --- /dev/null +++ b/src/constants/chains/baseGoerli.ts @@ -0,0 +1,12 @@ +import { baseGoerliAddresses } from 'op-viem/chains' +import type { L2Chain } from '../../types/OpConfig.js' + +export const baseGoerli: L2Chain = { + chainId: 84531, + l1ChaindId: 5, + l1Addresses: baseGoerliAddresses, + l2Addresses: { + l2L1MessagePasserAddress: { address: '0x4200000000000000000000000000000000000016', chainId: 84531 }, + l2StandardBridge: { address: '0x4200000000000000000000000000000000000010', chainId: 84531 }, + }, +} as const diff --git a/src/constants/chains/optimismGoerli.ts b/src/constants/chains/optimismGoerli.ts new file mode 100644 index 0000000..f87ca67 --- /dev/null +++ b/src/constants/chains/optimismGoerli.ts @@ -0,0 +1,12 @@ +import { optimismGoerliAddresses } from 'op-viem/chains' +import type { L2Chain } from '../../types/OpConfig.js' + +export const optimismGoerli: L2Chain = { + chainId: 420, + l1ChaindId: 5, + l1Addresses: optimismGoerliAddresses, + l2Addresses: { + l2L1MessagePasserAddress: { address: '0x4200000000000000000000000000000000000016', chainId: 420 }, + l2StandardBridge: { address: '0x4200000000000000000000000000000000000010', chainId: 420 }, + }, +} as const diff --git a/src/hooks/L1/useSimulateDepositERC20.ts b/src/hooks/L1/useSimulateDepositERC20.ts index 5deb703..f44f406 100644 --- a/src/hooks/L1/useSimulateDepositERC20.ts +++ b/src/hooks/L1/useSimulateDepositERC20.ts @@ -2,25 +2,39 @@ import { l1StandardBridgeABI } from '@eth-optimism/contracts-ts' import { type SimulateDepositERC20Parameters } from 'op-viem/actions' -import { useSimulateContract, type UseSimulateContractParameters } from 'wagmi' +import { type Config, useSimulateContract, type UseSimulateContractParameters } from 'wagmi' +import type { OpConfig } from '../../types/OpConfig.js' +import type { UseSimulateOPActionBaseParameters } from '../../types/UseSimulateOPActionBaseParameters.js' +import type { UseSimulateOPActionBaseReturnType } from '../../types/UseSimulateOPActionBaseReturnType.js' import { useOpConfig } from '../useOpConfig.js' const ABI = l1StandardBridgeABI const FUNCTION = 'depositERC20To' -export type UseSimulateDepositERC20Parameters = - & UseSimulateContractParameters - & SimulateDepositERC20Parameters +export type UseSimulateDepositERC20Parameters< + config extends Config = OpConfig, + chainId extends config['chains'][number]['id'] | undefined = undefined, +> = + & UseSimulateOPActionBaseParameters + & Pick & { l2ChainId: number } +export type UseSimulateDepositERC20ReturnType< + config extends Config = OpConfig, + chainId extends config['chains'][number]['id'] | undefined = undefined, +> = UseSimulateOPActionBaseReturnType + /** * Simulates a deposit of ERC20 tokens to L2 * @param parameters - {@link UseSimulateDepositERC20Parameters} * @returns wagmi [useSimulateContract return type](https://alpha.wagmi.sh/react/api/hooks/useSimulateContract#return-type). {@link UseSimulateDepositERC20ReturnType} */ -export function useSimulateDepositERC20( - { args, l2ChainId, ...rest }: UseSimulateDepositERC20Parameters, -) { +export function useSimulateDepositERC20< + config extends Config = OpConfig, + chainId extends config['chains'][number]['id'] | undefined = undefined, +>( + { args, l2ChainId, query, ...rest }: UseSimulateDepositERC20Parameters, +): UseSimulateDepositERC20ReturnType { const opConfig = useOpConfig(rest) const l2Chain = opConfig.l2chains[l2ChainId] @@ -28,8 +42,9 @@ export function useSimulateDepositERC20( address: l2Chain.l1Addresses.l1StandardBridge.address, abi: ABI, functionName: FUNCTION, - args: [args.l1Token, args.l2Token, args.to, args.amount, args.minGasLimit, args.extraData || '0x'], + args: [args.l1Token, args.l2Token, args.to, args.amount, args.minGasLimit, args.extraData ?? '0x'], chainId: l2Chain.l1ChaindId, + query: query as UseSimulateContractParameters['query'], ...rest, - }) + }) as unknown as UseSimulateDepositERC20ReturnType } diff --git a/src/hooks/L1/useSimulateDepositETH.ts b/src/hooks/L1/useSimulateDepositETH.ts index ec17045..e84beaa 100644 --- a/src/hooks/L1/useSimulateDepositETH.ts +++ b/src/hooks/L1/useSimulateDepositETH.ts @@ -2,34 +2,50 @@ import { optimismPortalABI } from '@eth-optimism/contracts-ts' import { type SimulateDepositETHParameters } from 'op-viem/actions' -import { useSimulateContract, type UseSimulateContractParameters } from 'wagmi' +import { type Config, useSimulateContract, type UseSimulateContractParameters } from 'wagmi' +import type { OpConfig } from '../../types/OpConfig.js' +import type { UseSimulateOPActionBaseParameters } from '../../types/UseSimulateOPActionBaseParameters.js' +import type { UseSimulateOPActionBaseReturnType } from '../../types/UseSimulateOPActionBaseReturnType.js' import { useOpConfig } from '../useOpConfig.js' const ABI = optimismPortalABI const FUNCTION = 'depositTransaction' -export type UseSimulateDepositETHParameters = - & UseSimulateContractParameters - & SimulateDepositETHParameters +export type UseSimulateDepositETHParameters< + config extends Config = OpConfig, + chainId extends config['chains'][number]['id'] | undefined = undefined, +> = + & UseSimulateOPActionBaseParameters + & Pick & { l2ChainId: number } +export type UseSimulateDepositETHReturnType< + config extends Config = OpConfig, + chainId extends config['chains'][number]['id'] | undefined = undefined, +> = UseSimulateOPActionBaseReturnType + /** * Simulates a deposit of ETH to L2 * @param parameters - {@link UseSimulateDepositETHParameters} * @returns wagmi [useSimulateContract return type](https://alpha.wagmi.sh/react/api/hooks/useSimulateContract#return-type). {@link UseSimulateDepositETHReturnType} */ -export function useSimulateDepositETH( - { args, l2ChainId, ...rest }: UseSimulateDepositETHParameters, -) { +export function useSimulateDepositETH< + config extends Config = OpConfig, + chainId extends config['chains'][number]['id'] | undefined = undefined, +>( + { args, l2ChainId, query, ...rest }: UseSimulateDepositETHParameters, +): UseSimulateDepositETHReturnType { const opConfig = useOpConfig(rest) const l2Chain = opConfig.l2chains[l2ChainId] return useSimulateContract({ - address: l2Chain.l1Addresses.l1StandardBridge.address, + address: l2Chain.l1Addresses.portal.address, abi: ABI, functionName: FUNCTION, - args: [args.to, args.amount, args.gasLimit, false, args.data || '0x'], + args: [args.to, args.amount, BigInt(args.gasLimit), false, args.data ?? '0x'], chainId: l2Chain.l1ChaindId, + value: args.amount, + query: query as UseSimulateContractParameters['query'], ...rest, - }) + }) as unknown as UseSimulateDepositETHReturnType } diff --git a/src/hooks/L1/useSimulateFinalizeWithdrawalTransaction.ts b/src/hooks/L1/useSimulateFinalizeWithdrawalTransaction.ts new file mode 100644 index 0000000..485f2ce --- /dev/null +++ b/src/hooks/L1/useSimulateFinalizeWithdrawalTransaction.ts @@ -0,0 +1,93 @@ +'use client' + +import { optimismPortalABI } from '@eth-optimism/contracts-ts' +import { useQuery } from '@tanstack/react-query' +import { getWithdrawalMessages, simulateFinalizeWithdrawalTransaction } from 'op-viem/actions' +import { type Hash } from 'viem' +import { type Config, useAccount, usePublicClient } from 'wagmi' +import { hashFn, simulateContractQueryKey } from 'wagmi/query' +import type { OpConfig } from '../../types/OpConfig.js' +import type { UseSimulateOPActionBaseParameters } from '../../types/UseSimulateOPActionBaseParameters.js' +import type { UseSimulateOPActionBaseReturnType } from '../../types/UseSimulateOPActionBaseReturnType.js' +import { useOpConfig } from '../useOpConfig.js' + +const ABI = optimismPortalABI +const FUNCTION = 'finalizeWithdrawalTransaction' + +export type UseSimulateFinalizeWithdrawalTransactionParameters< + config extends Config = OpConfig, + chainId extends config['chains'][number]['id'] | undefined = undefined, +> = + & UseSimulateOPActionBaseParameters + & { + args: { + l1WithdrawalTxHash: Hash + } + l2ChainId: number + } + +export type UseSimulateFinalizeWithdrawalTransactionReturnType< + config extends Config = OpConfig, + chainId extends config['chains'][number]['id'] | undefined = undefined, +> = UseSimulateOPActionBaseReturnType + +/** + * Simulates finalizing a withdrawal transaction. + * @param parameters - {@link UseSimulateFinalizeWithdrawalTransactionParameters} + * @returns wagmi [useSimulateContract return type](https://alpha.wagmi.sh/react/api/hooks/useSimulateContract#return-type). {@link UseSimulateFinalizeWithdrawalTransactionReturnType} + */ +export function useSimulateFinalizeWithdrawalTransaction< + config extends Config = OpConfig, + chainId extends config['chains'][number]['id'] | undefined = undefined, +>( + { args, l2ChainId, query: queryOverride, ...rest }: UseSimulateFinalizeWithdrawalTransactionParameters< + config, + chainId + >, +): UseSimulateFinalizeWithdrawalTransactionReturnType { + const opConfig = useOpConfig(rest) + const l2Chain = opConfig.l2chains[l2ChainId] + + if (!l2Chain) { + throw new Error('L2 chain not configured') + } + + const { address } = useAccount() + const l1PublicClient = usePublicClient({ chainId: l2Chain.l1ChaindId }) + const l2PublicClient = usePublicClient({ chainId: l2ChainId }) + const l1Addresses = opConfig.l2chains[l2ChainId].l1Addresses + + const query = { + async queryFn() { + const withdrawalMessages = await getWithdrawalMessages(l2PublicClient, { + hash: args.l1WithdrawalTxHash, + }) + + return simulateFinalizeWithdrawalTransaction(l1PublicClient, { + withdrawal: withdrawalMessages.messages[0], + account: address, + ...l1Addresses, + }) + }, + ...queryOverride, + queryKey: simulateContractQueryKey({ + ...{ + ...rest, + ...queryOverride, + gasPrice: undefined, + blockNumber: undefined, + type: undefined, + value: undefined, + ...args, + }, + account: address, + chainId: l2Chain.l1ChaindId, + }), + } + + const enabled = Boolean(address) && (queryOverride?.enabled ?? true) + return { + ...useQuery({ ...query, queryKeyHashFn: hashFn, enabled }), + queryKey: query.queryKey, + } +} diff --git a/src/hooks/L1/useSimulateProveWithdrawalTransaction.ts b/src/hooks/L1/useSimulateProveWithdrawalTransaction.ts index c505a10..13cffb9 100644 --- a/src/hooks/L1/useSimulateProveWithdrawalTransaction.ts +++ b/src/hooks/L1/useSimulateProveWithdrawalTransaction.ts @@ -1,55 +1,110 @@ 'use client' import { optimismPortalABI } from '@eth-optimism/contracts-ts' +import { useQuery } from '@tanstack/react-query' +import { + getLatestProposedL2BlockNumber, + getOutputForL2Block, + getProveWithdrawalTransactionArgs, + getWithdrawalMessages, + simulateProveWithdrawalTransaction, +} from 'op-viem/actions' import { type Hash } from 'viem' -import { useSimulateContract, type UseSimulateContractParameters } from 'wagmi' +import { type Config, useAccount, usePublicClient } from 'wagmi' +import { hashFn, simulateContractQueryKey } from 'wagmi/query' +import type { OpConfig } from '../../types/OpConfig.js' +import type { UseSimulateOPActionBaseParameters } from '../../types/UseSimulateOPActionBaseParameters.js' +import type { UseSimulateOPActionBaseReturnType } from '../../types/UseSimulateOPActionBaseReturnType.js' import { useOpConfig } from '../useOpConfig.js' -import { useProveWithdrawalArgs } from './useProveWithdrawalArgs.js' -export type UseProveWithdrawalTransactionParameters = - & UseSimulateContractParameters +const ABI = optimismPortalABI +const FUNCTION = 'proveWithdrawalTransaction' + +export type UseSimulateProveWithdrawalTransactionParameters< + config extends Config = OpConfig, + chainId extends config['chains'][number]['id'] | undefined = undefined, +> = + & UseSimulateOPActionBaseParameters & { args: { l1WithdrawalTxHash: Hash - l2ChainId: number } + l2ChainId: number } +export type UseSimulateProveWithdrawalTransactionReturnType< + config extends Config = OpConfig, + chainId extends config['chains'][number]['id'] | undefined = undefined, +> = UseSimulateOPActionBaseReturnType + /** - * Simulates a proof of ERC20 token withdrawal transaction to an L1 address. - * @param parameters - {@link UseProveWithdrawalTransactionParameters} - * @returns wagmi [useSimulateContract return type](https://alpha.wagmi.sh/react/api/hooks/useSimulateContract#return-type). {@link UseProveWithdrawalTransactionReturnType} + * Simulates proving a withdrawal transaction. + * @param parameters - {@link UseSimulateProveWithdrawalTransactionParameters} + * @returns wagmi [useSimulateContract return type](https://alpha.wagmi.sh/react/api/hooks/useSimulateContract#return-type). {@link UseSimulateProveWithdrawalTransactionReturnType} */ -export function useProveWithdrawalTransaction( - { args, query: queryOverride, config }: UseProveWithdrawalTransactionParameters, -) { - const opConfig = useOpConfig({ config }) - const l2Chain = opConfig.l2chains[args.l2ChainId] +export function useSimulateProveWithdrawalTransaction< + config extends Config = OpConfig, + chainId extends config['chains'][number]['id'] | undefined = undefined, +>( + { args, l2ChainId, query: queryOverride, ...rest }: UseSimulateProveWithdrawalTransactionParameters, +): UseSimulateProveWithdrawalTransactionReturnType { + const opConfig = useOpConfig(rest) + const l2Chain = opConfig.l2chains[l2ChainId] if (!l2Chain) { throw new Error('L2 chain not configured') } - const { withdrawalMessage, withdrawalOutputIndex, bedrockProof } = useProveWithdrawalArgs({ - l2ChainId: args.l2ChainId, - config: opConfig, - l1WithdrawalTxHash: args.l1WithdrawalTxHash, - }) - - return useSimulateContract({ - chainId: l2Chain.l1ChaindId, - abi: optimismPortalABI, - address: l2Chain.l1Addresses.portal.address, - functionName: 'proveWithdrawalTransaction', - args: !withdrawalMessage || !withdrawalOutputIndex || !bedrockProof ? undefined : [ - withdrawalMessage, - withdrawalOutputIndex, - bedrockProof.outputRootProof, - bedrockProof.withdrawalProof, - ], - query: { - enabled: Boolean(withdrawalMessage && withdrawalOutputIndex && bedrockProof), - ...queryOverride, + const { address } = useAccount() + const l1PublicClient = usePublicClient({ chainId: l2Chain.l1ChaindId }) + const l2PublicClient = usePublicClient({ chainId: l2ChainId }) + const l1Addresses = opConfig.l2chains[l2ChainId].l1Addresses + + const query = { + async queryFn() { + const withdrawalMessages = await getWithdrawalMessages(l2PublicClient, { + hash: args.l1WithdrawalTxHash, + }) + + const { l2BlockNumber } = await getLatestProposedL2BlockNumber(l1PublicClient, { + ...l1Addresses, + }) + + const output = await getOutputForL2Block(l1PublicClient, { + l2BlockNumber, + ...l1Addresses, + }) + + const simulateProveWithdrawalTransactionArgs = await getProveWithdrawalTransactionArgs(l2PublicClient, { + message: withdrawalMessages.messages[0], + output: output, + }) + + return simulateProveWithdrawalTransaction(l1PublicClient, { + args: simulateProveWithdrawalTransactionArgs, + account: address, + ...l1Addresses, + }) }, - }) + ...queryOverride, + queryKey: simulateContractQueryKey({ + ...{ + ...rest, + ...queryOverride, + gasPrice: undefined, + blockNumber: undefined, + type: undefined, + value: undefined, + ...args, + }, + account: address, + chainId: l2Chain.l1ChaindId, + }), + } + + const enabled = Boolean(address) && (queryOverride?.enabled ?? true) + return { + ...useQuery({ ...query, queryKeyHashFn: hashFn, enabled }), + queryKey: query.queryKey, + } } diff --git a/src/hooks/L1/useWriteDepositERC20.ts b/src/hooks/L1/useWriteDepositERC20.ts index 5a72ae4..6f000fd 100644 --- a/src/hooks/L1/useWriteDepositERC20.ts +++ b/src/hooks/L1/useWriteDepositERC20.ts @@ -1,29 +1,60 @@ import { l1StandardBridgeABI } from '@eth-optimism/contracts-ts' -import { type Config } from '@wagmi/core' -import { type WriteDepositERC20Parameters as WriteDepositERC20ActionParameters } from 'op-viem/actions' -import { useWriteContract, type UseWriteContractParameters } from 'wagmi' +import { type Config, waitForTransactionReceipt } from '@wagmi/core' +import { + getL2HashesForDepositTx, + type WriteDepositERC20Parameters as WriteDepositERC20ActionParameters, +} from 'op-viem/actions' +import { useEffect, useState } from 'react' +import { usePublicClient, useWriteContract } from 'wagmi' +import type { OpConfig } from '../../types/OpConfig.js' +import type { UseWriteOPActionBaseParameters } from '../../types/UseWriteOPActionBaseParameters.js' +import type { UseWriteOPActionBaseReturnType } from '../../types/UseWriteOPActionBaseReturnType.js' import { useOpConfig } from '../useOpConfig.js' -export type WriteDepositERC20Parameters = Omit & { l2ChainId: number } +export type WriteDepositERC20Parameters = Pick -export type UseWriteDepositERC20Parameters = - & UseWriteContractParameters - & WriteDepositERC20Parameters +export type UseWriteDepositERC20Parameters = + & UseWriteOPActionBaseParameters + & { l2ChainId: number } + +export type UseWriteDepositERC20ReturnType = + & Omit, 'write' | 'writeAsync'> + & { + writeDepositERC20: UseWriteOPActionBaseReturnType['write'] + writeDepositERC20Async: UseWriteOPActionBaseReturnType['writeAsync'] + l2TxHash: `0x${string}` | undefined + } /** * Deposits ERC20 tokens to L2 using the standard bridge * @param parameters - {@link UseWriteDepositERC20Parameters} * @returns wagmi [useWriteContract return type](https://alpha.wagmi.sh/react/api/hooks/useWrtieContract#return-type). {@link UseWriteDepositERC20ReturnType} */ -export function useWriteDepositERC20( - { args, l2ChainId, ...rest }: UseWriteDepositERC20Parameters, -) { +export function useWriteDepositERC20( + { l2ChainId, ...rest }: UseWriteDepositERC20Parameters, +): UseWriteDepositERC20ReturnType { const config = useOpConfig(rest) const l2Chain = config.l2chains[l2ChainId] - const { writeContract, writeContractAsync } = useWriteContract() + const l2Client = usePublicClient({ chainId: l2Chain.l1ChaindId }) + const [l2TxHash, setL2TxHash] = useState<`0x${string}` | undefined>(undefined) + const { writeContract, writeContractAsync, ...writeReturn } = useWriteContract() + + useEffect(() => { + void (async () => { + if (writeReturn.data) { + const l1TxReceipt = await waitForTransactionReceipt(config, { + chainId: l2Chain.l1ChaindId, + hash: writeReturn.data, + confirmations: 1, + }) + const l2Hashes = await getL2HashesForDepositTx(l2Client, { l1TxReceipt }) + setL2TxHash(l2Hashes[0]) + } + })() + }, [l2Client, writeReturn]) return { - writeDepositERC20: () => + writeDepositERC20: ({ args }: WriteDepositERC20Parameters) => writeContract({ chainId: l2Chain.l1ChaindId, address: l2Chain.l1Addresses.l1StandardBridge.address, @@ -31,7 +62,7 @@ export function useWriteDepositERC20( functionName: 'depositERC20To', args: [args.l1Token, args.l2Token, args.to, args.amount, args.minGasLimit, args.extraData || '0x'], }), - writeDepositERC20Async: () => + writeDepositERC20Async: ({ args }: WriteDepositERC20Parameters) => writeContractAsync({ chainId: l2Chain.l1ChaindId, address: l2Chain.l1Addresses.l1StandardBridge.address, @@ -39,5 +70,7 @@ export function useWriteDepositERC20( functionName: 'depositERC20To', args: [args.l1Token, args.l2Token, args.to, args.amount, args.minGasLimit, args.extraData || '0x'], }), - } + l2TxHash, + ...writeReturn, + } as unknown as UseWriteDepositERC20ReturnType } diff --git a/src/hooks/L1/useWriteDepositETH.ts b/src/hooks/L1/useWriteDepositETH.ts index e605db4..5cb8c62 100644 --- a/src/hooks/L1/useWriteDepositETH.ts +++ b/src/hooks/L1/useWriteDepositETH.ts @@ -1,41 +1,78 @@ import { optimismPortalABI } from '@eth-optimism/contracts-ts' -import { type Config } from '@wagmi/core' -import { type WriteDepositETHParameters as WriteDepositETHActionParameters } from 'op-viem/actions' -import { useWriteContract, type UseWriteContractParameters } from 'wagmi' +import { type Config, waitForTransactionReceipt } from '@wagmi/core' +import { + getL2HashesForDepositTx, + type WriteDepositETHParameters as WriteDepositETHActionParameters, +} from 'op-viem/actions' +import { useEffect, useState } from 'react' +import { usePublicClient, useWriteContract } from 'wagmi' +import type { OpConfig } from '../../types/OpConfig.js' +import type { UseWriteOPActionBaseParameters } from '../../types/UseWriteOPActionBaseParameters.js' +import type { UseWriteOPActionBaseReturnType } from '../../types/UseWriteOPActionBaseReturnType.js' import { useOpConfig } from '../useOpConfig.js' -export type WriteDepositETHParameters = Omit & { l2ChainId: number } +export type WriteDepositETHParameters = Pick -export type UseWriteDepositETHParameters = - & UseWriteContractParameters - & WriteDepositETHParameters +export type UseWriteDepositETHParameters = + & UseWriteOPActionBaseParameters + & { l2ChainId: number } + +export type UseWriteDepositETHReturnType = + & Omit, 'write' | 'writeAsync'> + & { + writeDepositETH: UseWriteOPActionBaseReturnType['write'] + writeDepositETHAsync: UseWriteOPActionBaseReturnType['writeAsync'] + l2TxHash: `0x${string}` | undefined + } /** * Deposits ETH to L2 using the OptimismPortal contract * @param parameters - {@link UseWriteDepositETHParameters} * @returns wagmi [useWriteContract return type](https://alpha.wagmi.sh/react/api/hooks/useWrtieContract#return-type). {@link UseWriteDepositETHReturnType} */ -export function useWriteDepositETH({ args, l2ChainId, ...rest }: UseWriteDepositETHParameters) { +export function useWriteDepositETH( + { l2ChainId, ...rest }: UseWriteDepositETHParameters, +): UseWriteDepositETHReturnType { const config = useOpConfig(rest) const l2Chain = config.l2chains[l2ChainId] - const { writeContract, writeContractAsync } = useWriteContract() + const l2Client = usePublicClient({ chainId: l2Chain.l1ChaindId }) + const [l2TxHash, setL2TxHash] = useState<`0x${string}` | undefined>(undefined) + const { writeContract, writeContractAsync, ...writeReturn } = useWriteContract() + + useEffect(() => { + void (async () => { + if (writeReturn.data) { + const l1TxReceipt = await waitForTransactionReceipt(config, { + chainId: l2Chain.l1ChaindId, + hash: writeReturn.data, + confirmations: 1, + }) + const l2Hashes = await getL2HashesForDepositTx(l2Client, { l1TxReceipt }) + setL2TxHash(l2Hashes[0]) + } + })() + }, [l2Client, writeReturn]) return { - writeDepositETH: () => + writeDepositETH: ({ args }: WriteDepositETHParameters) => writeContract({ chainId: l2Chain.l1ChaindId, address: l2Chain.l1Addresses.portal.address, abi: optimismPortalABI, functionName: 'depositTransaction', - args: [args.to, args.amount, BigInt(args.gasLimit), false, args.data || '0x'], + args: [args.to, args.amount, BigInt(args.gasLimit), false, args.data ?? '0x'], + value: args.amount, }), - writeDepositETHAsync: () => + writeDepositETHAsync: ({ args }: WriteDepositETHParameters) => writeContractAsync({ chainId: l2Chain.l1ChaindId, address: l2Chain.l1Addresses.portal.address, abi: optimismPortalABI, functionName: 'depositTransaction', - args: [args.to, args.amount, BigInt(args.gasLimit), false, args.data || '0x'], + args: [args.to, args.amount, BigInt(args.gasLimit), false, args.data ?? '0x'], + value: args.amount, }), - } + l2TxHash, + ...writeReturn, + } as unknown as UseWriteDepositETHReturnType } diff --git a/src/hooks/L1/useWriteFinalizeWithdrawalTransaction.ts b/src/hooks/L1/useWriteFinalizeWithdrawalTransaction.ts new file mode 100644 index 0000000..72bc7bc --- /dev/null +++ b/src/hooks/L1/useWriteFinalizeWithdrawalTransaction.ts @@ -0,0 +1,104 @@ +import { useMutation } from '@tanstack/react-query' +import { + getWithdrawalMessages, + simulateFinalizeWithdrawalTransaction, + writeFinalizeWithdrawalTranasction, +} from 'op-viem/actions' +import type { Hash } from 'viem' +import { type Config } from 'wagmi' +import { getPublicClient, getWalletClient } from 'wagmi/actions' +import type { OpConfig } from '../../types/OpConfig.js' +import type { UseWriteOPActionBaseParameters } from '../../types/UseWriteOPActionBaseParameters.js' +import type { UseWriteOPActionBaseReturnType } from '../../types/UseWriteOPActionBaseReturnType.js' +import { useOpConfig } from '../useOpConfig.js' + +export type WriteFinalizeWithdrawalTransactionParameters = { + args: { + l1WithdrawalTxHash: Hash + } +} + +export type UseWriteFinalizeWithdrawalTransactionParameters = + & UseWriteOPActionBaseParameters + & { + l2ChainId: number + } + +export type UseWriteFinalizeWithdrawalTransactionReturnType = + & Omit< + UseWriteOPActionBaseReturnType, + 'write' | 'writeAsync' + > + & { + writeFinalizeWithdrawalTransaction: UseWriteOPActionBaseReturnType< + WriteFinalizeWithdrawalTransactionParameters, + config, + context + >['write'] + writeFinalizeWithdrawalTransactionAsync: UseWriteOPActionBaseReturnType< + WriteFinalizeWithdrawalTransactionParameters, + config, + context + >['writeAsync'] + } + +type FinalizeWithdrawalTransactionMutationParameters = WriteFinalizeWithdrawalTransactionParameters & { + l1ChainId: number + l2ChainId: number +} + +async function writeMutation( + config: OpConfig, + { l1ChainId, l2ChainId, ...params }: FinalizeWithdrawalTransactionMutationParameters, +) { + const walletClient = await getWalletClient(config, { chainId: l1ChainId }) + const l1PublicClient = getPublicClient(config, { chainId: l1ChainId }) + const l2PublicClient = getPublicClient(config, { chainId: l2ChainId }) + const l1Addresses = config.l2chains[l2ChainId].l1Addresses + + const withdrawalMessages = await getWithdrawalMessages(l2PublicClient, { + hash: params.args.l1WithdrawalTxHash, + }) + + await simulateFinalizeWithdrawalTransaction(l1PublicClient, { + withdrawal: withdrawalMessages.messages[0], + account: walletClient.account.address, + ...l1Addresses, + }) + return writeFinalizeWithdrawalTranasction(walletClient, { + args: { withdrawal: withdrawalMessages.messages[0] }, + account: walletClient.account.address, + ...l1Addresses, + }) +} + +/** + * Deposits ETH to L2 using the OptimismPortal contract + * @param parameters - {@link UseWriteFinalizeWithdrawalTransactionParameters} + * @returns wagmi [useWriteContract return type](https://alpha.wagmi.sh/react/api/hooks/useWrtieContract#return-type). {@link UseWriteFinalizeWithdrawalTransactionReturnType} + */ +export function useWriteFinalizeWithdrawalTransaction( + { l2ChainId, ...rest }: UseWriteFinalizeWithdrawalTransactionParameters, +): UseWriteFinalizeWithdrawalTransactionReturnType { + const opConfig = useOpConfig(rest) + const l2Chain = opConfig.l2chains[l2ChainId] + + if (!l2Chain) { + throw new Error('L2 chain not configured') + } + + const mutation = { + mutationFn(params: WriteFinalizeWithdrawalTransactionParameters) { + return writeMutation(opConfig, { ...params, l1ChainId: l2Chain.l1ChaindId, l2ChainId: l2ChainId }) + }, + mutationKey: ['writeContract'], + } + + const { mutate, mutateAsync, ...result } = useMutation(mutation) + + return { + ...result, + writeFinalizeWithdrawalTransaction: mutate, + writeFinalizeWithdrawalTransactionAsync: mutateAsync, + } as unknown as UseWriteFinalizeWithdrawalTransactionReturnType +} diff --git a/src/hooks/L1/useWriteProveWithdrawalTransaction.ts b/src/hooks/L1/useWriteProveWithdrawalTransaction.ts index b06e030..8e4f45a 100644 --- a/src/hooks/L1/useWriteProveWithdrawalTransaction.ts +++ b/src/hooks/L1/useWriteProveWithdrawalTransaction.ts @@ -1,80 +1,117 @@ -import { optimismPortalABI } from '@eth-optimism/contracts-ts' +import { useMutation } from '@tanstack/react-query' +import { + getLatestProposedL2BlockNumber, + getOutputForL2Block, + getProveWithdrawalTransactionArgs, + getWithdrawalMessages, + simulateProveWithdrawalTransaction, + writeProveWithdrawalTransaction, +} from 'op-viem/actions' import type { Hash } from 'viem' -import { type UseSimulateContractParameters, useWriteContract } from 'wagmi' -import type { WithdrawalMessage } from '../../types/WithdrawalMessage.js' +import { type Config } from 'wagmi' +import { getPublicClient, getWalletClient } from 'wagmi/actions' +import type { OpConfig } from '../../types/OpConfig.js' +import type { UseWriteOPActionBaseParameters } from '../../types/UseWriteOPActionBaseParameters.js' +import type { UseWriteOPActionBaseReturnType } from '../../types/UseWriteOPActionBaseReturnType.js' import { useOpConfig } from '../useOpConfig.js' -import { useProveWithdrawalArgs } from './useProveWithdrawalArgs.js' -export type UseProveWithdrawalTransactionParameters = - & UseSimulateContractParameters +export type WriteProveWithdrawalTransactionParameters = { + args: { + l1WithdrawalTxHash: Hash + } +} + +export type UseWriteProveWithdrawalTransactionParameters = + & UseWriteOPActionBaseParameters + & { + l2ChainId: number + } + +export type UseWriteProveWithdrawalTransactionReturnType = + & Omit< + UseWriteOPActionBaseReturnType, + 'write' | 'writeAsync' + > & { - args: { - l1WithdrawalTxHash: Hash - l2ChainId: number - } + writeProveWithdrawalTransaction: UseWriteOPActionBaseReturnType< + WriteProveWithdrawalTransactionParameters, + config, + context + >['write'] + writeProveWithdrawalTransactionAsync: UseWriteOPActionBaseReturnType< + WriteProveWithdrawalTransactionParameters, + config, + context + >['writeAsync'] } -type OutputRootProof = { - version: `0x${string}` - stateRoot: `0x${string}` - messagePasserStorageRoot: `0x${string}` - latestBlockhash: `0x${string}` +type ProveWithdrawalTransactionMutationParameters = WriteProveWithdrawalTransactionParameters & { + l1ChainId: number + l2ChainId: number +} + +async function writeMutation( + config: OpConfig, + { l1ChainId, l2ChainId, ...params }: ProveWithdrawalTransactionMutationParameters, +) { + const walletClient = await getWalletClient(config, { chainId: l1ChainId }) + const l1PublicClient = getPublicClient(config, { chainId: l1ChainId }) + const l2PublicClient = getPublicClient(config, { chainId: l2ChainId }) + const l1Addresses = config.l2chains[l2ChainId].l1Addresses + + const withdrawalMessages = await getWithdrawalMessages(l2PublicClient, { + hash: params.args.l1WithdrawalTxHash, + }) + + const { l2BlockNumber } = await getLatestProposedL2BlockNumber(l1PublicClient, { + ...l1Addresses, + }) + + const output = await getOutputForL2Block(l1PublicClient, { + l2BlockNumber, + ...l1Addresses, + }) + + const args = await getProveWithdrawalTransactionArgs(l2PublicClient, { + message: withdrawalMessages.messages[0], + output: output, + }) + + await simulateProveWithdrawalTransaction(l1PublicClient, { + args, + account: walletClient.account.address, + ...l1Addresses, + }) + return writeProveWithdrawalTransaction(walletClient, { args, account: walletClient.account.address, ...l1Addresses }) } /** * Deposits ETH to L2 using the OptimismPortal contract - * @param parameters - {@link UseWriteDepositETHParameters} - * @returns wagmi [useWriteContract return type](https://alpha.wagmi.sh/react/api/hooks/useWrtieContract#return-type). {@link UseWriteDepositETHReturnType} + * @param parameters - {@link UseWriteProveWithdrawalTransactionParameters} + * @returns wagmi [useWriteContract return type](https://alpha.wagmi.sh/react/api/hooks/useWrtieContract#return-type). {@link UseWriteProveWithdrawalTransactionReturnType} */ -export function useWriteDepositETH({ args, ...rest }: UseProveWithdrawalTransactionParameters) { - const { writeContract, writeContractAsync } = useWriteContract() - +export function useWriteProveWithdrawalTransaction( + { l2ChainId, ...rest }: UseWriteProveWithdrawalTransactionParameters, +): UseWriteProveWithdrawalTransactionReturnType { const opConfig = useOpConfig(rest) - const l2Chain = opConfig.l2chains[args.l2ChainId] + const l2Chain = opConfig.l2chains[l2ChainId] if (!l2Chain) { throw new Error('L2 chain not configured') } - const { withdrawalMessage, withdrawalOutputIndex, bedrockProof } = useProveWithdrawalArgs({ - l2ChainId: args.l2ChainId, - config: opConfig, - l1WithdrawalTxHash: args.l1WithdrawalTxHash, - }) + const mutation = { + mutationFn(params: WriteProveWithdrawalTransactionParameters) { + return writeMutation(opConfig, { ...params, l1ChainId: l2Chain.l1ChaindId, l2ChainId: l2ChainId }) + }, + mutationKey: ['writeContract'], + } - const ready = Boolean(withdrawalMessage && withdrawalOutputIndex && bedrockProof) + const { mutate, mutateAsync, ...result } = useMutation(mutation) return { - writeProveWithdrawalTransaction: ready - ? () => - writeContract({ - chainId: l2Chain.l1ChaindId, - abi: optimismPortalABI, - address: l2Chain.l1Addresses.portal.address, - functionName: 'proveWithdrawalTransaction', - args: [ - withdrawalMessage as WithdrawalMessage, - withdrawalOutputIndex as bigint, - bedrockProof?.outputRootProof as OutputRootProof, - bedrockProof?.withdrawalProof as `0x${string}`[], - ], - }) - : undefined, - writeProveWithdrawalTransactionAsync: ready - ? () => - writeContractAsync({ - chainId: l2Chain.l1ChaindId, - abi: optimismPortalABI, - address: l2Chain.l1Addresses.portal.address, - functionName: 'proveWithdrawalTransaction', - args: [ - withdrawalMessage as WithdrawalMessage, - withdrawalOutputIndex as bigint, - bedrockProof?.outputRootProof as OutputRootProof, - bedrockProof?.withdrawalProof as `0x${string}`[], - ], - }) - : undefined, - ready, - } + ...result, + writeProveWithdrawalTransaction: mutate, + writeProveWithdrawalTransactionAsync: mutateAsync, + } as unknown as UseWriteProveWithdrawalTransactionReturnType } diff --git a/src/hooks/L2/useSimulateWithdrawERC20.ts b/src/hooks/L2/useSimulateWithdrawERC20.ts index 324f2d8..a1a59ab 100644 --- a/src/hooks/L2/useSimulateWithdrawERC20.ts +++ b/src/hooks/L2/useSimulateWithdrawERC20.ts @@ -1,21 +1,29 @@ 'use client' import { l2StandardBridgeABI } from '@eth-optimism/contracts-ts' -import type { Config, ResolvedRegister } from '@wagmi/core' +import type { Config } from '@wagmi/core' import { type SimulateWithdrawERC20Parameters } from 'op-viem/actions' -import { useChainId, useSimulateContract, type UseSimulateContractParameters } from 'wagmi' +import { useSimulateContract, type UseSimulateContractParameters } from 'wagmi' +import type { OpConfig } from '../../types/OpConfig.js' +import type { UseSimulateOPActionBaseParameters } from '../../types/UseSimulateOPActionBaseParameters.js' +import type { UseSimulateOPActionBaseReturnType } from '../../types/UseSimulateOPActionBaseReturnType.js' import { useOpConfig } from '../useOpConfig.js' const ABI = l2StandardBridgeABI const FUNCTION = 'withdrawTo' export type UseSimulateWithdrawERC20Parameters< - config extends Config = ResolvedRegister['config'], + config extends Config = OpConfig, chainId extends config['chains'][number]['id'] | undefined = undefined, > = - & UseSimulateContractParameters - & SimulateWithdrawERC20Parameters - & { chainId?: chainId } + & UseSimulateOPActionBaseParameters + & Pick + & { chainId: number } + +export type UseSimulateWithdrawERC20ReturnType< + config extends Config = OpConfig, + chainId extends config['chains'][number]['id'] | undefined = undefined, +> = UseSimulateOPActionBaseReturnType /** * Simulates a withdrawal of ERC20 tokens to an L1 address. @@ -23,19 +31,21 @@ export type UseSimulateWithdrawERC20Parameters< * @returns wagmi [useSimulateContract return type](https://alpha.wagmi.sh/react/api/hooks/useSimulateContract#return-type). {@link UseSimulateWithdrawERC20ReturnType} */ export function useSimulateWithdrawERC20< - config extends Config = ResolvedRegister['config'], + config extends Config = OpConfig, chainId extends config['chains'][number]['id'] | undefined = undefined, >( - { args, chainId, ...rest }: UseSimulateWithdrawERC20Parameters, -) { + { args, chainId, query, ...rest }: UseSimulateWithdrawERC20Parameters, +): UseSimulateWithdrawERC20ReturnType { const opConfig = useOpConfig(rest) - const l2ChainId = chainId || useChainId(rest) - const l2Chain = opConfig.l2chains[l2ChainId] + const l2Chain = opConfig.l2chains[chainId] return useSimulateContract({ address: l2Chain.l2Addresses.l2StandardBridge.address, abi: ABI, + chainId: l2Chain.chainId, functionName: FUNCTION, - args: [args.l2Token, args.to, args.amount, args.minGasLimit, args.extraData || '0x'], - }) + args: [args.l2Token, args.to, args.amount, args.minGasLimit, args.extraData ?? '0x'], + query: query as UseSimulateContractParameters['query'], + ...rest, + }) as unknown as UseSimulateWithdrawERC20ReturnType } diff --git a/src/hooks/L2/useSimulateWithdrawETH.ts b/src/hooks/L2/useSimulateWithdrawETH.ts index 6d88145..fbb8aad 100644 --- a/src/hooks/L2/useSimulateWithdrawETH.ts +++ b/src/hooks/L2/useSimulateWithdrawETH.ts @@ -1,9 +1,12 @@ 'use client' import { l2StandardBridgeABI } from '@eth-optimism/contracts-ts' -import type { Config, ResolvedRegister } from '@wagmi/core' +import type { Config } from '@wagmi/core' import { type SimulateWithdrawETHParameters } from 'op-viem/actions' -import { useChainId, useSimulateContract, type UseSimulateContractParameters } from 'wagmi' +import { useSimulateContract, type UseSimulateContractParameters } from 'wagmi' +import type { OpConfig } from '../../types/OpConfig.js' +import type { UseSimulateOPActionBaseParameters } from '../../types/UseSimulateOPActionBaseParameters.js' +import type { UseSimulateOPActionBaseReturnType } from '../../types/UseSimulateOPActionBaseReturnType.js' import { useOpConfig } from '../useOpConfig.js' const ABI = l2StandardBridgeABI @@ -11,12 +14,17 @@ const FUNCTION = 'withdrawTo' export const OVM_ETH = '0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000' export type UseSimulateWithdrawETHParameters< - config extends Config = ResolvedRegister['config'], + config extends Config = OpConfig, chainId extends config['chains'][number]['id'] | undefined = undefined, > = - & UseSimulateContractParameters - & SimulateWithdrawETHParameters - & { chainId?: chainId } + & UseSimulateOPActionBaseParameters + & Pick + & { chainId: number } + +export type UseSimulateWithdrawETHReturnType< + config extends Config = OpConfig, + chainId extends config['chains'][number]['id'] | undefined = undefined, +> = UseSimulateOPActionBaseReturnType /** * Simulates a withdrawal of ETH to an L1 address. @@ -24,19 +32,22 @@ export type UseSimulateWithdrawETHParameters< * @returns wagmi [useSimulateContract return type](https://alpha.wagmi.sh/react/api/hooks/useSimulateContract#return-type). {@link UseSimulateWithdrawETHReturnType} */ export function useSimulateWithdrawETH< - config extends Config = ResolvedRegister['config'], + config extends Config = OpConfig, chainId extends config['chains'][number]['id'] | undefined = undefined, >( - { args, chainId, ...rest }: UseSimulateWithdrawETHParameters, -) { + { args, chainId, query, ...rest }: UseSimulateWithdrawETHParameters, +): UseSimulateWithdrawETHReturnType { const opConfig = useOpConfig(rest) - const l2ChainId = chainId || useChainId(rest) - const l2Chain = opConfig.l2chains[l2ChainId] + const l2Chain = opConfig.l2chains[chainId] return useSimulateContract({ address: l2Chain.l2Addresses.l2StandardBridge.address, abi: ABI, functionName: FUNCTION, - args: [OVM_ETH, args.to, args.amount, args.minGasLimit, args.extraData || '0x'], - }) + chainId: l2Chain.chainId, + args: [OVM_ETH, args.to, args.amount, args.minGasLimit, args.extraData ?? '0x'], + value: args.amount, + query: query as UseSimulateContractParameters['query'], + ...rest, + }) as unknown as UseSimulateWithdrawETHReturnType } diff --git a/src/hooks/L2/useWriteWithdrawERC20.ts b/src/hooks/L2/useWriteWithdrawERC20.ts index 1d1ffdb..aba53b2 100644 --- a/src/hooks/L2/useWriteWithdrawERC20.ts +++ b/src/hooks/L2/useWriteWithdrawERC20.ts @@ -1,14 +1,23 @@ import { l2StandardBridgeABI } from '@eth-optimism/contracts-ts' import { type Config } from '@wagmi/core' import { type WriteWithdrawERC20Parameters as WriteWithdrawERC20ActionParameters } from 'op-viem/actions' -import { useChainId, useWriteContract, type UseWriteContractParameters } from 'wagmi' +import { useWriteContract } from 'wagmi' +import type { UseWriteOPActionBaseParameters } from '../../types/UseWriteOPActionBaseParameters.js' +import type { UseWriteOPActionBaseReturnType } from '../../types/UseWriteOPActionBaseReturnType.js' import { useOpConfig } from '../useOpConfig.js' -export type WriteWithdrawERC20Parameters = Omit & { chainId?: number } +export type WriteWithdrawERC20Parameters = Pick export type UseWriteWithdrawERC20Parameters = - & UseWriteContractParameters - & WriteWithdrawERC20Parameters + & UseWriteOPActionBaseParameters + & { chainId: number } + +export type UseWriteWithdrawERC20ReturnType = + & Omit, 'write' | 'writeAsync'> + & { + writeWithdrawERC20: UseWriteOPActionBaseReturnType['write'] + writeWithdrawERC20Async: UseWriteOPActionBaseReturnType['writeAsync'] + } /** * Withdraws ERC20 tokens to an L1 address. @@ -16,25 +25,24 @@ export type UseWriteWithdrawERC20Parameters + writeWithdrawERC20: ({ args }: WriteWithdrawERC20Parameters) => writeContract({ - chainId: l2Chain.l1ChaindId, + chainId: l2Chain.chainId, address: l2Chain.l2Addresses.l2StandardBridge.address, abi: l2StandardBridgeABI, functionName: 'withdrawTo', args: [args.l2Token, args.to, args.amount, args.minGasLimit, args.extraData || '0x'], }), - writeWithdrawERC20Async: () => + writeWithdrawERC20Async: ({ args }: WriteWithdrawERC20Parameters) => writeContractAsync({ - chainId: l2Chain.l1ChaindId, + chainId: l2Chain.chainId, address: l2Chain.l2Addresses.l2StandardBridge.address, abi: l2StandardBridgeABI, functionName: 'withdrawTo', diff --git a/src/hooks/L2/useWriteWithdrawETH.ts b/src/hooks/L2/useWriteWithdrawETH.ts index 9015828..487cc43 100644 --- a/src/hooks/L2/useWriteWithdrawETH.ts +++ b/src/hooks/L2/useWriteWithdrawETH.ts @@ -1,45 +1,57 @@ import { l2StandardBridgeABI } from '@eth-optimism/contracts-ts' import { type Config } from '@wagmi/core' import { type WriteWithdrawETHParameters as WriteWithdrawETHActionParameters } from 'op-viem/actions' -import { useChainId, useWriteContract, type UseWriteContractParameters } from 'wagmi' +import { useWriteContract } from 'wagmi' +import type { OpConfig } from '../../types/OpConfig.js' +import type { UseWriteOPActionBaseParameters } from '../../types/UseWriteOPActionBaseParameters.js' +import type { UseWriteOPActionBaseReturnType } from '../../types/UseWriteOPActionBaseReturnType.js' import { useOpConfig } from '../useOpConfig.js' import { OVM_ETH } from './useSimulateWithdrawETH.js' -export type WriteWithdrawETHParameters = Omit & { chainId?: number } +export type WriteWithdrawETHParameters = Pick -export type UseWriteWithdrawETHParameters = - & UseWriteContractParameters - & WriteWithdrawETHParameters +export type UseWriteWithdrawETHParameters = + & UseWriteOPActionBaseParameters + & { chainId: number } + +export type UseWriteWithdrawETHReturnType = + & Omit, 'write' | 'writeAsync'> + & { + writeWithdrawETH: UseWriteOPActionBaseReturnType['write'] + writeWithdrawETHAsync: UseWriteOPActionBaseReturnType['writeAsync'] + } /** * Withdraws ETH to an L1 address. * @param parameters - {@link UseWriteWithdrawETHParameters} * @returns wagmi [useWriteContract return type](https://alpha.wagmi.sh/react/api/hooks/useWrtieContract#return-type). {@link UseWriteWithdrawETHReturnType} */ -export function useWriteWithdrawETH( - { args, chainId, ...rest }: UseWriteWithdrawETHParameters, -) { +export function useWriteWithdrawETH( + { chainId, ...rest }: UseWriteWithdrawETHParameters, +): UseWriteWithdrawETHReturnType { const config = useOpConfig(rest) - const l2ChainId = chainId || useChainId(rest) - const l2Chain = config.l2chains[l2ChainId] - const { writeContract, writeContractAsync } = useWriteContract() + const l2Chain = config.l2chains[chainId] + const { writeContract, writeContractAsync, ...writeReturn } = useWriteContract() return { - writeWithdrawETH: () => + writeWithdrawETH: ({ args }: WriteWithdrawETHParameters) => writeContract({ - chainId: l2Chain.l1ChaindId, + chainId: l2Chain.chainId, address: l2Chain.l2Addresses.l2StandardBridge.address, abi: l2StandardBridgeABI, functionName: 'withdrawTo', - args: [OVM_ETH, args.to, args.amount, args.minGasLimit, args.extraData || '0x'], + args: [OVM_ETH, args.to, args.amount, args.minGasLimit, args.extraData ?? '0x'], + value: args.amount, }), - writeWithdrawETHAsync: () => + writeWithdrawETHAsync: ({ args }: WriteWithdrawETHParameters) => writeContractAsync({ - chainId: l2Chain.l1ChaindId, + chainId: l2Chain.chainId, address: l2Chain.l2Addresses.l2StandardBridge.address, abi: l2StandardBridgeABI, functionName: 'withdrawTo', - args: [OVM_ETH, args.to, args.amount, args.minGasLimit, args.extraData || '0x'], + args: [OVM_ETH, args.to, args.amount, args.minGasLimit, args.extraData ?? '0x'], + value: args.amount, }), - } + ...writeReturn, + } as unknown as UseWriteWithdrawETHReturnType } diff --git a/src/hooks/index.ts b/src/hooks/index.ts index 10b42c7..551066b 100644 --- a/src/hooks/index.ts +++ b/src/hooks/index.ts @@ -1,5 +1,13 @@ export { useSimulateDepositERC20, type UseSimulateDepositERC20Parameters } from './L1/useSimulateDepositERC20.js' export { useSimulateDepositETH, type UseSimulateDepositETHParameters } from './L1/useSimulateDepositETH.js' +export { + useSimulateFinalizeWithdrawalTransaction, + type UseSimulateFinalizeWithdrawalTransactionParameters, +} from './L1/useSimulateFinalizeWithdrawalTransaction.js' +export { + useSimulateProveWithdrawalTransaction, + type UseSimulateProveWithdrawalTransactionParameters, +} from './L1/useSimulateProveWithdrawalTransaction.js' export { useWriteDepositERC20, type UseWriteDepositERC20Parameters, @@ -10,6 +18,16 @@ export { type UseWriteDepositETHParameters, type WriteDepositETHParameters, } from './L1/useWriteDepositETH.js' +export { + useWriteFinalizeWithdrawalTransaction, + type UseWriteFinalizeWithdrawalTransactionParameters, + type WriteFinalizeWithdrawalTransactionParameters, +} from './L1/useWriteFinalizeWithdrawalTransaction.js' +export { + useWriteProveWithdrawalTransaction, + type UseWriteProveWithdrawalTransactionParameters, + type WriteProveWithdrawalTransactionParameters, +} from './L1/useWriteProveWithdrawalTransaction.js' export { useSimulateWithdrawERC20, type UseSimulateWithdrawERC20Parameters } from './L2/useSimulateWithdrawERC20.js' export { useSimulateWithdrawETH, type UseSimulateWithdrawETHParameters } from './L2/useSimulateWithdrawETH.js' export { diff --git a/src/hooks/useOpConfig.ts b/src/hooks/useOpConfig.ts index 3e87597..f396205 100644 --- a/src/hooks/useOpConfig.ts +++ b/src/hooks/useOpConfig.ts @@ -1,6 +1,9 @@ 'use client' import { type Config, useConfig } from 'wagmi' +import { base } from '../constants/chains/base.js' +import { baseGoerli } from '../constants/chains/baseGoerli.js' +import { optimismGoerli } from '../constants/chains/optimismGoerli.js' import { type OpConfig } from '../types/OpConfig.js' export type UseConfigParameters = ConfigParameter @@ -11,10 +14,12 @@ export type ConfigParameter = { export type UseConfigReturnType = config +const chains = { 8453: base, 84531: baseGoerli, 420: optimismGoerli } + export function useOpConfig( parameters: UseConfigParameters = {}, ): UseConfigReturnType { - const config = parameters.config ?? useConfig(parameters) + const config: UseConfigReturnType = { l2chains: chains, ...(parameters.config ?? useConfig(parameters)) } // TODO: Return a better error here if (!config) throw new Error('No Wagmi Context provider found') diff --git a/src/index.ts b/src/index.ts index a54bb2f..f1435b8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,13 @@ export { useSimulateDepositERC20, type UseSimulateDepositERC20Parameters } from './hooks/L1/useSimulateDepositERC20.js' export { useSimulateDepositETH, type UseSimulateDepositETHParameters } from './hooks/L1/useSimulateDepositETH.js' +export { + useSimulateFinalizeWithdrawalTransaction, + type UseSimulateFinalizeWithdrawalTransactionParameters, +} from './hooks/L1/useSimulateFinalizeWithdrawalTransaction.js' +export { + useSimulateProveWithdrawalTransaction, + type UseSimulateProveWithdrawalTransactionParameters, +} from './hooks/L1/useSimulateProveWithdrawalTransaction.js' export { useWriteDepositERC20, type UseWriteDepositERC20Parameters, @@ -10,6 +18,16 @@ export { type UseWriteDepositETHParameters, type WriteDepositETHParameters, } from './hooks/L1/useWriteDepositETH.js' +export { + useWriteFinalizeWithdrawalTransaction, + type UseWriteFinalizeWithdrawalTransactionParameters, + type WriteFinalizeWithdrawalTransactionParameters, +} from './hooks/L1/useWriteFinalizeWithdrawalTransaction.js' +export { + useWriteProveWithdrawalTransaction, + type UseWriteProveWithdrawalTransactionParameters, + type WriteProveWithdrawalTransactionParameters, +} from './hooks/L1/useWriteProveWithdrawalTransaction.js' export { useSimulateWithdrawERC20, type UseSimulateWithdrawERC20Parameters, diff --git a/src/types/UseSimulateOPActionBaseParameters.ts b/src/types/UseSimulateOPActionBaseParameters.ts index 78cb46b..07f4715 100644 --- a/src/types/UseSimulateOPActionBaseParameters.ts +++ b/src/types/UseSimulateOPActionBaseParameters.ts @@ -1,6 +1,8 @@ import type { Abi, ContractFunctionArgs, ContractFunctionName } from 'viem' -import type { Config, ResolvedRegister, UseSimulateContractParameters } from 'wagmi' +import type { Config, UseSimulateContractParameters } from 'wagmi' import type { SimulateContractData } from 'wagmi/query' +import type { ConfigParameter } from '../hooks/useOpConfig.js' +import type { OpConfig } from './OpConfig.js' export type UseSimulateOPActionBaseParameters< abi extends Abi | readonly unknown[] = Abi, @@ -8,7 +10,7 @@ export type UseSimulateOPActionBaseParameters< abi, 'nonpayable' | 'payable' > = ContractFunctionName, - config extends Config = ResolvedRegister['config'], + config extends Config = OpConfig, chainId extends config['chains'][number]['id'] | undefined = undefined, selectData = SimulateContractData< abi, @@ -27,9 +29,16 @@ export type UseSimulateOPActionBaseParameters< chainId, selectData >, - 'abi' | 'functionName' | 'args' | 'query' | 'address' + | 'value' + | 'type' + | 'gasPrice' + | 'blockNumber' + | 'address' + | 'abi' + | 'functionName' + | 'args' + | 'chainId' + | 'config' + | 'query' > - & { - query?: { enabled?: boolean } - config?: config - } + & ConfigParameter diff --git a/src/types/UseSimulateOPActionBaseReturnType.ts b/src/types/UseSimulateOPActionBaseReturnType.ts index 6415012..0b6ac31 100644 --- a/src/types/UseSimulateOPActionBaseReturnType.ts +++ b/src/types/UseSimulateOPActionBaseReturnType.ts @@ -1,6 +1,7 @@ import type { Abi, ContractFunctionArgs, ContractFunctionName } from 'viem' -import type { Config, ResolvedRegister, UseSimulateContractReturnType } from 'wagmi' +import type { Config, UseSimulateContractReturnType } from 'wagmi' import type { SimulateContractData } from 'wagmi/query' +import type { OpConfig } from './OpConfig.js' export type UseSimulateOPActionBaseReturnType< abi extends Abi | readonly unknown[] = Abi, @@ -8,7 +9,7 @@ export type UseSimulateOPActionBaseReturnType< abi, 'nonpayable' | 'payable' > = ContractFunctionName, - config extends Config = ResolvedRegister['config'], + config extends Config = OpConfig, chainId extends config['chains'][number]['id'] | undefined = undefined, selectData = SimulateContractData< abi, diff --git a/src/types/UseWriteOPActionBaseParameters.ts b/src/types/UseWriteOPActionBaseParameters.ts index 6840aa4..313defd 100644 --- a/src/types/UseWriteOPActionBaseParameters.ts +++ b/src/types/UseWriteOPActionBaseParameters.ts @@ -1,23 +1,7 @@ import type { Config, UseWriteContractParameters } from 'wagmi' +import type { OpConfig } from './OpConfig.js' export type UseWriteOPActionBaseParameters< - args extends { chainId?: number }, - config extends Config = Config, + config extends Config = OpConfig, context = unknown, -> = - & Omit< - UseWriteContractParameters< - config, - context - >, - 'mutation' - > - & { - mutation?: Omit['mutation'], 'onMutate'> & { - onMutate?: - | (( - args: args, - ) => Promise | context | void) - | undefined - } - } +> = UseWriteContractParameters diff --git a/src/types/UseWriteOPActionBaseReturnType.ts b/src/types/UseWriteOPActionBaseReturnType.ts index 7a8328a..1333e4e 100644 --- a/src/types/UseWriteOPActionBaseReturnType.ts +++ b/src/types/UseWriteOPActionBaseReturnType.ts @@ -1,12 +1,12 @@ import type { WriteContractReturnType } from '@wagmi/core' import type { Config, UseWriteContractReturnType } from 'wagmi' +import type { OpConfig } from './OpConfig.js' export type UseWriteOPActionBaseReturnType< - args extends { chainId?: number }, - config extends Config = Config, + args, + config extends Config = OpConfig, context = unknown, > = - & { guh: number } & Omit, 'writeContract' | 'writeContractAsync'> & { write: (args: args) => void