How it works

The swipe

A card authorization that sells shielded STRK, pays a merchant in USDC and records the settlement - as one transaction, so no intermediate state is ever exposed.

The naive version of this is three steps: withdraw from the pool, swap, then pay. Every one of those steps publishes something, and between them your value sits in the open. Sealed does it in a single privacy_invoke, so there is no in-between to observe and no leg that can succeed while another fails.

What happens in that one transaction

  1. The authorization arrives

    An issuer webhook posts the authorization. It is HMAC-signed; a tampered signature is rejected with 401 before anything touches a chain. This is a Lithic sandbox issuer, not a production card network.

  2. Policy decides, before money moves

    The CardProgram contract holds the per-swipe cap, the daily cap and the blocked categories. A blocked merchant is refused here and never reaches settlement. The daily spend counter is read back from the contract after the transaction, not tracked in the server's memory.

  3. The pool withdraws exactly what the swipe costs

    One withdrawal covers the merchant payment plus anything else the same invoke is doing. The amount that leaves is the amount needed, not a rounded-up float.

  4. The converter sells STRK for USDC just in time

    The JIT converter holds calldata quoted live from Ekubo and routed through a pinned AVNU router. It converts only at settlement, so no idle USDC balance sits around advertising what you are about to spend.

  5. The merchant is paid, the change re-shields

    Payment out, change back into the pool, one atomic step. The receipt carries AuthorizationSettled, and the replay map plus the daily spend total are readable on chain afterwards.

Why repeat swipes do not chain

Paying the same merchant twice from the same identity links those two payments to each other, whatever else is hidden. The shadow-account anonymizer derives a per-merchant identity so two visits do not share an address. Identities are deterministic per nonce, so the app can find them again without storing a map.

What the merchant and the chain each see

PartySeesDoes not see
The merchantA card number and an amount in USDCYour balance, your other activity, your Starknet address
A chain observerThat the pool was touched and a USDC payment was madeWhich notes were spent, or what remains
The hosted account operatorEvery swipe it settles, in fullNothing about your self-custody wallet notes

The third row is the one people skip. It has its own page.

What the tests actually hold

  • A tampered HMAC returns 401, so a forged authorization cannot settle.
  • A policy-blocked merchant does not settle, verified against the deployed contract.
  • A repeated authorization id returns confirmed and does not settle twice - replay protection lives in the contract's own map, not in a server-side set.
  • The settlement event parser is held by a mutation test: reading keys[1] instead of keys[0] turns it red. A parser test that passes either way proves nothing, so this one was checked by breaking it.