Skip to main content

Overview

The Bridging SDK enables cross-chain token swaps by combining CoW Protocol swaps with bridge providers like Across and Bungee. It automatically routes trades through optimal paths and manages the bridging process.

Installation

npm install @cowprotocol/sdk-bridging

BridgingSdk

Main SDK class for bridging tokens between different chains.

Constructor

import { BridgingSdk } from '@cowprotocol/sdk-bridging'
import { AcrossBridgeProvider } from '@cowprotocol/sdk-bridging'

const bridgingSdk = new BridgingSdk({
  providers: [new AcrossBridgeProvider()],
  enableLogging: true,
  cacheConfig: {
    enabled: true,
    intermediateTokensTtl: 5 * 60 * 1000,
    buyTokensTtl: 2 * 60 * 1000,
  },
})
options
BridgingSdkOptions
required
Configuration options for the SDK
options.providers
BridgeProvider[]
required
Array of bridge providers (e.g., AcrossBridgeProvider, BungeeBridgeProvider)
options.tradingSdk
TradingSdk
Optional TradingSdk instance. Creates a new one if not provided.
options.orderBookApi
OrderBookApi
Optional OrderBookApi instance
options.enableLogging
boolean
Enable debug logging
options.cacheConfig
BridgingSdkCacheConfig
Cache configuration settings
options.cacheConfig.enabled
boolean
default:"true"
Enable caching for networks and tokens
options.cacheConfig.intermediateTokensTtl
number
default:"300000"
TTL in milliseconds for intermediate tokens cache (default: 5 minutes)
options.cacheConfig.buyTokensTtl
number
default:"120000"
TTL in milliseconds for buy tokens cache (default: 2 minutes)
adapter
AbstractProviderAdapter
Optional provider adapter (ethers v5, ethers v6, or viem)

getQuote()

Get a cross-chain quote with a callback to post the order.
const quote = await bridgingSdk.getQuote({
  kind: OrderKind.SELL,
  amount: parseUnits('100', 6), // 100 USDC
  sellTokenChainId: SupportedChainId.MAINNET,
  sellTokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
  sellTokenDecimals: 6,
  buyTokenChainId: TargetChainId.BASE,
  buyTokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
  buyTokenDecimals: 6,
  signer: userSigner,
})

// Post the order
const result = await quote.postSwapOrderFromQuote()
quoteBridgeRequest
QuoteBridgeRequest
required
Quote parameters
quoteBridgeRequest.kind
OrderKind
required
Order type: OrderKind.SELL or OrderKind.BUY
quoteBridgeRequest.amount
bigint
required
Amount to sell or buy (in token atoms)
quoteBridgeRequest.sellTokenChainId
SupportedChainId
required
Source chain ID
quoteBridgeRequest.sellTokenAddress
string
required
Sell token contract address
quoteBridgeRequest.sellTokenDecimals
number
required
Sell token decimals
quoteBridgeRequest.buyTokenChainId
TargetChainId
required
Destination chain ID
quoteBridgeRequest.buyTokenAddress
string
required
Buy token contract address
quoteBridgeRequest.buyTokenDecimals
number
required
Buy token decimals
quoteBridgeRequest.signer
SignerLike
required
Wallet signer
quoteBridgeRequest.owner
string
Order owner address (defaults to signer address)
quoteBridgeRequest.swapSlippageBps
number
Slippage tolerance for the swap in basis points
quoteBridgeRequest.bridgeSlippageBps
number
Slippage tolerance for the bridge in basis points
advancedSettings
SwapAdvancedSettings
Optional advanced settings for the swap
quote
CrossChainQuoteAndPost
Returns either QuoteAndPost for same-chain swaps or BridgeQuoteAndPost for cross-chain swaps
swap
QuoteResults
CoW Protocol swap quote details
bridge
BridgeQuoteResults
Bridge quote details (only for cross-chain swaps)
amountsAndCosts
BridgeQuoteAmountsAndCosts
Bridging amounts and costs breakdown
fees
object
Bridge fees
bridgeFee
bigint
Relayer capital cost fee (in token atoms)
destinationGasFee
bigint
Destination gas fee (in token atoms)
expectedFillTimeSeconds
number
Estimated time to complete the bridge
postSwapOrderFromQuote
function
Callback function to post the order on-chain

getMultiQuotes()

