Transfer to a recipient who has not registered a private address yet. The send uses a derived escrow note and stays indistinguishable from a private transfer.

Disclosure policy

Sender may be public or private. Private sender and this escrow send both require Protocol Relay. Recipient, asset, and amount stay private.

Transact environment hooks

Unregistered recipients need resolveTransferRecipientAtExecute on transactEnvironment. The default chain resolver (resolveTransferRecipientFromChain) looks up the registry, then derives an escrow key from a random nonce and the recipient’s Stellar G-address. That pins exactly one recipient to the note. Public escrow recipient limbs stay zero on send, so the transaction matches an ordinary private transfer. The hook is registered during client bootstrap (see Setup). Use a client slot assigned after createStellarPrivacyClient — do not close over client before it exists. Custom resolvers should return escrowSend with the derived nonce and G-address limbs rather than a temporary private address.
Escrow sends require Protocol Relay and a zero public deposit. A positive public deposit is refused (not downgraded to Direct Submission). If relay is unconfigured, submission fails with escrow_relay_unconfigured and wallet submission is not offered. operation.execute() is Direct Submission and does not complete an escrow send.

Example

The addresses, contracts, and seed values below are placeholders, not runnable testnet data. Use the matching pool configuration and audit public key from Set up the SDK. Create the client using Frontend integration or Backend integration, and load real account state as described in State methods.
Call transfer with a public Stellar to address and the same private disclosure as a registered transfer.

Seed state

Run operation

Build relayOperation from operation.prepared (prepareRelayTransactPackageFromPrepared + serializeRelayPackage, submissionPath: 'relay'). Complete port implementations: Examples. The SDK derives the escrow note owner at execute-time resolution. It does not put the recipient G-address in pool calldata or the relay package on send.

Discover notes sent before registration

A recipient who registers later can still find notes that were sent to their public wallet. Escrow discovery uses blinded recipient tags, not the retired pending-claim client API. Your stand may provide a tag-issuance / storage origin. Production apps often fetch the challenge and issued tags from that service, then sign the challenge with the wallet. When your app builds the challenge string locally, use buildBlindedRecipientTagChallengeMessage so the UTF-8 bytes match issuance (same labeled-line shape as a private-note spend key). Sign the message with a current account signer, then present the signature to your tag-issuance integration. Issued blinded recipient tags (one per tag epoch) are how the recipient looks up notes without revealing their address to the index. To claim a discovered note, fetchEscrowOutputNoteEvents reads the output-note ciphertexts through the existing transact environment (do not pass an RPC URL). After proving the sweep, submit it with Direct Submission: the claimant wallet is from and signs the transaction envelope. Protocol Relay is not used for sweeps.
Do not reconstruct the message by hand. Issuance verifies the signed string byte-for-byte.

Examples

Explore the frontend and backend reference applications.

State methods

Seed state is a doc fixture; production data flows.

Disclosure policy

Private escrow disclosure constraints.