proveWithdrawal
Proves a withdrawal that occurred on an L2. Used in the Withdrawal flow.
Internally performs a contract write to the proveWithdrawalTransaction
function on the Optimism Portal contract.
Usage
import { account, publicClientL2, walletClientL1 } from './config'
const receipt = await getTransactionReceipt(publicClientL2, {
hash: '0xbbdd0957a82a057a76b5f093de251635ac4ddc6e2d0c4aa7fbf82d73e4e11039',
})
const [withdrawal] = getWithdrawals(receipt)
const output = await walletClientL1.getL2Output({
l2BlockNumber: receipt.blockNumber,
targetChain: publicClientL2.chain,
})
const args = await publicClientL2.buildProveWithdrawal({
account,
output,
withdrawal,
})
const hash = await walletClientL1.proveWithdrawal(args)
import { account, publicClientL2, walletClientL1 } from './config'
const receipt = await getTransactionReceipt(publicClientL2, {
hash: '0xbbdd0957a82a057a76b5f093de251635ac4ddc6e2d0c4aa7fbf82d73e4e11039',
})
const [withdrawal] = getWithdrawals(receipt)
const output = await walletClientL1.getL2Output({
l2BlockNumber: receipt.blockNumber,
targetChain: publicClientL2.chain,
})
const args = await publicClientL2.buildProveWithdrawal({
account,
output,
withdrawal,
})
const hash = await walletClientL1.proveWithdrawal(args)
import { createPublicClient, createWalletClient, custom, http } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { mainnet, optimism } from 'viem/chains'
import { publicActionsL2, walletActionsL1 } from 'viem/op-stack'
export const walletClientL1 = createWalletClient({
chain: mainnet,
transport: custom(window.ethereum)
}).extend(walletActionsL1())
export const publicClientL2 = createPublicClient({
chain: optimism,
transport: http()
}).extend(publicActionsL2())
// JSON-RPC Account
export const [account] = await walletClientL1.getAddresses()
// Local Account
export const account = privateKeyToAccount(...)
import { createPublicClient, createWalletClient, custom, http } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { mainnet, optimism } from 'viem/chains'
import { publicActionsL2, walletActionsL1 } from 'viem/op-stack'
export const walletClientL1 = createWalletClient({
chain: mainnet,
transport: custom(window.ethereum)
}).extend(walletActionsL1())
export const publicClientL2 = createPublicClient({
chain: optimism,
transport: http()
}).extend(publicActionsL2())
// JSON-RPC Account
export const [account] = await walletClientL1.getAddresses()
// Local Account
export const account = privateKeyToAccount(...)
WARNING
You must build the parameters on the L2 before calling this function. If the gas is too low, transaction execution will fail on the L2.
Building Parameters
The buildProveWithdrawal
Action builds & prepares the prove withdrawal transaction parameters.
We can use the resulting args
to prove the withdrawal transaction on the L1.
import { account, publicClientL2, walletClientL1 } from './config'
const receipt = await getTransactionReceipt(publicClientL2, {
hash: '0xbbdd0957a82a057a76b5f093de251635ac4ddc6e2d0c4aa7fbf82d73e4e11039',
})
const [withdrawal] = getWithdrawals(receipt)
const output = await walletClientL1.getL2Output({
l2BlockNumber: receipt.blockNumber,
targetChain: publicClientL2.chain,
})
const args = await publicClientL2.buildProveWithdrawal({
account,
output,
withdrawal,
})
const hash = await walletClientL1.proveWithdrawal(args)
import { account, publicClientL2, walletClientL1 } from './config'
const receipt = await getTransactionReceipt(publicClientL2, {
hash: '0xbbdd0957a82a057a76b5f093de251635ac4ddc6e2d0c4aa7fbf82d73e4e11039',
})
const [withdrawal] = getWithdrawals(receipt)
const output = await walletClientL1.getL2Output({
l2BlockNumber: receipt.blockNumber,
targetChain: publicClientL2.chain,
})
const args = await publicClientL2.buildProveWithdrawal({
account,
output,
withdrawal,
})
const hash = await walletClientL1.proveWithdrawal(args)
import { createPublicClient, createWalletClient, custom, http } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { mainnet, optimism } from 'viem/chains'
import { publicActionsL2, walletActionsL1 } from 'viem/op-stack'
export const walletClientL1 = createWalletClient({
chain: mainnet,
transport: custom(window.ethereum)
}).extend(walletActionsL1())
export const publicClientL2 = createPublicClient({
chain: optimism,
transport: http()
}).extend(publicActionsL2())
// JSON-RPC Account
export const [account] = await walletClientL1.getAddresses()
// Local Account
export const account = privateKeyToAccount(...)
import { createPublicClient, createWalletClient, custom, http } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { mainnet, optimism } from 'viem/chains'
import { publicActionsL2, walletActionsL1 } from 'viem/op-stack'
export const walletClientL1 = createWalletClient({
chain: mainnet,
transport: custom(window.ethereum)
}).extend(walletActionsL1())
export const publicClientL2 = createPublicClient({
chain: optimism,
transport: http()
}).extend(publicActionsL2())
// JSON-RPC Account
export const [account] = await walletClientL1.getAddresses()
// Local Account
export const account = privateKeyToAccount(...)
See more on the buildProveWithdrawal
Action.
Account Hoisting
If you do not wish to pass an account
to every proveWithdrawal
, you can also hoist the Account on the Wallet Client (see config.ts
).
import { account, publicClientL2, walletClientL1 } from './config'
const receipt = await getTransactionReceipt(publicClientL2, {
hash: '0xbbdd0957a82a057a76b5f093de251635ac4ddc6e2d0c4aa7fbf82d73e4e11039',
})
const [withdrawal] = getWithdrawals(receipt)
const output = await walletClientL1.getL2Output({
l2BlockNumber: receipt.blockNumber,
targetChain: publicClientL2.chain,
})
const args = await publicClientL2.buildProveWithdrawal({
output,
withdrawal,
})
const hash = await walletClientL1.proveWithdrawal(args)
import { account, publicClientL2, walletClientL1 } from './config'
const receipt = await getTransactionReceipt(publicClientL2, {
hash: '0xbbdd0957a82a057a76b5f093de251635ac4ddc6e2d0c4aa7fbf82d73e4e11039',
})
const [withdrawal] = getWithdrawals(receipt)
const output = await walletClientL1.getL2Output({
l2BlockNumber: receipt.blockNumber,
targetChain: publicClientL2.chain,
})
const args = await publicClientL2.buildProveWithdrawal({
output,
withdrawal,
})
const hash = await walletClientL1.proveWithdrawal(args)
import { createWalletClient, createPublicClient, custom, http } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { mainnet, optimism } from 'viem/chains'
import { publicActionsL2, walletActionsL1 } from 'viem/op-stack'
// Retrieve Account from an EIP-1193 Provider.
const [account] = await window.ethereum.request({
method: 'eth_requestAccounts'
})
export const walletClientL1 = createWalletClient({
account,
transport: custom(window.ethereum)
}).extend(walletActionsL1())
export const publicClientL2 = createPublicClient({
chain: optimism,
transport: http()
}).extend(publicActionsL2())
import { createWalletClient, createPublicClient, custom, http } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { mainnet, optimism } from 'viem/chains'
import { publicActionsL2, walletActionsL1 } from 'viem/op-stack'
// Retrieve Account from an EIP-1193 Provider.
const [account] = await window.ethereum.request({
method: 'eth_requestAccounts'
})
export const walletClientL1 = createWalletClient({
account,
transport: custom(window.ethereum)
}).extend(walletActionsL1())
export const publicClientL2 = createPublicClient({
chain: optimism,
transport: http()
}).extend(publicActionsL2())
import { createPublicClient, createWalletClient, custom, http } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { mainnet, optimism } from 'viem/chains'
import { publicActionsL2, walletActionsL1 } from 'viem/op-stack'
export const walletClientL1 = createWalletClient({
account: privateKeyToAccount('0x...'),
transport: custom(window.ethereum)
}).extend(walletActionsL1())
export const publicClientL2 = createPublicClient({
chain: optimism,
transport: http()
}).extend(publicActionsL2())
import { createPublicClient, createWalletClient, custom, http } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { mainnet, optimism } from 'viem/chains'
import { publicActionsL2, walletActionsL1 } from 'viem/op-stack'
export const walletClientL1 = createWalletClient({
account: privateKeyToAccount('0x...'),
transport: custom(window.ethereum)
}).extend(walletActionsL1())
export const publicClientL2 = createPublicClient({
chain: optimism,
transport: http()
}).extend(publicActionsL2())
Returns
The prove withdrawal Transaction hash.
Parameters
account
- Type:
Account | Address
The Account to send the transaction from.
Accepts a JSON-RPC Account or Local Account (Private Key, etc).
const hash = await client.proveWithdrawal({
account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
l2OutputIndex: 4529n,
outputRootProof: { /* ... */ },
withdrawalProof: [ /* ... */ ],
withdrawal: { /* ... */ },
targetChain: optimism,
})
const hash = await client.proveWithdrawal({
account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
l2OutputIndex: 4529n,
outputRootProof: { /* ... */ },
withdrawalProof: [ /* ... */ ],
withdrawal: { /* ... */ },
targetChain: optimism,
})
chain (optional)
- Type:
Chain
- Default:
client.chain
The L1 chain. If there is a mismatch between the wallet's current chain & this chain, an error will be thrown.
import { mainnet } from 'viem/chains'
const hash = await client.proveWithdrawal({
account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
chain: mainnet,
l2OutputIndex: 4529n,
outputRootProof: { /* ... */ },
withdrawalProof: [ /* ... */ ],
withdrawal: { /* ... */ },
targetChain: optimism,
})
import { mainnet } from 'viem/chains'
const hash = await client.proveWithdrawal({
account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
chain: mainnet,
l2OutputIndex: 4529n,
outputRootProof: { /* ... */ },
withdrawalProof: [ /* ... */ ],
withdrawal: { /* ... */ },
targetChain: optimism,
})
gas (optional)
- Type:
bigint
Gas limit for transaction execution on the L1.
null
to skip gas estimation & defer calculation to signer.
const hash = await client.proveWithdrawal({
account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
l2OutputIndex: 4529n,
gas: 420_000n,
outputRootProof: { /* ... */ },
withdrawalProof: [ /* ... */ ],
withdrawal: { /* ... */ },
targetChain: optimism,
})
const hash = await client.proveWithdrawal({
account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
l2OutputIndex: 4529n,
gas: 420_000n,
outputRootProof: { /* ... */ },
withdrawalProof: [ /* ... */ ],
withdrawal: { /* ... */ },
targetChain: optimism,
})
l2OutputIndex
- Type:
bigint
The index of the L2 output. Typically derived from the buildProveWithdrawal
Action.
const hash = await client.proveWithdrawal({
account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
l2OutputIndex: 4529n,
gas: 420_000n,
outputRootProof: { /* ... */ },
withdrawalProof: [ /* ... */ ],
withdrawal: { /* ... */ },
targetChain: optimism,
})
const hash = await client.proveWithdrawal({
account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
l2OutputIndex: 4529n,
gas: 420_000n,
outputRootProof: { /* ... */ },
withdrawalProof: [ /* ... */ ],
withdrawal: { /* ... */ },
targetChain: optimism,
})
maxFeePerGas (optional)
- Type:
bigint
Total fee per gas (in wei), inclusive of maxPriorityFeePerGas
.
const hash = await client.proveWithdrawal({
account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
l2OutputIndex: 4529n,
maxFeePerGas: parseGwei('20'),
outputRootProof: { /* ... */ },
withdrawalProof: [ /* ... */ ],
withdrawal: { /* ... */ },
targetChain: optimism,
})
const hash = await client.proveWithdrawal({
account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
l2OutputIndex: 4529n,
maxFeePerGas: parseGwei('20'),
outputRootProof: { /* ... */ },
withdrawalProof: [ /* ... */ ],
withdrawal: { /* ... */ },
targetChain: optimism,
})
maxPriorityFeePerGas (optional)
- Type:
bigint
Max priority fee per gas (in wei). Only applies to EIP-1559 Transactions
const hash = await client.proveWithdrawal({
account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
l2OutputIndex: 4529n,
maxFeePerGas: parseGwei('20'),
maxPriorityFeePerGas: parseGwei('2'),
outputRootProof: { /* ... */ },
withdrawalProof: [ /* ... */ ],
withdrawal: { /* ... */ },
targetChain: optimism,
})
const hash = await client.proveWithdrawal({
account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
l2OutputIndex: 4529n,
maxFeePerGas: parseGwei('20'),
maxPriorityFeePerGas: parseGwei('2'),
outputRootProof: { /* ... */ },
withdrawalProof: [ /* ... */ ],
withdrawal: { /* ... */ },
targetChain: optimism,
})
nonce (optional)
- Type:
number
Unique number identifying this transaction.
const hash = await client.proveWithdrawal({
account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
l2OutputIndex: 4529n,
outputRootProof: { /* ... */ },
withdrawalProof: [ /* ... */ ],
withdrawal: { /* ... */ },
nonce: 69,
targetChain: optimism,
})
const hash = await client.proveWithdrawal({
account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
l2OutputIndex: 4529n,
outputRootProof: { /* ... */ },
withdrawalProof: [ /* ... */ ],
withdrawal: { /* ... */ },
nonce: 69,
targetChain: optimism,
})
outputRootProof (optional)
- Type:
bigint
The proof of the L2 output. Typically derived from the buildProveWithdrawal
Action.
const hash = await client.proveWithdrawal({
account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
l2OutputIndex: 4529n,
gas: 420_000n,
outputRootProof: { /* ... */ },
withdrawalProof: [ /* ... */ ],
withdrawal: { /* ... */ },
targetChain: optimism,
})
const hash = await client.proveWithdrawal({
account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
l2OutputIndex: 4529n,
gas: 420_000n,
outputRootProof: { /* ... */ },
withdrawalProof: [ /* ... */ ],
withdrawal: { /* ... */ },
targetChain: optimism,
})
portalAddress (optional)
- Type:
Address
- Default:
targetChain.contracts.portal[chainId].address
The address of the Optimism Portal contract. Defaults to the Optimism Portal contract specified on the targetChain
.
If a portalAddress
is provided, the targetChain
parameter becomes optional.
const hash = await client.proveWithdrawal({
account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
l2OutputIndex: 4529n,
outputRootProof: { /* ... */ },
portalAddress: '0xbEb5Fc579115071764c7423A4f12eDde41f106Ed'
targetChain: optimism,
withdrawalProof: [ /* ... */ ],
withdrawal: { /* ... */ },
})
const hash = await client.proveWithdrawal({
account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
l2OutputIndex: 4529n,
outputRootProof: { /* ... */ },
portalAddress: '0xbEb5Fc579115071764c7423A4f12eDde41f106Ed'
targetChain: optimism,
withdrawalProof: [ /* ... */ ],
withdrawal: { /* ... */ },
})
targetChain
- Type:
Chain
The L2 chain to execute the transaction on.
import { mainnet } from 'viem/chains'
const hash = await client.proveWithdrawal({
account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
l2OutputIndex: 4529n,
outputRootProof: { /* ... */ },
withdrawalProof: [ /* ... */ ],
withdrawal: { /* ... */ },
targetChain: optimism,
})
import { mainnet } from 'viem/chains'
const hash = await client.proveWithdrawal({
account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
l2OutputIndex: 4529n,
outputRootProof: { /* ... */ },
withdrawalProof: [ /* ... */ ],
withdrawal: { /* ... */ },
targetChain: optimism,
})
withdrawalProof
- Type:
bigint
The proof of the L2 withdrawal. Typically derived from the buildProveWithdrawal
Action.
const hash = await client.proveWithdrawal({
account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
l2OutputIndex: 4529n,
gas: 420_000n,
outputRootProof: { /* ... */ },
withdrawalProof: [ /* ... */ ],
withdrawal: { /* ... */ },
targetChain: optimism,
})
const hash = await client.proveWithdrawal({
account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
l2OutputIndex: 4529n,
gas: 420_000n,
outputRootProof: { /* ... */ },
withdrawalProof: [ /* ... */ ],
withdrawal: { /* ... */ },
targetChain: optimism,
})
withdrawal
- Type:
bigint
The withdrawal. Typically derived from the buildProveWithdrawal
Action.
const hash = await client.proveWithdrawal({
account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
l2OutputIndex: 4529n,
gas: 420_000n,
outputRootProof: { /* ... */ },
withdrawalProof: [ /* ... */ ],
withdrawal: { /* ... */ },
targetChain: optimism,
})
const hash = await client.proveWithdrawal({
account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
l2OutputIndex: 4529n,
gas: 420_000n,
outputRootProof: { /* ... */ },
withdrawalProof: [ /* ... */ ],
withdrawal: { /* ... */ },
targetChain: optimism,
})