How Animica is built
Eight layers, each with one or two design decisions that explain everything else. Each section links to the long-form article. Where something exists in the protocol but is not enforced on mainnet, it says so.
1. Post-quantum signatures: ML-DSA-65
Every account key on Animica is an ML-DSA-65 keypair, the FIPS 204 standardisation of Dilithium3,
a lattice-based scheme at NIST security category 3. There is no ECDSA or Ed25519 anywhere in
consensus, which is what makes the chain post-quantum by default rather than by a future
migration. The trade-off is size: a signature is about 50 times larger than an ECDSA signature,
and that single fact shapes the transaction limit (131,072 bytes), the P2P framing, and the L2's
data-availability design. Mainnet accepts only scheme id 0x1003 for new transactions;
SPHINCS+ (0x1002) exists in the code as a legacy scheme but is consensus-stranded and
cannot sign on mainnet. Hashing throughout is NIST SHA-3, not Keccak-256.
| Public key | 1,952 bytes |
| Secret key | 4,032 bytes |
| Signature | 3,309 bytes |
| Scheme id | 0x1003 (4099) |
| Standard | FIPS 204 (ML-DSA-65, lineage name Dilithium3) |
Read: Why ML-DSA-65.
2. Addresses and HD derivation
An address is bech32m (BIP-350) with human-readable part anim and a 34-byte payload:
the 2-byte scheme id followed by SHA3-256 of the public key. Account addresses therefore begin
anim1zqp and are 66 characters long; contract addresses use scheme id
0x0000. Plain bech32 checksums are rejected. Because ML-DSA key generation is a pure
function of a 32-byte seed, HD wallets derive that seed with BIP-39 and SLIP-0010 (ed25519-style
hardened derivation) along m/44'/4279885'/account'/0'/index', where 4279885 is ASCII
"ANM". Every wallet that follows docs/wallet/HD_DERIVATION.md recovers the same
addresses from the same words.
Read: Addresses · Wallets and HD derivation.
3. Transactions without nonces
The v2 transaction body has no nonce. Instead it carries a validity window
(validAfter, validUntil block heights) and a random salt; the transaction
id must be unique within the window, which gives replay protection without the ordering problems
a nonce causes for wallets that sign offline or from several devices. The body is canonical CBOR
(RFC 8949 §4.2.1), the signing preimage is domain-separated (animica.tx.v1) and wrapped
with the chain id and fork id, hashed with SHA3-512 and signed with ML-DSA-65. The envelope is
{tx, sigs: [{alg: 4099, pubkey, sig}]}. Legacy nonce-based v1 transactions are
still accepted. A transfer costs 21,000 gas at a price of 1 nANM, so 0.000021 ANM; admission
requires the balance to cover amount plus gas limit × gas price.
Read: Transactions and fees.
4. PoIES consensus
Blocks are produced by SHA3-256 proof-of-work over the header and nonce. The acceptance rule,
PoIES (Proof-of-Integrated-External-Services), is written as a score: S = H(u) + Σψ ≥ Θ,
where the block hash maps to a uniform draw u, H(u) = −ln(u) measures
hash luck in nats, and Σψ is the weighted sum of verified useful-work proofs (AI,
quantum, storage, VDF) under per-type and global caps. Θ, exposed as thetaMicro in
micro-nats, is retargeted every block by an EMA on ln(dt/T) with a 60-second target
and, since block 75,000, bounded per-step and global limits.
The honest status: every mainnet block so far has Σψ = 0. The reference miner
attaches no proofs, and the useful-work verification rule armed at 75,000 is presence-gated and
runs in shadow mode on mainnet, so blocks are accepted on hash work alone. There is no finality
gadget; a 100-block reorg bound has been enforced since 75,000, and confirmations are the
measure of settlement.
Read: PoIES explained · Difficulty and Θ · Useful work: designed vs live.
5. The deterministic Python VM
Contracts are written in a validated subset of Python and compiled to a small IR with a stable
CBOR encoding. Determinism comes from subtraction: no floats, no I/O, no time or randomness, no
reflection, bounded integers and containers, and an import allowlist of
storage, events, hash, abi, treasury, syscalls. A static estimator gives a gas upper
bound before execution and the interpreter meters actual gas from vm_py/gas_table.json.
Storage is a byte-keyed, byte-valued map. On-chain execution of contract CALLs activated at block
75,000 with release 9.6.0; before that height every CALL reverted, which is why the fork is
history-safe.
Read: Python-VM contracts · Hello Counter.
6. The ANM-native L2
The 10.x rollup is deliberately narrow: one asset (ANM in nANM), a fixed set of payment transaction types, and ML-DSA-65 signatures end to end. State is a depth-256 sparse Merkle tree keyed by address; the executor builds an account-conflict graph and runs independent components in parallel with results identical to a sequential run. Batches close on count, bytes or age, are published as self-describing DA blobs from which anyone can re-derive the state root, and are anchored to L1 (consensus-interpreted from L1 height 80,000). The trust model is stated plainly: a designated sequencer orders transactions; what bounds it is re-derivability, the bridge's conservation invariant, and forced inclusion through L1.
Read: Animica L2.
7. AICF: AI compute with on-chain accounting
The AI Compute Framework connects three parties: requesters (users via the OpenAI-compatible API,
or contracts via syscalls), providers (registered, staked workers with heartbeats and SLA
scoring), and the chain (the aicf.* RPC namespace, credits, and settlement). Since
block 75,000, 25% of each block subsidy is earmarked for inference providers who claim it; the
unclaimed share rolls to the treasury. Every inference response from animica.dev/v1
carries a proof-of-inference receipt (model, prompt hash, output hash, seed) signed with
ML-DSA-65 under the domain animica.ai.proof-of-inference.v1, so a response can be
verified without trusting the server. The registry is small today, and the provider pages say so.
Read: AICF explained · Providers.
8. Post-quantum P2P
Nodes find each other through DNS seeds and peer exchange and gossip headers, blocks,
transactions and shares over TCP (port 30333), with QUIC and WebSocket transports in the code.
The handshake is mutually authenticated and post-quantum: an ephemeral Kyber-768 KEM per
connection, identity signatures with the node's lattice key, HKDF-SHA3-256 for the key schedule,
and ChaCha20-Poly1305 (or AES-256-GCM) for the session. Peer ids are SHA3-256 of the identity key.
Sync is header-first with pinned checkpoints in core/network_params.py as a recovery
aid for nodes wedged on an orphaned sibling.
Read: P2P networking and sync · Security and threat model.
Putting it together
A wallet derives an ML-DSA-65 key from a mnemonic, builds a CBOR transaction with a validity
window, signs it, and posts it to any node's /rpc. The node checks admission (chain id,
signature, balance, fee floor), gossips it over the Kyber-encrypted mesh, and a miner includes it
in a block whose SHA3-256 hash clears Θ. Every node re-executes the block, contract calls run in
the Python VM, and the explorer indexes the result. Nothing in that path depends on a server the
project controls, which is the property the whole design exists to provide.
Sources
docs/ANIMICA_2026_STATE.md · docs/pq/POLICY.md · docs/wallet/HD_DERIVATION.md · docs/consensus/poies_overview.md · docs/DIFFICULTY_ADJUSTMENT.md · docs/vm/OVERVIEW.md · docs/l2/ARCHITECTURE.md · docs/l2/SECURITY_ASSUMPTIONS.md · docs/aicf/OVERVIEW.md · docs/P2P_NETWORKING_GUIDE.md · docs/pq/HANDSHAKE.md · core/network_params.py · consensus/finality.py