Skip to main content
Featured for Wallets. Recover unused balances automatically. Canonical wallet-cleanup pattern.

Scenario

A user wants to swap 80% of a USDC balance to USDT but deliberately leave the remaining 20% untouched. In compose terms this is a core.split where only one of the two output handles is bound to a downstream node — the other is left dangling. Dangling resources stay on the per-signer proxy contract at the end of execution; sweepTo tells the backend to transfer them back to the sender (or any specified address) so nothing is stranded. This recipe is the canonical shape for dust recovery — any pattern where part of an input is intentionally unused and must not be left on the proxy.

What this recipe demonstrates

  • core.split with bps: 8000 (80/20) and only one of the two output handles bound downstream.
  • Implicit dust tracking — the unbound handle (b) never becomes an input to another op; the compiler treats its balance as a terminal residual resource.
  • sweepTo: builder.context.sender returns all residual balances to the sender at the end of the transaction, including the deliberately unused 20%.
  • A minimal two-node flow: one split, one swap.

Full example

Adapted from dustSweep.ts in the composer-sdk-examples repo.

What to observe

  • Inputs. One resource input (amountIn: USDC).
  • Nodes. Two: core.split then lifi.swap. Only split.a is referenced — split.b is never consumed.
  • Dangling handle. Destructuring const { a } = builder.core.split(...) quietly drops b from the TypeScript side; on the wire, split still declares both outputs and the compiler knows b is unused.
  • Terminal resources. Two: the swapped USDT (the intentional output) and the unused USDC from split.b (the dust). Both are swept to the sender by sweepTo.
  • sweepTo shape. request.run.sweepTo === { $ref: 'context.sender' } when you pass builder.context.sender. You can also pass a literal address string, as in the swap-to-recipient recipe.
  • producedResources[<name>].simulated?.amountOut. producedResources on the ComposeCompileResult lists both the USDT (from the swap) and the residual USDC amounts.