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.

createClient

import { createClient } from "@calm-xyz/react";

const calm = createClient({
  getAccessToken: async () => privyAuth.getIdentityToken(),
  baseUrl: "https://api.calmtreasury.xyz",  // optional
});

Options

getAccessToken
() => Promise<string | null>
required
Returns a Privy identity token. Called on session() only.
baseUrl
string
default:"https://api.calmtreasury.xyz"
API root.
fetch
typeof fetch
Override the global fetch. Useful for tracing, mocking, or running on a non-browser runtime.

Bootstrap

const session = await calm.session();
// → { wallet: "0xabc…", expiresAt: "2026-…" }
Every subsequent call uses credentials: "include". The cookie attaches automatically — you never see the JWT after this point.

Wallet operations

const state = await calm.wallets.get(session.wallet);
// → { wallet, kycState, hasAcceptedTos }

await calm.wallets.register(session.wallet, {
  first_name: "Ada",
  last_name:  "Lovelace",
  email:      "ada@example.com",
  country:    "US",
});

const { url: tosUrl } = await calm.wallets.tosLink(session.wallet);
const { url: kycUrl } = await calm.wallets.kycLink(session.wallet);

Virtual account

const va = await calm.wallets.virtualAccount.create(session.wallet, {
  currency: "usd",       // "usd" | "gbp" | "eur"
  chain:    "hyper_evm", // "arbitrum" | "base" | "ethereum" | "hyper_evm"
});

// or fetch the existing one:
const va = await calm.wallets.virtualAccount.get(session.wallet);

Full surface

MethodHTTP
calm.session()POST /v1/session
calm.wallets.get(wallet)GET /v1/wallets/:wallet
calm.wallets.register(wallet, body)POST /v1/wallets/:wallet
calm.wallets.tosLink(wallet)POST /v1/wallets/:wallet/tos-link
calm.wallets.kycLink(wallet)POST /v1/wallets/:wallet/kyc-link
calm.wallets.virtualAccount.create(wallet, body)POST /v1/wallets/:wallet/virtual-account
calm.wallets.virtualAccount.get(wallet)GET /v1/wallets/:wallet/virtual-account

Error handling

All non-2xx responses throw CalmApiError. See Errors for the full code table.
import { CalmApiError } from "@calm-xyz/react";

try {
  await calm.wallets.virtualAccount.create(wallet, body);
} catch (err) {
  if (err instanceof CalmApiError) {
    if (err.code === "kyc_required") {
      // surface "complete KYC first" to the user
    }
    if (err.code === "already_has_virtual_account") {
      // they're done — fetch the existing VA
    }
  }
}
CalmApiError shape:
class CalmApiError extends Error {
  status: number;       // HTTP status
  code: string;         // stable, machine-readable
  message: string;      // human-readable, may change wording
  details?: unknown;    // optional zod field errors on 400
}