Configuration Options
Trails is easy to get started, however we have deep configuration options to address most use cases.
Core Props
| Prop | Type | Required | Description |
|---|
apiKey | string | Yes | Your project access key provided by Trails |
mode | "pay" | "fund" | "earn" | "swap" | "withdraw" | Yes | Widget operation mode |
toAddress | string | No | Destination address for payments |
toAmount | string | No | Exact amount for payments (used in pay mode) |
toChainId | number | string | No | Controlled destination chain ID (locks selection) |
toToken | string | No | Controlled destination token symbol or contract address (locks selection) |
defaultToChainId | number | string | No | Default destination chain ID (user can change) |
defaultToToken | string | No | Default destination token symbol or contract address (user can change) |
toCalldata | string | No | Custom calldata for contract interactions |
fromChainId | number | string | No | Default origin chain ID (preselects source chain) |
fromToken | string | No | Default origin token symbol or contract address (preselects source token) |
fromAccount | string | No | Preselect a connected wallet address if multiple wallets are connected |
Recipient inputs in the widget support .eth ENS names, resolve them to addresses, and show ENS avatars when available.
UI & Rendering Options
| Prop | Type | Required | Description |
|---|
renderInline | boolean | No | Render widget inline instead of as a modal (default: false) |
children | React.ReactNode | No | Custom button content (when not renderInline) |
buttonText | string | No | Custom text for the trigger button (auto-generated if not provided) |
theme | "light" | "dark" | "auto" | No | Color theme; auto follows system preference (default: "auto") |
customCss | string | Record<string, string> | No | Custom CSS styles to apply to the component |
disableCss | boolean | No | Disable default CSS injection (for custom styling) |
toast | boolean | No | Show toast notifications for transaction updates |
hideDisconnect | boolean | No | Hide the disconnect button in the widget |
payMessage | string | No | Custom message to display during payment flow |
Wallet & Connection Options
| Prop | Type | Required | Description |
|---|
walletConnectProjectId | string | No | WalletConnect project ID for WalletConnect integration |
walletOptions | string[] | No | Array of wallet connector IDs to show (e.g., ["metamask", "walletconnect"]) |
isSmartWallet | boolean | No | Indicate if the connected wallet is a smart wallet (for ERC-4337 support) |
decoupleWagmi | boolean | No | Decouple from wagmi provider (use external wagmi config) |
wagmiConnectors | Connector[] | No | Custom wagmi connectors to use |
hideAddWallet | boolean | No | Hide the “Add wallet” option in the widget |
Transaction Options
| Prop | Type | Required | Description |
|---|
paymasterUrls | Array<{ chainId: number; url: string }> | No | Configure per-chain paymaster endpoints for gasless transactions |
swapProvider | RouteProvider | No | Preferred swap provider: "AUTO", "LIFI", "RELAY", "SUSHI", "ZEROX", or "CCTP". Default: "AUTO" automatically selects best provider |
bridgeProvider | RouteProvider | No | Preferred bridge provider: "AUTO", "LIFI", "RELAY", "CCTP". Default: "AUTO" automatically selects best provider for cross-chain transfers |
slippageTolerance | number | string | No | Slippage tolerance for swaps (e.g., 0.005 for 0.5%) |
priceImpactWarningThresholdBps | number | No | Price impact threshold in basis points before showing a warning (e.g., 500 for 5%) |
priceImpactWarningMessage | string | No | Custom message to display when price impact exceeds threshold |
priceImpactFallbackBridgeUrl | string | No | URL to redirect users when price impact is too high |
| Prop | Type | Required | Description |
|---|
appName | string | No | Your app’s name (shown in wallet connect dialogs) |
appUrl | string | No | Your app’s URL |
appImageUrl | string | No | Your app’s logo URL |
appDescription | string | No | Short description of your app |
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)
}
}}
/>