Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.polygon.technology/llms.txt

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

Trails is an intent-based orchestration layer that executes cross-chain transactions automatically. Developers specify what they want delivered; Trails handles routing, bridging, swapping, and gas, regardless of what chain or token the user starts from.

How it works

Trails is built on an intent address primitive: a unique contract address computed from the full transaction parameters. When a user deposits tokens into their intent address, Trails automatically executes every step needed to deliver the result: swaps, bridges, relaying, with no further input from the user.
  1. Intent definition: specify the origin token, destination token, amount, and target chain
  2. Intent address generation: Trails computes a unique address encoding all transaction parameters
  3. User deposits: the user transfers tokens to their intent address in a single confirmation
  4. Origin execution: a relayer executes the encoded origin transaction (swaps, bridges as needed)
  5. Destination settlement: bridged funds arrive and the final transaction executes on the destination chain
  6. Receipt: Trails confirms settlement; funds reach the recipient
The user signs once. Everything else is automatic.

Widget & SDK

The Trails Widget is a drop-in React UI. Use the mode-specific components when you know the job you want the user to complete, or use the Headless SDK when you want full control over the UI.
PathPackageBest for
Mode widgets0xtrails/widgetTyped drop-in flows: Pay, Fund, Swap, Earn, Withdraw
Generic widget0xtrails/widgetExisting TrailsWidget integrations with mode="pay" | "fund" | "swap" | "earn" | "withdraw"
Headless SDK0xtrailsCustom UI with quote previews and programmatic execution
Token amounts in the widget modes and Headless SDK are human-readable decimal strings, such as "25" for 25 USDC.

Pay

Accept any token from any chain and receive a specific token on a specific chain. Users pay from their full cross-chain balance.
import { Pay } from "0xtrails/widget";

<Pay
  apiKey="YOUR_API_KEY"
  to={{
    recipient: "0xYourAddress",
    chain: "polygon",
    token: "USDC",
    amount: "25",
  }}
  buttonText="Pay $25 USDC"
  onPaymentSuccess={({ sessionId }) => {
    // verify server-side: getIntentReceipt({ intentId: sessionId })
  }}
/>

Fund

Deposit funds into any wallet or chain from any starting token. Fund mode includes built-in funding paths from a connected wallet, crypto transfer, exchange, or fiat onramp.
import { Fund } from "0xtrails/widget";

<Fund
  apiKey="YOUR_API_KEY"
  to={{
    recipient: "0xUserDepositAddress",
    chain: "polygon",
    token: "USDC",
  }}
  defaultInputMode="fiat"
  buttonText="Add funds"
/>

Swap

Exchange any token for any other token across chains. Use the Swap widget for a drop-in UI:
import { Swap } from "0xtrails/widget";

<Swap
  apiKey="YOUR_API_KEY"
  from={{ chain: "ethereum", token: "ETH", amount: "1" }}
  to={{ chain: "polygon", token: "USDC" }}
  buttonText="Swap to USDC"
  onSwapSuccess={({ sessionId }) => console.log("Swap complete:", sessionId)}
/>
Or use useQuote when you want to render the quote and button yourself:
import { useQuote } from "0xtrails";

const { send, isLoadingQuote, quoteError } = useQuote({
  from: { chain: "ethereum", token: "ETH", amount: "1" },
  to: { chain: "polygon", token: "USDC" },
  slippageTolerance: "0.005",
  onStatusUpdate: (states) => console.log("Swap status:", states),
});

if (isLoadingQuote) return <p>Loading quote...</p>;
if (quoteError) return <p>{quoteError.message}</p>;

return <button disabled={!send} onClick={() => send?.()}>Swap</button>;

Direct API

The Direct API lets you build the full intent lifecycle in server-side code, with no frontend required.

Install

pnpm install @0xtrails/api

Initialize

import { TrailsApi } from "@0xtrails/api";

const trails = new TrailsApi("YOUR_API_KEY");
API key obtained from the Trails Dashboard. All requests use X-Access-Key header. Base URL: https://trails-api.sequence.app/rpc/Trails/.

Step 1: Get a quote

const { intent, feeOptions } = await trails.quoteIntent({
  ownerAddress: "0xSenderAddress",
  originChainId: 1,
  originTokenAddress: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
  destinationChainId: 137,
  destinationTokenAddress: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
  originTokenAmount: "1000000000000000000", // 1 ETH in wei
  destinationToAddress: "0xRecipientAddress",
  tradeType: "EXACT_INPUT",
  options: {
    slippageTolerance: "0.005",
  },
});
Quotes are valid for 5 minutes.

Step 2: Commit the quote

const { intentId } = await trails.commitIntent({ intent });
Once committed, you have 10 minutes to execute.

Step 3: Execute

Transfer method: send tokens to the intent deposit address, then confirm:
const depositTxHash = await walletClient.sendTransaction({
  to: intent.depositAddress,
  value: parseEther("1"),
});

await trails.executeIntent({
  intentId,
  depositTransactionHash: depositTxHash,
});
Permit method (ERC-2612, gasless): sign two off-chain signatures instead of a transfer:
await trails.executeIntent({
  intentId,
  depositSignature: {
    feeOption: feeOptions[0],
    permitSignature: "0x...",
    intentSignature: "0x...",
    nonce: 1,
    deadline: Math.floor(Date.now() / 1000) + 300,
  },
});

Step 4: Monitor until complete

const { intentReceipt, done } = await trails.waitIntentReceipt({ intentId });

if (done && intentReceipt.status === "SUCCEEDED") {
  console.log("Settled:", intentReceipt.transactionHash);
}
Poll getIntentReceipt for non-blocking status checks. Terminal states: SUCCEEDED, FAILED.

Supported chains and tokens

Trails supports all EVM-compatible chains. To query available tokens and supported networks:
const { tokens } = await trails.getTokenList({ chainId: 137 });
const prices = await trails.getTokenPrices({ tokenAddresses: ["0x3c499c..."] });
See Supported Chains for the full network list.

Get started

Trails quickstart

Integrate the Widget, Headless SDK, or Direct API in minutes.

API reference

Full endpoint reference, request/response schemas, and error codes.