Overview
A Crypto Wallet is the customer-facing resource for holding crypto on a single blockchain. Each wallet has one on-chainaddress on one chain, and its balances[] reflect the deposits and pending movements Conduit has observed for that address.
Wallets are scoped to a customer. No wallets are created automatically during onboarding — you create each one on demand, on the chain you need. A customer can hold multiple wallets across different chains.
The crypto-wallets feature must be enabled for your client. Calls to these endpoints while the feature is disabled return a feature-not-enabled error.
Custody Model
Every wallet on this surface is non-custodial: the customer holds the keys (passkey or roster of signers) and must sign every outbound transfer. Conduit does not hold customer signing keys.| Who controls the key | How funds are moved |
|---|---|
| Customer (passkey or signer roster) | Conduit and the customer’s signers co-sign; Conduit broadcasts once the signing threshold is met |
POST /v2/customers/:id/wallets returns 409 WALLET_CUSTODY_NOT_CLAIMED until that’s done. Receiving crypto works once a wallet exists; the custody model determines what happens on outbound — see Non-Custodial Wallets for the full co-signing flow.
The Wallet Resource
| Field | Type | Description |
|---|---|---|
id | string | Wallet ID, prefixed wlt_. |
chain | enum | The blockchain this wallet operates on. |
address | string | null | The on-chain address. null while the wallet is provisioning. |
status | enum | Lifecycle status — see below. |
custodyModel | enum | null | non_custodial for wallets on the current surface. The wire still accepts custodial for legacy ops-managed wallets, but the public customer surface only mints non_custodial. Omitted until the customer’s custody model is determined. |
rotatedAt | string | null | When this wallet was rotated, if it has been. |
replacedByWalletId | string | null | The wallet that replaced this one after rotation. |
clientReferenceId | string | null | Your external reference, if you supplied one at creation. |
balances[] | array | Per-asset balances, each with available, pending, and frozen amounts. |
createdAt | string | When the wallet was created. |
updatedAt | string | When the wallet was last updated. |
Balances
Each entry inbalances[] splits a single asset into three buckets:
available— settled funds you can move out.pending— funds observed on-chain but not yet fully settled.frozen— funds held and temporarily unavailable.
Status lifecycle
| Status | Meaning |
|---|---|
pending | The wallet has been requested and Conduit is provisioning its on-chain address. address is null until provisioning completes. |
active | The wallet has an address and can receive and send funds. |
disabled | The wallet is no longer in use — for example, it has been rotated and replaced. |
A wallet enters
pending with a null address while it is being provisioned. Rather than polling, subscribe to crypto_wallet.completed to learn when provisioning has finished and the address is populated.Supported Chains
Wallets can be created on the following chains. Thechain value is always lowercase.
chain | Network |
|---|---|
ethereum | Ethereum |
base | Base |
polygon | Polygon |
solana | Solana |
tron | Tron |
Creating Wallets
Wallets are provisioned in two steps: claim non-custodial control once per customer, then create one wallet per chain.Claim non-custodial control (once per customer)
Opt the customer into the non-custodial multi-signer model:Returns
202. The customer’s signers complete their enrollment via per-signer verification URLs delivered through wallet_signer.invited webhooks. Once the final signer has enrolled, crypto_wallet.completed fires; from that point the customer can create wallets.Create a wallet per chain
Once the customer has claimed non-custodial control, create wallets one chain at a time:Returns
201 with the new wallet. clientReferenceId is optional. The idempotency-key header is required — replaying the same key returns the same wallet rather than creating a duplicate. The wallet starts in pending until its address is provisioned.Before the claim completes, the same request returns 409 WALLET_CUSTODY_NOT_CLAIMED. See Non-Custodial Wallets for the multi-signer model and the WALLET_CUSTODY_NOT_CLAIMED error page for the resolution path.Reading Wallets
| Endpoint | Returns |
|---|---|
GET /v2/customers/{customerId}/wallets | A cursor-paginated list of the customer’s wallets. Accepts an optional clientReferenceId filter. |
GET /v2/customers/{customerId}/wallets/{walletId} | A single wallet. |
Key Rotation
Rotating a wallet replaces its on-chain key. It produces a new wallet with a newaddress; the old wallet moves to disabled. The two are linked: the old wallet’s replacedByWalletId points to the new wallet, and the new wallet carries the same replacedByWalletId back-reference so the chain of replacements is traceable.
200 with the replacement wallet. The idempotency-key header is required.
A wallet.rotated webhook fires when rotation completes, carrying both the old walletId and the replacedByWalletId.
Receiving Crypto
Share the wallet’saddress and incoming deposits surface in the wallet’s balances[]. The end-to-end flow — including how deposits are detected and credited — is covered in the Receive Crypto guide.
Related
Non-Custodial Wallets
The two-signature model, the customer verify page, and outbound co-signing.
Receive Crypto
How deposits arrive and credit a wallet’s balances.