> ## 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.

# Cross-Chain Money Actions

> Execute a swap, bridge, and protocol interaction as a single atomic transaction across any chain.

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 typed destination actions from the intent wallet
              → User lands in the desired protocol state
```

Composable actions describe the destination steps with typed builders such as `deposit`, `lend`, `swap`, and `assertCondition`. Amounts are human-readable decimal strings, so `"100"` means 100 USDC when the selected token is USDC.

## Composing actions

The example below routes funds to Polygon USDC, lends 10 USDC into an Aave USDC market, swaps the remaining USDC to USDT, then deposits the USDT into a Morpho vault. Use `useEarnMarkets` to discover live `marketId` values for Morpho, Aave, and other supported earn providers.

```tsx theme={null}
import { useQuote, dynamic, lend, swap, deposit } from "0xtrails";

const aaveUsdcMarketId = "polygon-usdc-aave-v3-lending";
const morphoUsdtVaultId = "polygon-usdt-bbqusdt0-0xb7c9988d3922f25a336a469f3bb26ca61fe79e24-4626-vault";

export function ComposedYieldButton() {

  const userWalletAddress = "0x..."

  const { send, isLoadingQuote, quoteError } = useQuote({
    from: { chain: "base", token: "USDC", amount: "100" },
    to: { chain: "polygon", token: "USDC" },
    actions: [
      lend({
        marketId: aaveUsdcMarketId,
        amount: "10"
      }),
      swap({
        tokenIn: "USDC",
        tokenOut: "USDT",
        amountIn: dynamic(),
        fee: "0.3",
      }),
      deposit({
        marketId: morphoUsdtVaultId,
        amount: dynamic()
      }),
    ],
    onStatusUpdate: (states) => console.log("Intent status:", states),
  });

  if (isLoadingQuote) return <button disabled>Preparing...</button>;
  if (quoteError) return <p>{quoteError.message}</p>;

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

The user can start on Base, Ethereum, Arbitrum, or another supported chain. Trails handles any required bridge or swap before running the destination actions.

## What you can compose

Use typed builders for common money actions:

| Action               | Builder                                 | Notes                                                      |
| -------------------- | --------------------------------------- | ---------------------------------------------------------- |
| Yield vault deposit  | `deposit({ marketId, amount })`         | ERC-4626-style vaults such as Morpho                       |
| Lending supply       | `lend({ marketId, amount })`            | Lending markets such as Aave                               |
| Destination swap     | `swap({ tokenIn, tokenOut, amountIn })` | On-chain swap after funds arrive                           |
| Safety check         | `assertCondition({ erc20Balance })`     | Reverts the whole destination batch if the condition fails |
| Custom contract call | `custom(...)` or `to.calls`             | Escape hatch for unsupported protocols                     |

Use `dynamic()` when a later action should consume whatever amount is available at execution time:

```tsx theme={null}
import { useQuote, dynamic, swap, lend } from "0xtrails";

const { send } = useQuote({
  from: { chain: "arbitrum", token: "USDC", amount: "100" },
  to: { chain: "polygon", token: "USDC" },
  actions: [
    swap({
      tokenIn: "USDC",
      tokenOut: "USDT",
      amountIn: dynamic(),
      fee: "0.3",
    }),
    lend({
      marketId: "polygon-usdt-aave-v3-lending",
      amount: dynamic(),
    }),
  ],
});
```

## Widget integration

For built-in earn flows, use the `Earn` mode widget. It gives users a ready-made UI for depositing into supported earn markets:

```tsx theme={null}
import { Earn } from "0xtrails/widget";

<Earn
  apiKey="YOUR_API_KEY"
  to={{
    chain: "polygon",
    token: "USDC",
    amount: "100",
  }}
  buttonText="Start earning"
  onEarnSuccess={({ sessionId }) => updateUserState(sessionId)}
/>
```

For a custom protocol sequence, use `useQuote({ actions })` as shown above so your app controls the exact destination actions.

## 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.

<Card title="Offer yield accounts to your users" icon="piggy-bank" href="/wallets/morpho-vault-deposit#how-it-works">
  Step-by-step guide: wallet setup, Morpho vault deposit with composable actions, and withdraw flow.
</Card>

## Next steps

<CardGroup cols={2}>
  <Card title="Fund from Anywhere" icon="wallet" href="/trails/fund">
    Let users fund your protocol from any token, chain, credit card, or bank account.
  </Card>

  <Card title="Smart Sessions" icon="bolt" href="/wallets/smart-sessions">
    Automate recurring actions without per-transaction prompts.
  </Card>

  <Card title="Trails API reference" icon="code" href="https://docs.trails.build/api-reference/introduction">
    Full endpoint reference for QuoteIntent, CommitIntent, and ExecuteIntent.
  </Card>
</CardGroup>
