> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rhino.fi/llms.txt
> Use this file to discover all available pages before exploring further.

# EVM (Ethereum / L2s)

> This guide explains how to interact with the [**Bridge Contract**](https://github.com/rhinofi/contracts_public/blob/master/bridge-deposit/DVFDepositContract.sol) on EVM-compatible blockchains.

## **Contract Overview**

The `BridgeContract` exposes the following key function for bridging:

```solidity theme={null}
/**
* 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

<AccordionGroup>
  <Accordion title="Bridge Contract ABI">
    ```json bridgeAbi.json theme={null}
    [
      {
        "inputs": [
          {
            "internalType": "address",
            "name": "token",
            "type": "address"
          },
          {
            "internalType": "uint256",
            "name": "amount",
            "type": "uint256"
          },
          {
            "internalType": "uint256",
            "name": "commitmentId",
            "type": "uint256"
          }
        ],
        "name": "depositWithId",
        "outputs": [],
        "stateMutability": "nonpayable",
        "type": "function"
      },
      {
        "inputs": [
          {
            "internalType": "uint256",
            "name": "commitmentId",
            "type": "uint256"
          }
        ],
        "name": "depositNativeWithId",
        "outputs": [],
        "stateMutability": "payable",
        "type": "function"
      }
    ]
    ```
  </Accordion>

  <Accordion title="ERC20 ABI">
    ```json erc20Abi.json theme={null}
    [
      {
        "inputs": [
          {
            "internalType": "address",
            "name": "owner",
            "type": "address"
          },
          {
            "internalType": "address",
            "name": "spender",
            "type": "address"
          }
        ],
        "name": "allowance",
        "outputs": [
          {
            "internalType": "uint256",
            "name": "",
            "type": "uint256"
          }
        ],
        "stateMutability": "view",
        "type": "function"
      },
      {
        "inputs": [
          {
            "internalType": "address",
            "name": "spender",
            "type": "address"
          },
          {
            "internalType": "uint256",
            "name": "amount",
            "type": "uint256"
          }
        ],
        "name": "approve",
        "outputs": [
          {
            "internalType": "bool",
            "name": "",
            "type": "bool"
          }
        ],
        "stateMutability": "nonpayable",
        "type": "function"
      }
    ]
    ```
  </Accordion>
</AccordionGroup>

### 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:

<CodeGroup>
  ```bash yarn theme={null}
  yarn add ethers
  ```

  ```bash npm theme={null}
  npm install ethers
  ```
</CodeGroup>

## Interacting with the Contract

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

<Info>
  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 [the API bridge example](/api-integration/bridge#6-full-example) for details.
</Info>

<CodeGroup>
  ```javascript ethers theme={null}
  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()
  }
  ```
</CodeGroup>
