The IUmbraSigner Interface
The Umbra SDK requires a signer that implementsIUmbraSigner:
signMessage is critical - it is used to derive the master seed from a wallet signature. The other methods sign the Solana transactions that interact with the Umbra program.
The SDK exports ready-made helper functions for every common signer source. You do not need to implement IUmbraSigner yourself.
Option 1: In-Memory Keypair (Testing)
Use the SDK’s built-in helpers to generate or load an in-memory keypair. Best for scripts, CI, and local development.Option 2: Wallet Standard Browser Wallet (Production)
Modern Solana wallets — Phantom, Backpack, Solflare, and others — implement the Wallet Standard. UsecreateSignerFromWalletAccount to adapt them to IUmbraSigner.
You obtain the wallet and account objects by discovering registered wallets with getWallets() from @wallet-standard/app, then calling the wallet’s standard:connect feature.
useWallets() hook from @wallet-standard/react and the useConnect() / useDisconnect() hooks for a more ergonomic integration:
Re-create the client whenever the wallet connection changes. Since the client holds a reference to the signer, stale signers will cause transactions to fail.
"solana:signTransaction" and "solana:signMessage" features — an error is thrown immediately if either is missing.
How signing works
- The
@solana/kittransaction is serialized to wire-format bytes viagetTransactionEncoder() - The bytes are passed directly to the wallet’s
solana:signTransactionfeature - The wallet returns signed wire bytes
getTransactionDecoder()reconstructs the@solana/kitTransaction, and signatures are merged back in
@solana/web3.js.
Master Seed Derivation
The first time any cryptographic operation runs (typically duringregister()), the SDK calls signer.signMessage with a deterministic message to derive the master seed (overridable via dependency injection). This produces a one-time wallet signing prompt.
The message that the user signs is a multi-paragraph legal consent and acknowledgement. It is exported as UMBRA_MESSAGE_TO_SIGN from the @umbra-privacy/sdk/shared subpath:
deferMasterSeedSignature option in getUmbraClient. See Creating a Client - Master Seed Derivation.
Persisting the Master Seed
By default, the master seed lives only in memory. If you want to avoid re-deriving it on every page load, you can persist it using themasterSeedStorage dependency override: