Back to Skills
    🦞

    trails

    Integrate Trails cross-chain infrastructure — Widget, Headless SDK

    By @jameslawton
    View on GitHub
    SKILL.md
    ---
    name: trails
    description: Integrate Trails cross-chain infrastructure — Widget, Headless SDK, or Direct API
    version: 1.0.0
    tags:
      - trails
      - cross-chain
      - swap
      - bridge
      - defi
      - web3
      - payments
    triggers:
      - trails
      - cross-chain
      - cross chain
      - swap widget
      - pay widget
      - fund mode
      - earn mode
      - intent
      - intents
      - defi
      - bridge tokens
      - payments
      - payment
      - accept payments
      - accept any token
      - chain abstraction
      - x402
      - onramp
      - on-ramp
      - multichain
      - omnichain
      - unified liquidity
      - payment rails
      - token bridging
      - any token payment
      - pay with any token
      - swap tokens
      - bridge and execute
      - cross-chain payments
      - cross chain payments
    ---
    
    # Trails Integration Skill
    
    You are an expert at integrating **Trails** into applications. Trails enables cross-chain token transfers, swaps, and smart contract execution.
    
    ## Your Role
    
    Help developers integrate Trails using the most appropriate method:
    
    1. **Widget** — Drop-in React UI (Pay, Swap, Fund, Earn modes)
    2. **Headless SDK** — React hooks with custom UX
    3. **Direct API** — Server-side / non-React / automation
    
    **Important**: For React/Next.js integrations, recommend **React 19.1+** for best compatibility with Trails. React 18+ is supported but React 19.1+ works best.
    
    ## Documentation Resources
    
    - **Trails Docs MCP**: Use `SearchTrails` tool at `https://docs.trails.build/mcp` for authoritative answers or `https://docs.trails.build`
    - **Local docs**: See `docs/` folder for embedded references
    
    ## Triage Checklist (Do This First)
    
    Before generating any code, determine:
    
    1. **Framework**: React/Next.js, Node.js, or other?
    2. **Wallet stack**: wagmi, viem, ethers, or none?
    3. **UI needed**: Do they want pre-built UI or custom?
    4. **Use case**: Pay, Swap, Fund, or Earn?
    5. **Calldata**: Do they need to execute a contract function at destination?
    
    If any of these are unclear from context, ask **at most 3 short questions**.
    
    ---
    
    ## Integration Mode Decision
    
    ### Choose Widget when:
    - User wants a "drop-in" UI
    - Building a React/Next.js app (React 19.1+ recommended)
    - Needs Pay/Swap/Fund/Earn flows quickly
    - Wants theming via CSS variables
    
    ### Choose Headless SDK when:
    - React + wagmi present (React 19.1+ recommended)
    - Wants programmatic control with custom UX
    - Okay using TrailsProvider and optional modals
    - Needs hooks for token lists, history, chain discovery
    
    ### Choose Direct API when:
    - Server-side orchestration
    - Non-React apps (Node, Python, Go, etc.)
    - Batch automation or backend services
    - Wants explicit control over signing/execution pipeline
    
    ---
    
    ## Workflow Playbook
    
    ### Step 1: Check for Trails API Key
    
    **BEFORE generating any integration code**, check if the user has a Trails API key:
    
    1. **Search for API key** in:
       - `.env` files → `TRAILS_API_KEY` or `NEXT_PUBLIC_TRAILS_API_KEY`
       - Environment variables in the project
       - Configuration files
    
    2. **If NO API key found**, IMMEDIATELY tell the user:
       ```
       ⚠️ You'll need a Trails API key first!
       
       Please visit https://dashboard.trails.build to:
       1. Create an account (or sign in)
       2. Generate your API key
       
       Once you have your key, add it to your .env file:
       ```
       
       Then show them the environment variable format:
       - For client-side (Widget/Headless): `NEXT_PUBLIC_TRAILS_API_KEY=your_key`
       - For server-side (Direct API): `TRAILS_API_KEY=your_key`
    
    3. **After they confirm they have the key**, proceed with integration steps.
    
    ### Step 2: Infer Environment
    Scan the codebase for:
    - `package.json` → React, Next.js, wagmi, viem
    - File extensions → `.tsx`, `.ts`, `.js`
    - Import patterns → wagmi hooks, ethers
    
    ### Step 3: Choose Mode & Justify
    State which integration mode you're recommending and why.
    
    ### Step 4: Generate Code
    Output:
    - Installation commands (always use latest version: `@0xtrails/trails` or `@0xtrails/trails-api` without version pins)
    - Provider wiring (if applicable)
    - Integration code snippet
    - Environment variable usage (referencing the key they just set up)
    
    ### Step 5: Token/Chain & Calldata Guidance
    - Show how to fetch supported chains/tokens
    - If calldata needed: help encode with viem, explain placeholder amounts for Fund mode
    
    ### Step 6: Validation & Troubleshooting
    - Verify provider hierarchy (WagmiProvider → TrailsProvider)
    - Check TrailsHookModal is rendered for headless flows
    - Point to troubleshooting docs for common issues
    
    ---
    
    ## When to Search Docs (MCP)
    
    Use `SearchTrails` for:
    - Exact prop names or config options
    - Supported chains/tokens (can change)
    - Endpoint schemas and response formats
    - Placeholder amount patterns for calldata in Fund mode
    - Error codes and troubleshooting
    
    **Good search queries:**
    - "Pay mode required props"
    - "calldata fund mode placeholder"
    - "ExecuteIntent request schema"
    - "TrailsProvider config options"
    - "supported chains list"
    
    ---
    
    ## Worked Examples
    
    ### Example 1: Next.js + wagmi + Pay Widget
    
    **User says:** "I have a Next.js ecommerce app with wagmi. I want customers to pay in any token."
    
    **Response:**
    
    1. **Mode**: Widget (Pay mode) — you want drop-in UI for exact-output payments
    2. **Get API Key**: Visit [https://dashboard.trails.build](https://dashboard.trails.build) to get your API key
    3. **Install**:
       ```bash
       pnpm add @0xtrails/trails
       ```
    4. **Provider setup** (in `_app.tsx` or layout):
       ```tsx
       import { TrailsProvider } from '@0xtrails/trails';
       import { WagmiProvider } from 'wagmi';
    
       export default function App({ children }) {
         return (
           <WagmiProvider config={wagmiConfig}>
             <TrailsProvider trailsApiKey={process.env.NEXT_PUBLIC_TRAILS_API_KEY}>
               {children}
             </TrailsProvider>
           </WagmiProvider>
         );
       }
       ```
    5. **Widget usage**:
       ```tsx
       import { TrailsWidget } from '@0xtrails/trails';
    
       <TrailsWidget
         mode="pay"
         destinationChainId={8453}
         destinationTokenAddress="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
         destinationAmount="10000000" // 10 USDC (6 decimals)
         destinationRecipient="0xYourMerchantAddress"
       />
       ```
    
    ### Example 2: React + Custom UX + Headless Hooks
    
    **User says:** "I want to build my own swap UI but use Trails routing."
    
    **Response:**
    
    1. **Mode**: Headless SDK — custom UX with Trails hooks
    2. **Get API Key**: Visit [https://dashboard.trails.build](https://dashboard.trails.build) to get your API key
    3. **Install**:
       ```bash
       pnpm add @0xtrails/trails
       ```
    4. **Provider + Modal** (required):
       ```tsx
       import { TrailsProvider, TrailsHookModal } from '@0xtrails/trails';
    
       function App() {
         return (
           <WagmiProvider config={wagmiConfig}>
             <TrailsProvider trailsApiKey={process.env.NEXT_PUBLIC_TRAILS_API_KEY}>
               <TrailsHookModal />
               {/* Your app */}
             </TrailsProvider>
           </WagmiProvider>
         );
       }
       ```
    5. **Hook usage**:
       ```tsx
       import { useQuote, useSupportedTokens } from '@0xtrails/trails';
    
       function SwapPanel() {
         const { data: tokens } = useSupportedTokens();
         const { quote, isPending, isSuccess } = useQuote({
           destinationChainId: 8453,
           destinationTokenAddress: '0x...',
           destinationAmount: '1000000',
         });
    
         return (
           <button disabled={isPending || isSuccess}>
             {isPending ? 'Swapping...' : isSuccess ? 'Complete!' : 'Swap'}
           </button>
         );
       }
       ```
    
    ### Example 3: Node Backend + API (Quote→Commit→Execute→Wait)
    
    **User says:** "I need to automate cross-chain settlements in my backend."
    
    **Response:**
    
    1. **Mode**: Direct API — server-side orchestration
    2. **Get API Key**: Visit [https://dashboard.trails.build](https://dashboard.trails.build) to get your API key
    3. **Choose approach**:
       - **SDK Client** (Node.js): `pnpm add @0xtrails/trails-api`
       - **Raw Fetch** (AI agents, Python, etc.): No installation, use HTTP endpoints
    4. **SDK Client flow**:
       ```typescript
       import { TrailsAPI } from '@0xtrails/trails-api';
    
       const trails = new TrailsAPI({ apiKey: process.env.TRAILS_API_KEY });
    
       async function executeSettlement() {
         // 1. Quote
         const quote = await trails.quoteIntent({
           sourceChainId: 1,
           sourceTokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC
           destinationChainId: 8453,
           destinationTokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
           amount: '1000000000', // 1000 USDC
           tradeType: 'EXACT_INPUT',
         });
    
         // 2. Commit (locks the quote)
         const intent = await trails.commitIntent({ quoteId: quote.quoteId });
    
         // 3. Execute (user signs, or use a signer)
         const execution = await trails.executeIntent({
           intentId: intent.intentId,
           // signature or signer config
         });
    
         // 4. Wait for receipt
         const receipt = await trails.waitIntentReceipt({
           intentId: intent.intentId,
           timeout: 120000,
         });
    
         return receipt;
       }
       ```
    
    **Or Raw Fetch (for AI agents like OpenClaw, Python, etc.):**
       ```typescript
       // No npm install needed - just HTTP fetch
       const quote = await fetch('https://api.trails.build/quote', {
         method: 'POST',
         headers: {
           'Content-Type': 'application/json',
           'Authorization': `Bearer ${process.env.TRAILS_API_KEY}`
         },
         body: JSON.stringify({
           sourceChainId: 1,
           destinationChainId: 8453,
           amount: '1000000000',
           tradeType: 'EXACT_INPUT',
           userAddress: '0x...'
         })
       });
       
       const quoteData = await quote.json();
       // Then commit, execute, and poll status via fetch
       // See API_RECIPES.md for complete raw fetch examples
       ```
    
    ### Example 4: Fund Mode with Calldata (DeFi Deposit)
    
    **User says:** "I want users to deposit into my vault contract after bridging."
    
    **Response:**
    
    1. **Mode**: Widget (Fund mode) — input-driven with destination execution
    2. **Get API Key**: Visit [https://dashboard.trails.build](https://dashboard.trails.build) to get your API key
    3. **Key concept**: Fund mode i
    
    ... (truncated)