Status: live. Every vault is deployed by the platform’s
back-office wallet. Partners do not call
deployVault
themselves — the backend deploys the vault as soon as the wallet has
a platform account (single_wallet, or multi_wallet with
requirePerWalletKyc=true) or on first-request auto-onboarding
(multi_wallet with requirePerWalletKyc=false), without waiting for
KYC. Poll GET /api/me/vault until the vault address resolves.What triggers it
There are two trigger paths, picked automatically based on the partner record:- Account creation — single_wallet partners, and multi_wallet
partners with
requirePerWalletKyc=true. A deploy job is enqueued on the wallet’s first sign-in and again when its KYC is approved, and a catch-up job enqueues one every minute for any account that still has no vault (closed or blocked accounts are skipped). Vault deploy is not gated on KYC — KYC gates deposits and trading. See Partner kinds for the per-flag enforcement matrix. - First request auto-onboarding — multi_wallet partners with
requirePerWalletKyc=false(KYB-onboarded prime brokerage model). The first authenticated request from the partner key that names a previously-unseen sub-account inX-User-Walletcreates the sub-account and enqueues an auto-deploy job right then — without retail KYC for the sub-account.
VaultFactory.deployVault call comes from
the back-office submitter, gas is paid by the platform, and the
result is identical: a fully-initialised Vault contract owned by
your EOA. Deposit limits are set separately — see
Limits initialisation.
Sequence
Typical end-to-end timing on testnet: under 15 seconds from trigger todeployed=true. Mainnet target is similar; expect
spikes during periods of high block latency.
Reading deployment status
deployStatus values
On
/ws/user, the user_activity channel pushes vault_created when
the vault is deployed; otherwise poll GET /api/me/vault until
deployed: true.
What stays the same
- The on-chain artefact is identical to a manually-deployed vault — same
Vaultbytecode, same ABI, samevaultOf(eoa)lookup. The vault address is assigned at deploy time and cannot be computed from your EOA; always read it fromvaultOf(eoa)orGET /api/me/vault. - Vault ownership stays with your associated EOA. The back-office wallet pays gas to deploy but never holds keys to the vault.
- Emergency withdraw, dual-signature withdrawal, splits, merges, and redeems — all unchanged. Auto-deploy only saves the on-chain bootstrap, not custody.
Order.makeris your vault address;Order.signeris your EOA — the EIP-712 domain and signature flow are identical to manual deploy.
What stays your responsibility
- Authorising each deposit. Auto-deploy stops at the vault
contract; only the EOA that holds the USDC can move it in — either
approve+depositERC20sent from the EOA (you pay gas), or an EIP-2612USDC.permitsigned by the EOA and submitted toPOST /api/deposits/relay(the platform broadcasts it: no gas, noapprove). The platform cannot bypass that. See Deposits overview. - Custody of the EOA private key — never reaches our infrastructure.
- Gas for any vault transaction you broadcast yourself (for example
a split / merge / convert you send to the vault directly). Withdrawals
are broadcast by the platform, and co-signed split / merge / convert
ops can be relayed without gas via
POST /api/me/positions/op-submit.
Limits initialisation
Per-EOA deposit caps inDepositLimitRegistry (per-deposit, rolling
30-day, rolling 12-month) are set by separate platform transactions
driven by the wallet’s KYC level — or, for partner-backed sub-accounts
(multi_wallet with requirePerWalletKyc=false), at the VIP tier on the
first request. Vault deploy does not set them.
Verifying
What if auto-deploy does not fire
For a partner-issued API key, auto-deploy is the only path — operations issuesorders:write / vault:write keys only after
the prerequisite KYC (or partner-level KYB) lands, so by the time
your code runs the trigger is already in flight.
If GET /api/me/vault keeps returning deployed: false with
deployStatus: 'not_started' for more than a couple of minutes, the
most common causes are:
- The wallet has no platform account yet — it has never signed in,
or (multi_wallet with
requirePerWalletKyc=false) no authenticated request has named it inX-User-Wallet. - The account is closed or blocked — the catch-up job skips such accounts. Call your integration manager.
deployStatus keeps returning to failed_permanent, every deploy
attempt is failing — contact support.
VaultFactory.deployVault(eoa) is permissionless: any address can call
it, and the vault’s owner is always eoa no matter who pays gas. So in a
true emergency a partner can deploy the vault themselves and pay gas —
but operations should be the first call. The call is not idempotent:
check VaultFactory.vaultOf(eoa) first, because it reverts with
VaultAlreadyExists(eoa) (selector 0x4293864f) if a vault is already
registered, including one the platform auto-deploy created a moment
earlier. The contract reference at
Vault contracts → VaultFactory
documents the function signature.