Skip to main content

Forwarding Address API Reference

Protocol

The API uses JSON-RPC 2.0 over HTTP POST with Content-Type: application/json.


Discovery

forwarding_getRoutes

Returns all supported source-to-destination routes with token metadata. This is the single source of truth for which chains and tokens are supported. Routes, tokens, fees, and minimums can change dynamically.

Parameters (all optional):

NameTypeRequiredDescription
sourceChainIdnumberNoFilter routes by source chain
destinationChainIdnumberNoFilter routes by destination chain

Request:

{
"jsonrpc": "2.0",
"id": 1,
"method": "forwarding_getRoutes",
"params": [{}]
}

Response:

{
"jsonrpc": "2.0",
"id": 1,
"result": {
"routes": [
{
"sourceChainId": 1,
"sourceChainName": "Ethereum",
"destinationChainId": 42161,
"destinationChainName": "Arbitrum One",
"tokens": [
{
"address": "0x0000000000000000000000000000000000000000",
"symbol": "ETH",
"decimals": 18,
"destinationAddress": "0x0000000000000000000000000000000000000000",
"minAmount": "10000000000000000",
"feeBps": 50
},
{
"address": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
"symbol": "USDT",
"decimals": 6,
"destinationAddress": "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9",
"minAmount": "1000000",
"feeBps": 50
}
]
}
]
}
}

Token fields:

FieldDescription
addressToken contract address on the source chain. 0x000...000 represents native ETH
symbolHuman-readable token symbol
decimalsToken decimal places (source chain)
destinationAddressToken contract address on the destination chain. Use this when verifying arrival or displaying the output token
minAmountMinimum deposit in smallest unit. Deposits below this threshold are not forwarded
feeBpsService fee in basis points (50 = 0.5%)

Core

forwarding_getAddress

Computes the deterministic CREATE2 proxy address for a given parameter set. Pure computation with no side effects. Safe to call repeatedly. The same inputs always produce the same address.

Parameters:

NameTypeRequiredDescription
recipientaddressYesDestination address that receives forwarded tokens
custodialWithdraweraddressYesEmergency recovery address that can withdraw stuck funds after a timelock. For most integrations, use the platform's address. See custodialWithdrawer
destinationChainIdnumberYesTarget chain ID where assets will be delivered
saltbytes32NoOptional 32-byte hex value. Use different salts to generate multiple forwarding addresses for the same recipient

Request:

{
"jsonrpc": "2.0",
"id": 1,
"method": "forwarding_getAddress",
"params": [{
"recipient": "0xAbCdEf0123456789AbCdEf0123456789AbCdEf01",
"custodialWithdrawer": "0xAbCdEf0123456789AbCdEf0123456789AbCdEf01",
"destinationChainId": 10
}]
}

Response:

{
"jsonrpc": "2.0",
"id": 1,
"result": {
"address": "0xDEF456..."
}
}

forwarding_activate

Activates relayer monitoring for a forwarding address on specified source chains. Returns the address, active status, and TTL expiration timestamp.

Key behaviors:

  • Idempotent: calling again resets the TTL. Use this to keep an address active.
  • TTL-based: monitoring expires after the TTL. The address must be reactivated to resume forwarding.
  • Reusable: call activate again after expiration.

Parameters:

NameTypeRequiredDescription
recipientaddressYesDestination recipient address
custodialWithdraweraddressYesWithdrawal-authorized address. See custodialWithdrawer
destinationChainIdnumberYesTarget chain ID
sourceChainIdsnumber[]YesArray of source chain IDs to activate monitoring on
saltbytes32NoOptional salt (must match the one used in forwarding_getAddress)

Request:

{
"jsonrpc": "2.0",
"id": 1,
"method": "forwarding_activate",
"params": [{
"recipient": "0xAbCdEf0123456789AbCdEf0123456789AbCdEf01",
"custodialWithdrawer": "0xAbCdEf0123456789AbCdEf0123456789AbCdEf01",
"destinationChainId": 10,
"sourceChainIds": [1, 42161]
}]
}

Response:

{
"jsonrpc": "2.0",
"id": 1,
"result": {
"address": "0xDEF456...",
"active": true,
"expiresAt": 1741132800
}
}
FieldDescription
expiresAtUnix timestamp (seconds) when monitoring expires. Do not hardcode this value; the default TTL may change

forwarding_getActivation

Checks the activation status of a forwarding address across all source chains it was registered on.

note

This endpoint tracks activation status (whether the relayer is monitoring this address), not deposit or forwarding completion status.

Parameters:

NameTypeRequiredDescription
addressaddressYesThe forwarding address to check

Request:

{
"jsonrpc": "2.0",
"id": 1,
"method": "forwarding_getActivation",
"params": [{
"address": "0xDEF456..."
}]
}

Response:

{
"jsonrpc": "2.0",
"id": 1,
"result": {
"address": "0xDEF456...",
"sourceChains": [
{
"sourceChainId": 1,
"status": "active",
"expiresAt": 1741132800
},
{
"sourceChainId": 42161,
"status": "expired",
"expiredAt": 1740528000
}
]
}
}

