Overview
Before a user can deposit into an EncryptedTokenAccount or interact with the Stealth Pool, they need an on-chain Umbra user account. Registration creates this account and optionally registers the cryptographic keys needed for ETAs and anonymous transfers. Registration is idempotent — it checks on-chain state before each step and skips any sub-steps already completed (handling key rotation when keys have changed). Each call may submit on-chain transactions with SOL costs, so in practice you should check whether the account is already registered before calling it.Usage
Options
Register the X25519 token-encryption pubkey for Shared-mode ETAs. Without this, deposits stay in MXE-only mode and you cannot query your balance locally.
Register the on-chain user commitment via MPC + ZK. Required to receive receiver-burnable Stealth Pool Notes. Can be used independently of
confidential.Per-step lifecycle hooks plus top-level phase hooks. Skippable step slots take
{ onPreSend, onPostSend, onSkipped }.The hook slot names are
initUserAccount, registerX25519PublicKey, registerAnonymousUsage. Each is SkippableDirectTransactionStepHooks or SkippableMpcTransactionStepHooks — { onPreSend, onPostSend, onSkipped }.The registration flow
Registration is two independent on-chain instructions. Bothinit_if_needed the EncryptedUserAccount PDA, so either can run first.
register_user_for_confidential_usage
Synchronous. Initialises the
EncryptedUserAccount PDA (if needed) and stores the X25519 token-encryption pubkey derived from your master seed. Enables Shared encryption mode — deposits get encrypted under both the Arcium MPC key and your key, so you can decrypt your own balance locally.Run when confidential: true.register_user_for_anonymous_usage_v18
MPC + ZK. Initialises the user account (if needed), stages master-viewing-key material, runs Fiat-Shamir + Groth16, queues the Arcium MPC computation, and on callback stores the on-chain user commitment. Enables you to receive receiver-burnable Stealth Pool Notes.Run when
anonymous: true.Both sub-steps require the master seed to be derived (overridable via dependency injection). The wallet signing prompt fires the first time the seed is needed if it has not been derived yet in this session.
On-Chain Account
After registration, the user’sEncryptedUserAccount PDA stores:
- X25519 public key (for Shared mode deposits addressed to this user)
- Poseidon user commitment (for ZK proof generation)
- Generation index (monotonic counter used for nonce derivation)
- Random generation seed (entropy mixed into nonces)
- Status flags for each registration step
Error Handling
Registration can fail at several distinct points. UseisRegistrationError from @umbra-privacy/sdk/errors and switch on err.stage to handle each one.
register() again — it checks on-chain state and skips the sub-step that already completed.
See Error Handling for a full reference of all error types.