Skip to main content

Configuration Options

Trails is easy to get started, however we have deep configuration options to address most use cases.

Core Props

PropTypeRequiredDescription
apiKeystringNoYour project access key provided by Trails
mode"pay" | "fund" | "earn" | "swap" | "receive"YesWidget operation mode
toAddressstringNoDestination address for payments
toAmountstringNoExact amount for payments (used in pay mode)
toChainIdnumber | stringNoDestination chain ID
toTokenstringNoDestination token symbol or contract address
toCalldatastringNoCustom calldata for contract interactions

UI & Rendering Options

PropTypeRequiredDescription
renderInlinebooleanNoRender widget inline instead of as a modal (default: false)
childrenReact.ReactNodeNoCustom button content (when not renderInline)
buttonTextstringNoCustom text for the trigger button (auto-generated if not provided)
theme"light" | "dark" | "auto"NoColor theme; auto follows system preference (default: "auto")
customCssstring | Record<string, string>NoCustom CSS styles to apply to the component

Wallet & Connection Options

PropTypeRequiredDescription
walletConnectProjectIdstringNoWalletConnect project ID for WalletConnect integration

Transaction Options

PropTypeRequiredDescription
paymasterUrlsArray<{ chainId: number; url: string }>NoConfigure per-chain paymaster endpoints for gasless transactions
quoteProvider"auto" | "lifi" | "relay" | "cctp"NoPreferred quote provider (default: "auto"). "auto" automatically selects best provider, "lifi" uses LiFi aggregator for multi-source routing, "relay" uses Relay for fast direct transfers, "cctp" uses Circle’s CCTP for native USDC transfers
slippageTolerancenumber | stringNoSlippage tolerance for swaps (e.g., 0.005 for 0.5%)

Event Handlers

PropTypeRequiredDescription
onOriginConfirmation(data: { txHash: string; chainId: number; sessionId: string }) => voidNoCalled when origin transaction is confirmed
onDestinationConfirmation(data: { txHash: string; chainId: number; sessionId: string }) => voidNoCalled when destination transaction is confirmed
onCheckoutStart(data: { sessionId: string }) => voidNoCalled when checkout process starts
onCheckoutQuote(data: { sessionId: string; quote: any }) => voidNoCalled when quote is received
onCheckoutComplete(data: { sessionId: string }) => voidNoCalled when checkout completes successfully
onCheckoutError(data: { sessionId: string; error: string }) => voidNoCalled when checkout encounters an error (including user rejection)
onCheckoutStatusUpdate(data: { sessionId: string; transactionStates: TransactionState[] }) => voidNoCalled when transaction status updates

Smart Contract Interactions

Execute custom contract calls with payments:
import { encodeFunctionData } from 'viem'

const calldata = encodeFunctionData({
  abi: contractABI,
  functionName: 'mintNFT',
  args: [recipient, tokenId]
})

<TrailsWidget
  apiKey="YOUR_API_KEY"
  mode="pay"
  toAddress="0x..." // Contract address
  toAmount="0.1"
  toChainId={1}
  toToken="ETH"
  toCalldata={calldata}
  onCheckoutComplete={(result) => {
    console.log('NFT minted:', result)
  }}
/>

Event Handling Examples

Complete Event Handling

import { getIsUserRejectionError } from '0xtrails'

<TrailsWidget
  apiKey="YOUR_API_KEY"
  mode="pay"
  toAddress="0x..."
  toAmount="1"
  toChainId={8453}
  toToken="USDC"
  onOriginConfirmation={({ txHash, chainId, sessionId }) => {
    console.log('Origin tx confirmed:', { txHash, chainId, sessionId })
  }}
  onDestinationConfirmation={({ txHash, chainId, sessionId }) => {
    console.log('Destination tx confirmed:', { txHash, chainId, sessionId })
  }}
  onCheckoutStatusUpdate={({ sessionId, transactionStates }) => {
    transactionStates.forEach((state, index) => {
      console.log(`Step ${index + 1}: ${state.label} - ${state.state}`)
      if (state.state === 'confirmed') {
        console.log('Transaction confirmed:', state.transactionHash)
      }
    })
  }}
  onCheckoutComplete={({ sessionId }) => {
    console.log('Transaction completed successfully:', sessionId)
  }}
  onCheckoutError={({ sessionId, error }) => {
    console.error('Transaction failed:', sessionId, error)
    
    // Check if user rejected the transaction
    if (getIsUserRejectionError(error)) {
      console.log('User rejected the transaction')
      // Handle user rejection (e.g., show "Transaction cancelled" message)
    } else {
      // Handle other errors (show error notification, retry logic, etc.)
    }
  }}
/>

Handling User Rejection

User rejection occurs when a user declines to sign a transaction in their wallet. This is handled through the onCheckoutError callback:
import { getIsUserRejectionError, TrailsWidget } from '0xtrails'

<TrailsWidget
  apiKey="YOUR_API_KEY"
  mode="pay"
  toAddress="0x..."
  onCheckoutError={({ sessionId, error }) => {
    if (getIsUserRejectionError(error)) {
      // User cancelled the transaction
      showNotification('Transaction cancelled by user')
    } else {
      // Other error occurred
      showNotification('Transaction failed: ' + error)
    }
  }}
/>