Every deposit, transfer, and withdraw call prepares an operation. Check its status, then choose direct submission or Protocol Relay. The execute stages below describe direct submission.

Two-phase model

Prepare runs before the wallet prompt so validation errors (insufficient_state, unsupported_disclosure) surface without a signature request. Execute is one-shot — calling execute() twice on the same prepared operation throws an execution error.

Prepare outcomes

Rejected

Do not call execute() when status === 'rejected'. Inspect operation.errors — an array of structured PrivacySdkError values.

Prepared

When status === 'prepared', the operation includes: The prepared payload is useful for advanced UI (showing change amounts). You can treat it as opaque for a basic integration.

Execute flow and progress events

Pass onEvent to receive stage updates during execute:
You can also pass signal: AbortSignal to cancel long-running execute work.

Direct Submission vs Protocol Relay

operation.execute() is Direct Submission: the connected wallet (or server keypair) signs and the transact engine submits to Soroban. It never calls @arcanetech/privacy-sdk-relay. After prepare, choose the path with requiredSubmissionMethod from @arcanetech/privacy-sdk-stellar/transact. Pass the same zkConfigNonce as the pool (SDK default 3n when omitted; demos use 7n): Relaying is off until relayConfig.origin is set. An unset origin Direct-submits a typical deposit and never contacts a relayer. An escrow send without origin fails with escrow_relay_unconfigured — it is not downgraded to Direct. Runnable wiring: Examples. Operation examples: Withdraw, Transfer to unregistered recipient.

Error model

Prepare-time errors appear in operation.errors when status === 'rejected'. Execute-time errors arrive through progress events (status: 'error') or as thrown/rejected promises from execute().

Persisted state after success

On the storageCommit stage the SDK updates local domain state:
  • mark spent private records as consumed
  • insert new output records (recipient note, change note)
  • refresh pool commitment snapshot
  • append delivery metadata when configured
Save private records using protected storage scoped to the account and network. Restore them before preparing a spend. Redux alone does not preserve state across reloads. See State adapters and Frontend integration.

Operations

What each operation kind does.

State adapters

Why prepare reads SDK state.

Disclosure policy

Policy errors during prepare and execute.

Examples

Frontend or backend demo with Direct and Relay.