Skip to content

Docs · RPC compatibility

Ethereum / EVM-Compatible RPC

Point ethers.js, web3.js and MetaMask at an Animica node and they connect through familiar eth_* / net_* / web3_* methods. This is an Ethereum RPC-compatible facade, with a path toward full EVM execution — Animica stays its own post-quantum PoIES useful-work L1.

RPC facade, not EVM execution. Animica does not run Solidity bytecode. Read this as “Ethereum tooling can connect,” not “Animica is EVM-compatible” — the latter is only true once Solidity deployment/execution ships (a future phase).

Open the EVM Bridge → Prefer a UI? Connect MetaMask, get a deposit address, send & withdraw at evm.animica.org .

Connect

Ethereum clients POST JSON-RPC. Methods answer at both / and /rpc. The public mainnet endpoint is https://mainnet.animica.org .

# curl
curl -s https://mainnet.animica.org/ \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}'
# -> {"jsonrpc":"2.0","id":1,"result":"0x95"}   (chain id 149)

# ethers v6
import { JsonRpcProvider } from "ethers";
const provider = new JsonRpcProvider("https://mainnet.animica.org");
await provider.getBlockNumber();

# web3.py
from web3 import Web3
w3 = Web3(Web3.HTTPProvider("https://mainnet.animica.org"))
w3.is_connected(); w3.eth.chain_id        # 149
w3.eth.block_number; w3.eth.get_block("latest")

Add Animica to a wallet

MetaMask → Add networkAdd a network manually, then use:

Network name Animica
RPC URL https://mainnet.animica.org
Chain ID 149
Currency symbol ANM
Decimals 9 (1 ANM = 1e9 nANM)
Block explorer https://explorer.animica.org

Chain id 149 is the lowest unregistered EIP-155 id (Ethereum mainnet is 1, which would collide). It is registered with ethereum-lists/chains , which feeds chainid.network and chainlist.org. The native currency uses 9 decimals (nANM is the wei-style smallest unit).

Implemented methods

40 methods across eight groups.

Connect & chain
eth_chainIdnet_versionnet_listeningnet_peerCountweb3_clientVersionweb3_sha3eth_blockNumbereth_syncingeth_protocolVersioneth_miningeth_hashrateeth_coinbase
Blocks
eth_getBlockByNumbereth_getBlockByHasheth_getBlockTransactionCountByNumbereth_getBlockTransactionCountByHash
Accounts
eth_getBalanceeth_getTransactionCounteth_getCodeeth_getStorageAteth_accounts
Transactions (read)
eth_getTransactionByHasheth_getTransactionReceipteth_getTransactionByBlockNumberAndIndex
Gas, fees & call
eth_gasPriceeth_maxPriorityFeePerGaseth_feeHistoryeth_estimateGaseth_call
Logs & filters
eth_getLogseth_newFiltereth_newBlockFiltereth_newPendingTransactionFiltereth_uninstallFiltereth_getFilterChangeseth_getFilterLogs
Write & sign (bounded)
eth_sendRawTransactioneth_sendTransactioneth_sign
Address bridge (Animica)
animica_evmBindanimica_evmAlias

How the mapping works

Ethereum methodAnimica source
eth_chainId / net_version dedicated EVM id 149 (override ANIMICA_EVM_CHAIN_ID)
eth_blockNumber chain.getHead().height → hex
eth_getBlockBy{Number,Hash} chain.getBlockByHeight / …ByHash → Ethereum block shape
eth_getBalance state.getBalance (nANM as the wei-style smallest unit)
eth_getTransactionCount state.getNonce / getPendingNonce
eth_getTransactionByHash / …Receipt tx.getTransactionByHash (+ tx.getTransactionStatus)
eth_gasPrice / eth_estimateGas synthetic — Animica fee is account-model, not a gas market
web3_sha3 real keccak-256 (eth_utils)

Hex encoding is strict Ethereum: QUANTITY is 0x-compact (0x0 for zero), DATA is 0x with even length. Animica 0x+64-hex hashes pass through as 32-byte hashes.

The address & signature boundary

