> ## Documentation Index
> Fetch the complete documentation index at: https://anypay-docs-update-resources-2026-06-29.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Fund

> Trails supports depositing funds directly into your protocol, exchange, app, or chain with any token from any chain or via fiat onramps.

## Fund with Trails

Traditional funding flows require users to find an external bridge, swap to the required deposit token, pay multiple gas fees across networks, and navigate complex UIs.

Trails handles all of that in a single transaction. Users can deposit from any token they hold on any supported chain — or use a fiat onramp, exchange transfer, or QR code — all in one embedded experience.

## Use cases

Funding flows are exact-input by default. The user selects how much to send; the destination receives the resulting amount after routing.

* Transfer funds into a perpetual exchange
* Bootstrap liquidity in a lending protocol vault
* Onboard users to a new chain
* Top up a prediction market or gaming app account
* Deposit into staking contracts

## Examples

### Deposit USDC to Polygon

```tsx theme={null}
import { Fund } from '0xtrails/widget'

export const BaseDeposit = () => {
  return (
    <Fund
      apiKey="YOUR_API_KEY"
      to={{
        recipient: "0x...",
        currency: "USDC",
        chain: "polygon",
      }}
      onFundingSuccess={({ sessionId }) => {
        console.log('Deposit completed:', sessionId)
      }}
    />
  )
}
```

### Depositing into a lending protocol

For protocols like Aave that are natively supported, use the `lend` composable action. This handles approval, the supply call, and dynamic amount resolution without encoding any calldata by hand:

```tsx theme={null}
import { useTrailsSendTransaction, lend, erc20Utils } from '0xtrails'

export function AaveLendButton({ recipient }: { recipient: `0x${string}` }) {
  const { sendTransaction, isPending } = useTrailsSendTransaction({
    actions: [
      lend({
        marketId: 'base-usdc-aave-v3-lending',
        amount: '100',
      }),
    ],
  })

  return (
    <button
      disabled={isPending}
      onClick={() =>
        sendTransaction({
          to: recipient,
          tokenAddress: erc20Utils.USDC.addressOn('base'),
          tokenAmount: '100', // human-readable USDC amount
        })
      }
    >
      {isPending ? 'Sending...' : 'Supply 100 USDC to Aave'}
    </button>
  )
}
```

Use `useEarnMarkets` to discover available market IDs. See [Markets and Providers](/sdk/composable-actions/markets-and-providers).

### Depositing into a vault

For ERC-4626 and vault-style protocols (Morpho, Yearn, SummerFi), use the `deposit` composable action:

```tsx theme={null}
import { useTrailsSendTransaction, deposit, erc20Utils } from '0xtrails'

export function YearnDepositButton({ recipient }: { recipient: `0x${string}` }) {
  const { sendTransaction, isPending } = useTrailsSendTransaction({
    actions: [
      deposit({
        marketId: 'katana-usdc-yearn-v3-vault',
        amount: '100',
      }),
    ],
  })

  return (
    <button
      disabled={isPending}
      onClick={() =>
        sendTransaction({
          to: recipient,
          tokenAddress: erc20Utils.USDC.addressOn('katana'),
          tokenAmount: '100',
        })
      }
    >
      {isPending ? 'Sending...' : 'Deposit 100 USDC to Yearn'}
    </button>
  )
}
```

### Depositing into a custom contract

For protocols not covered by composable actions, use `TRAILS_ROUTER_PLACEHOLDER_AMOUNT` in `to.calldata`:

<CodeGroup>
  ```tsx CustomVaultDeposit.tsx theme={null}
  import { Fund } from '0xtrails/widget'
  import { TRAILS_ROUTER_PLACEHOLDER_AMOUNT } from '0xtrails'
  import { encodeFunctionData } from 'viem'
  import { customVaultABI } from './abi.ts'

  export const CustomVaultDeposit = () => {
    const VAULT_CONTRACT = "0x..."

    const depositCalldata = encodeFunctionData({
      abi: customVaultABI,
      functionName: 'deposit',
      args: [
        TRAILS_ROUTER_PLACEHOLDER_AMOUNT, // replaced with actual output at execution
        "0x...",                          // receiver address
      ],
    })

    return (
      <Fund
        apiKey="YOUR_API_KEY"
        to={{
          recipient: VAULT_CONTRACT,
          currency: "USDC",
          chain: "katana",
          calldata: depositCalldata,
        }}
        onFundingSuccess={({ sessionId }) => {
          console.log('Vault deposit completed:', sessionId)
        }}
      />
    )
  }
  ```

  ```typescript abi.ts theme={null}
  export const customVaultABI = [
    {
      type: "function",
      name: "deposit",
      stateMutability: "nonpayable",
      inputs: [
        { name: "amount", type: "uint256" },
        { name: "receiver", type: "address" },
      ],
      outputs: [{ name: "shares", type: "uint256" }],
    },
  ] as const
  ```
</CodeGroup>

### Trustless deposit address via API (quote → commit → execute)

Create a deposit address flow server-side using the Trails API directly:

<CodeGroup>
  ```ts DepositAddressFlow.ts theme={null}
  const quoteResponse = await fetch('https://trails-api.sequence.app/rpc/Trails/QuoteIntent', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Access-Key': 'YOUR_ACCESS_KEY',
    },
    body: JSON.stringify({
      ownerAddress: userWallet,
      originChainId: 137,
      originTokenAddress: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174',
      destinationChainId: 8453,
      destinationTokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
      destinationToAddress: appCreditAddress,
      destinationTokenAmount: '50000000', // 50 USDC (6 decimals)
      tradeType: 'EXACT_OUTPUT',
    }),
  })

  const { intent } = await quoteResponse.json()
  const intentAddress = intent.depositTransaction.toAddress

  const commitResponse = await fetch('https://trails-api.sequence.app/rpc/Trails/CommitIntent', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Access-Key': 'YOUR_ACCESS_KEY',
    },
    body: JSON.stringify({ intent }),
  })

  const { intentId } = await commitResponse.json()

  // Ask the user to deposit to the intent address, then execute
  const executeResponse = await fetch('https://trails-api.sequence.app/rpc/Trails/ExecuteIntent', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Access-Key': 'YOUR_ACCESS_KEY',
    },
    body: JSON.stringify({
      intentId,
      depositTransactionHash: userDepositTxHash,
    }),
  })
  ```
</CodeGroup>

<Note>
  Quotes expire after **10 minutes**.
</Note>

## Next steps

* [**Composable actions**](/use-cases/composable-actions) — programmatic DeFi deposits using `lend`, `deposit`, and `swap`
* [**Fund mode configuration**](/sdk/modes/fund) — complete configuration options
* [**SDK configuration**](/sdk/configuration) — widget setup and event handling
* [**Theming**](/sdk/theming) — customize appearance
* [**Hooks reference**](/sdk/hooks) — programmatic control
