> ## Documentation Index
> Fetch the complete documentation index at: https://docs.li.fi/llms.txt
> Use this file to discover all available pages before exploring further.

# Swap and Deposit

> Swap WETH to USDC, then zap the USDC into an Aave lending position in a single flow.

## Scenario

某用户持有 WETH，希望在 Ethereum 主网上获得带收益的 Aave USDC（`aEthUSDC`）。这需要两个操作：一次将 WETH 转换为 USDC 的交换，以及一次将该 USDC 存入 Aave 的 zap。compose 栈将其表达为一个双节点 `Flow`，其中交换的 `amountOut` 句柄被直接接入 zap 的 `amountIn` 绑定，无需手动记账，也无需中间转移。

这个 recipe 是**链式 swap → zap** flow 的标准结构：先由路由提供方执行交换，再执行协议专属的 zap，两者都由后端降级（lower）为 VM 指令。

## What this recipe demonstrates

* 将某个 op 的类型化输出句柄接入下游 op 的输入（`swapOutputs.amountOut` → `zap.amountIn`）。
* 运行不带滑点 guard 的 `lifi.swap`（该交换的 `amountOut` port 携带 `providesMinimum`，因此滑点由提供方强制执行）。
* 在 `lifi.zap` 输出上附加一个 `slippage` guard（参见 [guards 概念页](/composer/composer-api/concepts/simulation-and-guards)）。
* 使用 `materialisers.directDeposit` 以固定金额为 flow 提供资金，并使用 `sweepTo: builder.context.sender` 返还任何残余代币。

## Full example

改编自 `composer-sdk-examples` 仓库中的 [`swapAndZap.ts`](https://github.com/lifinance/composer-sdk-examples/blob/main/examples/swapAndZap.ts)。

```ts theme={"system"}
import {
  createComposeSdk,
  guards,
  materialisers,
  resources,
} from '@lifi/composer-sdk';

const WETH = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2';
const USDC = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48';
// Aave aEthUSDC receipt token on Ethereum mainnet
const A_ETH_USDC = '0x98C23E9d8f34FEFb1B7BD6a91B7FF122F4e16F5c';

const sdk = createComposeSdk({
  baseUrl: 'https://composer.li.quest',
  apiKey: process.env.LIFI_API_KEY,
});

// Declare the flow with a single WETH input on Ethereum mainnet.
const builder = sdk.flow(1, {
  name: 'swap-and-zap-weth-to-aave',
  inputs: {
    amountIn: resources.erc20(WETH, 1),
  },
});

// Swap WETH → USDC via LI.FI.
const swapOutputs = builder.lifi.swap('swap', {
  bind: { amountIn: builder.inputs.amountIn },
  config: {
    resourceOut: resources.erc20(USDC, 1),
    slippage: 0.03,
  },
});

// Zap the swapped USDC into Aave's aEthUSDC position via LI.FI.
// The swap's amountOut handle is threaded directly into the zap's amountIn.
// See /composer/composer-api/concepts/ref-grammar for how handles translate to refs.
builder.lifi.zap('zap', {
  bind: { amountIn: swapOutputs.amountOut },
  config: {
    resourceOut: resources.erc20(A_ETH_USDC, 1),
  },
  guards: [guards.slippage({ port: 'amountOut', bps: 100 })],
});

const result = await builder.compile({
  signer: '0xYourSignerAddress',
  inputs: {
    amountIn: materialisers.directDeposit({
      amount: '1000000000000000000', // 1 WETH (18 decimals)
    }),
  },
  sweepTo: builder.context.sender,
});
```

## What to observe

* **Inputs.** 一个资源输入（`amountIn: WETH`）。`directDeposit` materialiser 精确地将 `10^18` wei（1 WETH）转入 VM；不执行任何余额读取。
* **Nodes.** 恰好两个：`flow.nodes[0].op === 'lifi.swap'`，`flow.nodes[1].op === 'lifi.zap'`。
* **Handle threading.** zap 的 `bind.amountIn` 是引用 `swap.amountOut`，没有中间资源或转移。
* **Guards.** 只有 zap 携带滑点 guard（`port: 'amountOut'`，`bps: 100`，即 1%）。交换没有 guard，因为其 `amountOut` port 已经提供了一个最小值。
* **Terminal resource.** zap 产生的 Aave `aEthUSDC` 是终端资源，并被清扫给发送方。
* **`producedResources[<name>].simulated?.amountOut`.** 在 `ComposeCompileResult` 上，`producedResources` 包含该 zap 的输出，其模拟得到的 `aEthUSDC` 金额位于 `.simulated?.amountOut`。
