Custodial Wallet Development
Custodial wallet — system where user's private keys are stored and managed by service. User authenticates via login/password (or OAuth), not seed phrase. Exchanges (Binance, Coinbase), payment services (MoonPay), corporate treasury solutions — all work custodially.
Custodial model simpler for users and inevitable for mass adoption: explaining seed phrase to average user — unsolved task. Service pays for simplicity: responsibility for key safekeeping, regulatory compliance (VASP, custody licensing) and target for hackers — keys stored centrally.
Key Storage Architecture
HSM as Security Foundation
Hardware Security Module (HSM) — specialized equipment for storing and using cryptographic keys. Keys never leave HSM in open form: all signing operations happen inside protected chip.
HSM levels:
- AWS CloudHSM / Azure Dedicated HSM — cloud HSM with FIPS 140-2 Level 3. Scales well, API-managed
- Thales Luna HSM — on-premise HSM, physical control. Required for strict compliance
- Ledger Vault / Fireblocks — specialized crypto custody products with HSM + MPC inside
For most projects: AWS CloudHSM or equivalent — reasonable choice. Hardware-grade security without maintaining infrastructure.
MPC Instead of Single-Key
Modern standard for custodial storage — MPC, not classic HSM with one key. MPC splits private key into shares between parties (e.g., 2 of 3): client server, backup server, user themselves. No participant knows full key. Signature generated via protocol without key reconstruction.
MPC advantages over multisig:
- One blockchain transaction (multisig — multiple signatures, higher gas on legacy chains)
- No on-chain privacy issues (no distributed traces)
- Works with any blockchain without protocol changes
Libraries: Fireblocks MPC SDK, ZenGo's open-source TSS, tss-lib (Go).
Hierarchical Keys (HD Wallet)
BIP-32/BIP-44 standard: one master seed generates key tree. For custodial service with millions of users — no need separate key per user.
Master Seed (in HSM)
└── m/44'/60'/0' (Ethereum account 0)
└── m/44'/60'/0'/0 (external chain)
├── m/44'/60'/0'/0/0 (user 1)
├── m/44'/60'/0'/0/1 (user 2)
└── m/44'/60'/0'/0/N (user N)
Master seed stored in HSM. Child key derivation via HSM API. User private keys — derivatives not stored separately; computed from master seed + derivation path when signing needed.
Critical: derivation path for each user must be recorded in database. Losing this mapping = losing access to addresses.
Service Architecture
System Components
Key Management Service (KMS): isolated service, only one with HSM access. Takes signing requests. Doesn't store user state — only generates signatures.
Transaction Service: handles user requests. Validates, rate limits, fraud detection. After approval — sends signing request to KMS.
User Account Service: user management, balances, transaction history. Stores addresses and derivation paths.
Blockchain Gateway: monitors incoming transactions, broadcasts signed, gets confirmations.
User → API Gateway → Transaction Service → [fraud check + approval]
→ KMS (sign request)
→ Blockchain Gateway (broadcast)
Service separation critical: Transaction Service compromise doesn't give key access — KMS accepts only authorized internal services via mutual TLS.
Approval Workflow
interface TransactionRequest {
userId: string;
toAddress: string;
amount: string;
token: string;
chainId: number;
}
class TransactionApprovalService {
async process(request: TransactionRequest): Promise<ApprovalResult> {
await this.validateAddress(request.toAddress);
await this.validateBalance(request.userId, request.amount, request.token);
const riskScore = await this.riskEngine.score(request);
if (riskScore > HIGH_RISK_THRESHOLD) {
await this.requireAdditionalAuth(request.userId);
}
if (riskScore > BLOCK_THRESHOLD) {
await this.flagForManualReview(request);
return { status: 'PENDING_REVIEW' };
}
await this.checkRateLimits(request.userId, request.amount);
const signedTx = await this.kms.sign({
derivationPath: await this.getUserDerivationPath(request.userId),
transaction: await this.buildTransaction(request)
});
return { status: 'APPROVED', signedTx };
}
}
Risk Engine
Fraud detection — separate critical component.
Risk signals:
- New device fingerprint — first login from new device + large transaction
- Unusual geography — transaction from never-seen country
- Velocity anomaly — 10 transactions in 5 minutes vs normal 1/day
- Address risk — recipient in blacklist (Chainalysis, Elliptic)
- Amount anomaly — amount significantly exceeds history average
class RiskEngine {
async score(request: TransactionRequest): Promise<number> {
const signals = await Promise.all([
this.checkAddressReputation(request.toAddress),
this.checkVelocity(request.userId),
this.checkAmountAnomaly(request.userId, request.amount),
this.checkGeography(request.userId),
this.checkDeviceFingerprint(request.userId)
]);
return signals.reduce((total, signal) =>
total + signal.score * signal.weight, 0
);
}
}
Regulatory Requirements
Custodial wallet — typically VASP (Virtual Asset Service Provider) per FATF standards. Requirements:
Travel Rule (FATF Recommendation 16): for transactions above threshold (1000 USD/EUR in most jurisdictions) — transmit sender and recipient info with transaction. Protocols: IVMS101 (data standard), TRP (Travel Rule Protocol), OpenVASP.
KYC/AML: user identity verification, transaction monitoring for suspicious activity, financial authority reporting.
Custody licensing: in some jurisdictions (EU, UK, some US states), crypto asset custody requires special license. MiCA (Markets in Crypto-Assets, EU) introduces custody provider requirements 2024–2025.
Architecture must be designed for compliance from day one, not added later.
Operational Security
Disaster Recovery
Master seed loss = all user funds lost. Backup strategy:
- Geographic distribution: backup copies master seed (encrypted) in different HSMs in different regions
- Shamir's Secret Sharing: master seed split into N shares, minimum K for recovery. Shares held by different people/locations
- Recovery drill: regular recovery procedure tests (quarterly)
Key Rotation
Periodical operational key rotation (not master seed, but HSM API keys). Master seed rotation via migration: generate new seed, derive new addresses, gradually move funds.
Incident Response Plan
What if compromise suspected:
- Immediate withdrawal freeze
- API key rotation
- Access logs audit
- User notification and regulator (if required)
Stack and Timeline
Backend: Node.js / Go + PostgreSQL + Redis. KMS: AWS CloudHSM via PKCS#11. Blockchain: viem (EVM), @solana/web3.js, bitcoinjs-lib for multi-chain. MPC: optional — Fireblocks API or open-source TSS. Compliance: Chainalysis KYT integration.
| Component | Timeline |
|---|---|
| HD wallet + KMS integration | 2–3 weeks |
| Transaction service + approval workflow | 2–3 weeks |
| Risk engine (basic) | 1–2 weeks |
| Blockchain gateway (1–2 networks) | 1–2 weeks |
| Admin panel + reporting | 2–3 weeks |
MVP (Ethereum + ERC-20, basic risk engine): 8–10 weeks. Production with multi-chain, MPC, compliance integration: 4–6 months.
Cost depends on supported networks, compliance requirements, expected load.







