github.com/ethereum-optimism/optimism@v1.7.2/packages/sdk/tasks/finalize-withdrawal.ts (about)

     1  import { task, types } from 'hardhat/config'
     2  import { HardhatRuntimeEnvironment } from 'hardhat/types'
     3  import { Wallet, providers } from 'ethers'
     4  import { predeploys } from '@eth-optimism/core-utils'
     5  import 'hardhat-deploy'
     6  import '@nomiclabs/hardhat-ethers'
     7  
     8  import {
     9    CrossChainMessenger,
    10    StandardBridgeAdapter,
    11    MessageStatus,
    12  } from '../src'
    13  
    14  task('finalize-withdrawal', 'Finalize a withdrawal')
    15    .addParam(
    16      'transactionHash',
    17      'L2 Transaction hash to finalize',
    18      '',
    19      types.string
    20    )
    21    .addParam('l2Url', 'L2 HTTP URL', 'http://localhost:9545', types.string)
    22    .setAction(async (args, hre: HardhatRuntimeEnvironment) => {
    23      const txHash = args.transactionHash
    24      if (txHash === '') {
    25        console.log('No tx hash')
    26      }
    27  
    28      const signers = await hre.ethers.getSigners()
    29      if (signers.length === 0) {
    30        throw new Error('No configured signers')
    31      }
    32      const signer = signers[0]
    33      const address = await signer.getAddress()
    34      console.log(`Using signer: ${address}`)
    35  
    36      const l2Provider = new providers.StaticJsonRpcProvider(args.l2Url)
    37      const l2Signer = new Wallet(hre.network.config.accounts[0], l2Provider)
    38  
    39      let Deployment__L1StandardBridgeProxy = await hre.deployments.getOrNull(
    40        'L1StandardBridgeProxy'
    41      )
    42      if (Deployment__L1StandardBridgeProxy === undefined) {
    43        Deployment__L1StandardBridgeProxy = await hre.deployments.getOrNull(
    44          'Proxy__OVM_L1StandardBridge'
    45        )
    46      }
    47  
    48      let Deployment__L1CrossDomainMessengerProxy =
    49        await hre.deployments.getOrNull('L1CrossDomainMessengerProxy')
    50      if (Deployment__L1CrossDomainMessengerProxy === undefined) {
    51        Deployment__L1CrossDomainMessengerProxy = await hre.deployments.getOrNull(
    52          'Proxy__OVM_L1CrossDomainMessenger'
    53        )
    54      }
    55  
    56      const Deployment__L2OutputOracleProxy = await hre.deployments.getOrNull(
    57        'L2OutputOracleProxy'
    58      )
    59      const Deployment__OptimismPortalProxy = await hre.deployments.getOrNull(
    60        'OptimismPortalProxy'
    61      )
    62  
    63      if (Deployment__L1StandardBridgeProxy?.address === undefined) {
    64        throw new Error('No L1StandardBridgeProxy deployment')
    65      }
    66  
    67      if (Deployment__L1CrossDomainMessengerProxy?.address === undefined) {
    68        throw new Error('No L1CrossDomainMessengerProxy deployment')
    69      }
    70  
    71      if (Deployment__L2OutputOracleProxy?.address === undefined) {
    72        throw new Error('No L2OutputOracleProxy deployment')
    73      }
    74  
    75      if (Deployment__OptimismPortalProxy?.address === undefined) {
    76        throw new Error('No OptimismPortalProxy deployment')
    77      }
    78  
    79      const messenger = new CrossChainMessenger({
    80        l1SignerOrProvider: signer,
    81        l2SignerOrProvider: l2Signer,
    82        l1ChainId: await signer.getChainId(),
    83        l2ChainId: await l2Signer.getChainId(),
    84        bridges: {
    85          Standard: {
    86            Adapter: StandardBridgeAdapter,
    87            l1Bridge: Deployment__L1StandardBridgeProxy?.address,
    88            l2Bridge: predeploys.L2StandardBridge,
    89          },
    90        },
    91        contracts: {
    92          l1: {
    93            L1StandardBridge: Deployment__L1StandardBridgeProxy?.address,
    94            L1CrossDomainMessenger:
    95              Deployment__L1CrossDomainMessengerProxy?.address,
    96            L2OutputOracle: Deployment__L2OutputOracleProxy?.address,
    97            OptimismPortal: Deployment__OptimismPortalProxy?.address,
    98          },
    99        },
   100      })
   101  
   102      console.log(`Fetching message status for ${txHash}`)
   103      const status = await messenger.getMessageStatus(txHash)
   104      console.log(`Status: ${MessageStatus[status]}`)
   105  
   106      if (status === MessageStatus.READY_TO_PROVE) {
   107        const proveTx = await messenger.proveMessage(txHash)
   108        const proveReceipt = await proveTx.wait()
   109        console.log('Prove receipt', proveReceipt)
   110  
   111        const finalizeInterval = setInterval(async () => {
   112          const currentStatus = await messenger.getMessageStatus(txHash)
   113          console.log(`Message status: ${MessageStatus[currentStatus]}`)
   114        }, 3000)
   115  
   116        try {
   117          await messenger.waitForMessageStatus(
   118            txHash,
   119            MessageStatus.READY_FOR_RELAY
   120          )
   121        } finally {
   122          clearInterval(finalizeInterval)
   123        }
   124  
   125        const tx = await messenger.finalizeMessage(txHash)
   126        const receipt = await tx.wait()
   127        console.log(receipt)
   128        console.log('Finalized withdrawal')
   129      }
   130    })