What RwALM is
RwALM is an agent-guided risk and liquidity control layer for tokenized real-world assets on Robinhood Chain. It is not a Robinhood product. It does not custody assets, guarantee returns, or provide financial advice.
Operating modes
- Demo Mode — fully interactive with no wallet and no deployed contract. State persists in localStorage.
- Testnet Mode — real reads via the RPC proxy and real wallet writes (deposit / withdraw / borrow / repay) once contract addresses are pasted into
src/lib/onchain/deployments.ts. Every write is gated by a bytecode check and an explicit confirmation dialog. - Mainnet Read-Only — reads only. Writes remain disabled unless
VITE_ENABLE_MAINNET_WRITES=true.
Authentication (Sign-In with Ethereum)
RwALM authenticates via SIWE against Lovable Cloud. The wallet signs a nonce challenge served from /api/public/siwe/nonce; the server verifies via /api/public/siwe/verify and mints a Supabase session keyed to a synthetic email derived from the wallet address. A wallet-switch flow signs out the previous session, re-prompts the wallet's account picker, and re-links the correct MIRA thread for the new address. Agent threads and messages are stored in agent_threads / agent_messages under strict RLS scoped to the signed-in owner; Demo Mode users get an equivalent localStorage-backed thread.
Live on-chain data
The app reads Robinhood Chain (mainnet id 4663, testnet id 46630) through a same-origin JSON-RPC proxy at /api/public/rpc/[network] that prefers Alchemy when ALCHEMY_RH_KEY is set and falls back to the public RPC with a reason header. Balances are fetched with multicall; USD prices come from CoinGecko; ERC-4626 positions are read via convertToAssets. An RPC diagnostics panel on the Portfolio page reports which provider served the last probe, block height, and latency.
On-chain writes and transaction tracking
Writes are built with viem's wallet client. The chain is switched (or added) automatically, ERC-20 allowances are checked before deposit, and mainnet writes throw unless VITE_ENABLE_MAINNET_WRITES is on. Every submitted hash is persisted in a localStorage tx-tracker and observed via waitForTransactionReceipt; a header button shows the pending count and links each tx to Blockscout.
Deployment validator
The Vault page ships a validator that iterates every entry in DEPLOYMENTS.testnet, probes vault / asset / lendingPool / debtToken with getBytecode, and marks each address as Ready, Not writable, Placeholder, EOA, or Invalid. Every address links straight to Blockscout so you can confirm verification before signing. Writes internally call assertContractDeployed, so a placeholder or undeployed address is rejected before the wallet prompts.
The risk engine
Deterministic pure functions compute market value, borrow-limit and liquidation contributions per position, and portfolio-level current LTV, available borrow, and health factor. When debt is zero the health factor displays as ∞, never a fabricated large number. Prices carry a source, block, timestamp, and stale flag; a stale price disqualifies its position and refuses any dependent proposal.
MIRA — Mandate Intelligence & Risk Agent
MIRA answers intent-based questions ("max safe borrow", "survive a −30% crash?", "withdraw headroom", "deleverage plan"). Each turn runs the deterministic engine to produce a ground-truth snapshot (before/after LTV, HF, stress HF, mandate checks, warnings) and then calls the Lovable AI Gateway (Gemini 2.5 Flash) via a server function to write a plain-English answer over those numbers — the LLM never fabricates prices, balances, or receipts. The panel renders both the LLM text and a compact engine card, plus an actionable proposal card when a signable action is suggested. Sessions persist across refresh (cloud for signed-in wallets, localStorage in Demo Mode), and a reset button clears the current thread in whichever store is active. Quick-prompt buttons cover the common risk / borrow scenarios.
Mandate
Set a maximum LTV, minimum normal and stressed health factors, a stress percentage, approved assets, per-tx and daily borrow caps, minimum oracle freshness, a safety reserve, and a notification threshold. MIRA refuses any proposal that would breach the mandate and names the failing rule.
Smart-contract scaffold (Phase 3)
The contracts/ folder ships a Foundry project: RwALMVault.sol (ERC-4626 collateral vault, pausable, calls the policy on every deposit / mint / withdraw / redeem), MandatePolicy.sol (on-chain LTV and HF gates owned by a mandate multisig), a Deploy.s.sol script, and tests. After forge script … --broadcast, paste the printed addresses into DEPLOYMENTS.testnet in src/lib/onchain/deployments.ts and the whole app picks them up automatically. Contracts are prototypes and require a professional audit before real-value use.
Guard Mode (experimental)
A prefunded safety reserve plus a public keeper that may only call a protect() function; the contract independently verifies protection is required and only draws from the reserve to repay debt. The keeper cannot withdraw collateral, change recipients, borrow, transfer arbitrary tokens, or alter the mandate.
Design and UI
"Graphite terminal" aesthetic — Instrument Serif for display, Inter for UI, an electric emerald (#00F08A) / signal red (#FF4D57) accent pair over deep graphite. Buttons lift with a shimmer sweep and emerald ring on hover; panels lift and glow; nav links animate an underline. The hero uses a gradient bevel frame instead of a colored glow.
Disclaimer
Experimental software. Not financial advice. Smart contracts and tokenized assets involve risk. RwALM is not affiliated with, endorsed by, or sponsored by Robinhood.