Testing on Optimistic Test Networks

On this page, you can find some testing tools that may be helpful for you.


This guide demonstrates how to utilize the Optimism SDK for transferring native tokens between Layer 1 (BSC) and Layer 2 (Combo). Although it is possible to use the bridge contracts directly, a mistake in usage could result in the permanent locking of tokens in the bridge, causing loss of their value. By using the SDK, safety measures are put in place to prevent such errors in a transparent manner.


  1. Setup
    Ensure your computer has:
  1. Clone this repository and enter it
git clone https://github.com/ethereum-optimism/optimism-tutorial.git
cd optimism-tutorial/cross-dom-bridge-erc20
  1. Install the necessary packages.
  1. Copy .env.example to .env and edit it:
  • Set TESTNET_PRIVKEY to point to an account that has BNB on the BSC test network

Add the following configuration

  1. Edit the sample code
    The sample code is in index.js,
const getSigners = async () => {
    const l1RpcProvider = new ethers.providers.JsonRpcProvider(l1Url)
    const l2RpcProvider = new ethers.providers.JsonRpcProvider(l2Url)
    const l1Wallet = new ethers.Wallet(privateKey, l1RpcProvider)
    const l2Wallet = new ethers.Wallet(privateKey, l2RpcProvider)

    return [l1Wallet, l2Wallet]

const setup = async() => {
  const [l1Signer, l2Signer] = await getSigners()
  addr = l1Signer.address
  contractss = getAllOEContracts(l2ChainId, {
    overrides: {
      l1: {
        AddressManager: selfAddressManager,
        L1CrossDomainMessenger: selfL1CrossDomainMessenger,
        L1StandardBridge: selfL1StandardBridge,
        StateCommitmentChain: selfStateCommitmentChain,
        CanonicalTransactionChain: selfCanonicalTransactionChain,
        BondManager: selfBondManager,
        OptimismPortal: selfOptimismPortal,
        L2OutputOracle: selfL2OutputOracle

  crossChainMessenger = new optimismSDK.CrossChainMessenger({
    l1ChainId: l1ChainId,    // Goerli value, 1 for mainnet
    l2ChainId: l2ChainId,  // Goerli value, 10 for mainnet
    l1SignerOrProvider: l1Signer,
    l2SignerOrProvider: l2Signer,
    bedrock: true,
    contracts: contractss

  bridgess = getBridgeAdapters(l2ChainId, crossChainMessenger, {
    overrides: {
     Standard: {
       Adapter: StandardBridgeAdapter,
       l1Bridge: selfL1StandardBridge,
       l2Bridge: predeploys.predeploys.L2StandardBridge
     ETH: {
       Adapter: ETHBridgeAdapter,
       l1Bridge: selfL1StandardBridge,
       l2Bridge: predeploys.predeploys.L2StandardBridge

  crossChainMessenger.bridges = bridgess
}    // setup

  1. Test the script. Execute index.js. After you execute it, wait. It is not unusual for each operation to take minutes on BSC testnet. On the production network the withdrawals take around a week each, because of the challenge period.
  2. Expected output
    The output from the script should be similar to:
Deposit BNB
On L1:37333651400 Gwei    On L2: Gwei
Transaction hash (on L1): 0xfcf55f6e66edbe57675f25b50dcd0367a3159d44eaa70074a939cfe939ed6ac3
Waiting for status to change to RELAYED
Time so far 15.071 seconds
On L1:37320845231 Gwei    On L2:10000000 Gwei
depositETH took 65.913 seconds

Withdraw BNB
On L1:35316460582 Gwei    On L2:1979474759 Gwei
Transaction hash (on L2): 0x7881d9a8885a40bfb2d79785daf25512632ea6c5ae99e8989807dc6c0e755ea4
Waiting for status to be READY_TO_PROVE
Time so far 14.333 seconds
Time so far 1414.251 seconds
In the challenge period, waiting for status READY_FOR_RELAY
Time so far 1431.372 seconds
Ready for relay, finalizing message now
Time so far 1751.363 seconds
Waiting for status to change to RELAYED
Time so far 1763.781 seconds
On L1:35322748742 Gwei    On L2:1969299679 Gwei
withdrawETH took 2005.966 seconds

As you can see, the total running time is about six minutes. It could be longer.