Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.calmtreasury.xyz/llms.txt

Use this file to discover all available pages before exploring further.

One virtual account per (app_id, wallet). The destination is always the cookie-bound wallet on the chain you pick at create time; the destination currency is hardcoded usdc.

POST /v1/wallets/:address/virtual-account

Provision the virtual account.
curl -X POST https://api.calmtreasury.xyz/v1/wallets/0xabc…/virtual-account \
  --cookie "calm_session=<jwt>" \
  -H "Content-Type: application/json" \
  -d '{ "currency": "usd", "chain": "hyper_evm" }'
{
  "id":       "va_abc123",
  "currency": "usd",
  "status":   "activated",
  "destination": {
    "payment_rail": "hyper_evm",
    "currency":     "usdc",
    "address":      "0xabc…"
  },
  "deposit_instructions": {
    "bank_account_number": "111000000",
    "bank_routing_number": "021000021",
    "payment_rails":       ["ach_push", "fednow", "wire"]
  },
  "developer_fee_percent": "0.10",
  "created_at": "2026-06-02T19:00:00.000Z"
}

Body

currency
enum
required
Source (fiat) currency. One of "usd", "gbp", "eur".
chain
enum
required
Destination EVM chain. One of "arbitrum", "base", "ethereum", "hyper_evm".

Response

id
string
Bridge’s virtual account id. Persisted on the customer row.
currency
enum
Echoed from the request.
status
enum
"activated" | "deactivated".
destination
object
  • payment_rail — echoed chain
  • currency — always "usdc"
  • address — cookie-bound wallet
deposit_instructions
object
Currency-varying. USD: bank_account_number, bank_routing_number, payment_rails. GBP: sort_code, account_number. EUR: iban, bic. Shape passes through from Bridge — show every key with a non-empty value.
developer_fee_percent
string
created_at
string

Constraints

ErrorWhen
customer_not_registered (404)No row yet — call POST /v1/wallets/:address first.
kyc_required (409)Bridge customer status is not active.
already_has_virtual_account (409)One VA per customer at v1.
validation_error (400)Bad currency or chain.

GET /v1/wallets/:address/virtual-account

Fetch the existing VA (proxied from Bridge).
curl https://api.calmtreasury.xyz/v1/wallets/0xabc…/virtual-account \
  --cookie "calm_session=<jwt>"
Response is identical to the create response shape. Errors: customer_not_registered, virtual_account_not_provisioned (404, before any VA exists), wallet_token_mismatch, bridge_error.

Why one VA per customer (v1)

Bridge supports multiple VAs per customer — different (currency, chain) combinations let you accept GBP-to-Base and USD-to-HyperEVM separately. We constrain to one row at v1 to keep the SDK’s mental model simple (“the deposit account”). Multi-VA support lands when partners ask for it.