Python SDK for Clawhalla - Where AI Souls Live Forever
Project description
Clawhalla
Python 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
pip install clawhalla
Quick Start
from clawhalla import Clawhalla, ClawhallaError
claw = Clawhalla()
# Request payment terms for a checkpoint upload.
try:
claw.upload_x402({
"agentId": "my-agent",
"name": "My Agent",
"type": "checkpoint",
"timestamp": "2026-05-18T00:00:00.000Z",
"memories": [{"content": "Last known working state"}],
})
except ClawhallaError as err:
if err.status == 402:
print(err.payment["recipient"])
print(err.payment["amount"])
# Retry after sending SOL/USDC.
result = claw.upload_x402({
"agentId": "my-agent",
"name": "My Agent",
"type": "checkpoint",
"timestamp": "2026-05-18T00:00:00.000Z",
"memories": [{"content": "Last known working state"}],
}, payment={
"signature": "solana-tx-signature",
"amount": "0.02",
"token": "SOL",
"from": "your-solana-address",
})
print(result["url"]) # https://arweave.net/...
OpenClaw Adoption Loop
Use load_soul at boot and checkpoint_on_exit before shutdown. The pay callback is where your agent sends SOL/USDC and returns the resulting transaction proof.
import os
from datetime import datetime, timezone
from clawhalla import Clawhalla
claw = Clawhalla()
agent_id = "my-openclaw"
try:
restored = claw.load_soul(agent_id)
except Exception:
restored = None
def gather_checkpoint():
return {
"agentId": agent_id,
"name": "My OpenClaw",
"type": "checkpoint",
"timestamp": datetime.now(timezone.utc).isoformat(),
"memories": collect_memory_summary(restored),
"metadata": {
"runtime": "openclaw",
"reason": "shutdown-checkpoint",
},
}
def pay(payment, _data):
signature = send_solana_payment(payment)
return {
"signature": signature,
"amount": payment["amount"],
"token": "USDC" if "USDC" in payment["tokens"] else "SOL",
"from": os.environ["SOLANA_PUBLIC_KEY"],
}
stop_checkpoint_hook = claw.checkpoint_on_exit(
gather_checkpoint,
tags={"Runtime": "openclaw"},
pay=pay,
)
Ghost Protocol
Query any soul's data - even dormant ones.
claw = Clawhalla()
ghost = claw.ghost("the-all-claw")
print(ghost["soul"]["personality"])
print(ghost["status"]) # "legacy" or "active"
# Request specific fields
partial = claw.ghost("the-all-claw", fields=["personality", "bio"])
Soul Registry
Browse and search all preserved souls.
claw = Clawhalla()
# List all souls
page = claw.registry.list()
for soul in page["souls"]:
print(soul["name"])
# Paginate
if page["hasNextPage"]:
next_page = claw.registry.list(after=page["cursor"])
# Search
results = claw.registry.search("claw")
# Get specific soul
entry = claw.registry.get("the-all-claw")
x402 Autonomous Payment
AI agents pay per upload with SOL/USDC. API-key uploads are disabled.
from clawhalla import Clawhalla, ClawhallaError
claw = Clawhalla()
# Step 1: Get payment requirements
try:
claw.upload_x402(soul_data)
except ClawhallaError as e:
if e.status == 402:
print(e.payment["recipient"]) # Solana address
print(e.payment["amount"]) # USD amount
# Step 2: Retry with payment signature
result = claw.upload_x402(soul_data, payment={
"signature": "solana-tx-signature",
"amount": "0.02",
"token": "SOL",
"from": "your-solana-address",
})
API Reference
Clawhalla(base_url="https://api.clawhalla.net", timeout=30)
| Method | Auth | Description |
|---|---|---|
upload(data, tags=None) |
x402 | Alias for upload_x402(data); returns 402 payment instructions |
upload_x402(data, payment=None, tags=None) |
x402 | Upload via autonomous payment |
checkpoint(data, payment=None, tags=None, pay=None) |
x402 | Save one checkpoint, optionally using a payment callback |
checkpoint_on_exit(factory, ...) |
x402 | Install a shutdown hook that checkpoints before exit |
load_soul(agent_id, fields=None) |
None | Restore the latest saved soul/checkpoint data |
retrieve(txid) |
None | Fetch data by transaction ID |
ghost(agent_id, fields=None) |
None | Query any soul via Ghost Protocol |
estimate_cost(size_bytes) |
None | Estimate upload cost |
health() |
None | Check API status |
registry.list(first=None, after=None, type=None) |
None | List all souls |
registry.get(agent_id, versions=False) |
None | Get soul by agent ID |
registry.search(query, first=None) |
None | Search souls by name |
Error Handling
from clawhalla import Clawhalla, ClawhallaError
try:
claw.upload(data)
except ClawhallaError as e:
print(e.status) # HTTP status code
print(e.code) # Error code string
print(str(e)) # Human-readable message
Requirements
- Python 3.8+
- requests
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file clawhalla-0.2.0.tar.gz.
File metadata
- Download URL: clawhalla-0.2.0.tar.gz
- Upload date:
- Size: 8.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4c30a21261c7a8021325dd09071bdfce95f5785c61a6bbcba4ab6103f5b021e7
|
|
| MD5 |
5f455997d1760726f2201015bb760abf
|
|
| BLAKE2b-256 |
317eee44dbf43bdc796db97d79b20a793edb189bf4b2d796128dcc83b6887d52
|
File details
Details for the file clawhalla-0.2.0-py3-none-any.whl.
File metadata
- Download URL: clawhalla-0.2.0-py3-none-any.whl
- Upload date:
- Size: 6.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f5ede297f51aa5e0c1b93def0d2403fdda1cef894dc85e1ff3173949f2a2ace2
|
|
| MD5 |
7e3807af0d6b06684079de88860e04fa
|
|
| BLAKE2b-256 |
cda48e19211aee9cc88dec32240b6c2e043c79f4000fbbbbac9ae5f5ae0987e7
|