Skip to main content

Highlights

  • Trails v1.5 intent protocol is now live in production with many improvements to the intent protocol from gas savings, flexibility, 1-click gasless flows, and expanding chain routes.
  • The Trails API supports both v1 (original) and v1.5 (new) intent protocols out-of-the-box and apps using older Trails SDK versions will default to using the v1 intent protocol as before.
  • We recommend apps to upgrade to the latest 0xtrails@0.15.0 sdk to take advantage of many upgrades and the new v1.5 intent protocol.
  • Please review the upgrade / migration notes below in detail.

Upgrade / Migration Notes

This guide covers the breaking changes in SDK 0.15.0 and intent protocol v1.5, and how to update your integration.
useQuote amount units changed. from.amount and to.amount are now human-readable decimal strings (e.g. "1.5"), not raw smallest-unit values. Internally they are scaled via parseUnits using the token’s decimals. Passing a wei-style string like "1500000000000000000" will quote a vastly larger trade than intended — audit every useQuote call site before upgrading.To pass raw values, use from.amountRaw or to.amountRaw instead.

Summary checklist

1

Migrate useQuote to structured inputs

Replace flat props (fromTokenAddress, fromChainId, etc.) with from: { token, chain, amount } and to: { token, chain, recipient, ... }.
2

Update amount units

Change from.amount / to.amount in useQuote and tokenAmount / fromAmount in useTrailsSendTransaction from raw wei to human-readable decimal strings or use the raw value amount props.
3

Remove paymasterUrls if used

Delete the paymasterUrls prop from any TrailsWidget usage.
4

Rename lifecycle callbacks

Rename all onCheckout* callbacks to the new names (see table above).
5

Migrate to.calldata (if used)

Replace to.calldata on useQuote with actions (for supported protocols) or to.calls (for custom contracts).

Breaking changes

useQuote amount units changed

NOTE: useQuote hook is an optional low-level integration some developers use. If you’re using Trails with just the widget, this secton does not apply to you. If you are using useQuote please please the notes and upgrade. from.amount and to.amount are now human-readable decimal strings (e.g. "1.5"), not raw smallest-unit integers. They are scaled internally using parseUnits with the token’s decimals. Use from.amountRaw or to.amountRaw for passing raw values.
If you need to pass a raw value (bigint or string), use from.amountRaw or to.amountRaw instead of from.amount / to.amount. The same applies to useTrailsSendTransaction: tokenAmount and fromAmount are now human-readable decimal strings. Native value remains raw wei bigint (wagmi-compatible). Use tokenAmountRaw or fromAmountRaw to pass raw values. You can also pass tokenDecimals / fromDecimals overrides to skip the registry or on-chain decimal lookup.

useQuote restructured inputs

useQuote now takes structured from and to objects instead of flat props. The flat fields — fromTokenAddress, fromChainId, toTokenAddress, toChainId, toAddress, toApprove, toCalldata, swapAmount, tradeType — are all gone. Trade type is now inferred: set from.amount for exact-input, to.amount for exact-output.

useQuote to.calldata deprecated

Passing to.calldata on useQuote now logs a runtime deprecation warning and is mutually exclusive with actions and to.calls. Migrate to one of:
  • actions — composable DeFi primitives (lend, deposit, swap, etc.)
  • to.calls — raw ABI-encoded Call[] for custom contracts

paymasterUrls removed from TrailsWidget

The paymasterUrls prop has been removed from TrailsWidget. Remove it from your configuration — it has no replacement.

Widget lifecycle callback renames

All TrailsWidget checkout lifecycle callbacks were renamed. The onCheckout prefix is gone.

New features

Composable actions

useQuote gains an actions array for composing destination-side DeFi flows: All amount props for actions are in human-readable form only.
Action factories: swap, lend, deposit, custom, assertCondition
  • Use lend for lending markets (Aave), deposit for ERC-4626 vaults (Morpho, Yearn).
  • Discover marketId values with useEarnMarkets filtered by type: "lending" or type: "vault".
Runtime sentinels:
  • dynamic() — resolves to the intent wallet’s ERC-20 balance at execution time
  • self() — resolves to address(this) (the intent wallet under DELEGATECALL)
Low-level escape hatch: useQuote({ to: { calls } }) accepts raw Call[] (or Call[][]) for hand-rolled ABI-encoded transactions. Calls support dynamicAmountToken, hydrateEntries, and sweepTokens for runtime hydration and dust recovery.

New hooks


Mode-specific widget components

New typed wrappers exported from 0xtrails/widget, each with a tighter prop shape than the generic TrailsWidget:
TrailsWidget with mode="pay" | "fund" | "swap" | "earn" | "withdraw" continues to work. These wrappers are additive.

Other additions

  • intentProtocolVersion prop on TrailsWidget — pin the intent protocol version per-instance.
  • fromAmount prop on TrailsWidget — pre-populate source amount in human-readable units (e.g. "1.5").
  • fundOptions additions on TrailsWidget — new paymentMethodType field (Meld payment method pre-selection, e.g. "CREDIT_DEBIT_CARD") and meshExchangeKey field (Mesh exchange pre-selection, e.g. "coinbase").
  • Wallet-less quote preview — pass walletAddress to useQuote before a wallet is connected.
  • Auto-refresh expired quotes (widget only) — The Trails Widget now schedule a refetch when a quote’s expiresAt passes (waking on the next user interaction), so the “Intent quote has expired” pre-signing error no longer appears in the built-in UI.
  • New utilities: erc20Utils, buildCall, buildApproveAndCall, buildErc20Approve, getAmountWithSlippage, resolveChainId, resolveChainName.
  • API helpers: getEarnMarkets, getEarnBalances, getEarnProviders.
  • New error codes: CHAIN_MISMATCH, CALL_RESOLUTION_FAILED.
  • 0xtrails/hydrate subpath — Hydrate builders, selectors, and calldata helpers for v1.5 execution flows.