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

# Retrieving funds (recipient side)

> How recipients detect, claim, and sweep funds delivered to their stealth addresses.

<Warning>
  **The TypeScript SDK is WIP.** Today, this flow is wired through three relayer endpoints: [`GET /recipient/addresses`](/api/relayer), [`POST /recipient/derive-stealth-key`](/api/relayer), and [`POST /recipient/relay-proxy`](/api/relayer) (gasless sweep via the deployed Safe). Funds at a stealth address are owned by a Safe; the recipient signs a Safe tx hash with the stealth key and the relayer broadcasts.
</Warning>

When an intent settles, funds land at a fresh stealth address on the destination chain (and a Safe at that address holds them). The recipient detects it, derives the stealth key, signs a Safe tx, and the relayer broadcasts gas-paid. This page covers how to wire that into your app.

## Detect incoming intents

Using the recipient's viewing key, list intents addressed to them:

```ts theme={null}
const incoming = await tachyon.recipient.listIncoming();
// [{ intentId, sourceAsset, destAsset, amount, settledAt, stealthAddress, ... }, ...]
```

The result includes both intents that have been swept and those that haven't. Filter as needed:

```ts theme={null}
const unswept = incoming.filter((i) => i.swept === false);
```

## Sweep a single intent (gasless)

```ts theme={null}
const txHash = await tachyon.recipient.sweep(intentId);
```

Under the hood this calls [`POST /recipient/relay-proxy`](/api/relayer), the recipient signs a Safe transaction with their derived stealth key, and the relayer broadcasts and pays gas. The recipient does **not** need native gas on the destination chain to sweep.

## Auto-sweep on detection

Most integrators want to sweep on detection. The SDK exposes a long-lived listener:

```ts theme={null}
tachyon.recipient.subscribe(async (intent) => {
  await tachyon.recipient.sweep(intent.intentId);
  ui.notify(`Received ${formatAmount(intent.amount, intent.destAsset)}`);
});
```

This runs as long as your app is open. For server-side persistence, use a polling job:

```ts theme={null}
setInterval(async () => {
  const incoming = await tachyon.recipient.listIncoming({ unsweptOnly: true });
  for (const intent of incoming) {
    await tachyon.recipient.sweep(intent.intentId);
  }
}, 30_000);
```

## Sweep behavior

* **Sweep target**: wherever the recipient's Safe transaction sends, typically their main wallet on the destination chain.
* **Asset**: the destination asset of the intent (`tokenOut`).
* **Privacy on the sweep**: the sweep transaction is a normal on-chain transfer. Observers see it. The link from sender to recipient is still hidden, they only see the stealth-address Safe sending to the recipient's destination.
* **Gas**: paid by the relayer when you use [`POST /recipient/relay-proxy`](/api/relayer). The recipient does not need native gas on the destination chain for a relay-proxy sweep.

## What if the recipient isn't using a Tachyon-aware app?

The funds are still under the recipient's control, the stealth key is derived from their viewing/spending keys, and the Safe at that stealth address holds the funds. Without an SDK-aware app, they won't auto-sweep, but they can:

* Open any Tachyon-compatible wallet, register via [`POST /recipient/register`](/api/relayer) with their EOA, and list stealth balances via [`GET /recipient/addresses`](/api/relayer)
* Derive the stealth key ([`POST /recipient/derive-stealth-key`](/api/relayer)) and broadcast a Safe transaction themselves (or via [`POST /recipient/relay-proxy`](/api/relayer) for gasless broadcast)

There is no separate hosted "claim" URL, the recipient dashboard at [testnet.app.tachyon.pe](https://testnet.app.tachyon.pe) surfaces incoming stealth balances and offers a one-click sweep.

## Handling failed sweeps

If a sweep transaction reverts (e.g., out of gas), the funds stay at the stealth address. Retry with more gas:

```ts theme={null}
try {
  await tachyon.recipient.sweep(intentId);
} catch (err) {
  // Relay-proxy sweeps can fail if the Safe tx reverts on destination chain.
  // The funds stay safe at the stealth Safe, retry or investigate the target call.
  console.error("sweep failed:", err.code, err.message);
}
```

<Card title="Error reference" icon="circle-exclamation" href="/reference/errors">
  Full list of SDK error codes.
</Card>
