Skip to main content
Trails lets you compose multiple onchain operations: bridge, swap, deposit, stake, or any contract call, into a single user-facing transaction. The user approves once. Trails handles routing, execution, and gas across every step. This is the foundation for any flow where funds need to move and land in a specific protocol state: a yield vault, a liquidity position, a staking contract, a cross-chain swap. The source chain, token, and amount are flexible. The destination action is whatever your protocol requires.

How it works

User approves once
  → Trails quotes the full route
      → Funds bridge and swap to the destination chain and token
          → Trails executes your encoded contract call with the exact arrived amount
              → User lands in the desired protocol state
TRAILS_ROUTER_PLACEHOLDER_AMOUNT stands in for the arrived amount in your calldata. Trails substitutes the real figure at execution time, so slippage and bridge variance are absorbed automatically.

Encoding a composable action

Pass destinationCalldata with the encoded function call for whatever action you want executed on arrival. The example below deposits into an ERC-4626 yield vault, but the same pattern works for any protocol:
import { encodeFunctionData } from "viem";
import { TRAILS_ROUTER_PLACEHOLDER_AMOUNT } from "0xtrails";

const depositCalldata = encodeFunctionData({
  abi: [{
    type: "function",
    name: "deposit",
    inputs: [
      { name: "assets", type: "uint256" },
      { name: "receiver", type: "address" },
    ],
    outputs: [{ name: "shares", type: "uint256" }],
  }],
  functionName: "deposit",
  args: [TRAILS_ROUTER_PLACEHOLDER_AMOUNT, "0xUserAddress"],
});

const response = await fetch("https://trails-api.sequence.app/rpc/Trails/QuoteIntent", {
  method: "POST",
  headers: { "Content-Type": "application/json", "X-Access-Key": "YOUR_API_KEY" },
  body: JSON.stringify({
    ownerAddress: "0xUserAddress",
    originChainId: 1,            // any supported chain
    originTokenAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // any token
    destinationChainId: 137,
    destinationTokenAddress: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359", // USDC on Polygon
    destinationToAddress: "0xYourProtocolAddress",
    destinationTokenAmount: "100000000", // 100 USDC (6 decimals)
    destinationCalldata: depositCalldata,
    tradeType: "EXACT_OUTPUT",
  }),
});

const { intent } = await response.json();
The user can be on Ethereum mainnet holding ETH, USDT, or any supported token. Trails bridges to Polygon, swaps to USDC, and executes the deposit in one flow.

What you can compose

Any protocol interaction that takes a token amount as input works with this pattern:
ActionABI functionNotes
Yield vault depositdeposit(uint256 assets, address receiver)ERC-4626 standard
Liquidity provisionaddLiquidity(...)AMM-specific ABI
Stakingstake(uint256 amount)Protocol-specific
Lending supplysupply(address asset, uint256 amount, ...)Aave-style
Custom contract callAny payable functionEncode via encodeFunctionData

Widget integration

For drop-in UI, pass toCalldata to the Trails Widget. The widget handles the full funding and action flow:
import { TrailsWidget } from "0xtrails/widget";

<TrailsWidget
  apiKey="YOUR_API_KEY"
  mode="fund"
  toAddress="0xYourProtocolAddress"
  toChainId={137}
  toToken="USDC"
  toCalldata={depositCalldata}
  onCheckoutComplete={({ sessionId }) => updateUserState(sessionId)}
>
  <button>Deposit</button>
</TrailsWidget>

Example: yield accounts

One common use of composable actions is offering savings accounts in a fintech or neobank app. Users deposit USDC into a yield vault. The entire flow (bridge, swap, deposit) happens in a single tap, with no gas, no wallet management, and no protocol knowledge required from the user.

Offer yield accounts to your users

Step-by-step guide: wallet setup, Morpho vault deposit, permit signing, and withdraw flow.

Next steps

Fund from Anywhere

Let users fund your protocol from any token, chain, credit card, or bank account.

Smart Sessions

Automate recurring actions without per-transaction prompts.

Trails API reference

Full endpoint reference for QuoteIntent, CommitIntent, and ExecuteIntent.