Estimation

forwarding_estimateOutput

Estimates the output amount a recipient will receive after service fee and bridge fee. This method is decoupled from forwarding addresses: it takes chain IDs directly and does not require the address to be activated.

Parameters:

NameTypeRequiredDescription
sourceChainIdnumberYesSource chain where the deposit originates
destinationChainIdnumberYesDestination chain ID
tokenaddressYesToken address on source chain (0x000...000 for native ETH)
amountstringYesInput amount in smallest unit (e.g. "1000000000000000000" for 1 ETH)
modestringNo"fast" (default) or "slow". Selects the bridge routing strategy

Request:

{
"jsonrpc": "2.0",
"id": 1,
"method": "forwarding_estimateOutput",
"params": [{
"sourceChainId": 1,
"destinationChainId": 42161,
"token": "0x0000000000000000000000000000000000000000",
"amount": "1000000000000000000",
"mode": "fast"
}]
}

Response:

{
"jsonrpc": "2.0",
"id": 1,
"result": {
"destinationChainId": 42161,
"outputToken": "0x...",
"outputTokenSymbol": "ETH",
"outputAmount": "990000000000000000",
"relayerBotFee": "5000000000000000",
"bridgeProtocolFee": "5000000000000000"
}
}
FieldDescription
outputAmountInput amount minus relayerBotFee minus bridgeProtocolFee. In smallest unit
relayerBotFeeRelayer service fee in smallest unit
bridgeProtocolFeeBridge protocol fee in smallest unit

Mode Control

forwarding_setMode

Sets the bridging mode for a monitored forwarding address. Optionally targets specific source chains.

Parameters:

NameTypeRequiredDescription
addressaddressYesThe forwarding proxy address to update
modestringYes"fast" or "slow"
sourceChainIdsnumber[]NoSpecific source chains to update. If omitted, updates all source chains for this address

Request:

{
"jsonrpc": "2.0",
"id": 1,
"method": "forwarding_setMode",
"params": [{
"address": "0xDEF456...",
"mode": "fast"
}]
}

Response:

{
"jsonrpc": "2.0",
"id": 1,
"result": {
"address": "0xDEF456...",
"mode": "fast",
"updated": 2
}
}
FieldDescription
updatedNumber of source chain entries that were updated

Emergency Recovery

forwarding_deploy

Deploys the CREATE2 proxy contract on specified source chains.

In normal operation, the relayer auto-deploys the contract on first deposit, so integrators typically do not need to call this. It is exposed for emergency fund recovery: if tokens are stuck in the forwarding address (e.g. the relayer did not process them), the contract must be deployed before the recipient can withdraw directly on-chain.

Parameters:

NameTypeRequiredDescription
recipientaddressYesDestination recipient address
custodialWithdraweraddressYesWithdrawal-authorized address
destinationChainIdnumberYesTarget chain ID
sourceChainIdsnumber[]NoSource chains to deploy on. If omitted, deploys on all supported source chains
saltbytes32NoMust match the salt used in forwarding_getAddress if one was used

Request:

{
"jsonrpc": "2.0",
"id": 1,
"method": "forwarding_deploy",
"params": [{
"recipient": "0xAbCdEf0123456789AbCdEf0123456789AbCdEf01",
"custodialWithdrawer": "0xAbCdEf0123456789AbCdEf0123456789AbCdEf01",
"destinationChainId": 10,
"sourceChainIds": [1]
}]
}

Response:

{
"jsonrpc": "2.0",
"id": 1,
"result": {
"1": "0xabc123...txhash"
}
}

Returns a map of sourceChainId to deployment transaction hash.


TypeScript Types

These types match the API response shapes and can serve as a reference for building your integration.

interface RouteToken {
address: string;
symbol: string;
decimals: number;
destinationAddress: string; // token address on destination chain
minAmount: string; // smallest unit, decimal string
feeBps: number; // basis points (50 = 0.5%)
}

interface Route {
sourceChainId: number;
sourceChainName: string;
destinationChainId: number;
destinationChainName: string;
tokens: RouteToken[];
}

interface RoutesResult {
routes: Route[];
}

interface AddressResult {
address: string;
}

interface ActivationResult {
address: string;
active: boolean;
expiresAt: number; // Unix timestamp (seconds)
}

interface SourceChainActivation {
sourceChainId: number;
status: "active" | "expired";
expiresAt?: number; // present when active
expiredAt?: number; // present when expired
}

interface ActivationStatus {
address: string;
sourceChains: SourceChainActivation[];
}

interface EstimateResult {
destinationChainId: number;
outputToken: string;
outputTokenSymbol: string;
outputAmount: string; // smallest unit
relayerBotFee: string; // smallest unit
bridgeProtocolFee: string; // smallest unit
}

interface SetModeResult {
address: string;
mode: "fast" | "slow";
updated: number;
}

interface DeployResult {
[sourceChainId: string]: string; // chainId -> txHash
}