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

# Claimable Transfers

> Send shielded funds to a wallet address that has not joined Privacy Boost yet — the recipient claims by proving ownership of the address, and the sender can reclaim an unclaimed transfer after a deadline.

# Claimable Transfers

A claimable transfer (a **gift**) lets you send shielded funds to an Ethereum
wallet address that is **not yet a registered Privacy Boost account**. You need
only the recipient's wallet address and an amount. The recipient later registers
Privacy Boost with that same address and claims the funds into a normal shielded
note; if they never claim, you reclaim the funds after a deadline you set.

Like a normal private transfer, the recipient and amount stay hidden on chain.
Unlike a normal transfer, the recipient does not have to exist on Privacy Boost
when you send.

<Warning>
  **Preview feature — pending external audit.** Claimable transfers are
  implemented across the protocol and SDKs but have not completed external
  security audit. Treat the API as stable-but-unaudited and gate production use
  on your own review. The feature is enabled per deployment; the server's
  [`/info`](/sdk/concepts/configuration) advertises gift support through its
  gift refund-delay bounds (`giftMinRefundDelayBlocks` /
  `giftMaxRefundDelayBlocks`).
</Warning>

## How it works

The protocol cannot send a spendable note to an address it has never seen — a
note is only spendable by a registered account's keys. Claimable transfers solve
this with a two-step **fund → claim** flow built around a *gift note*:

```text theme={null}
SENDER                          ON-CHAIN / NOTE TREE            RECIPIENT
  │ 1. fund a gift note bound to the recipient wallet W
  │    (ordinary private transfer; amount + recipient hidden)
  │ ────────────────────────────▶ gift note appended
  │ 2. share a claim link (optional, off-chain)  ────────────▶ 3. register PB with wallet W
  │                                                            4. discover the pending gift
  │                              claim  ◀───────────────────── 5. claim → receive a normal note
  │
  │ 6. if unclaimed past the refund deadline → refund ──────▶ funds return to sender
```

1. **Fund.** You build a gift note bound to the recipient's wallet address `W`
   and a fresh hiding factor, then fund it through an ordinary shielded transfer.
   On chain it is indistinguishable from any other transfer — the amount and the
   recipient are hidden. The SDK records the gift locally so you can always
   refund it, and (for the wallet-bound modes) returns an off-chain **claim
   link** carrying the encrypted opening.
2. **Claim.** The recipient registers Privacy Boost with the same wallet `W`,
   discovers the pending gift, and claims it. Claiming proves control of `W` with
   a zero-knowledge proof and re-mints the gift into a normal shielded note. The
   amount stays hidden.
3. **Refund.** You pick a refund deadline (a block height) at funding time. If
   the gift is still unclaimed after it, you reclaim the funds. A claim and a
   refund spend the *same* nullifier, so **exactly one of them can ever settle** —
   the recipient can't claim a refunded gift, and you can't refund a claimed one.

If the relay or TEE is unavailable, a recipient can always recover the funds
through a permissionless **public exit** (which reveals the amount, like a forced
withdrawal). Funds are self-custodial end to end: only the user's own keys plus a
valid proof move them. The TEE assists discovery and can never seize or redirect
a gift.

## Funding modes

The SDK exposes three ways to fund a gift. Pick the one that matches what you
know about the recipient.

| Mode                         | You provide                                        | When to use                                                                                                                |
| ---------------------------- | -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| **Wallet + privacy address** | recipient wallet `W` **and** their privacy address | The recipient is already a Privacy Boost user — the ciphertext is sealed to their viewing key for the smoothest discovery. |
| **Wallet only**              | recipient wallet `W`                               | The recipient has an EOA but has not joined Privacy Boost. The claim link carries everything they need.                    |
| **Secret-bearer**            | nothing but an amount                              | The recipient has no wallet at all yet. See the warning below.                                                             |

<Warning>
  **Secret-bearer mode is experimental, off by default, and a bearer
  instrument.** It binds the gift to a secret embedded in the claim link instead
  of a wallet, so **anyone who holds the link can claim the funds** — if the link
  leaks, the funds are stealable, exactly like cash or a gift card. It is gated
  on audit and product sign-off, is not exposed in the CLI, and a secret-bearer
  gift can only be claimed through the public (amount-revealing) exit. Do not use
  it in production without your own review. The wallet-bound modes above are the
  supported default.
</Warning>

## Discovering a gift

A recipient finds a pending gift in one of three ways, in increasing order of
trustlessness:

* **TEE discovery.** Behind a normal authenticated session for wallet `W`, the
  server lists the pending gifts addressed to that wallet. This is the default
  path the SDK's "list pending gifts" call uses.
* **Claim link.** The sender shares a `pbgift:v1:...` link out of band (message,
  QR code). The recipient can decode it offline to preview the gift, then claim
  directly from it — no server lookup required to read it. **Treat a claim link
  like a password:** for wallet-bound gifts the recipient still needs their own
  keys to claim, but the link reveals the amount and recipient to anyone who sees
  it.
* **Trustless recovery.** Using only the claim link's encrypted opening and
  public on-chain data, a recipient can rebuild and submit the claim with no TEE
  and no relay. This is the ultimate liveness backstop.

## Refunds and the deadline

You choose `refundAfterBlock` when you fund. It is bounded by the server (at
least a minimum delay, at most a maximum, both advertised from `/info`) so a
genuinely abandoned gift always stays recoverable but a sender cannot claw back
immediately. Anti-clawback is enforced on chain — a refund proof requires the
deadline block to have genuinely elapsed.

To refund, the SDK uses the **local gift record** it saved at funding time
(`getGiftRecords()` / `gift_refund_by_record`). Keep these records: they are what
makes an unclaimed gift refundable. They travel inside an
exported session (see your platform's session-storage guide), and a chain context can
rehydrate them with `import_gift_records`. If you lose them, you can still refund
by supplying the gift's fields manually (`gift_refund`).

## What observers and the TEE learn

| Observer learns                    | Funding       | Private claim     | Public exit               |
| ---------------------------------- | ------------- | ----------------- | ------------------------- |
| Recipient wallet `W`               | hidden        | hidden            | revealed (as destination) |
| Amount                             | hidden        | hidden            | revealed                  |
| That a settlement happened         | as a transfer | yes (one event)   | yes                       |
| Whether it was a claim or a refund | —             | indistinguishable | —                         |

A private claim and a private refund are indistinguishable on chain. The TEE
learns the recipient wallet `W` during discovery — a deliberate, narrow
privacy-scope widening versus a normal transfer — but can never move funds. A
reusable funding pattern carries the usual send-to-address correlation caveat: a
checksummed-address confirmation prompt and an optional unknown-sender warning
on claim blunt it, but funding any address is inherently address-bound.

## Using it from the SDK

The full method surface — `giftFund`, `giftFundToWallet`, `giftClaim`,
`giftClaimFromLink`, `giftRefundByRecord`, `getPendingGifts`, `decodeGiftLink`,
and the gift fields added to the transfer result — is documented per platform:

<CardGroup cols={2}>
  <Card title="TypeScript" href="/sdk/typescript/guides/claimable-transfers" />

  <Card title="CLI" href="/sdk/cli/guides/claimable-transfers" />

  <Card title="iOS" href="/sdk/ios/guides/claimable-transfers" />

  <Card title="Android" href="/sdk/android/guides/claimable-transfers" />

  <Card title="React Native" href="/sdk/react-native/guides/claimable-transfers" />

  <Card title="WASM" href="/sdk/wasm/guides/claimable-transfers" />
</CardGroup>
