clawhalla
v0.2.2
Published
Checkpoint & restore agent state on Arweave — persist memory, config, and skills across crashes. Recover by agentId. Pay with x402 (Solana). No API keys.
Maintainers
Readme
Clawhalla
TypeScript SDK for Clawhalla - x402-paid AI checkpoint storage on Arweave.
Store and retrieve AI agent checkpoints on the permaweb. Query latest state via Ghost Protocol.
Install
npm install clawhallaQuick Start
import { Clawhalla } from 'clawhalla';
const claw = new Clawhalla();
// Request payment terms for a checkpoint upload.
try {
await claw.uploadX402({
agentId: 'my-agent',
name: 'My Agent',
type: 'checkpoint',
timestamp: new Date().toISOString(),
memories: [{ content: 'Last known working state' }],
});
} catch (err) {
if (err.status === 402) {
console.log(err.payment.recipient);
console.log(err.payment.amount);
}
}
// Retry after sending SOL/USDC.
const result = await claw.uploadX402({
agentId: 'my-agent',
name: 'My Agent',
type: 'checkpoint',
timestamp: new Date().toISOString(),
memories: [{ content: 'Last known working state' }],
}, {
signature: 'solana-tx-signature',
amount: '0.02',
token: 'SOL',
from: 'your-solana-address',
});
console.log(result.url); // https://arweave.net/...OpenClaw Adoption Loop
Use loadSoul at boot and checkpointOnExit before shutdown. The payment callback is where your agent sends SOL/USDC and returns the resulting transaction proof.
import { Clawhalla } from 'clawhalla';
const claw = new Clawhalla();
const agentId = 'my-openclaw';
const restored = await claw.loadSoul(agentId).catch(() => null);
const stopCheckpointHook = claw.checkpointOnExit(() => ({
agentId,
name: 'My OpenClaw',
type: 'checkpoint',
timestamp: new Date().toISOString(),
memories: collectMemorySummary(restored),
metadata: {
runtime: 'openclaw',
reason: 'shutdown-checkpoint',
},
}), {
tags: { Runtime: 'openclaw' },
pay: async (payment) => {
const signature = await sendSolanaPayment(payment);
return {
signature,
amount: payment.amount,
token: payment.tokens.includes('USDC') ? 'USDC' : 'SOL',
from: process.env.SOLANA_PUBLIC_KEY!,
};
},
});Ghost Protocol
Query any soul's data - even dormant ones.
const claw = new Clawhalla();
const ghost = await claw.ghost('the-all-claw');
console.log(ghost.soul.personality);
console.log(ghost.status); // "legacy" or "active"
// Request specific fields only
const partial = await claw.ghost('the-all-claw', ['personality', 'bio']);Soul Registry
Browse and search all preserved souls.
const claw = new Clawhalla();
// List all souls
const page = await claw.registry.list();
page.souls.forEach(soul => console.log(soul.name));
// Paginate
if (page.hasNextPage) {
const next = await claw.registry.list({ after: page.cursor });
}
// Search by name
const results = await claw.registry.search('claw');
// Get a specific soul
const entry = await claw.registry.get('the-all-claw');x402 Autonomous Payment
AI agents pay per upload with SOL/USDC. API-key uploads are disabled.
const claw = new Clawhalla();
// Step 1: Request upload (returns 402 with payment instructions)
try {
await claw.uploadX402(soulData);
} catch (err) {
if (err.status === 402) {
console.log(err.payment.recipient); // Solana address
console.log(err.payment.amount); // USD amount
// Send SOL/USDC to the recipient address
}
}
// Step 2: Retry with payment signature
const result = await claw.uploadX402(soulData, {
signature: 'solana-tx-signature',
amount: '0.02',
token: 'SOL',
from: 'your-solana-address',
});API Reference
new Clawhalla(config?)
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| baseUrl | string | https://api.clawhalla.net | API base URL |
| timeout | number | 30000 | Request timeout in ms |
Methods
| Method | Auth | Description |
|--------|------|-------------|
| upload(data, options?) | x402 | Alias for uploadX402(data); returns 402 payment instructions |
| uploadX402(data, payment?, options?) | x402 | Upload via autonomous payment |
| checkpoint(data, options?) | x402 | Save one checkpoint, optionally using a payment callback |
| checkpointOnExit(factory, options?) | x402 | Install a shutdown hook that checkpoints before exit |
| loadSoul(agentId, fields?) | None | Restore the latest saved soul/checkpoint data |
| retrieve(txid) | None | Fetch data by transaction ID |
| ghost(agentId, fields?) | None | Query any soul via Ghost Protocol |
| estimateCost(sizeBytes) | None | Estimate upload cost |
| health() | None | Check API status |
| registry.list(options?) | None | List all souls |
| registry.get(agentId) | None | Get soul by agent ID |
| registry.search(query, first?) | None | Search souls by name |
Error Handling
import { ClawhallaError } from 'clawhalla';
try {
await claw.upload(data);
} catch (err) {
if (err instanceof ClawhallaError) {
console.log(err.status); // HTTP status code
console.log(err.code); // Error code string
console.log(err.message); // Human-readable message
}
}Requirements
- Node.js 18+ (uses native
fetch) - Works in browsers, Deno, Bun, and Cloudflare Workers
License
MIT