Get quotes from multiple bridge providers in parallel with progressive results.
const results = await bridgingSdk.getMultiQuotes({
  quoteBridgeRequest: {
    kind: OrderKind.SELL,
    amount: parseUnits('100', 6),
    sellTokenChainId: SupportedChainId.MAINNET,
    sellTokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
    sellTokenDecimals: 6,
    buyTokenChainId: TargetChainId.BASE,
    buyTokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
    buyTokenDecimals: 6,
    signer: userSigner,
  },
  providerDappIds: ['across', 'bungee'],
  options: {
    onQuoteResult: (result) => {
      console.log(`Quote from ${result.providerDappId}:`, result.quote)
    },
    totalTimeout: 40000,
    providerTimeout: 20000,
  },
})
request
MultiQuoteRequest
required
Multi-quote request parameters
request.quoteBridgeRequest
QuoteBridgeRequest
required
Base quote parameters
request.providerDappIds
string[]
Optional array of provider IDs to query. If not provided, queries all available providers.
request.options
MultiQuoteOptions
Optional behavior configuration
request.options.onQuoteResult
function
Callback invoked as soon as each provider returns a result
request.options.totalTimeout
number
default:"40000"
Maximum time to wait for all providers (milliseconds)
request.options.providerTimeout
number
default:"20000"
Maximum time to wait for each provider (milliseconds)
results
MultiQuoteResult[]
Array of results from each provider
providerDappId
string
Provider identifier
quote
BridgeQuoteAndPost | null
Quote result, or null if the provider failed
error
Error
Error if the provider failed

getBestQuote()

Get the best quote from multiple providers based on buyAmount after slippage.
const bestQuote = await bridgingSdk.getBestQuote({
  quoteBridgeRequest: quoteParams,
  providerDappIds: ['across', 'bungee'],
  options: {
    onQuoteResult: (result) => {
      console.log('New best quote found:', result)
    },
  },
})

if (bestQuote) {
  await bestQuote.quote.postSwapOrderFromQuote()
}
request
MultiQuoteRequest
required
Same parameters as getMultiQuotes()
bestQuote
MultiQuoteResult | null
The best quote result found, or null if no successful quotes

getSourceNetworks()

Get available source networks for bridging.
const sourceNetworks = await bridgingSdk.getSourceNetworks()
// Returns all supported CoW Protocol chains
networks
ChainInfo[]
Array of supported source chain information

getTargetNetworks()

Get available target networks for bridging.
const targetNetworks = await bridgingSdk.getTargetNetworks()
networks
ChainInfo[]
Array of supported destination chains across all providers

getBuyTokens()

Get available buy tokens for a specific target chain.
const { tokens, isRouteAvailable } = await bridgingSdk.getBuyTokens({
  buyChainId: TargetChainId.BASE,
  sellChainId: SupportedChainId.MAINNET,
  sellTokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
})
params
BuyTokensParams
required
Token query parameters
params.buyChainId
TargetChainId
required
Destination chain ID
params.sellChainId
SupportedChainId
Source chain ID (for filtering)
params.sellTokenAddress
string
Sell token address (for filtering)
result
GetProviderBuyTokens
tokens
TokenInfo[]
Array of available buy tokens
isRouteAvailable
boolean
Whether any route is available

getOrder()

Get details about a cross-chain order.
const order = await bridgingSdk.getOrder({
  chainId: SupportedChainId.MAINNET,
  orderId: '0x...',
  env: 'prod',
})
params
GetOrderParams
required
params.chainId
SupportedChainId
required
Chain where order was settled
params.orderId
string
required
Order unique identifier
params.env
CowEnv
Environment (‘prod’ or ‘staging’)
order
CrossChainOrder | null
Order details including bridge status, or null if not found

Cache Management

The SDK provides methods to manage the internal cache.
// Clear all caches
bridgingSdk.clearCache()

// Clean up expired entries
bridgingSdk.cleanupExpiredCache()

// Get cache statistics
const stats = bridgingSdk.getCacheStats()
console.log('Cache stats:', stats)
// { intermediateTokens: 5, buyTokens: 12 }

Bridge Providers

AcrossBridgeProvider

Bridge provider using the Across Protocol.
import { AcrossBridgeProvider } from '@cowprotocol/sdk-bridging'

const acrossProvider = new AcrossBridgeProvider({
  bridgeUrl: 'https://across.to/api',
})

BungeeBridgeProvider

Bridge provider using Bungee (Socket).
import { BungeeBridgeProvider } from '@cowprotocol/sdk-bridging'

