SDKsTypeScript@t402/wdk-bridge

@t402/wdk-bridge

Cross-chain USDT0 bridging with automatic source chain selection using LayerZero OFT.

Installation

pnpm add @t402/wdk-bridge

Features

  • Multi-chain management: View balances across all configured chains
  • Automatic routing: Select best source chain based on balances and fees
  • Fee optimization: Choose strategy - cheapest, fastest, or preferred
  • LayerZero tracking: Monitor delivery via LayerZero Scan API

Quick Start

import { WdkBridgeClient } from '@t402/wdk-bridge'
 
// Create bridge client with WDK accounts
const bridge = new WdkBridgeClient({
  accounts: {
    ethereum: ethereumWdkAccount,
    arbitrum: arbitrumWdkAccount,
    ink: inkWdkAccount
  },
  defaultStrategy: 'cheapest'
})
 
// Get multi-chain balances
const summary = await bridge.getBalances()
console.log('Total USDT0:', summary.totalUsdt0)
console.log('Bridgeable chains:', summary.bridgeableChains)
 
// Auto-bridge to Ethereum
const result = await bridge.autoBridge({
  toChain: 'ethereum',
  amount: 100_000000n, // 100 USDT0
  recipient: '0x...'
})
 
console.log('Bridge TX:', result.txHash)
console.log('From chain:', result.fromChain)
console.log('Message GUID:', result.messageGuid)
 
// Wait for delivery
const delivery = await result.waitForDelivery({
  onStatusChange: (status) => console.log('Status:', status)
})
 
console.log('Delivered!', delivery.dstTxHash)

Route Selection

Get available routes before bridging:

const routes = await bridge.getRoutes('ethereum', 100_000000n)
 
routes.forEach(route => {
  console.log(`${route.fromChain} -> ${route.toChain}`)
  console.log(`  Fee: ${route.nativeFee} wei`)
  console.log(`  Time: ~${route.estimatedTime / 60} minutes`)
  console.log(`  Available: ${route.available}`)
  if (!route.available) {
    console.log(`  Reason: ${route.unavailableReason}`)
  }
})

Route Strategies

StrategyDescription
cheapestSelect route with lowest native fee (default)
fastestSelect route with fastest estimated delivery
preferredUse preferred source chain if available
// Use fastest route
const bridge = new WdkBridgeClient({
  accounts: { ... },
  defaultStrategy: 'fastest'
})
 
// Or specify per-request
const result = await bridge.autoBridge({
  toChain: 'ethereum',
  amount: 100_000000n,
  recipient: '0x...',
  preferredSourceChain: 'arbitrum' // Use 'preferred' strategy
})

Direct Bridge

Bridge from a specific chain:

const result = await bridge.bridge({
  fromChain: 'arbitrum',
  toChain: 'ethereum',
  amount: 50_000000n, // 50 USDT0
  recipient: '0x...',
  slippageTolerance: 0.3 // 0.3%
})

Track Messages

Track bridge transactions manually:

// Get message status
const message = await bridge.trackMessage(messageGuid)
console.log('Status:', message.status)
// INFLIGHT -> CONFIRMING -> DELIVERED
 
// Wait for delivery
const delivered = await bridge.waitForDelivery(messageGuid, {
  timeout: 600000, // 10 minutes
  pollInterval: 10000, // 10 seconds
  onStatusChange: (status) => console.log('Status:', status)
})

Supported Chains

ChainChain IDLayerZero EIDUSDT0 Address
Ethereum1301010x6C96dE32CEa08842dcc4058c14d3aaAD7Fa41dee
Arbitrum42161301100xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9
Ink57073302910x0200C29006150606B650577BBE7B6248F58470c1
Berachain80084303620x779Ded0c9e1022225f8E0630b35a9b54bE713736
Unichain130303200x588ce4F028D8e7B53B687865d6A67b3A54C75518

Estimated Bridge Times

RouteTime
Ethereum -> Arbitrum~3 minutes
Arbitrum -> Ethereum~15 minutes
L2 -> L2~5 minutes

API Reference

WdkBridgeClient

interface WdkBridgeClient {
  // Configuration
  getConfiguredChains(): string[]
  hasChain(chain: string): boolean
  setRpcUrl(chain: string, url: string): void
 
  // Balances
  getChainBalance(chain: string): Promise<ChainBalance>
  getBalances(): Promise<BalanceSummary>
 
  // Routing
  getRoutes(toChain: string, amount: bigint): Promise<BridgeRoute[]>
 
  // Bridging
  autoBridge(params: AutoBridgeParams): Promise<WdkBridgeResult>
  bridge(params: BridgeParams): Promise<WdkBridgeResult>
 
  // Tracking
  trackMessage(guid: string): Promise<LayerZeroMessage>
  waitForDelivery(guid: string, options?: WaitOptions): Promise<LayerZeroMessage>
}
 
interface AutoBridgeParams {
  toChain: string
  amount: bigint
  recipient: Address
  preferredSourceChain?: string
  slippageTolerance?: number
}
 
interface WdkBridgeResult {
  txHash: Hex
  messageGuid: Hex
  amountSent: bigint
  amountToReceive: bigint
  fromChain: string
  toChain: string
  estimatedTime: number
  waitForDelivery(options?: WaitOptions): Promise<DeliveryResult>
}
 
interface BalanceSummary {
  balances: ChainBalance[]
  totalUsdt0: bigint
  chainsWithBalance: string[]
  bridgeableChains: string[]
}