Ethereum assumes 20-byte 0x addresses and secp256k1 ECDSA. Animica is post-quantum (anim1…, ML-DSA / SPHINCS+). The facade bridges the two:

Deterministic alias

Every Animica account has a 20-byte EVM alias = 0x ‖ keccak256(anim1)[-20:], with a binding registry so eth_getBalance(0xalias) resolves back. animica_evmAlias(anim1) returns the alias; animica_evmBind records it. An alias is a display/lookup handle — not key-compatibility.

Send path — the custodial relayer

Set ANIMICA_EVM_RELAYER=1 and eth_sendRawTransaction becomes a working bridge: each EVM address gets a relayer-held native account A(E); an EVM signature authorizes a native transfer from it. Fund A(E) (via animica_evmAccount), then send normally. Custodial (operator holds the keys); off by default.

What works vs. what doesn't

Works today
  • MetaMask "Add network" and EIP-1193 provider connect
  • ethers.js / web3.js provider connect (JsonRpcProvider, Web3)
  • eth_blockNumber, block / tx / receipt lookups
  • eth_getBalance & eth_getTransactionCount for bridged addresses
  • ANM as an ERC-20 (Import token 0xbb22…00af): name/symbol/decimals/balanceOf
  • Real Solidity deploy + execute with ANIMICA_EVM_EXECUTION=1 (node-local EVM)
  • explorer & indexer read traffic; web3_sha3 (real keccak-256)
Not yet (facade alone)
  • PoIES-consensus-validated EVM — execution is node-local sequencer state, not yet re-validated by all validators
  • ANM-metered gas + payable value forwarding (v1: gas sponsored, msg.value must be 0)
  • Native Animica (Python-VM) contracts via eth_call — those use the native ABI, not EVM

Roadmap

  1. EVM RPC facade (shipped) — eth_* connect + read.
  2. Custodial relayer (shipped) — ANIMICA_EVM_RELAYER=1 moves value between EVM and native Animica via managed accounts.
  3. ERC facade (shipped) — ANM presented as a read-only ERC-20 (eth_call); real Solidity ERC-20/721 deploy + run on the execution lane.
  4. EVM execution lane (shipped, node-local) — ANIMICA_EVM_EXECUTION=1 runs real Solidity. Next: PoIES re-validation (consensus-level EVM), ANM-metered gas, payable value forwarding.

FAQ

Is Animica EVM-compatible?

Animica exposes an Ethereum RPC-compatible facade, with a path toward full EVM execution. Ethereum tooling (ethers, web3, MetaMask, explorers) can connect through familiar eth_* methods. But Animica does NOT run Solidity bytecode — it stays its own post-quantum PoIES useful-work L1. "EVM-compatible" in the full sense (deploy & execute Solidity) is a future phase, not today.

What chain id does Animica use for EVM?

Chain id 149 (0x95) for eth_chainId / net_version — the lowest unregistered EIP-155 id. Animica's native chain id stays 1 internally; the facade advertises a dedicated id so it doesn't collide with Ethereum mainnet (also 1) in wallet chain-lists. Override with ANIMICA_EVM_CHAIN_ID.

How do Ethereum 0x addresses map to Animica anim1 accounts?

Every Animica account gets a deterministic 20-byte EVM alias = 0x ‖ keccak256(anim1)[-20:], with a binding registry so eth_getBalance(0xalias) resolves back. An alias is a display/lookup handle, not key-compatibility — a secp256k1 key cannot control an anim1 (ML-DSA/SPHINCS+) account.

Can I send a transaction from MetaMask?

Yes, when the node operator enables the custodial relayer (ANIMICA_EVM_RELAYER=1). Each EVM address maps to a relayer-held native account A(E); you fund A(E) (animica_evmAccount returns its anim1), then sign a normal EVM tx and eth_sendRawTransaction moves ANM natively from A(E). It is custodial (the operator holds the keys) and enforces chainId 149, monotonic nonces, replay protection, and AES-256-GCM key-at-rest. With the relayer off, sends return a clear -32004 instead of failing silently.

See also: Bitcoin-Core-Compatible RPC · All docs · EVM_RPC_COMPAT.md