The Java SDK is stateless. It does not hold wallet state between calls. AfterDocumentation Index
Fetch the complete documentation index at: https://www.dynamic.xyz/docs/llms.txt
Use this file to discover all available pages before exploring further.
createWalletAccount(), the returned KeygenResult carries two distinct pieces of state — each belongs in a different storage tier:
| Returned value | Sensitivity | Where to store | How it’s used |
|---|---|---|---|
WalletProperties | Non-sensitive | Normal cache: Redis, Postgres, etc. Read on every request. | Identifies the wallet; passed to every sign / export operation. |
List<ServerKeyShare> | 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. |
walletProperties explicitly, and operations without cached List<ServerKeyShare> (and without backup fallback) will fail.
Persisting WalletProperties
WalletProperties is non-sensitive identity + backup-pointer metadata. It exposes toJson() / fromJson(...) with snake_case keys (cross-SDK compatible with Python and Rust) and toNodeJson() / fromNodeJson(...) with camelCase (Node v1 interop). Cache it like any other per-user record:
externalServerKeySharesBackupInfo field on WalletProperties is not recoverable via SDK-scoped endpoints — fetchWalletMetadata(accountAddress) returns identity only. Operations that need it (password verification, share recovery) will fail if it’s missing.
Mutating operations (updatePassword, refresh, reshare) return new backup info — merge it into the cached WalletProperties via WalletProperties.withBackupInfo(...) before writing back to your cache.
Storing List<ServerKeyShare>
When you set .backUpToDynamic(false) during wallet creation, you are responsible for securely storing the List<ServerKeyShare> 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.
ServerKeyShare is JSON-serializable — use ServerKeyShare.toJson() / fromJson(...) or your vault’s native format before persisting.
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 (AWS SDK for Java v2):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
Use
google-cloud-kms or google-cloud-secretmanager — same envelope pattern as AWS KMS, integrated with Google Cloud IAM and audit logging.3. Azure Key Vault
3. Azure Key Vault
Use
azure-security-keyvault-secrets — Azure-managed secrets with Managed Identity auth.4. HashiCorp Vault
4. HashiCorp Vault
Use
vault-java-driver or spring-cloud-vault to read/write secrets to a Vault KV mount. Works well if your stack already runs Vault.Security Requirements Checklist
Regardless of your storage method, follow these requirements:- Never log plaintext key shares — redact
externalServerKeySharesfrom all logs, error messages, and monitoring.ServerKeyShare.toString()is redacted by the SDK; mirror that in your own code. - 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 — null out decrypted byte arrays after use; prefer
char[]for passwords so you can clear them deterministically