Skip to main content
Cross-chain payments use a separate API key from the OMS Payments API. Get yours from the Trails Dashboard while the two systems share authentication.
The SDK is a React component library that handles funding flows, cross-chain routing, and fiat on-ramps. You drop in a component; the SDK handles routing, execution, and state.

Install

npm install 0xtrails
React 18 or later is required. React 19.1+ is recommended for best compatibility.

Drop in a component

The Fund component opens a payment widget that accepts card, bank, exchange, and wallet funding. Import it directly and pass the destination plus an optional callback. There is no provider to set up.
FundButton.tsx
import { Fund } from "0xtrails";

export function FundButton() {
  return (
    <Fund
      apiKey="YOUR_API_KEY"
      to={{
        recipient: "0xYOUR_PRODUCT_WALLET",
        token: "USDC",
        chain: "polygon",
      }}
      onFundingSuccess={(result) => {
        console.log("Funded:", result);
      }}
    />
  );
}
The widget renders inline or as a modal depending on your layout. See Configuration for the full props reference.

Fund directly into a product action

Pass to.calldata to encode a destination action that executes automatically when funds arrive. A customer can fund from a debit card and deposit into a yield vault in one step. Use dynamic() in the encoded args wherever the arrived amount should appear:
VaultFundButton.tsx
import { Fund, dynamic } from "0xtrails";
import { encodeFunctionData } from "viem";

const calldata = encodeFunctionData({
  abi: VAULT_ABI,
  functionName: "deposit",
  args: [dynamic(), "0xCUSTOMER_ADDRESS"],
});

export function VaultFundButton() {
  return (
    <Fund
      apiKey="YOUR_API_KEY"
      to={{
        recipient: "0xYOUR_VAULT_CONTRACT",
        token: "USDC",
        chain: "polygon",
        calldata,
      }}
      onFundingSuccess={(result) => {
        console.log("Deposited:", result);
      }}
    />
  );
}
See Dynamic values for how dynamic() resolves at execution time.

Non-React sites

For pages without React, load the widget via CDN:
<div id="trails-widget"></div>
<script src="https://cdn.trails.build/widget.js"></script>
<script>
  TrailsWidget.init({
    containerId: "trails-widget",
    accessKey: "YOUR_ACCESS_KEY",
    mode: "fund",
    destinationChainId: 137,
    destinationTokenAddress: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
    destinationToAddress: "0xYOUR_PRODUCT_WALLET",
  });
</script>
For direct server-side control without a UI layer, use the direct API instead.