Skip to main content

Overview

Each of your customers gets Crypto Wallets of their own: keys they control, ready to receive, hold, and send crypto across the supported chains. Network fees are sponsored, so a wallet never needs a native-coin balance.
  • Receive: share the wallet’s address; deposits are detected on-chain, screened, and credited to balances[], with a webhook at each step.
  • Hold: per-asset balances, split into available, pending, and frozen.
  • Send: payouts and conversions leave only after the customer’s signers approve. Who those signers are (people with passkeys, your backend with server-held keys, or a mix) is the customer’s signing mode.
Each wallet lives on one chain with one on-chain address, and it is scoped to a customer. No wallets are created during onboarding; they are provisioned when the customer claims non-custodial control (see Creating Wallets), which by default provisions a wallet on the default set of supported chains in one step, or on the specific chains you request.
Only receiving crypto to fund a conversion? You may not need customer wallets at all: a deposit-funded order returns a funding address per order, with no claim, no signer roster, and no co-signature.

Custody

Wallets provisioned on this surface are non-custodial: the customer holds the signing keys, and moving funds out takes both the customer’s approval and Conduit’s compliance co-signature; neither side can act alone. Conduit broadcasts once the customer’s signing threshold is met; it never holds the customer’s keys. Receiving crypto works as soon as a wallet exists. The co-signing that governs outbound transfers is covered in Non-Custodial Wallets.

Signing modes

Signers don’t have to be humans. Every customer has a signing mode (passkey required, programmatic, or programmatic unattended) that decides whether payout approvals come from people with passkeys, from your servers, or a mix. Conduit sets it for each customer. See Signing modes to choose between them, and Programmatic payout signing for the machine flow.

The Wallet Resource

Balances

Each entry in balances[] 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.
Balances reflect deposits as they arrive. See Receiving crypto below.

Status lifecycle

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. The chain value is always lowercase. The three EVM chains (ethereum, base, and polygon) share a single on-chain address. A customer’s wallets on those chains all resolve to the same address, so funding one and reading another are the same account on each network. solana and tron each have their own distinct address.
solana is created only when you request it explicitly in chains; it is not part of the default chain set. solana wallets are address-only for now: you can create the wallet and receive on it, but outbound payouts and orders on Solana are not yet available. Payouts and orders are supported on the EVM chains and tron (tron carries USDT only). An order naming an unsupported asset/chain combination is refused with UNSUPPORTED_ASSET; a payout is refused as a validation error on assetAmount.chain. More generally, a chain being listed here (or a wallet being created for it) does not imply Conduit yet supports moving every asset on that chain.

Creating Wallets

Wallets are provisioned by claiming non-custodial control once per customer, which by default provisions a wallet on the default set of supported chains. Adding a wallet on a chain not in that set (or one you excluded from the claim) is an optional second step. One prerequisite: the customer needs the crypto_wallet feature approved before it can claim. Requesting it and tracking the approval is Step 1 of Add a Crypto Wallet.
1

Claim non-custodial control (once per customer)

Opt the customer into the non-custodial multi-signer model:
The request body may include an optional chains array naming which chains to provision. Omit it, the recommended default, and the default set of supported chains (ethereum, base, polygon, tron) is provisioned in one claim, so a customer that later needs a new chain does not have to re-authenticate its signers. Provisioning one wallet up front on each chain covers future use with no further signer ceremony. solana is not in the default set: name it in chains to provision it.Because the three EVM chains share a single address and key, provisioning them costs one admin approval, not three. tron is provisioned as its own address in the same claim.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 and the claim’s wallets activate. Polling GET /v2/customers/{customerId}/wallets/claims/{claimId} returns a chains field listing every chain provisioned for the claim.
2

Add a wallet on another chain (optional)

When you omit chains at claim time, wallets on the default set of supported chains already exist and this step is unnecessary. To add a wallet on a chain not in that set (such as solana) or one you explicitly excluded, call:
clientReferenceId is optional: 1-255 characters from A-Za-z, 0-9, underscore, hyphen, colon, and period; no spaces. The idempotency-key header is required; replaying the same key returns the same result rather than creating a duplicate.The response has two success shapes, depending on whether the new wallet needs fresh signing material — plus a retryable 409 while that material is still being set up:
  • 201 Created with the wallet: when the chain reuses key material the customer already controls. Adding an EVM chain (ethereum, base, or polygon) while the customer already has an EVM wallet reuses the existing shared address and key, so no admin approval is needed and the wallet is returned immediately, already active on the shared address.
  • 202 Accepted with { "ceremonyId": "wcm_…", "verificationUrl": "…" }: when the wallet needs new signing material (a chain that does not share the existing key, or a second wallet on a chain). This parks an admin-cosign ceremony rather than creating the wallet inline: route verificationUrl to one of the customer’s admins to approve on the verify page. A wallet_ceremony.awaiting_admin_approval webhook carries the same admin link. On approval, wallet.created and crypto_wallet.completed fire and the wallet is active; if the admin declines, wallet_ceremony.failed fires and no wallet is created. Retrying while a ceremony for the same chain is already pending is idempotent: the call re-mints that pending ceremony’s approval and returns 202 again. While the new signing material is still being set up there is no link to return yet, so the call is refused with a retryable 409 CEREMONY_IN_FLIGHT — retry shortly and the 202 arrives once the material is ready. The same 409 is returned when a concurrent request for the same chain has not finished recording its ceremony. Wait for the pending ceremony to resolve rather than opening a second one.
Before the customer has claimed non-custodial control, the same request returns 422 WALLET_NO_PROVIDER_ACCOUNT. See Non-Custodial Wallets for the multi-signer model and the WALLET_NO_PROVIDER_ACCOUNT error page for the resolution path.

Reading Wallets

Key Rotation

Rotating a wallet replaces its on-chain key. It produces a new wallet with a new address; 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.
Returns 200 with the replacement wallet. The idempotency-key header is required.
Move the funds out before rotating: the new key controls a different address, so rotation is blocked while the wallet still holds a balance worth moving. A leftover at or below the asset’s dust floor does not block it.
A wallet.rotated webhook fires when rotation completes, carrying both the old walletId and the replacedByWalletId.

Receiving Crypto

Share the wallet’s address 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.

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.

Add a Crypto Wallet

Step-by-step: enable the feature, claim non-custodial control, enroll the roster, and activate.

Signing modes

Who approves payouts (people with passkeys, your servers, or both) and how to choose.