The Node SDK is stateless. It does not hold wallet state between calls. AfterDocumentation Index
Fetch the complete documentation index at: https://docs.dynamic.xyz/docs/llms.txt
Use this file to discover all available pages before exploring further.
createWalletAccount() (or importPrivateKey()), you receive two distinct pieces of state — each belongs in a different storage tier:
| Returned value | Sensitivity | Where to store | How it’s used |
|---|---|---|---|
walletMetadata | Non-sensitive | Normal cache: Redis, Postgres, etc. Read on every request. | Identifies the wallet; passed to every sign / export / backup operation. |
externalServerKeyShares | Sensitive (MPC key material) | Secrets vault: HSM, KMS-wrapped DB column, AWS Secrets Manager, etc. | The customer-side half of MPC signing. Combined with your Dynamic API key, provides signing authority. |
walletMetadata explicitly, and any operation that doesn’t have a cached externalServerKeyShares[] (or fallback backup) will fail.
Persisting walletMetadata
walletMetadata is non-sensitive identity + backup-pointer metadata. Cache it like you would any other per-user record:
externalServerKeySharesBackupInfo field on walletMetadata is not recoverable via SDK-scoped endpoints — fetchWalletMetadata(accountAddress) returns identity only. Operations that need it — sign (signMessage / signTransaction / signTypedData), export (exportKey / exportPrivateKey), password verification, share recovery, refresh, reshare, updatePassword — will throw if it’s missing.
BTC wallets must persist addressType. Bitcoin signing and backup operations read addressType (taproot or native_segwit) from walletMetadata. fetchWalletMetadata does not return it, and storeEncryptedBackupByWallet cannot infer it server-side. If your BTC cache omits addressType, subsequent backups fail.
Re-cache after mutating operations. updatePassword, refreshWalletAccountShares, and reshare return a new backupInfo reflecting the updated backup state. Merge it back and persist:
Storing externalServerKeyShares
When you set backUpToDynamic: false during wallet creation, you are responsible for securely storing the externalServerKeyShares returned by createWalletAccount. These key shares, combined with your Dynamic developer API key, provide signing authority and must be protected with defense-in-depth strategies.
Recommended Storage Approaches
1. Envelope Encryption with Cloud KMS (Recommended)
1. Envelope Encryption with Cloud KMS (Recommended)
Use a cloud Key Management Service to encrypt the key shares before storing them in your database.AWS KMS Example:Benefits:
- Centralized key management with automatic rotation
- Hardware-backed security (FIPS 140-2 Level 3)
- Audit logging of all encryption/decryption operations
- Fine-grained IAM policies
2. Google Cloud KMS & Secret Manager
2. Google Cloud KMS & Secret Manager
Similar to AWS KMS, but integrated with Google Cloud’s ecosystem.
3. Azure Key Vault
3. Azure Key Vault
Microsoft Azure’s managed secrets and key management service.
Security Requirements Checklist
Regardless of your storage method, follow these requirements:- Never log plaintext key shares — redact
externalServerKeySharesfrom all logs, error messages, and monitoring - Encrypt at rest — use AES-256-GCM or equivalent; ensure database/storage has encryption enabled
- Encrypt in transit — all communication must use TLS 1.3
- Implement access controls — restrict which services and roles can decrypt key shares
- Enable audit logging — track all access to encrypted materials with timestamps and actor identity
- Separate encryption keys — don’t reuse keys across environments (dev/staging/prod)
- Use unique encryption per record — generate new IVs for each encryption operation
- Implement key rotation — rotate encryption keys periodically (e.g., every 90 days)
- Plan for key compromise — document incident response for key material exposure
- Secure deletion — overwrite secrets in memory after use; use secure deletion for storage