Skip to main content
Private Send lets your users transfer funds from their non-custodial wallet without exposing the link between their wallet and the public delivery transaction. The privacy option is opt-in per transaction. Users choose to enable it on a specific send and keep custody of their funds throughout: keys never leave the wallet, and every transaction is signed by the user. What is hidden depends on the privacy mode. Sender privacy is always provided; recipient and amount visibility depend on whether the user picks sender-private or fully-shielded. See Privacy modes for the per-mode breakdown.

How it works

A Private Send moves funds in two on-chain steps separated by a shielded pool. The wallet first deposits the user’s funds into the pool; the privacy layer then withdraws to the recipient from the pool. The deposit and the withdrawal are not publicly linked. When the user enables privacy on a send and chooses a token, amount, and recipient, the wallet requests a prepared order from the privacy enclave. The enclave returns a signed order that includes the privacy fee and the deposit calldata. The wallet verifies the response signature, the request nonce, the deposit destination against an allowlist of known privacy-layer contracts, and reconciles the amount before asking the user to sign. For ERC-20 tokens, the user signs an approval transaction before the deposit. Native-token sends skip this step. The user then signs the deposit, which moves the funds from their wallet into the shielded pool. Inside the pool the funds are represented as private notes; the deposit and the later withdrawal are not publicly linked. The privacy layer then issues a private withdrawal that delivers the funds to the recipient. The amount debited from the user’s wallet equals the requested send amount plus the privacy fee. The fee is disclosed before the user confirms. The send lifecycle includes an explicit verification gate before the deposit. If any verification step fails, Private Send is disabled for that transaction and the wallet falls back to the normal transfer path.

Privacy modes

The wallet exposes two modes. Both break the link between the sender’s wallet and the public delivery; they differ in whether the recipient and amount are also shielded. Sender-private. The default mode described in How it works. The sender’s wallet is unlinkable from the delivery transaction. The recipient address and amount remain visible on the delivering transaction. Fully-shielded transfers. The recipient receives funds at a one-time stealth address derived from their viewing key, and the delivering transaction does not expose the final recipient or the amount. The only divergence from the sender-private flow is the final delivery leg: the private withdrawal targets a stealth address rather than a plain recipient address. Anonymity-set considerations are stronger in this mode because no recipient or amount metadata is exposed on chain.

What is and isn’t private

PropertySender-privateFully-shielded
Link from sender wallet to deliveryBroken (shielded)Broken (shielded)
Recipient addressVisible on deliveryShielded (stealth address)
AmountVisible on deliveryShielded
User custody of fundsRetainedRetained
Anonymity setGrows with pool usageGrows with pool usage
Unlinkability strengthens as more transactions flow through the shielded pool: a larger anonymity set makes statistical linkage harder.

Security and verification model

Private Send’s integrity rests on a layered trust chain. Four cryptographic layers establish what code is running, that it is the code we reviewed, and that requests and responses are bound to that code. Two client-side controls layer defense in depth on top. Enclave attestation establishes what code is running. The privacy provider’s API runs inside a hardware-backed Trusted Execution Environment (TEE). The enclave exposes an attestation endpoint that returns a token signed by the cloud provider’s Confidential Computing attestation service. The token cryptographically commits to the exact container image digest running in the enclave: any change to the server code changes the digest and invalidates the attestation. The wallet requests this token with a fresh nonce, so the attestation cannot be replayed. Source-to-digest provenance establishes that the running code is the code we reviewed. The enclave’s source is published, and every production build is signed via a transparency-log-backed supply-chain attestation (Sigstore and cosign, with a Rekor transparency-log entry per build). Our backend independently verifies that the attested image digest was built from the published source by the expected CI pipeline, and maintains a signed allowlist of approved image digests. The wallet only trusts attestations whose digest is on that allowlist. Response signing establishes that an API response actually came from the enclave and was not tampered with. On attestation, the enclave generates an ephemeral signing keypair and binds its public key into the attestation token as the token audience, proving the key was generated inside the enclave. Every API response carries a signature over the response body in a response-signature header, which the wallet verifies against that attested key. The enclave also echoes the request’s per-request nonce inside the signed response, so a previously captured response cannot be replayed. Request signing and EIP-712 binding establish that the enclave acts only on what the user authorized. At session creation the wallet generates a session-scoped signing keypair (separate from the wallet key), registers its public key with the enclave, and signs every subsequent request payload with it in a request-signature header. The enclave rejects any request whose signature does not match. For sensitive transactions, the wallet additionally signs an EIP-712 typed-data struct that binds the exact parameters: destination address, token, chain, and a single-use nonce. If any field is altered in transit, the reconstructed struct does not match and the enclave rejects the request. This turns request tampering into a prevented failure rather than a detected-after-the-fact one. Destination allowlisting and amount reconciliation are client-side controls. Before submitting any transaction, the wallet validates that the deposit destination and any approval target match a known privacy-layer contract, and reconciles the amount it is about to move against what the user requested plus the disclosed fee. A response that tried to redirect funds or inflate the amount is rejected client-side before the user signs. Fail-closed gating is the final client-side control. If any verification step fails (bad attestation, an image digest not on the allowlist, a signature mismatch, or the verification service being unreachable), Private Send is disabled for that transaction and the wallet falls back to the normal (non-private) transfer path or surfaces the privacy option as unavailable. There is no “unverified privacy” mode. The feature can also be remotely disabled if a concern is identified.
LayerGuaranteesMechanism
Enclave attestationThe privacy service runs unmodified, known codeConfidential Computing attestation token (nonce-bound) over the image digest
Source provenanceThat code is the build we reviewedTransparency-log-backed (Sigstore and cosign) signature; verified digest allowlist
Response signingResponses are genuinely from the enclave, untampered, non-replayableEnclave-attested ephemeral key signs each response; per-request nonce echoed
Request signingRequests reach the enclave unalteredSession-scoped key signs each request payload
Transaction bindingThe enclave acts only on user-authorized parametersEIP-712 typed-data struct binding destination, token, chain, nonce
Client controlsFunds cannot be redirected or inflated even on a provider flawContract allowlist, amount reconciliation, fail-closed gating
Sigstore is the supply-chain signing project; EIP-712 is the typed-data signing standard. No partner-specific links are used in this section.

Recovery

Because a Private Send is a two-step deposit-then-deliver flow, an interrupted or failed delivery can leave funds resting in the shielded pool. The wallet provides a recovery flow that returns those funds to the user’s own wallet. Funds in this state are never lost: they remain in the pool, associated with the user, and recoverable. Recovery is non-custodial. The destination is the user’s own connected wallet, and it is bound into the EIP-712 typed-data struct that authorizes the recovery, so the destination cannot be redirected. Recovery requires a connected wallet: it is a signed operation, not a read.

Supported networks and tokens

Private Send is available on Ethereum, Polygon, Base, Arbitrum, and Optimism. The wallet surfaces availability dynamically based on the selected token and chain: the privacy option only appears when the chosen combination is supported. See Supported networks for the canonical wallet-wide list of chains.

Security

Key security, enclave-bound authentication, and the non-custodial guarantee.

Smart sessions

Scoped transaction permissions so users approve once.

Wallet operations

Send transactions, sign messages, and check balances.

Recovery

Multi-auth linking and timed recovery for user wallet access.