Overview
Before a user can deposit tokens or interact with the mixer, they need an on-chain Umbra user account. Registration creates this account and optionally registers the cryptographic keys needed for encrypted balances and anonymous transfers. Registration is idempotent - it checks on-chain state before each step and skips any steps already completed, including handling key rotation when keys have changed. That said, 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 key for Shared encryption mode. Without this, deposits use MXE-only mode and you cannot query your balance locally.
Register the user commitment for mixer / anonymous transfer support. Can be used independently of
confidential.Optional lifecycle hooks called before and after each step.
pre receives the signed transaction before it is sent; post receives the transaction and its confirmed signature. Skipped steps do not invoke callbacks.The Three Registration Steps
Registration performs up to three on-chain transactions, in order:Account Initialization
Creates the
EncryptedUserAccount PDA - a program-derived address that serves as the root of your Umbra identity. This is always the first step.X25519 Key Registration
Derives your X25519 public key from your master seed and stores it on-chain. This key enables Shared encryption mode - deposits will be encrypted under both the Arcium MPC key and your key, allowing you to decrypt your own balance locally.Required if
confidential: true.All three steps require the master seed to be derived (overridable via dependency injection). The wallet signing prompt will appear on step 1 if the seed 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 steps that already completed.
See Error Handling for a full reference of all error types.