Phase 7: Retiring the Custody Infrastructure
April 20, 2026 — Phase 7 is the cleanup. By the time we get here, EVM and Solana volumes are on contract receivers and SubscriptionHub, Bitcoin is on 2-of-2 multisig, and every new payment link avoids the legacy sweep path. This phase removes the legacy code and the legacy secrets.
TL;DR
- Drop
hd_wallet_seed, theWALLET_ENCRYPTION_KEYconfig, and the derivation logic for flagged chains. - Delete EVM/SOL paths in
api/src/withdrawals/:SmartAccountWalletService.drainSmartAccountWallet,solana-withdrawal-transfer.service.ts, related spec files. - Keep the BTC path (reduced to Phase 5's 2-of-2 model).
- Update TOS, privacy policy, and SOC2 controls to reflect a materially smaller custody surface.
- Publish a postmortem summarizing what we learned.
What this phase changes
Before this phase lands, the codebase has two of everything — the old sweep path and the new contract path — behind feature flags. After this phase, the new path is the only path on EVM and Solana.
What we delete
Database
hd_wallet_seedtable and its TypeORM entity at api/src/payments/infrastructure/persistence/relational/entities/hd-wallet-seed.entity.ts.wallet_address.derivationPathcolumn is retained for historical lookups but becomes nullable; no new rows write it for EVM/SOL.- A migration archives the encrypted seed rows to cold storage for seven years (regulatory retention), then drops the table.
Code
In api/src/payments/wallet.service.ts:
- Delete
encryptSeed,decryptSeed,getOrCreateHDWallet,generateAddressForNetwork(EVM + SOL branches),getNextAvailableIndex, and the@account-kit/wallet-clientdynamic import. getOrCreateAddressForPaymentLinkbecomes a thin wrapper overfactory.computeAddressfor EVM andfindProgramAddressSyncfor Solana.
In api/src/withdrawals/services/smart-account-wallet.service.ts:
- Delete
drainSmartAccountWallet,transferFromSmartAccount,batchTransferFromSmartAccount,getSmartAccountClientForDepositWallet, andderivePrivateKey. - The module stays (it still has a small footprint for BTC-related helpers and for reading balances).
Other deletions:
- api/src/withdrawals/services/solana-withdrawal-transfer.service.ts
- Corresponding
.spec.tsfiles and fixtures. - The
subscription-auto-charge.processor.tscustodial branch (theSubscriptionHub.chargebranch is what remains).
Config
WALLET_ENCRYPTION_KEY— dropped from.env, deployment secrets, and docs.- Any Alchemy Account Kit signer material in config (API keys for
@account-kit/*remain if still used for paymaster).
What stays
- BTC hot wallet — reduced to the 2-of-2 multisig model from Phase 5. No EVM/SOL HD seeds remain.
- Alchemy paymaster policy — used by the keeper to sponsor
charge()where applicable. - Relay bridge executors — still orchestrate cross-chain settlement; callers are keeper EOAs, not custodial signers.
- All webhooks, emails, invoicing, dashboard, analytics — unchanged.
Legal and compliance updates
- Terms of Service: "OrcaRail does not custody EVM or Solana funds during payment settlement" becomes a factual statement, not aspirational copy.
- Privacy policy: remove references to stored seed material.
- SOC2 scope: custody controls shrink; audit findings map to the new smaller surface.
- Money transmitter posture: re-review with counsel. Fewer custody touchpoints simplify the analysis in several jurisdictions.
Postmortem
A companion post will summarize what we learned across Phases 0 to 7 — what took longer than expected, what went smoother, what the real engineering cost of non-custody was, and how merchants reacted. Expected cadence: one post within 30 days of Phase 7 shipping.
Deprecations (none new)
This phase is itself the deprecation. Every useOnChainReceiver-flagged path becomes default-on; the flag is deleted.
Migration plan
By the time Phase 7 runs, every new payment and subscription for 12+ months has been non-custodial. The migration is about long-tail legacy links:
- Legacy open payment links past expiry → settle any residual dust via a one-time script, then stop.
- Legacy subscriptions that never migrated → email notice 30 days before shutdown, offer one-click migration in dashboard, suspend auto-charge if no migration.
- Residual balances on legacy deposit addresses → sweep with the old drain path one last time, to merchant withdrawal addresses, then retire the keys.
Risks and mitigations
- Residual dust on old addresses. Mitigation: final-sweep script run before decommission; any unrecoverable dust published in a public report.
- Legal risk from deleting too early. Mitigation: 7-year archival of encrypted seed rows (never decryptable without the encryption key, which is destroyed in ceremony); auditors can still verify historical state.
- Someone depends on an undocumented API shape. Mitigation: 90-day public deprecation notice; API changelog entry; targeted outreach to top merchants.
Status checklist
- All EVM + SOL merchants on non-custodial flow for at least 90 days
- Residual legacy subscriptions zeroed
- Final-sweep script completed
- Migration completed for
hd_wallet_seedto cold archive - Code deletions merged
- TOS + privacy policy updated and shipped
- Postmortem post published
The end of the roadmap
After Phase 7, the custody posture is:
- EVM, Solana: non-custodial. OrcaRail holds zero seed material.
- Bitcoin: reduced custody via 2-of-2 multisig with merchant signer.
- In-flight moment: eliminated on EVM/SOL; reduced to a multisig refund path on BTC.
That is what we set out to do in the Non-Custodial Roadmap.
Reference docs: Phase 7 status · Security model · Roadmap
