Skip to main content

Accounts & vaults

An account is a custody vault in your workspace. You activate assets on it, generate deposit addresses, read balances, and send transfers from it.

Vault types

Choose the type deliberately at creation with vaultType — the two behave differently:

web3 — MPC-EOA (use for EVM)

A single MPC-controlled EOA where one EVM address holds every EVM asset (ETH plus all ERC-20s).

  • Deposits are detected by ZenVault's on-chain watcher, which catches every deposit — internal or external.
  • Outbound is signed via Web3 eth-sign; for contract-call/approve you supply evm transaction params (gas + chainId), and ZenVault assigns the nonce.
  • Web3 vaults pay their own gas — see Gas.

asset — asset vault (use for non-EVM)

A custody asset vault with a per-coin address. Use for BTC, TRON, SOL, and other non-EVM chains.

  • Deposits are detected by ZenVault's custody monitoring.
  • Gas is handled for you — no gas wallet needed.

:::tip Set vaultType explicitly If omitted, the type is inferred from firstAssetCanonical (an EVM asset → web3), defaulting to asset. Inference is a fallback — pass vaultType to be deterministic. The chosen type is echoed back as tags.vaultType. :::

Purpose

purpose is a label for how you use the vault: one of hot, warm, cold, escrow, gas, or generic (default). gas is special — there is exactly one gas wallet per workspace (see Gas).

External references — the per-user/per-merchant pattern

Stamp your own id on a vault with externalRef (unique per workspace) at create time, then resolve it later without paging the whole workspace:

GET /v1/accounts?externalRef=mch_42
→ { "items": [ { "id": "...", "externalRef": "mch_42", ... } ], "nextCursor": null }

This is the standard way to map a merchant or end-user to a dedicated vault. externalRef is editable via PATCH (send "" to clear); a duplicate returns 409.

See the Accounts API for full request/response shapes.