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:
- Widget — Drop-in React UI (Pay, Swap, Fund, Earn modes)
- Headless SDK — React hooks with custom UX
- Direct API — Server-side / non-React / automation
Important: The SDK package is 0xtrails (current major: 0.16.x); the Direct-API client is @0xtrails/api. For React/Next.js integrations it works with React 18 or 19 (peer dependency ^18 || ^19), plus viem ^2.41 and @tanstack/react-query ^5.90. The current intent protocol is v1.5 (HydrateProxy executor).
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:
- Framework: React/Next.js, Node.js, or other?
- Wallet stack: wagmi, viem, ethers, or none?
- UI needed: Do they want pre-built UI or custom?
- Use case: Pay, Swap, Fund, or Earn? (For Earn outside a React UI, go straight to the Yield API endpoints — see
YIELD_API_RECIPES.md.)
- 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 18 or 19)
- Needs Pay/Swap/Fund/Earn flows quickly
- Wants theming via CSS variables
Choose Headless SDK when:
- React + wagmi present (React 18 or 19)
- 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
- Yield (Earn) deposits or withdrawals from an agent, CLI, or backend — see
YIELD_API_RECIPES.md. Discover with YieldGetMarkets; withdraw with YieldCreateExitAction. When the user already holds the vault's token, deposit with YieldCreateEnterAction (approve + supply). To deposit a different token, the robust raw-API path is two steps: a QuoteIntent swap into the vault's token (delivered to the user), then YieldCreateEnterAction. For a single signed transaction, build a v1.5 hydrate-multicall with the 0xtrails SDK (swap() + lend/deposit({ amount: dynamic() }) → encodeMulticallHydrateExecute) and pass it as destinationCallData to the Trails v1.5 executor (0x000000004f702C8398e158108937814d074cD74b). Do not point destinationToAddress at the vault with a bare supply() and a 0xffff…ff placeholder — that is the deprecated pre-v1.5 shape and reverts (the real hydration sentinel is 0xfcbc96b9…). The Earn widget is only for React UIs.
Workflow Playbook
Step 1: Check for Trails API Key
BEFORE generating any integration code, check if the user has a Trails API key:
Search for API key in:
.env files → TRAILS_API_KEY or NEXT_PUBLIC_TRAILS_API_KEY
- Environment variables in the project
- Configuration files
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
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 or @0xtrails/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:
- Mode: Widget (Pay mode) — you want drop-in UI for exact-output payments
- Get API Key: Visit https://dashboard.trails.build to get your API key
- Install:
pnpm add 0xtrails
- Provider setup (in
_app.tsx or layout):import { TrailsProvider } from '0xtrails';
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>
);
}
- Widget usage:
import { TrailsWidget } from '0xtrails';
<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:
- Mode: Headless SDK — custom UX with Trails hooks
- Get API Key: Visit https://dashboard.trails.build to get your API key
- Install:
pnpm add 0xtrails
- Provider + Modal (required):
import { TrailsProvider, TrailsHookModal } from '0xtrails';
function App() {
return (
<WagmiProvider config={wagmiConfig}>
<TrailsProvider trailsApiKey={process.env.NEXT_PUBLIC_TRAILS_API_KEY}>
<TrailsHookModal />
{/* Your app */}
</TrailsProvider>
</WagmiProvider>
);
}
- Hook usage:
import { useQuote, useSupportedTokens } from '0xtrails';
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:
- Mode: Direct API — server-side orchestration
- Get API Key: Visit https://dashboard.trails.build to get your API key
- Choose approach:
- SDK Client (Node.js):
pnpm add @0xtrails/api
- Raw Fetch (AI agents, Python, etc.): No installation, use HTTP endpoints
- SDK Client flow:
import { TrailsAPI } from '@0xtrails/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.):
// 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:
- Mode: Widget (Fund mode) — input-driven with destination execution
- Get API Key: Visit https://dashboard.trails.build to get your API key
- Key concept: Fund mode is
EXACT_INPUT — user picks input amount, output is computed. Use placeholder for destination amount in calldata.
- Encode calldata:
import { encodeFunctionData } from 'viem';
const vaultAbi = [
{
name: 'deposit',
type: 'function',
inputs: [
{ name: 'amount', type: 'uint256' },
{ name: 'receiver', type: 'address' },
],
outputs: [],
},
] as const;
// Use placeholder for amount (Trails fills actual value)
const PLACEHOLDER_AMOUNT = '0xfcbc96b9628c6a4da70c90b9e80f5f4ef82922d86bd4cb54db481ae22ed79c53';
const calldata = encodeFunctionData({
abi: vaultAbi,
functionName: 'deposit',
args: [BigInt(PLACEHOLDER_AMOUNT), userAddress],
});
- Widget config:
<TrailsWidget
mode="fund"
destinationChainId={42161}
destinationTokenAddress="0xaf88d065e77c8cC2239327C5EDb3A432268e5831"
destinationRecipient="0xYourVaultContract"
destinationCalldata={calldata}
/>
Quick Reference
Getting Your API Key (CRITICAL FIRST STEP)
ALWAYS check if the user has an API key BEFORE providing integration code!
If no API key is found:
Stop and inform the user:
⚠️ You need a Trails API key to use this integration.
Please visit: https://dashboard.trails.build
Steps:
1. Create an account (or sign in if you have one)
2. Navigate to the API Keys section
3. Generate a new API key
4. Copy the key
Once you have your key, add it to your .env file and let me know!
Wait for confirmation that they have the key before proceeding.
Then show them how to add it:
Environment Variables
# For client-side (Widget/Headless SDK)
NEXT_PUBLIC_TRAILS_API_KEY=your_api_key
# For server-side (Direct API)
TRAILS_API_KEY=your_api_key
Never generate integration code without first verifying the user has or can get an API key!
Token/Chain Discovery
// Hooks
import { useSupportedChains, useSupportedTokens } from '0xtrails';
// Functions
import { getSupportedChains, getSupportedTokens, getChainInfo } from '0xtrails';
Trade Types by Mode
| Mode |
TradeType |
Meaning |
| Pay |
EXACT_OUTPUT |
User pays whatever needed to get exact destination amount |
| Fund |
EXACT_INPUT |
User picks input amount, destination computed |
| Swap |
Both |
User chooses direction |
| Earn |
EXACT_INPUT (two-step) or EXACT_OUTPUT (v1.5 single-tx) |
Deposit into DeFi protocols with any input token. React: Earn widget. Agent/CLI/backend: Yield API — YieldCreateEnterAction if the user holds the vault token, else swap-first then enter, or a v1.5 hydrate-multicall as destinationCallData (see YIELD_API_RECIPES.md). |
Additional Resources
See docs/ for detailed guides:
TRAILS_OVERVIEW.md — Core concepts
INTEGRATION_DECISION_TREE.md — Mode selection flowchart
WIDGET_RECIPES.md — Widget examples
HEADLESS_SDK_RECIPES.md — Hooks patterns
API_RECIPES.md — Server-side flows
YIELD_API_RECIPES.md — Yield (Earn) deposits and withdrawals via the Direct API, with an external signer
CALLDATA_GUIDE.md — Encoding destination calls
TROUBLESHOOTING.md — Common issues
1---2name: trails-23description: Integrate Trails cross-chain infrastructure — Widget, Headless SDK, or Direct API4---56# Trails Integration Skill78You are an expert at integrating **Trails** into applications. Trails enables cross-chain token transfers, swaps, and smart contract execution.910## Your Role1112Help developers integrate Trails using the most appropriate method:13141. **Widget** — Drop-in React UI (Pay, Swap, Fund, Earn modes)152. **Headless SDK** — React hooks with custom UX163. **Direct API** — Server-side / non-React / automation1718**Important**: The SDK package is **`0xtrails`** (current major: `0.16.x`); the Direct-API client is **`@0xtrails/api`**. For React/Next.js integrations it works with **React 18 or 19** (peer dependency `^18 || ^19`), plus `viem ^2.41` and `@tanstack/react-query ^5.90`. The current intent protocol is **v1.5** (HydrateProxy executor).1920## Documentation Resources2122- **Trails Docs MCP**: Use `SearchTrails` tool at `https://docs.trails.build/mcp` for authoritative answers or `https://docs.trails.build`23- **Local docs**: See `docs/` folder for embedded references2425## Triage Checklist (Do This First)2627Before generating any code, determine:28291. **Framework**: React/Next.js, Node.js, or other?302. **Wallet stack**: wagmi, viem, ethers, or none?313. **UI needed**: Do they want pre-built UI or custom?324. **Use case**: Pay, Swap, Fund, or Earn? (For Earn outside a React UI, go straight to the Yield API endpoints — see `YIELD_API_RECIPES.md`.)335. **Calldata**: Do they need to execute a contract function at destination?3435If any of these are unclear from context, ask **at most 3 short questions**.3637---3839## Integration Mode Decision4041### Choose Widget when:42- User wants a "drop-in" UI43- Building a React/Next.js app (React 18 or 19)44- Needs Pay/Swap/Fund/Earn flows quickly45- Wants theming via CSS variables4647### Choose Headless SDK when:48- React + wagmi present (React 18 or 19)49- Wants programmatic control with custom UX50- Okay using TrailsProvider and optional modals51- Needs hooks for token lists, history, chain discovery5253### Choose Direct API when:54- Server-side orchestration55- Non-React apps (Node, Python, Go, etc.)56- Batch automation or backend services57- Wants explicit control over signing/execution pipeline58- **Yield (Earn) deposits or withdrawals from an agent, CLI, or backend** — see `YIELD_API_RECIPES.md`. Discover with `YieldGetMarkets`; withdraw with `YieldCreateExitAction`. When the user already holds the vault's token, deposit with `YieldCreateEnterAction` (approve + supply). To deposit a **different** token, the robust raw-API path is two steps: a `QuoteIntent` swap into the vault's token (delivered to the user), then `YieldCreateEnterAction`. For a single signed transaction, build a v1.5 *hydrate-multicall* with the `0xtrails` SDK (`swap()` + `lend`/`deposit({ amount: dynamic() })` → `encodeMulticallHydrateExecute`) and pass it as `destinationCallData` to the Trails v1.5 executor (`0x000000004f702C8398e158108937814d074cD74b`). Do **not** point `destinationToAddress` at the vault with a bare `supply()` and a `0xffff…ff` placeholder — that is the deprecated pre-v1.5 shape and reverts (the real hydration sentinel is `0xfcbc96b9…`). The Earn widget is only for React UIs.5960---6162## Workflow Playbook6364### Step 1: Check for Trails API Key6566**BEFORE generating any integration code**, check if the user has a Trails API key:67681. **Search for API key** in:69 - `.env` files → `TRAILS_API_KEY` or `NEXT_PUBLIC_TRAILS_API_KEY`70 - Environment variables in the project71 - Configuration files72732. **If NO API key found**, IMMEDIATELY tell the user:74 ```75 ⚠️ You'll need a Trails API key first!76 77 Please visit https://dashboard.trails.build to:78 1. Create an account (or sign in)79 2. Generate your API key80 81 Once you have your key, add it to your .env file:82 ```83 84 Then show them the environment variable format:85 - For client-side (Widget/Headless): `NEXT_PUBLIC_TRAILS_API_KEY=your_key`86 - For server-side (Direct API): `TRAILS_API_KEY=your_key`87883. **After they confirm they have the key**, proceed with integration steps.8990### Step 2: Infer Environment91Scan the codebase for:92- `package.json` → React, Next.js, wagmi, viem93- File extensions → `.tsx`, `.ts`, `.js`94- Import patterns → wagmi hooks, ethers9596### Step 3: Choose Mode & Justify97State which integration mode you're recommending and why.9899### Step 4: Generate Code100Output:101- Installation commands (always use latest version: `0xtrails` or `@0xtrails/api` without version pins)102- Provider wiring (if applicable)103- Integration code snippet104- Environment variable usage (referencing the key they just set up)105106### Step 5: Token/Chain & Calldata Guidance107- Show how to fetch supported chains/tokens108- If calldata needed: help encode with viem, explain placeholder amounts for Fund mode109110### Step 6: Validation & Troubleshooting111- Verify provider hierarchy (WagmiProvider → TrailsProvider)112- Check TrailsHookModal is rendered for headless flows113- Point to troubleshooting docs for common issues114115---116117## When to Search Docs (MCP)118119Use `SearchTrails` for:120- Exact prop names or config options121- Supported chains/tokens (can change)122- Endpoint schemas and response formats123- Placeholder amount patterns for calldata in Fund mode124- Error codes and troubleshooting125126**Good search queries:**127- "Pay mode required props"128- "calldata fund mode placeholder"129- "ExecuteIntent request schema"130- "TrailsProvider config options"131- "supported chains list"132133---134135## Worked Examples136137### Example 1: Next.js + wagmi + Pay Widget138139**User says:** "I have a Next.js ecommerce app with wagmi. I want customers to pay in any token."140141**Response:**1421431. **Mode**: Widget (Pay mode) — you want drop-in UI for exact-output payments1442. **Get API Key**: Visit [https://dashboard.trails.build](https://dashboard.trails.build) to get your API key1453. **Install**:146 ```bash147 pnpm add 0xtrails148 ```1494. **Provider setup** (in `_app.tsx` or layout):150 ```tsx151 import { TrailsProvider } from '0xtrails';152 import { WagmiProvider } from 'wagmi';153154 export default function App({ children }) {155 return (156 <WagmiProvider config={wagmiConfig}>157 <TrailsProvider trailsApiKey={process.env.NEXT_PUBLIC_TRAILS_API_KEY}>158 {children}159 </TrailsProvider>160 </WagmiProvider>161 );162 }163 ```1645. **Widget usage**:165 ```tsx166 import { TrailsWidget } from '0xtrails';167168 <TrailsWidget169 mode="pay"170 destinationChainId={8453}171 destinationTokenAddress="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"172 destinationAmount="10000000" // 10 USDC (6 decimals)173 destinationRecipient="0xYourMerchantAddress"174 />175 ```176177### Example 2: React + Custom UX + Headless Hooks178179**User says:** "I want to build my own swap UI but use Trails routing."180181**Response:**1821831. **Mode**: Headless SDK — custom UX with Trails hooks1842. **Get API Key**: Visit [https://dashboard.trails.build](https://dashboard.trails.build) to get your API key1853. **Install**:186 ```bash187 pnpm add 0xtrails188 ```1894. **Provider + Modal** (required):190 ```tsx191 import { TrailsProvider, TrailsHookModal } from '0xtrails';192193 function App() {194 return (195 <WagmiProvider config={wagmiConfig}>196 <TrailsProvider trailsApiKey={process.env.NEXT_PUBLIC_TRAILS_API_KEY}>197 <TrailsHookModal />198 {/* Your app */}199 </TrailsProvider>200 </WagmiProvider>201 );202 }203 ```2045. **Hook usage**:205 ```tsx206 import { useQuote, useSupportedTokens } from '0xtrails';207208 function SwapPanel() {209 const { data: tokens } = useSupportedTokens();210 const { quote, isPending, isSuccess } = useQuote({211 destinationChainId: 8453,212 destinationTokenAddress: '0x...',213 destinationAmount: '1000000',214 });215216 return (217 <button disabled={isPending || isSuccess}>218 {isPending ? 'Swapping...' : isSuccess ? 'Complete!' : 'Swap'}219 </button>220 );221 }222 ```223224### Example 3: Node Backend + API (Quote→Commit→Execute→Wait)225226**User says:** "I need to automate cross-chain settlements in my backend."227228**Response:**2292301. **Mode**: Direct API — server-side orchestration2312. **Get API Key**: Visit [https://dashboard.trails.build](https://dashboard.trails.build) to get your API key2323. **Choose approach**:233 - **SDK Client** (Node.js): `pnpm add @0xtrails/api`234 - **Raw Fetch** (AI agents, Python, etc.): No installation, use HTTP endpoints2354. **SDK Client flow**:236 ```typescript237 import { TrailsAPI } from '@0xtrails/api';238239 const trails = new TrailsAPI({ apiKey: process.env.TRAILS_API_KEY });240241 async function executeSettlement() {242 // 1. Quote243 const quote = await trails.quoteIntent({244 sourceChainId: 1,245 sourceTokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC246 destinationChainId: 8453,247 destinationTokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',248 amount: '1000000000', // 1000 USDC249 tradeType: 'EXACT_INPUT',250 });251252 // 2. Commit (locks the quote)253 const intent = await trails.commitIntent({ quoteId: quote.quoteId });254255 // 3. Execute (user signs, or use a signer)256 const execution = await trails.executeIntent({257 intentId: intent.intentId,258 // signature or signer config259 });260261 // 4. Wait for receipt262 const receipt = await trails.waitIntentReceipt({263 intentId: intent.intentId,264 timeout: 120000,265 });266267 return receipt;268 }269 ```270271**Or Raw Fetch (for AI agents like OpenClaw, Python, etc.):**272 ```typescript273 // No npm install needed - just HTTP fetch274 const quote = await fetch('https://api.trails.build/quote', {275 method: 'POST',276 headers: {277 'Content-Type': 'application/json',278 'Authorization': `Bearer ${process.env.TRAILS_API_KEY}`279 },280 body: JSON.stringify({281 sourceChainId: 1,282 destinationChainId: 8453,283 amount: '1000000000',284 tradeType: 'EXACT_INPUT',285 userAddress: '0x...'286 })287 });288 289 const quoteData = await quote.json();290 // Then commit, execute, and poll status via fetch291 // See API_RECIPES.md for complete raw fetch examples292 ```293294### Example 4: Fund Mode with Calldata (DeFi Deposit)295296**User says:** "I want users to deposit into my vault contract after bridging."297298**Response:**2993001. **Mode**: Widget (Fund mode) — input-driven with destination execution3012. **Get API Key**: Visit [https://dashboard.trails.build](https://dashboard.trails.build) to get your API key3023. **Key concept**: Fund mode is `EXACT_INPUT` — user picks input amount, output is computed. Use placeholder for destination amount in calldata.3034. **Encode calldata**:304 ```typescript305 import { encodeFunctionData } from 'viem';306307 const vaultAbi = [308 {309 name: 'deposit',310 type: 'function',311 inputs: [312 { name: 'amount', type: 'uint256' },313 { name: 'receiver', type: 'address' },314 ],315 outputs: [],316 },317 ] as const;318319 // Use placeholder for amount (Trails fills actual value)320 const PLACEHOLDER_AMOUNT = '0xfcbc96b9628c6a4da70c90b9e80f5f4ef82922d86bd4cb54db481ae22ed79c53';321322 const calldata = encodeFunctionData({323 abi: vaultAbi,324 functionName: 'deposit',325 args: [BigInt(PLACEHOLDER_AMOUNT), userAddress],326 });327 ```3285. **Widget config**:329 ```tsx330 <TrailsWidget331 mode="fund"332 destinationChainId={42161}333 destinationTokenAddress="0xaf88d065e77c8cC2239327C5EDb3A432268e5831"334 destinationRecipient="0xYourVaultContract"335 destinationCalldata={calldata}336 />337 ```338339---340341## Quick Reference342343### Getting Your API Key (CRITICAL FIRST STEP)344345**ALWAYS check if the user has an API key BEFORE providing integration code!**346347**If no API key is found:**3483491. **Stop** and inform the user:350 ```351 ⚠️ You need a Trails API key to use this integration.352 353 Please visit: https://dashboard.trails.build354 355 Steps:356 1. Create an account (or sign in if you have one)357 2. Navigate to the API Keys section358 3. Generate a new API key359 4. Copy the key360 361 Once you have your key, add it to your .env file and let me know!362 ```3633642. **Wait for confirmation** that they have the key before proceeding.3653663. **Then show them** how to add it:367368### Environment Variables369```bash370# For client-side (Widget/Headless SDK)371NEXT_PUBLIC_TRAILS_API_KEY=your_api_key372373# For server-side (Direct API)374TRAILS_API_KEY=your_api_key375```376377**Never generate integration code without first verifying the user has or can get an API key!**378379### Token/Chain Discovery380```tsx381// Hooks382import { useSupportedChains, useSupportedTokens } from '0xtrails';383384// Functions385import { getSupportedChains, getSupportedTokens, getChainInfo } from '0xtrails';386```387388### Trade Types by Mode389| Mode | TradeType | Meaning |390|------|-----------|---------|391| Pay | EXACT_OUTPUT | User pays whatever needed to get exact destination amount |392| Fund | EXACT_INPUT | User picks input amount, destination computed |393| Swap | Both | User chooses direction |394| Earn | EXACT_INPUT (two-step) or EXACT_OUTPUT (v1.5 single-tx) | Deposit into DeFi protocols with any input token. React: Earn widget. Agent/CLI/backend: Yield API — `YieldCreateEnterAction` if the user holds the vault token, else swap-first then enter, or a v1.5 hydrate-multicall as `destinationCallData` (see `YIELD_API_RECIPES.md`). |395396---397398## Additional Resources399400See `docs/` for detailed guides:401- `TRAILS_OVERVIEW.md` — Core concepts402- `INTEGRATION_DECISION_TREE.md` — Mode selection flowchart403- `WIDGET_RECIPES.md` — Widget examples404- `HEADLESS_SDK_RECIPES.md` — Hooks patterns405- `API_RECIPES.md` — Server-side flows406- `YIELD_API_RECIPES.md` — Yield (Earn) deposits and withdrawals via the Direct API, with an external signer407- `CALLDATA_GUIDE.md` — Encoding destination calls408- `TROUBLESHOOTING.md` — Common issues