Bulk Addresses

Create up to one million custodial wallets in one API call. Run one MPC key ceremony per batch, derive addresses locally, and create onchain activity only when a wallet is funded. Track progress in the background.

Chris Sutton
Chris Sutton

DFNS now supports Bulk Addresses. One API call creates up to one million custodial wallets, each with its own address, name, and tags, provisioned in the background and ready to receive funds. It exists for a specific kind of customer: the payments platform, exchange, or fintech that gives every end user a wallet of their own and onboards users by the hundred thousand.

The problem with a million key ceremonies

Creating a wallet on DFNS normally means generating a fresh key through a distributed cryptographic ceremony: multi-party computation across independent signers, so that no single machine ever holds the key. That is the right way to create a wallet. It is also, by design, deliberate work, and it is the wrong tool for a platform that needs to assign a deposit address to each of three million users before a launch.

Bulk Addresses solves this with hierarchical deterministic derivation. DFNS runs the MPC ceremony exactly once per batch to mint a single master key, then derives every child wallet from it mathematically, locally, with no further MPC ceremony per wallet and nothing written onchain until a wallet actually receives funds. A problem bound by cryptographic ceremonies becomes a problem bound by database writes, which is a problem we know how to make fast.

DFNS has long argued that one key per wallet is the safer default, and for standard wallet creation it still is. Bulk Addresses is a deliberate, opt-in exception for one job: provisioning custodial deposit addresses at a scale where a key ceremony per wallet is impractical. The trade-off is explicit. Every wallet in a batch shares one master key, so the batch is the unit of risk, which is why batches are custodial-only, the master never leaves MPC, and the feature is enabled per organization.

How it works

Call the endpoint with a network, a count, and a name prefix, optionally with tags and the key store to mint the master key in. The request is signed as a user action like any other sensitive operation, and the API responds immediately with a job handle. No wallets are created inside the request itself.

A background worker then drains the batch in chunks of two thousand wallets, deriving each child’s public key, computing its address locally, and inserting the wallet, its key record, its zero-balance seed, and its permission assignments together, atomically, with a checkpoint after every chunk. An interrupted job resumes exactly where it stopped. Child identifiers are deterministic, and name prefixes are unique per organization, so a retried job never produces a duplicate wallet and the operation is safe to repeat.

You watch the job’s progress through a status endpoint, completed count climbing toward total count, through Pending, In Progress, and Completed, with Partially Completed and Failed states carrying a reason if something stops a job short. Once complete, every wallet the job produced can be listed through a dedicated endpoint, paged up to two thousand at a time so a million wallets do not mean a million round trips. Each wallet is named by its prefix and index, carries the batch’s tags, and is a fully standard custodial wallet from that moment: it receives funds, appears in history, fires webhooks, and falls under your policies like any wallet created one at a time.

Supported networks at launch are Ethereum, the Layer 2s Base, Arbitrum, and Optimism, BNB Smart Chain, Tron, and Solana, plus their testnets. The common thread is that on these chains an address is a pure function of a public key, so every address can be computed locally with no onchain step. Chains that require an activation transaction before an address exists are excluded for now.

Custodial by construction

Because every wallet in a batch derives from one master key, Bulk Addresses are custodial only, and that is enforced as a security invariant rather than offered as a setting. There is no field in the request to ask for a non-custodial wallet, the constraint is checked again in the worker and again in the key delegation layer, the batch master key can never be exported, and the master chain code, which together with the master public key would let anyone enumerate and link every sibling address, is never exposed in any API response. The master itself is an MPC key, generated across independent signers and never assembled in one place.

The design choice is worth stating plainly. HD derivation trades per-wallet key independence for speed, which is a trade worth making for custodial deposit addresses that an institution operates at scale on behalf of its users, and exactly wrong for wallets whose keys users should hold themselves. Bulk Addresses is built for the first case and structurally prevents the second.

Who it is for

A payments platform assigning a deposit address to every user at onboarding, in a batch tagged by cohort. An exchange provisioning addresses for a new market ahead of launch rather than at the moment of each first deposit. A neobank or fintech embedding wallets for a customer base that already numbers in the millions. In each case, the operational difference is the same: a million wallets becomes one API call, one job to watch, and one line in the audit trail that records who requested it.

Bulk Addresses is available on the Enterprise plan, enabled per organization. Talk to your account manager or sales@dfns.co to switch it on.

Get started

Related articles

Contact us