Contract Overview

The BridgeContract exposes the following key function for bridging:

/**
* Deposit ERC20 tokens to the contract address with a commitment ID
*/
function depositWithId(
  address token,
  uint256 amount,
  uint256 commitmentId
) public;

/**
* Deposit native chain currency into contract address with a commitment ID
*/
function depositNativeWithId(
  uint256 commitmentId
) external payable;

ABIs

Setup

For this example we’ll use ethers.js to interact with the contract, but you can replace it with any EVM library of your choice.

Make sure to install it first:

yarn add ethers

Interacting with the Contract

To execute a bridge transaction, call the depositWithId (ERC20) or depositNativeWithId (native) function as follows:

The commitmentId required by the contract corresponds to the quoteId returned by the API.

To obtain the commitmentId, first request a quote from the API, then commit it. The response will include the quoteId, which should be used as the commitmentId in the contract call.

See Quickstart for details.

import ethers from 'ethers'
import getBridgeConfigs from './getBridgeConfigs'
import erc20Abi from './erc20Abi'
import bridgeAbi from './bridgeAbi'

export const callEvmBridgeContract = async ({
  address,
  amount,
  chain,
  token,
  commitmentId,
}) => {
  // See API Integration -> Fetch Bridge Configs for the full implementation
  const configs = await getBridgeConfigs()
  const chainConfig = configs[chain]

  // Replace with your wallet implementation
  const wallet = new ethers.Wallet(EVM_PRIVATE_KEY, new ethers.JsonRpcProvider(chainConfig.rpc))

  const tokenConfig = chainConfig.tokens[token]
  const tokenAmount = +amount * 10 ** tokenConfig.decimals
  const tokenAddress = tokenConfig.address

  const bridgeContractAddress = chainConfig.contractAddress

  const isNativeToken = chainConfig.nativeTokenName === token

  const bridgeContract = new ethers.Contract(bridgeContractAddress, bridgeAbi, wallet)

  // For ERC20 tokens we call 'depositWithId' and for native tokens we call 'depositNativeWithId'
  if (!isNativeToken) {
    // make sure to check token allowance first for erc20 tokens
    const erc20Contract = new ethers.Contract(tokenAddress, erc20Abi, wallet)
    const contractAllowance = await erc20Contract.allowance(address, bridgeContractAddress)
    const allowance = parseFloat(contractAllowance.toString()) / 10 ** tokenConfig.decimals

    if (allowance === 0 || allowance < parseFloat(amount)) {
     const tx = await erc20Contract.approve(bridgeContractAddress, tokenAmount)
     await tx.wait()
    }
    // Call the contract
    const tx = await bridgeContract.depositWithId(tokenAddress, tokenAmount, BigInt(`0x${commitmentId}`))
    return tx.wait()
  }

  const tx = await bridgeContract.depositNativeWithId(BigInt(`0x${commitmentId}`), {
    value: parseUnits(amount, 'ether'),
  })
  return tx.wait()
}