Build on Animica
Everything below runs against mainnet today. Each section gives you the shortest working snippet
and links to the long-form guide. Amounts are integer nANM (1 ANM = 10⁹ nANM), addresses are
bech32m anim1…, signatures are ML-DSA-65, and the RPC path /rpc is required.
Python: the animica package
pip install animica installs the node, the CLI, the wallet, the miners and the MCP
server in one package (current line 10.x). The CLI is the quickest way to create an account and
query the chain; for code, the JSON-RPC surface is small enough that a plain HTTP client is often
all you need. The richer in-repo SDK (sdk/python, module omni_sdk) adds
transaction builders, keystores and contract clients.
pip install --upgrade animica
animica wallet new # creates an ML-DSA-65 account, prints anim1zqp... address
animica wallet list
animica wallet show 0 # balance in ANM and nANM
animica node status --rpc-url https://rpc.animica.org/rpc
import requests
RPC = "https://rpc.animica.org/rpc"
def call(method, params=None):
r = requests.post(RPC, json={"jsonrpc": "2.0", "id": 1,
"method": method, "params": params or []})
r.raise_for_status()
body = r.json()
if "error" in body:
raise RuntimeError(body["error"]) # e.g. {"code": -32013, "message": "insufficient funds"}
return body["result"]
head = call("chain.getHead")
print(head["height"], head["thetaMicro"])
bal_hex = call("state.getBalance", ["anim1zqpn54yt2fz07wg5zz33qplkh7tewv30tm5s9cdwvag6kf6myvd2d5sj9pzp7"])
print(int(bal_hex, 16) / 1_000_000_000, "ANM") # balances are integer nANM
Guides: wallets and HD derivation · transactions and fees.
TypeScript SDK
@animica/sdk lives in sdk/typescript and targets Node 18+ and modern
browsers: typed JSON-RPC, address and bech32m helpers, transaction builders and contract clients.
It never signs server-side; keys stay in the application or in the user's wallet (the browser
extension injects window.animica). Build it from the monorepo with pnpm; the package
exports are documented in sdk/typescript/README.md.
// sdk/typescript in the monorepo (package name @animica/sdk)
import { RpcHttp } from '@animica/sdk/rpc/http'
const rpc = new RpcHttp({ url: 'https://rpc.animica.org/rpc', timeoutMs: 10_000 })
const head = await rpc.call('chain.getHead', [])
console.log(head.height, head.hash)
// Dry-run admission before broadcasting a signed, CBOR-encoded tx:
const verdict = await rpc.call('mempool.simulateAdmission', ['0x<cbor>'])
JSON-RPC
POST https://rpc.animica.org/rpc, JSON-RPC 2.0, CORS *. Namespaces are
chain.*, state.*, tx.*, mempool.*,
net.*, aicf.* and flat l2_*; EVM-style aliases such as
eth_chainId and eth_gasPrice (returns 0x1) exist for tooling
compatibility. There is no chain.getHeight (use chain.getHead) and no public
WebSocket. Use mempool.simulateAdmission to dry-run a signed transaction before
broadcasting it, and tx.decodeRawTransaction to inspect one.
# Head
curl -s -X POST https://rpc.animica.org/rpc -H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"chain.getHead","params":[]}'
# Balance (hex nANM)
curl -s -X POST https://rpc.animica.org/rpc -H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":2,"method":"state.getBalance","params":["anim1zqp..."]}'
# Status of a transaction: read confirmations; finalized only flips at 12 confirmations
curl -s -X POST https://rpc.animica.org/rpc -H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":3,"method":"tx.getStatus","params":["0x<txhash>"]}'
# Broadcast
curl -s -X POST https://rpc.animica.org/rpc -H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":4,"method":"tx.sendRawTransaction","params":["0x<cbor-envelope>"]}'
# Discover every method
curl -s https://rpc.animica.org/openrpc.json | jq '.methods[].name'
| Error code | Meaning |
|---|---|
-32010 | Invalid transaction (decode or structural failure) |
-32011 | Chain id mismatch (signed for a different network) |
-32012 | Bad signature |
-32013 | Insufficient funds for amount + gasLimit × gasPrice |
-32016 | Gas limit too low |
-32017 | Fee (gas price) below the floor |
-32018 | Transaction too large (limit 131,072 bytes) |
-32020 | Duplicate transaction id |
Full method list: rpc.animica.org/openrpc.json · guide: JSON-RPC API.
Smart contracts: the Python VM
Contracts are a strict, deterministic subset of Python: integers, bytes, booleans and addresses;
if/while/for range; integer arithmetic and bit operations; and
only from stdlib import storage, events, hash, abi, treasury, syscalls. No floats, no
I/O, no time or random, no eval. The compiler validates the
AST, lowers it to a small IR, and produces a static gas upper bound; the interpreter meters gas at
runtime from vm_py/gas_table.json. Storage values are bytes, and a missing key reads as
empty bytes. On-chain CALL execution has been live since block 75,000. Contract addresses use
scheme id 0x0000.
# vm_py/examples/counter/contract.py (abridged)
from typing import Final
from stdlib import abi, events, storage
K_COUNTER: Final[bytes] = b"counter:value"
def _load() -> int:
raw = storage.get(K_COUNTER) # storage values are bytes; missing key -> b""
return int.from_bytes(raw, "big", signed=True) if raw else 0
def get() -> int:
return _load()
def inc() -> None:
new = _load() + 1
storage.set(K_COUNTER, new.to_bytes(32, "big", signed=True))
events.emit(b"Counter.Incremented", {b"new": new})
def set(n: int) -> None:
abi.require(n >= 0, b"counter: negative")
storage.set(K_COUNTER, n.to_bytes(32, "big", signed=True))
events.emit(b"Counter.Set", {b"value": n})
# Validate + compile to IR and get a static gas estimate
python -m vm_py.cli.compile vm_py/examples/counter/contract.py --out /tmp/counter.ir
# Deploy and call with the in-repo Python SDK (sdk/python, omni_sdk)
PYTHONPATH=sdk/python python -m omni_sdk.cli.main deploy package ...
PYTHONPATH=sdk/python python -m omni_sdk.cli.main call read <address> get
PYTHONPATH=sdk/python python -m omni_sdk.cli.main call write <address> inc
Guides: Python-VM smart contracts · Hello Counter tutorial · Studio for a browser workflow.
The ANM-native L2
The 10.x L2 (l2/) is a payment rollup whose only asset is ANM and whose transactions
are ML-DSA-65 signed end to end. A designated sequencer orders transactions into batches; anyone
can re-derive the committed state root from the published DA blob; the bridge enforces that
withdrawable L2 ANM never exceeds ANM locked on L1; and forced inclusion via L1 bounds censorship.
L2 chain id is 1001 on mainnet. Treat soft confirmations as a promise by the sequencer and
L1_FINALIZED as the only final state.
# Run the L2 sequencer/verifier inside your node process
ANIMICA_L2_ENABLE=1 animica node up
# Flat l2_* methods on the same RPC server
curl -s -X POST http://127.0.0.1:8545/rpc -H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"l2_status","params":[]}'
curl -s -X POST http://127.0.0.1:8545/rpc -H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":2,"method":"l2_getBalance","params":["anim1zqp..."]}'
Guide: Animica L2 rollup.
AICF: AI compute
AICF is the framework that turns AI work into on-chain accounting: providers register and stake,
jobs are matched and served off-chain, and receipts settle in ANM. As a developer you can use it
two ways. The free, keyless OpenAI-compatible endpoint at animica.dev/v1 is served by
registered miners and returns ML-DSA-65-signed proof-of-inference receipts you can verify offline
with animica ai verify. For paid, budgeted access, mint a key at
console.animica.org.
The contract-side syscalls (ai_enqueue, read_result) are specified in
docs/aicf/CLIENT_GUIDE.md; use the HTTP APIs for production work today.
# Free, keyless, OpenAI-compatible (30 requests/min/IP)
curl -s https://animica.dev/v1/chat/completions \
-H 'content-type: application/json' \
-d '{"model":"animica-chat","messages":[{"role":"user","content":"What is PoIES?"}]}'
# Models and their serving flags
curl -s https://animica.dev/v1/models
# Chain-side AICF registry (59 aicf.* methods)
curl -s -X POST https://rpc.animica.org/rpc -H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"aicf.listProviders","params":[]}'
Guides: AICF explained · become a provider · pricing.
MCP server for AI agents
animica-mcp exposes chain reads, mining information and AICF inference as Model
Context Protocol tools, so Claude Desktop, Claude Code, Cursor or any MCP client can query the
network and use inference. It holds no private keys and cannot sign transactions; it is safe to
give to an agent. The server is also available as animica mcp serve inside the main
package.
pip install animica-mcp
animica-mcp # stdio transport (Claude Desktop, Claude Code, Cursor)
animica mcp serve --transport http # streamable HTTP, same tools
# Claude Desktop / Cursor config
{
"mcpServers": {
"animica": { "command": "animica-mcp" }
}
}
x402: per-call payments for agents
Animica runs an x402 gateway and facilitator at
x402.animica.dev.
A request to a paid resource returns HTTP 402 with machine-readable payment requirements; the
client signs a payment, retries, and receives the resource with a receipt. Products include
quantum randomness, bulk chain data, address history, web search and inference. The ANM-native
lane uses the CAIP-2 identifier animica:1, and the payer pays its own gas, which is
why ANM-lane prices are lower than the USDC lane.
# Discover paid products and their 402 requirements
curl -s https://x402.animica.dev/x402
# First call returns 402 + PAYMENT-REQUIRED; your x402 client signs a payment and retries.
# The ANM-native lane identifies the chain as CAIP-2 "animica:1" (never "eip155:1").
curl -i https://x402.animica.dev/x402/qrng
Guide: x402 agent payments.
Accepting ANM
For a checkout flow, pay.animica.dev
offers a merchant REST API (/api/v1/payment-intents, Bearer key plus an
Idempotency-Key header, amounts in base units) with a 2.00% fee. For self-hosted
acceptance, watch an address with state.getBalance or the explorer API and wait for
the confirmation depth you are comfortable with. See
how to buy and accept ANM.
Sources
AGENTS.md · spec/openrpc.json · docs/rpc-quickstart.md · sdk/typescript/README.md · sdk/python/README.md · docs/vm/OVERVIEW.md · vm_py/examples/counter/contract.py · docs/tutorials/HELLO_COUNTER.md · docs/l2/ARCHITECTURE.md · docs/l2/RUNNING.md · docs/l2/SECURITY_ASSUMPTIONS.md · docs/AICF.md · docs/aicf/CLIENT_GUIDE.md · docs/x402.md · animica-mcp/README.md