const bungeeProvider = new BungeeBridgeProvider({
  bridgeUrl: 'https://api.socket.tech',
  apiKey: 'your-api-key',
})

NearIntentsBridgeProvider

Bridge provider for NEAR Protocol intents.
import { NearIntentsBridgeProvider } from '@cowprotocol/sdk-bridging'

const nearProvider = new NearIntentsBridgeProvider()

Types

QuoteBridgeRequest

Parameters for requesting a bridge quote.
interface QuoteBridgeRequest {
  kind: OrderKind
  amount: bigint
  sellTokenChainId: SupportedChainId
  sellTokenAddress: string
  sellTokenDecimals: number
  buyTokenChainId: TargetChainId
  buyTokenAddress: string
  buyTokenDecimals: number
  signer: SignerLike
  owner?: string
  swapSlippageBps?: number
  bridgeSlippageBps?: number
}

BridgeQuoteResult

Result of a bridge quote request.
interface BridgeQuoteResult {
  id?: string
  isSell: boolean
  amountsAndCosts: BridgeQuoteAmountsAndCosts
  expectedFillTimeSeconds?: number
  quoteTimestamp: number
  fees: {
    bridgeFee: bigint
    destinationGasFee: bigint
  }
  limits: {
    minDeposit: bigint
    maxDeposit: bigint
  }
}

BridgeQuoteAndPost

Combined quote result for cross-chain swaps.
interface BridgeQuoteAndPost {
  swap: QuoteResults
  bridge: BridgeQuoteResults
  postSwapOrderFromQuote(
    advancedSettings?: SwapAdvancedSettings,
    signingStepManager?: SigningStepManager
  ): Promise<OrderPostingResult>
}

Examples

Basic Cross-Chain Swap

import { BridgingSdk, AcrossBridgeProvider } from '@cowprotocol/sdk-bridging'
import { OrderKind } from '@cowprotocol/sdk-order-book'
import { SupportedChainId, TargetChainId } from '@cowprotocol/sdk-config'

const sdk = new BridgingSdk({
  providers: [new AcrossBridgeProvider()],
})

// Get a quote for swapping USDC from Mainnet to Base
const quote = await sdk.getQuote({
  kind: OrderKind.SELL,
  amount: parseUnits('100', 6),
  sellTokenChainId: SupportedChainId.MAINNET,
  sellTokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
  sellTokenDecimals: 6,
  buyTokenChainId: TargetChainId.BASE,
  buyTokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
  buyTokenDecimals: 6,
  signer: userSigner,
  swapSlippageBps: 50, // 0.5%
  bridgeSlippageBps: 50, // 0.5%
})

// Post the order
const result = await quote.postSwapOrderFromQuote()
console.log('Order posted:', result.orderUid)

Compare Multiple Providers

const results = await sdk.getMultiQuotes({
  quoteBridgeRequest: {
    kind: OrderKind.SELL,
    amount: parseUnits('1000', 6),
    sellTokenChainId: SupportedChainId.MAINNET,
    sellTokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
    sellTokenDecimals: 6,
    buyTokenChainId: TargetChainId.BASE,
    buyTokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
    buyTokenDecimals: 6,
    signer: userSigner,
  },
  providerDappIds: ['across', 'bungee'],
  options: {
    onQuoteResult: (result) => {
      if (result.quote) {
        console.log(`${result.providerDappId}: ${result.quote.bridge.amountsAndCosts.afterFee.buyAmount} tokens`)
      }
    },
  },
})

// Find the best quote manually
const bestQuote = results
  .filter((r) => r.quote !== null)
  .reduce((best, current) => {
    const currentAmount = current.quote!.bridge.amountsAndCosts.afterSlippage.buyAmount
    const bestAmount = best.quote!.bridge.amountsAndCosts.afterSlippage.buyAmount
    return currentAmount > bestAmount ? current : best
  })

console.log('Best provider:', bestQuote.providerDappId)

Get Available Tokens

// Get all available buy tokens on Base
const { tokens, isRouteAvailable } = await sdk.getBuyTokens({
  buyChainId: TargetChainId.BASE,
})

console.log('Available tokens:', tokens.length)
tokens.forEach((token) => {
  console.log(`${token.symbol}: ${token.address}`)
})

// Filter by sell token
const usdcTargets = await sdk.getBuyTokens({
  buyChainId: TargetChainId.BASE,
  sellChainId: SupportedChainId.MAINNET,
  sellTokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
})

Build docs developers (and LLMs) love