From a522585cb98a291b3983471433bd3ce2ae2c0c99 Mon Sep 17 00:00:00 2001 From: Anil Kumar <150643132+anil-rome@users.noreply.github.com> Date: Sun, 19 Jul 2026 20:10:10 +0300 Subject: [PATCH] =?UTF-8?q?docs(agents):=20AGENTS.md=20v3.1=20=E2=80=94=20?= =?UTF-8?q?funding=20on-ramp=20(bridge=20USDC,=20no=20faucet)=20+=20choose?= =?UTF-8?q?-your-core=20by=20compute;=20trim=20non-build=20claims?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AGENTS.md | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 318fdd0..15f211a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,10 +1,10 @@ # AGENTS.md — building on Rome with an AI coding agent @@ -20,7 +20,7 @@ This file gives you the facts, organized by **what you're starting from**. Find ## Find your starting point ### You have Solidity — a contract, or an EVM app to fork -Deploy it as it is, with standard Hardhat or Foundry (one caveat: `forge script` needs `--skip-simulation`; `forge create`, `cast`, and Hardhat work normally). The moment it's on Rome it's open to EVM users, Solana users, and users arriving from other chains **at once** — you don't write per-audience code. Nothing about your Solidity changes. When you want Solana liquidity or data, call a Solana program via CPI (see the rules below). +Deploy it as it is, with standard Hardhat or Foundry (one caveat: `forge script` needs `--skip-simulation`; `forge create`, `cast`, and Hardhat work normally). The same contract serves EVM (MetaMask) and Solana (Phantom) users — you don't write per-audience code, and nothing about your Solidity changes. When you want Solana liquidity or data, call a Solana program via CPI (see the rules below). **Read:** [compound-on-rome-comet](https://github.com/rome-protocol/compound-on-rome-comet) and [rome-aave-v3](https://github.com/rome-protocol/rome-aave-v3) — Compound v3 and Aave v3 running unchanged. ### You have a Solana program @@ -28,17 +28,27 @@ It keeps doing what it already does for your Solana users — no changes. To ope **Read:** [cardo](https://github.com/rome-protocol/cardo) — drives Jupiter, Meteora, Marinade, and Mango from an EVM account. ### You have one lane and want to open the other — the Parity Pattern -Keep **one** source of truth: a native Solana program written authority-agnostic, plus a thin EVM router. A Phantom user drives the program directly; a MetaMask user drives it through the router and Rome auto-signs their PDA — **both act on the same reserves/state at near-CU parity**. Because the LP/position token is an SPL mint, it's automatically an ERC-20, so a position opened on one lane is spendable on the other. Keep the account set lean and ALT-friendly to keep the EVM lane cheap, and test both lanes. -**Read:** [rome-dex](https://github.com/rome-protocol/rome-dex) (AMM), [aerarium](https://github.com/rome-protocol/aerarium) (lending). +Keep **one** source of truth, written authority-agnostic, and open the other lane to it. This comes in **both** shapes (see *Which side is your core?* below): a **native Solana program + thin EVM router**, or a **Solidity core that Solana users reach via a synthetic sender**. Either way a Phantom user and a MetaMask user act on the **same reserves/state** — Rome auto-signs the EVM user's PDA. Because the LP/position token is an SPL mint, it's automatically an ERC-20, so a position opened on one lane is spendable on the other. Keep the account set lean and ALT-friendly to keep the EVM lane cheap, and test both lanes. +**Read:** [rome-dex](https://github.com/rome-protocol/rome-dex) (AMM — native core + router) and [aerarium](https://github.com/rome-protocol/aerarium) (lending — Solidity core + synthetic sender). ### You're building greenfield — bring your idea -Use both sides from day one: one pool both audiences trade, one market both borrow from, an oracle that brings Solana prices into the EVM. Decide the architecture up front — **Solidity-first** (a Solidity app that calls Solana via CPI) is the default; reach for a **native program + router** only when a Solana wallet must act natively on shared state, or a hot path needs native-CU efficiency. Resolve everything from the registry; use the SDK for writes. +Use both sides from day one: one pool both audiences trade, one market both borrow from, an oracle that brings Solana prices into the EVM. Decide the architecture up front — see *Which side is your core?* below (Solidity-core is the default; go native-core for compute-heavy hot paths). Resolve everything from the registry; use the SDK for writes. **Read:** [rome-dex](https://github.com/rome-protocol/rome-dex), [appia](https://github.com/rome-protocol/appia), [rome-oracle-gateway](https://github.com/rome-protocol/rome-oracle-gateway). **Scaffold:** `create-rome-app` (ships with the docs release). ### Your users are on their home turf — reach Rome from another chain -Your users don't move — from their home chain (an L2, Solana, …) they reach your Rome app without leaving. The bridge is **on-chain**: `RomeBridgeWithdraw` (egress from Rome) + the rome-evm `settle_inbound_bridge` program (inbound credit, authorized by the user's own signed **EIP-712** intent — trustless, no privileged settler key). Transport is Circle CCTP (USDC) or Wormhole. The off-chain **`rome-bridge-api`** orchestrates it: quote a route → verify the source tx → fee-sponsor the settle. It holds no keys and can only *trigger* what the user already signed. +Your users don't move — from their home chain (an L2, Solana, …) they reach your Rome app without leaving. The bridge is **on-chain**: `RomeBridgeWithdraw` (egress from Rome) + the rome-evm `settle_inbound_bridge` program (inbound credit, authorized by the user's own signed **EIP-712** intent). Transport is Circle CCTP (USDC) or Wormhole. The off-chain **`rome-bridge-api`** orchestrates it: quote a route → verify the source tx → sponsor the settle fee. **Read:** [appia](https://github.com/rome-protocol/appia) (a from-home app), [rome-bridge-api](https://github.com/rome-protocol/rome-bridge-api) (the orchestrator; see its `docs/BRIDGE_API_ARCHITECTURE.md`). +## Which side is your core? (choose by compute) +Going dual-lane has two mirror-image shapes — pick by **compute weight + what you already have**: +- **(a) Solidity core; Solana users arrive via a synthetic sender.** Best for a hardened/audited Solidity contract, standard EVM tooling, or light-to-moderate compute. A Phantom user's Solana signature runs as an EVM tx from their Rome-derived PDA — no EVM key. *Example: [aerarium](https://github.com/rome-protocol/aerarium).* +- **(b) Native Solana program core; EVM users arrive via a thin CPI router.** Best for compute-heavy hot paths — native is **~6× more CU-efficient** than the EVM interpreter (≈200K vs ≈1.24M CU on a swap) — or when you already have a Solana program. *Example: [rome-dex](https://github.com/rome-protocol/rome-dex).* + +**Rule:** heavy / perf-critical → native core + router; hardened Solidity / lighter compute → Solidity core + synthetic. + +## Getting funded — USDC is the gas token; bridge it in +Every Rome chain's gas token is **USDC** (Circle). **There is no Rome faucet.** Fund a wallet by **bridging USDC into Rome** from a chain where you already have it: get testnet USDC on a source chain (Sepolia, an L2, or Solana) from *that chain's* own faucet, then bridge to Hadrian/Martius (the on-chain `settle_inbound_bridge`, orchestrated by `rome-bridge-api`; CCTP for USDC). + ## The rules that bite on every path (different from vanilla EVM) 1. **Every write goes through `submitRomeTx`.** Do not send state-changing txs with raw `wagmi`/`ethers`/`viem` `writeContract`/`sendTransaction` — Rome writes have specific fee + submission semantics; use the SDK's `submitRomeTx`. Reads stay vanilla. @@ -46,15 +56,13 @@ Your users don't move — from their home chain (an L2, Solana, …) they reach 3. **Calling Solana from Solidity (CPI — the differentiator).** Precompiles: **CPI `0xFF…08`**, **Helper `0xFF…09`**, **Withdraw `0x42…16`**. The account rules agents get wrong: the accounts array must be **non-empty**; the **operator and the program_id must NOT** appear in it; to sign as your contract use `HELPER.pda(address(this))` as the signer (the precompile signs as `msg.sender`, so a router contract cannot sign a *user's* PDA). Full ABI + per-selector billing: the precompile reference (docs). 4. **Never hardcode addresses — read the registry.** Chain ids, RPC URLs, contract addresses, token mints, and Solana program ids all come from **`@rome-protocol/registry`** (or the `rome-mcp` `getChain`/`getTokens`/`getContracts` tools). Hardcoded values drift and break across deploys. 5. **Test both lanes with a fresh wallet.** A feature must work on the EVM lane (MetaMask) *and* the Solana lane (Phantom). Verify each with a brand-new wallet and a tiny amount before claiming done. -6. **When a tx fails, use the taxonomy + the cross-VM map.** Rome surfaces specific failures (starved pool-payer rent, StateHolder rent, emulation-vs-simulation mismatches, nonce races). Match them against the error taxonomy (docs). To see the Solana settlement of a Rome tx, map it with `solanaTxForEvmTx`. +6. **When a tx fails, use the taxonomy + the cross-VM map.** Rome surfaces specific failures (rent-starved pool payer or StateHolder, emulation-vs-simulation mismatches, nonce races). Match them against the error taxonomy (docs). To see the Solana settlement of a Rome tx, map it with `solanaTxForEvmTx`. ## The SDK — `@rome-protocol/sdk` The TypeScript SDK ([`rome-sdk-ts`](https://github.com/rome-protocol/rome-sdk-ts)) is your write path and your CPI toolkit: `submitRomeTx` + fee sizing, PDA/ATA derivation, CPI `invoke`/`invoke_signed` encoders, precompile bindings, and a `/bridge` module. Use it for every write and every Solana-from-Solidity call rather than hand-rolling calldata. -## Live tools for your agent -> **Shipping with the Rome docs release** — the `rome-mcp` server and the `doctor` self-check below are being published alongside the docs site and are not on npm yet. Until then, read the registry directly via `@rome-protocol/registry` and verify manually (see below). - -The **`rome-mcp`** server will give your agent live registry / balance / gas / bridge / faucet / docs access — a one-line `npx @rome-protocol/rome-mcp` install for Claude Code, Cursor, and Zed. It's **read-only + a rate-limited devnet faucet** (so an autonomous build→verify loop can self-fund fresh test wallets) and holds no keys — your app does the signing (via the SDK). +## Live facts for your agent +Live chain facts (ids, RPC, addresses, mints, program ids) come from **`@rome-protocol/registry`** (see rule 4). A read-only **`rome-mcp`** server — registry / balance / gas / bridge-quote, no keys, no faucet — is coming with the docs release; until then, read the registry directly. Your app always does the signing, via the SDK. ## Verify before you claim done -Before saying a change works: check RPC config, confirm every write goes through `submitRomeTx`, and run a **both-lane smoke** against devnet with a fresh wallet and a tiny amount. A one-command self-check (`npx @rome-protocol/doctor`) and a runnable funded end-to-end harness (fund → deploy → wrap → CPI-swap → assert) in `create-rome-app` scaffolds ship with the docs release. +Before saying a change works: check RPC config, confirm every write goes through `submitRomeTx`, and run a **both-lane smoke** against devnet with a fresh wallet and a tiny amount (fund → deploy → act → assert on each lane). A scaffold + one-command self-check are coming with the docs release.