Import
import {
createEvmBuilder ,
getEvmProof ,
parseInitTransferEvent ,
getInitTransferTopic ,
BRIDGE_TOKEN_FACTORY_ABI ,
ERC20_ABI ,
} from "@omni-bridge/evm"
createEvmBuilder
Factory function to create an EVM transaction builder for a specific chain.
Signature
function createEvmBuilder ( config : EvmBuilderConfig ) : EvmBuilder
Parameters
Configuration object for the EVM builder. network
'mainnet' | 'testnet'
required
The network to connect to.
The EVM chain to build transactions for. One of: ChainKind.Eth, ChainKind.Base, ChainKind.Arb, ChainKind.Pol, ChainKind.Bnb
Returns
An EVM transaction builder instance. The chain ID for this builder’s configured chain (readonly).
The bridge contract address for this builder’s configured chain (readonly).
buildTransfer
(validated: ValidatedTransfer) => EvmUnsignedTransaction
Builds an unsigned transfer transaction.
buildApproval
(token: Address, amount: bigint) => EvmUnsignedTransaction
Builds an ERC20 approval transaction for the bridge contract.
buildMaxApproval
(token: Address) => EvmUnsignedTransaction
Builds a max (unlimited) approval transaction for the bridge contract.
buildFinalization
(payload: TransferPayload, signature: Uint8Array) => EvmUnsignedTransaction
Builds a finalization transaction for incoming transfers.
buildLogMetadata
(token: Address) => EvmUnsignedTransaction
Builds a token metadata logging transaction.
buildDeployToken
(signature: Uint8Array, metadata: TokenMetadata) => EvmUnsignedTransaction
Builds a bridged token deployment transaction.
Example
import { createEvmBuilder } from "@omni-bridge/evm"
import { ChainKind } from "@omni-bridge/core"
// Create builder for Ethereum mainnet
const ethBuilder = createEvmBuilder ({
network: "mainnet" ,
chain: ChainKind . Eth ,
})
// Create builder for Base
const baseBuilder = createEvmBuilder ({
network: "mainnet" ,
chain: ChainKind . Base ,
})
// Create builder for Arbitrum testnet
const arbBuilder = createEvmBuilder ({
network: "testnet" ,
chain: ChainKind . Arb ,
})
console . log ( ethBuilder . chainId ) // 1
console . log ( ethBuilder . bridgeAddress ) // "0x..."
EvmBuilder Methods
buildTransfer
Builds an unsigned transfer transaction for bridging tokens from an EVM chain.
Signature
builder . buildTransfer ( validated : ValidatedTransfer ): EvmUnsignedTransaction
Parameters
validated
ValidatedTransfer
required
A validated transfer object from bridge.validateTransfer(). The source chain in the validated transfer must match the builder’s configured chain.
Returns
An unsigned transaction object compatible with viem and ethers v6.
Example
import { createBridge } from "@omni-bridge/core"
import { createEvmBuilder } from "@omni-bridge/evm"
import { ChainKind } from "@omni-bridge/core"
const bridge = createBridge ({ network: "mainnet" })
const evm = createEvmBuilder ({ network: "mainnet" , chain: ChainKind . Eth })
// Validate the transfer
const validated = await bridge . validateTransfer ({
token: "eth:0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" ,
amount: 1000000 n , // 1 USDC
fee: 0 n ,
nativeFee: 0 n ,
sender: "eth:0xYourAddress" ,
recipient: "near:alice.near" ,
})
// Build the unsigned transaction
const tx = evm . buildTransfer ( validated )
// Send with viem
await walletClient . sendTransaction ( tx )
// Or send with ethers v6
await signer . sendTransaction ( tx )
Native Token Transfers
When bridging native tokens (ETH, BNB, etc.), use the zero address:
import { parseEther } from "viem"
const validated = await bridge . validateTransfer ({
token: "eth:0x0000000000000000000000000000000000000000" ,
amount: parseEther ( "0.1" ),
fee: 0 n ,
nativeFee: 0 n ,
sender: "eth:0xYourAddress" ,
recipient: "near:alice.near" ,
})
const tx = evm . buildTransfer ( validated )
// tx.value includes the transfer amount
Transaction Value Calculation
The value field is calculated automatically based on token type:
Token Type tx.value ContainsERC20 tokens nativeFee onlyNative tokens (ETH, BNB, etc.) amount + nativeFee
// ERC20: value = nativeFee
const validated = await bridge . validateTransfer ({
token: "eth:0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" , // USDC
amount: 1000000 n ,
nativeFee: 1000000000000000 n , // 0.001 ETH
// ...
})
const tx = evm . buildTransfer ( validated )
console . log ( tx . value ) // 1000000000000000n (just nativeFee)
// Native ETH: value = amount + nativeFee
const validated = await bridge . validateTransfer ({
token: "eth:0x0000000000000000000000000000000000000000" ,
amount: 1000000000000000000 n , // 1 ETH
nativeFee: 1000000000000000 n , // 0.001 ETH
// ...
})
const tx = evm . buildTransfer ( validated )
console . log ( tx . value ) // 1001000000000000000n (amount + nativeFee)
For ERC20 tokens, you must call buildApproval() first to approve the bridge contract to spend your tokens.
buildApproval
Builds an ERC20 approval transaction for the bridge contract.
Signature
builder . buildApproval ( token : Address , amount : bigint ): EvmUnsignedTransaction
Parameters
The ERC20 token contract address (without chain prefix), e.g., "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48".
The amount to approve in the token’s smallest unit.
Returns
An unsigned approval transaction. The to field is the token contract address, and value is always 0n.
Example
const approvalTx = evm . buildApproval (
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" , // USDC
1000000 n // 1 USDC
)
await walletClient . sendTransaction ( approvalTx )
buildMaxApproval
Builds an unlimited (max uint256) approval transaction for the bridge contract.
Signature
builder . buildMaxApproval ( token : Address ): EvmUnsignedTransaction
Parameters
The ERC20 token contract address (without chain prefix).
Returns
An unsigned approval transaction for type(uint256).max.
Example
// Approve unlimited USDC spending
const approvalTx = evm . buildMaxApproval (
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
)
await walletClient . sendTransaction ( approvalTx )
Max approvals are convenient for repeated transfers but carry higher security risk. Consider using exact amounts for better security.
buildFinalization
Builds a finalization transaction for completing incoming transfers to an EVM chain.
Signature
builder . buildFinalization (
payload : TransferPayload ,
signature : Uint8Array
): EvmUnsignedTransaction
Parameters
The transfer payload containing transfer details. The nonce on the destination chain.
The origin chain identifier.
The nonce on the origin chain.
The token address on the destination chain.
The recipient address on the destination chain.
The fee recipient address (OmniAddress format).
The MPC signature authorizing the finalization.
Returns
An unsigned finalization transaction. The value is always 0n.
Example
const finalizeTx = evm . buildFinalization (
{
destinationNonce: 42 n ,
originChain: 1 , // NEAR
originNonce: 123 n ,
tokenAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" ,
amount: 1000000 n ,
recipient: "0xRecipientAddress" ,
feeRecipient: "near:relayer.near" ,
},
signature // MPC signature bytes
)
await walletClient . sendTransaction ( finalizeTx )
Builds a transaction to log token metadata on-chain. This is used to register token information for bridging.
Signature
builder . buildLogMetadata ( token : Address ): EvmUnsignedTransaction
Parameters
The ERC20 token contract address to log metadata for.
Returns
An unsigned transaction to call logMetadata on the bridge contract.
Example
const logTx = evm . buildLogMetadata (
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" // USDC
)
await walletClient . sendTransaction ( logTx )
buildDeployToken
Builds a transaction to deploy a bridged token representation on the EVM chain.
Signature
builder . buildDeployToken (
signature : Uint8Array ,
metadata : TokenMetadata
): EvmUnsignedTransaction
Parameters
The MPC signature authorizing the token deployment.
The token metadata for the bridged token. The original token identifier (e.g., NEAR account ID).
The number of decimal places.
Returns
An unsigned transaction to deploy the bridged token contract.
Example
const deployTx = evm . buildDeployToken ( signature , {
token: "wrap.near" ,
name: "Wrapped NEAR" ,
symbol: "wNEAR" ,
decimals: 24 ,
})
await walletClient . sendTransaction ( deployTx )
Proof Utilities
getEvmProof
Generates a Merkle proof for an EVM transaction, used for cross-chain verification.
Signature
async function getEvmProof (
txHash : Hex ,
topic : Hex ,
chain : EvmChainKind ,
network : Network ,
customRpcUrl ?: string
) : Promise < EvmProof >
Parameters
The transaction hash to generate a proof for, e.g., "0x...".
The event topic to prove. Use getInitTransferTopic() for transfer proofs.
The EVM chain where the transaction occurred. One of: ChainKind.Eth, ChainKind.Base, ChainKind.Arb, ChainKind.Pol, ChainKind.Bnb
The network: "mainnet" or "testnet".
Optional custom RPC URL. If not provided, uses default public RPC endpoints.
Returns
The Merkle proof data for cross-chain verification. The index of the log entry within the receipt.
RLP-encoded log entry data.
The transaction index within the block.
RLP-encoded receipt data.
RLP-encoded block header data.
Example
import { getEvmProof , getInitTransferTopic } from "@omni-bridge/evm"
import { ChainKind } from "@omni-bridge/core"
const proof = await getEvmProof (
"0x1234567890abcdef..." ,
getInitTransferTopic (),
ChainKind . Eth ,
"mainnet"
)
// Use with custom RPC
const proofWithCustomRpc = await getEvmProof (
"0x1234567890abcdef..." ,
getInitTransferTopic (),
ChainKind . Eth ,
"mainnet" ,
"https://my-rpc-endpoint.com"
)
parseInitTransferEvent
Parses the InitTransfer event from transaction logs. Works with both viem and ethers receipt log formats.
Signature
function parseInitTransferEvent ( logs : readonly LogEntry []) : EvmInitTransferEvent
Parameters
logs
readonly LogEntry[]
required
Array of log entries from a transaction receipt. topics
readonly string[] | string[]
required
The log topics.
Returns
Parsed event data. Show EvmInitTransferEvent
The token contract address.
The transfer nonce on the origin chain.
The native token fee amount.
The recipient address (OmniAddress format).
Optional message attached to the transfer.
Throws
Throws an error if no InitTransfer event is found in the logs.
Example
import { parseInitTransferEvent } from "@omni-bridge/evm"
// With viem
const receipt = await publicClient . getTransactionReceipt ({ hash: txHash })
const event = parseInitTransferEvent ( receipt . logs )
console . log ( `Transfer nonce: ${ event . originNonce } ` )
console . log ( `Amount: ${ event . amount } ` )
console . log ( `Recipient: ${ event . recipient } ` )
// With ethers v6
const receipt = await provider . getTransactionReceipt ( txHash )
const event = parseInitTransferEvent ( receipt . logs )
getInitTransferTopic
Returns the topic hash for the InitTransfer event.
Signature
function getInitTransferTopic () : Hex
Returns
The keccak256 hash of the InitTransfer event signature: "0xaa7e1f77d43faa300bc5ae8f012f0b7cf80174f4c0b1cffeab250cb4966bb88c"
Example
import { getInitTransferTopic } from "@omni-bridge/evm"
const topic = getInitTransferTopic ()
// "0xaa7e1f77d43faa300bc5ae8f012f0b7cf80174f4c0b1cffeab250cb4966bb88c"
Contract ABIs
BRIDGE_TOKEN_FACTORY_ABI
The ABI for the bridge token factory contract. Includes functions for:
initTransfer - Initiate a cross-chain transfer
finTransfer - Finalize an incoming transfer
deployToken - Deploy a bridged token
logMetadata - Log token metadata
nearToEthToken - Look up bridged token address
InitTransfer - Event emitted on transfer initiation
import { BRIDGE_TOKEN_FACTORY_ABI } from "@omni-bridge/evm"
ERC20_ABI
A minimal ERC20 ABI with approve and allowance functions.
import { ERC20_ABI } from "@omni-bridge/evm"
Types
EvmUnsignedTransaction
An unsigned EVM transaction object compatible with both viem and ethers v6.
interface EvmUnsignedTransaction {
to : `0x ${ string } ` // Target contract address
data : `0x ${ string } ` // Encoded function call data
value : bigint // ETH value to send
chainId : number // Chain ID
}
Can be passed directly to:
viem: walletClient.sendTransaction(tx)
ethers v6: signer.sendTransaction(tx)
EvmBuilderConfig
Configuration for creating an EVM builder.
interface EvmBuilderConfig {
network : "mainnet" | "testnet"
chain : EvmChainKind
}
Metadata for deploying a bridged token.
interface TokenMetadata {
token : string // Original token identifier
name : string // Token name
symbol : string // Token symbol
decimals : number // Decimal places
}
TransferPayload
Payload for finalizing an incoming transfer.
interface TransferPayload {
destinationNonce : bigint
originChain : number
originNonce : bigint
tokenAddress : Address
amount : bigint
recipient : Address
feeRecipient : string
}
EvmProof
Merkle proof data for cross-chain verification.
interface EvmProof {
log_index : bigint
log_entry_data : Uint8Array
receipt_index : bigint
receipt_data : Uint8Array
header_data : Uint8Array
proof : Uint8Array []
}
EvmInitTransferEvent
Parsed InitTransfer event from bridge transactions.
interface EvmInitTransferEvent {
sender : string
tokenAddress : string
originNonce : bigint
amount : bigint
fee : bigint
nativeTokenFee : bigint
recipient : string
message : string
}
LogEntry
Log entry format compatible with both viem and ethers receipts.
interface LogEntry {
topics : readonly string [] | string []
data : string
}
Complete Transfer Example
import { createBridge , ChainKind } from "@omni-bridge/core"
import { createEvmBuilder , parseInitTransferEvent } from "@omni-bridge/evm"
import { createPublicClient , createWalletClient , http , parseUnits } from "viem"
import { mainnet } from "viem/chains"
import { privateKeyToAccount } from "viem/accounts"
// Setup clients
const account = privateKeyToAccount ( "0x..." )
const publicClient = createPublicClient ({ chain: mainnet , transport: http () })
const walletClient = createWalletClient ({
chain: mainnet ,
transport: http (),
account ,
})
// Create bridge and builder
const bridge = createBridge ({ network: "mainnet" })
const evm = createEvmBuilder ({ network: "mainnet" , chain: ChainKind . Eth })
// 1. Validate the transfer
const validated = await bridge . validateTransfer ({
token: "eth:0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" , // USDC
amount: parseUnits ( "100" , 6 ), // 100 USDC
fee: 0 n ,
nativeFee: 0 n ,
sender: `eth: ${ account . address } ` ,
recipient: "near:recipient.near" ,
})
// 2. Approve the bridge (for ERC20 tokens)
const approvalTx = evm . buildApproval (
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" ,
validated . params . amount
)
const approvalHash = await walletClient . sendTransaction ( approvalTx )
await publicClient . waitForTransactionReceipt ({ hash: approvalHash })
// 3. Execute the transfer
const transferTx = evm . buildTransfer ( validated )
const transferHash = await walletClient . sendTransaction ( transferTx )
const receipt = await publicClient . waitForTransactionReceipt ({
hash: transferHash ,
})
// 4. Parse the transfer event
const event = parseInitTransferEvent ( receipt . logs )
console . log ( `Transfer initiated with nonce: ${ event . originNonce } ` )