Skip to main content

Documentation Index

Fetch the complete documentation index at: https://anypay-docs-sdk-0-15-0-updates.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

Swap with Trails

Trails enables cross-chain token swapping in one click, from any wallet. Users exchange tokens without manually bridging assets or interacting with multiple DEXs — available via the widget or API. Traditional cross-chain swapping requires token approvals, manual bridging, finding DEXs on each chain, and paying gas on each network. Trails optimizes the UX across all liquidity sources and chains in a single user confirmation.

Use cases

  • Cross-chain token swaps (ETH on Mainnet → USDC on Base)
  • Same-chain token exchanges with optimal routing
  • Portfolio rebalancing across chains
  • Converting between stablecoins with minimal slippage

Examples

Simple swap — user picks everything

import { Swap } from '0xtrails/widget'

export const BasicSwap = () => {
  return (
    <Swap
      apiKey="YOUR_API_KEY"
      onSwapSuccess={({ sessionId }) => {
        console.log('Swap completed:', sessionId)
      }}
      onSwapError={({ sessionId, error }) => {
        console.error('Swap failed:', sessionId, error)
      }}
    >
      <button>Swap Tokens</button>
    </Swap>
  )
}

Pre-configured cross-chain swap

import { Swap } from '0xtrails/widget'

export const ETHtoUSDC = () => {
  return (
    <Swap
      apiKey="YOUR_API_KEY"
      from={{ currency: "ETH", chain: "ethereum" }}
      to={{ currency: "USDC", chain: "base" }}
      onSwapSuccess={({ sessionId }) => {
        console.log('Swap completed:', sessionId)
      }}
    >
      <button>Swap ETH → USDC</button>
    </Swap>
  )
}

Custom bridge provider

import { Swap } from '0xtrails/widget'

export const CCTPSwap = () => {
  return (
    <Swap
      apiKey="YOUR_API_KEY"
      bridgeProvider="CCTP"
      from={{ currency: "USDC", chain: "ethereum" }}
      to={{ currency: "USDC", chain: "base" }}
      onSwapSuccess={({ sessionId }) => {
        console.log('Swap completed:', sessionId)
      }}
    >
      <button>Bridge USDC via CCTP</button>
    </Swap>
  )
}

Headless swap with useQuote

For custom UI implementations, use the useQuote hook directly:
import { useQuote } from '0xtrails'
import { useWalletClient, useAccount } from 'wagmi'
import { useState } from 'react'

export const CustomSwapComponent = () => {
  const { data: walletClient } = useWalletClient()
  const { address } = useAccount()
  const [amount, setAmount] = useState('1') // human-readable USDC amount

  const { quote, send, isLoadingQuote, quoteError } = useQuote({
    walletClient,
    from: {
      token: 'USDC',
      chain: 'ethereum',
      amount,
    },
    to: {
      token: 'USDC',
      chain: 'base',
      recipient: address,
    },
    slippageTolerance: '0.005', // 0.5%
    onStatusUpdate: (states) => {
      console.log('Swap progress:', states)
    },
  })

  const handleSwap = async () => {
    if (!send) return
    
    try {
      const result = await send()
      console.log('Swap result:', result)
    } catch (error) {
      console.error('Swap failed:', error)
    }
  }

  if (isLoadingQuote) {
    return <div>Loading quote...</div>
  }

  if (quoteError) {
    return <div>Error getting quote: {String(quoteError)}</div>
  }

  if (!quote) {
    return <div>No quote available</div>
  }

  return (
    <div>
      <p>From: {quote.originAmountFormatted} {quote.originToken.symbol} on {quote.originChain.name}</p>
      <p>To: {quote.destinationAmountFormatted} {quote.destinationToken.symbol} on {quote.destinationChain.name}</p>
      <p>Fee: {quote.totalFeeAmountUsdDisplay}</p>
      <p>Estimated time: {quote.completionEstimateSeconds}s</p>
      <button onClick={() => swap?.()}>Execute Swap</button>
    </div>
  )
}

Next steps