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

# Dust sweep

> 将 USDC 按 80/20 拆分，仅交换较大的部分，并将未使用的余额扫回给发送方。

<Tip>
  **为钱包精选。** 自动回收未使用的余额。典型的钱包清理模式。
</Tip>

## 场景

一位用户想将 USDC 余额的 80% 交换为 USDT，但有意保留剩下的 20% 不动。用 compose 术语来说，这就是一个 `core.split`，其中两个输出句柄只有一个被绑定到下游节点 —— 另一个则被悬空。悬空的资源在执行结束时会留在每签名者的代理合约上；`sweepTo` 告诉后端将它们转回给发送方（或任何指定地址），这样就不会有任何东西被搁置。

本配方是 **dust 回收**的典型形态 —— 任何一种输入的一部分被有意不使用、且不能留在代理上的模式。

## 本配方演示了什么

* 带 `bps: 8000`（80/20）的 `core.split`，且两个输出句柄只有一个被绑定到下游。
* 隐式 dust 跟踪 —— 未绑定的句柄（`b`）从未成为另一个 op 的输入；编译器将其余额视为一个终端残余资源。
* `sweepTo: builder.context.sender` 在交易结束时将**所有**残余余额返还给发送方，包括那有意未使用的 20%。
* 一个极简的双节点 flow：一次拆分，一次交换。

## 完整示例

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

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

const USDC = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48';
const USDT = '0xdAC17F958D2ee523a2206206994597C13D831ec7';

const sdk = createComposeSdk({ baseUrl: 'https://composer.li.quest' });

const builder = sdk.flow(1, {
  name: 'dust-sweep',
  inputs: {
    amountIn: resources.erc20(USDC, 1),
  },
});

// Split USDC 80/20.
// Only the 80% portion (`a`) is consumed by the swap.
// The 20% portion (`b`) is intentionally left unbound — it stays on
// the proxy as dust and gets swept back to the sender.
const { a } = builder.core.split('split', {
  bind: { source: builder.inputs.amountIn },
  config: { bps: 8000 },
});

// Swap only the 80% portion to USDT.
builder.lifi.swap('swap', {
  bind: { amountIn: a },
  config: {
    resourceOut: resources.erc20(USDT, 1),
    slippage: 0.03,
  },
});

// sweepTo ensures the unused 20% USDC is transferred back to the
// sender rather than being stranded on the proxy.
// See /composer/composer-api/concepts/sweeping-and-amounts for the full semantics.
const result = await builder.compile({
  signer: '0xYourSignerAddress',
  inputs: {
    amountIn: materialisers.directDeposit({ amount: '10000000' }), // 10 USDC
  },
  sweepTo: builder.context.sender,
});
```

## 需要留意什么

* **Inputs。** 一个资源输入（`amountIn: USDC`）。
* **Nodes。** 两个：先 `core.split` 再 `lifi.swap`。只有 `split.a` 被引用 —— `split.b` 从未被消费。
* **悬空句柄。** 解构 `const { a } = builder.core.split(...)` 会在 TypeScript 一侧悄悄丢弃 `b`；在线上，`split` 仍然声明两个输出，且编译器知道 `b` 未被使用。
* **终端资源。** 两个：被交换出的 USDT（有意的输出）**以及**来自 `split.b` 的未使用 USDC（dust）。两者都被 `sweepTo` 扫走给发送方。
* **`sweepTo` 形态。** 当你传入 `builder.context.sender` 时，`request.run.sweepTo === { $ref: 'context.sender' }`。你也可以传入一个字面地址字符串，就像 `swap-to-recipient` 配方那样。
* **`producedResources[<name>].simulated?.amountOut`。** `ComposeCompileResult` 上的 `producedResources` 会同时列出 USDT（来自交换）和残余 USDC 的金额。
