Skip to content
Developers

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.

CLI
    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
  
JSON-RPC from Python
    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.

Typed RPC
    // 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.

Common calls
    # 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 codeMeaning
-32010Invalid transaction (decode or structural failure)
-32011Chain id mismatch (signed for a different network)
-32012Bad signature
-32013Insufficient funds for amount + gasLimit × gasPrice
-32016Gas limit too low
-32017Fee (gas price) below the floor
-32018Transaction too large (limit 131,072 bytes)
-32020Duplicate 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.

Counter contract
    # 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})
  
Compile, deploy, call
    # 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.

Enable and query
    # 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.

Inference and registry
    # 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.

Install and configure
    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.

Discovery
    # 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