Clients

Create and manage clients, retrieve wallet addresses and metadata, inspect share statuses, and access client-scoped wallet operations.

A client is the entity that represents one end user. It holds wallets, share-pair statuses, and addresses. You manage clients through wallets.custodian.

Create a Client

const newClient = await wallets.custodian.createClient({
  body: {
    isAccountAbstracted: true,
  },
});

// newClient.id           — permanent client ID, store in your DB
// newClient.clientApiKey — permanent auth token for this client
// newClient.clientSessionToken — short-lived session token (alternative to clientApiKey)

isAccountAbstracted - set to true if you want account abstraction support (ERC-4337).

Get a Client

Fetch a client's full details from the custodian side (all wallets, addresses, share statuses):

const details = await wallets.custodian.getClient({
  path: { clientId: "cli_..." },
});

Returns a ClientDetails object.

List Clients

const page = await wallets.custodian.listClients({
  query: { take: 50 },
});

// page.results   — array of ClientDetails
// page.metadata.cursor — pass to next call for pagination
// page.metadata.total  — total number of clients

// Next page:
const nextPage = await wallets.custodian.listClients({
  query: { take: 50, cursor: page.metadata?.cursor ?? undefined },
});

Maximum take is 100.

Initialise a Client-Scoped API

Once you have a clientApiKey or a fresh clientSessionToken, create a scoped WalletsClient:

const client = wallets.initClient({
  token: newClient.clientApiKey!,
});

Use the clientApiKey for server-to-server calls (it's permanent). Use a clientSessionToken for short-lived sessions (see Sessions).

ClientDetails Shape

interface ClientDetails {
  id?: string;
  createdAt?: string;
  isAccountAbstracted?: boolean;
  ejectedAt?: string | null;

  custodian?: {
    id?: string;
    name?: string;
  };

  environment?: {
    id?: string;
    name?: string;
    backupWithPortalEnabled?: boolean;
    isMultiBackupEnabled?: boolean;
  };

  metadata?: {
    namespaces?: Record<string, {
      address?: string;  // wallet address for this namespace
      curve?: "SECP256K1" | "ED25519";
    }>;
  };

  wallets?: Array<{
    id?: string;
    curve?: "SECP256K1" | "ED25519";
    publicKey?: string | null;
    ejectableUntil?: string | null;
    createdAt?: string;
    signingSharePairs?: Array<{
      id?: string;
      status?: string;  // "STORED_CLIENT" | "STORED_DATABASE" | "completed" | "incomplete"
      createdAt?: string;
    }>;
    backupSharePairs?: Array<{
      id?: string;
      status?: string;
      backupMethod?: string;
      createdAt?: string;
    }>;
  }>;
}

Wallet Addresses

Addresses live in details.metadata.namespaces. The namespace key is the CAIP-2 chain ID:

const details = await client.getClientDetails();

// EVM address (same across all EVM chains)
const evmAddress = details.metadata?.namespaces?.["eip155"]?.address;

// Solana address
const solAddress = details.metadata?.namespaces?.["solana"]?.address;