Documentation Index Fetch the complete documentation index at: https://bridge.near.tools/llms.txt
Use this file to discover all available pages before exploring further.
This guide walks you through bridging USDC from Ethereum to NEAR. By the end, you’ll understand the pattern that works for all chains.
Install
npm install @omni-bridge/core @omni-bridge/evm
The Pattern
Every transfer follows these steps:
Get fees — Query the relayer fee so your transfer gets finalized automatically
Validate — Check that addresses, amounts, and tokens are valid
Approve — For ERC20 tokens, approve the bridge to spend them
Build & Send — Get an unsigned transaction and broadcast it
import { createBridge , ChainKind , BridgeAPI } from "@omni-bridge/core"
import { createEvmBuilder } from "@omni-bridge/evm"
import { createWalletClient , http } from "viem"
import { mainnet } from "viem/chains"
import { privateKeyToAccount } from "viem/accounts"
// Setup
const bridge = createBridge ({ network: "mainnet" })
const evm = createEvmBuilder ({ network: "mainnet" , chain: ChainKind . Eth })
const api = new BridgeAPI ( "mainnet" )
const account = privateKeyToAccount ( "0x..." )
const wallet = createWalletClient ({
chain: mainnet ,
transport: http (),
account ,
})
const sender = `eth: ${ account . address } `
const recipient = "near:alice.near"
const token = "eth:0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" // USDC
const amount = 1_000_000 n // 1 USDC (6 decimals)
// 1. Get the relayer fee quote
const fee = await api . getFee ( sender , recipient , token , amount )
// 2. Validate the transfer
const validated = await bridge . validateTransfer ({
token ,
amount ,
sender ,
recipient ,
fee: BigInt ( fee . transferred_token_fee ?? "0" ),
nativeFee: fee . native_token_fee ?? 0 n ,
})
// 3. Approve the bridge to spend your tokens (ERC20 only)
const approval = evm . buildApproval (
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" ,
amount
)
await wallet . sendTransaction ( approval )
// 4. Build and send the transfer
const tx = evm . buildTransfer ( validated )
const hash = await wallet . sendTransaction ( tx )
console . log ( "Transfer initiated:" , hash )
That’s it. The transfer is now in progress. Because you included fees, relayers will automatically finalize it on NEAR within a few minutes.
What Just Happened
Let’s break down the key parts:
Relayer Fees
The getFee() call returns the fee required for relayers to finalize your transfer on the destination chain. You can pay in the transfer token (fee) or in native ETH (nativeFee). Without fees, you’d need to finalize manually.
See Relayer Fees for more details.
Addresses include a chain prefix so the SDK knows which chain they belong to:
"eth:0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" // Token on Ethereum
"near:alice.near" // Account on NEAR
"sol:EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" // Token on Solana
See OmniAddress Format for the full list.
Validation
validateTransfer() does the heavy lifting:
Checks that addresses are valid for their chains
Verifies the token is registered on the bridge
Ensures the amount survives decimal normalization
Returns a ValidatedTransfer object the builders need
Unsigned Transactions
buildTransfer() returns a plain object — not a signed transaction:
{
to : "0x..." , // Bridge contract
data : "0x..." , // Encoded function call
value : 0 n , // Native token amount (for ETH transfers)
chainId : 1 // Ethereum mainnet
}
This works directly with viem’s sendTransaction() or ethers’ signer.sendTransaction().
Using Testnet
For development, switch to testnet:
const bridge = createBridge ({ network: "testnet" })
const evm = createEvmBuilder ({ network: "testnet" , chain: ChainKind . Eth })
Testnet uses Sepolia for Ethereum. Make sure your wallet and RPC are configured for the right network.
Track Your Transfer
Check the status using the API client:
import { BridgeAPI } from "@omni-bridge/core"
const api = new BridgeAPI ( "mainnet" )
const status = await api . getTransferStatus ({ transactionHash: hash })
console . log ( "Current status:" , status [ status . length - 1 ])
// "Initialized" → "Signed" → "FinalisedOnNear" → "Finalised"
See Tracking Transfers for polling patterns and status meanings.
Next Steps
Now that you understand the pattern, pick the guide for your source chain:
EVM Chains Ethereum, Base, Arbitrum, Polygon, BNB
Or learn more about the core concepts:
Transfer Flow How cross-chain transfers work
Decimal Normalization Why small amounts can fail