Skip to content

feature: shielded gifting via Stellar claimable balances #139

Description

@tech-adrian

Problem

withdraw in contracts/pool/src/lib.rs pays out directly to a recipient address supplied and bound at proof time (recipient_hash_from_address, per docs/THREAT_MODEL.md). This means the recipient must be a specific, known Stellar address at the moment the proof is generated — there's no way to shield-then-gift value to someone who hasn't chosen (or doesn't yet have) a receiving address, or to let the sender construct the payout before the recipient is even involved.

Why it matters

"Send privately to someone who isn't onboarded yet" is a basic gifting/remittance use case competing wallets support. Today it forces a public withdraw to a known address plus an out-of-band handoff, which is exactly the amount/timing leak the shielded design exists to avoid.

Scope

  • contracts/pool/src/lib.rs: new withdraw_claimable entrypoint that, instead of a direct token::Client::transfer, creates a Stellar claimable balance (via the host's claimable-balance operations) predicated on a claim condition the recipient can satisfy later.
  • circuits/shielded_pool/src/main.nr: evaluate whether the claim predicate (e.g. a recipient's future address or a hash-preimage claim) needs to be bound into the proof the same way recipient_hash_from_address binds a direct payout today.
  • frontend/src/lib/stellar.ts: claimable-balance creation/claim helpers.
  • frontend/src/app/withdraw/page.tsx: new "gift" mode alongside direct withdraw.
  • New frontend/src/app/claim/page.tsx: recipient-side claim UX (paste a claim reference, connect a wallet, claim).
  • frontend/src/lib/notes.ts: encode/share the claim reference alongside (or instead of) a note secret when gifting.
  • Contract tests covering claim, double-claim rejection, and claimant-mismatch rejection.
  • README.md/DESIGN.md: document the gifting flow and its privacy properties relative to direct withdraw.

Acceptance criteria

  • A shielded note can be withdrawn as a claimable balance without specifying a final on-chain recipient address at proof-generation time.
  • Only the intended claimant can claim it, and a double-claim attempt is rejected by the contract.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions