Built on Rome Protocol — EVM chains that run natively inside the Solana runtime, where Solidity apps call Solana programs atomically (CPI) and Solana users drive EVM apps: two VMs, one chain, one block.
Aerarium is a Compound v3 lending app on Rome, with two route-isolated lanes over one shared pool — live at aerarium.devnet.romeprotocol.xyz:
/evm— EVM gate (MetaMask / wagmi), standard signed transactions./solana— Solana-native gate (Phantom → RomeDoTxUnsigned), no Ethereum key; the connected Solana wallet's synthetic EVM address ismsg.sender.
Both lanes read and write the same Comet, so supply / borrow / liquidate state is identical regardless of which wallet a user brings.
| You can | From /evm (MetaMask) |
From /solana (Phantom) |
|---|---|---|
| Supply USDC, earn interest | ✓ | ✓ |
| Supply collateral (wETH, wSOL) | ✓ | ✓ |
| Borrow USDC against collateral | ✓ | ✓ |
| Repay + withdraw | ✓ | ✓ |
MetaMask (EVM key) Phantom (Solana key — no EVM key)
│ signed EVM tx │ DoTxUnsigned (synthetic sender:
│ (submitRomeTx) │ the wallet's Rome-derived EVM identity)
▼ ▼
┌─────────────────────────────────────┐
│ ONE Comet (Compound v3) │ one pool, one state,
│ on a Rome EVM chain inside │ both audiences
│ the Solana runtime │
└─────────────────────────────────────┘
Why this works on Rome:
- Single state — both wallet lanes hit the same on-chain Comet; no bridging, no wrapped-asset fragmentation, no sync delay.
- Dual-lane access — MetaMask (EVM) and Phantom (Solana-native, no Ethereum key) reach the same contracts over one state.
- App Sovereignty — runs on its own Rome EVM chain with a custom gas token and its own fee revenue; registry-configurable to any Rome chain.
For how EVM execution and CPI work on Solana, see the Rome Protocol documentation.
Integrating your own app on Rome? See
docs/INTEGRATION.md— the reusable patterns behind Aerarium (chain-agnostic registry config, dual EVM + Solana-native lanes, account discovery, cached-oracle + keeper, CU budgeting) and the chain-agnostic dev tooling, with Aerarium/Hadrian as the worked example.
Aerarium is not pinned to any one chain. Chain identity — chain id, RPC, explorer, contract addresses, Multicall3, Solana program id, and cluster — is resolved per chain from the Rome registry at build time (npm run build:registry-config → lib/registry/generated.json, also run as part of npm run build). Pointing the app at another Rome chain is a registry edit plus NEXT_PUBLIC_DEFAULT_CHAIN_ID — no code change.
npm install
npm run build:registry-config # regenerate chain config from the registry
npm run dev # http://localhost:3000Set the chain and endpoints via env (see .env.example). With the registry checked out alongside (monorepo layout) or ROME_REGISTRY_ROOT set, the build picks up every chain that has an apps/compound/<chainId>-<slug>.json entry.
npm test # vitest (unit + guards)
npm run test:e2e # Playwright smokeCompound on Rome with unified USDC.
app/ Next.js routes — /evm (MetaMask lane) and /solana (Phantom lane)
components/ UI (markets, positions, supply/borrow flows)
lib/ registry-driven chain config, lanes, oracle + account discovery
hooks/ store/ data + state
scripts/ registry config generation, dev tooling
tests/ vitest unit + guards; Playwright e2e smoke
docs/ INTEGRATION.md — the reusable patterns behind this app
Apache-2.0 — see LICENSE. Aerarium is an original UI over Compound III (Comet) deployments; it does not fork BUSL-licensed Compound contracts — see NOTICE for provenance and third-party attributions.
See AGENTS.md — the Rome-specific rules a coding agent needs.