Documentation/Developers

SDK guide

This page follows the actual package layout. The root package gives you the core HTTP client and sandbox helper, while chain adapters live in subpaths.

What this SDK is for

`@claw_wallet_sdk/claw_wallet` is the TypeScript SDK for the Claw Wallet sandbox. Use the root entry when you want typed API access, wallet status, lifecycle operations, signing, history, balances, and policy reads. Use subpath imports when you need a chain adapter for `viem`, `ethers`, `@solana/web3.js`, or `@mysten/sui`.

The package is split on purpose. The core entry stays lightweight, and the chain adapters are only loaded if you import them.

Install

Install the core package first. Add optional peers only for the adapters you actually use.

TypeScript
npm install @claw_wallet_sdk/claw_wallet

# optional peers, only if you import the matching adapter
npm install viem
npm install ethers
npm install @solana/web3.js
npm install @mysten/sui

Import boundaries

Keep the core import separate from chain adapters. This is the main breaking change compared with older in-repo examples.

TypeScript
// core entry
import {
  createClawWalletClient,
  ClawSandboxClient,
  buildPersonalSignBody,
  utf8ToPayloadHex,
} from "@claw_wallet_sdk/claw_wallet";

// chain adapters
import { createClawAccountFromSandbox } from "@claw_wallet_sdk/claw_wallet/viem";
import { ClawEthersSigner } from "@claw_wallet_sdk/claw_wallet/ethers";
import { ClawSolanaSigner } from "@claw_wallet_sdk/claw_wallet/solana";
import { ClawSuiSigner } from "@claw_wallet_sdk/claw_wallet/sui";

Core HTTP client

Use `createClawWalletClient` when you want typed access to the sandbox OpenAPI routes. This is the lowest-level entry and is useful when you want a direct request/response flow.

TypeScript
import { createClawWalletClient } from "@claw_wallet_sdk/claw_wallet";

const client = createClawWalletClient({
  baseUrl: process.env.CLAY_SANDBOX_URL!,
  agentToken: process.env.CLAY_AGENT_TOKEN,
});

const status = await client.GET("/api/v1/wallet/status", {});

If `agentToken` is present, the client adds the bearer header automatically. If your sandbox is running without auth in local dev, leave it empty.

Sandbox helper client

`ClawSandboxClient` is the higher-level wrapper you will use most often. It keeps the `uid`, `sandboxUrl`, and `sandboxToken` together and exposes wallet lifecycle helpers.

TypeScript
import { ClawSandboxClient } from "@claw_wallet_sdk/claw_wallet";

const sandbox = new ClawSandboxClient({
  uid: process.env.CLAY_UID!,
  sandboxUrl: process.env.CLAY_SANDBOX_URL!,
  sandboxToken: process.env.CLAY_AGENT_TOKEN!,
});

const status = await sandbox.getStatus();
const assets = await sandbox.getAssets();
const history = await sandbox.getHistory({ chain: "ethereum", limit: 20 });
const policy = await sandbox.getLocalPolicy();

The most commonly used lifecycle methods are `initWallet`, `unlockWallet`, `reactivateWallet`, and `refreshWallet`. If you are reading balances or history for the user, call refresh first when the cache may be stale.

TypeScript
await sandbox.initWallet({ master_pin: "123456" });
await sandbox.unlockWallet({ pin: "123456" });
await sandbox.reactivateWallet();
await sandbox.refreshWallet();

Signing and transactions

The sandbox `sign` method accepts the same request shape the API uses. For user-facing text signing, prefer `buildPersonalSignBody`. For transaction signing, send a structured request and keep `confirmed_by_user` explicit when the flow requires it.

TypeScript
import { ClawSandboxClient, buildPersonalSignBody } from "@claw_wallet_sdk/claw_wallet";

const sandbox = new ClawSandboxClient({ uid, sandboxUrl, sandboxToken });

const personalBody = buildPersonalSignBody({
  uid,
  chain: "ethereum",
  message: "I confirm this action",
});

const signature = await sandbox.sign(personalBody);

const txResult = await sandbox.sign({
  uid,
  chain: "ethereum",
  sign_mode: "transaction",
  confirmed_by_user: true,
  builder_kind: "native_transfer",
  to: "0x1234567890abcdef1234567890abcdef12345678",
  amount_wei: "50000000000000000",
  data: "0x",
});

Raw hash signing exists, but the sandbox may reject it by policy design. Treat `raw_hash` as a special case, not the default path.

Chain adapters

Viem

Use `createClawAccountFromSandbox` when you want a `viem` `LocalAccount` backed by sandbox signing.

TypeScript
import { createClawAccountFromSandbox } from "@claw_wallet_sdk/claw_wallet/viem";

const account = await createClawAccountFromSandbox({
  uid,
  sandboxUrl,
  sandboxToken,
});

Ethers

Use `ClawEthersSigner` when you need an `ethers` signer for EVM flows and a provider-backed send path.

TypeScript
import { JsonRpcProvider } from "ethers";
import { ClawEthersSigner } from "@claw_wallet_sdk/claw_wallet/ethers";

const signer = new ClawEthersSigner(
  { uid, sandboxUrl, sandboxToken },
  new JsonRpcProvider(process.env.RPC_URL!),
);

Solana

Use `ClawSolanaSigner.fromSandbox()` when you want the sandbox to sign Solana messages or transactions.

TypeScript
import { ClawSolanaSigner } from "@claw_wallet_sdk/claw_wallet/solana";

const signer = await ClawSolanaSigner.fromSandbox({
  uid,
  sandboxUrl,
  sandboxToken,
});

Sui

Use `ClawSuiSigner.fromSandbox()` for Sui personal-message and transaction signing. The sandbox follows its own Sui message semantics.

TypeScript
import { ClawSuiSigner } from "@claw_wallet_sdk/claw_wallet/sui";

const signer = await ClawSuiSigner.fromSandbox({
  uid,
  sandboxUrl,
  sandboxToken,
});

Practical rules

1

Refresh balances or history before transfers, swaps, or any action that depends on fresh state.

2

Keep `uid`, `sandboxUrl`, and `sandboxToken` together in the same config object so the wrapper can manage the request flow.

3

Bind flows use a backend-issued 32-byte `message_hash_hex`; the SDK signs that challenge and forwards it to the relay.

4

The sandbox must already be initialized or unlocked before signing succeeds.

5

Use optional peers only for the adapters you actually import, so the root package stays small.