Maren
GitHub
Reference

Networks

Chain IDs, RPCs verified live, and the oracle staleness behaviour to design around.

Maren's chain definitions live in packages/sdk/src/chains.ts. The RPC hosts here were each confirmed with a live cast chain-id, not copied from a doc page, because several official Mezo doc pages list hosts that do not resolve.

Chain facts

FactMainnetMatsnet
NameMezoMezo Matsnet
Chain ID3161231611
Chain ID, hex0x7b7c0x7b7b
Gas tokenBTCBTC
Decimals1818
Maren deployedNo, addresses are zeroYes, chain 31611

BTC has 18 decimals here, not 8. Mezo is an EVM chain and BTC is its gas token, so it follows the EVM convention. Every balance, gas estimate, and msg.value is a 1e18-scaled quantity. Reusing a Bitcoin-side 1e8 assumption produces errors of ten orders of magnitude, silently, in the direction of thinking the user is rich.

RPC endpoints

Order is load-bearing: a client pinned to one URL has no answer for the hour that URL is degraded. Every Maren client fails over across the list rather than pinning one host.

PriorityRPCNotes
Primaryhttps://rpc.test.mezo.orgAnswered every method in a repeated sweep
Fallbackhttps://mezo-testnet.drpc.orgVerified 0x7b7b; free tier times out on some 10,000-block log scans

Explorer: https://explorer.test.mezo.org (API at https://api.explorer.test.mezo.org/api).

Some official Mezo RPC hosts do not resolve. rpc.mezo.org, testnet-rpc.mezo.org, and testnet-explorer.mezo.org are listed in Mezo's own documentation and return NXDOMAIN. Do not "fix" the URLs above to match the docs without re-running cast chain-id against them first. None of Alchemy, QuickNode, Ankr, Infura, or Chainstack support Mezo at all.

A -32601 "method does not exist" on Mezo is not proof of a missing feature. During testing an endpoint returned -32601 for eth_call, eth_getLogs, and eth_estimateGas across a full probe sweep, then served all of them correctly an hour later: a degraded backend behind a load balancer, not a capability limit. Never certify or condemn an endpoint on a single probe.

Verify a chain yourself

cast chain-id --rpc-url https://rpc.test.mezo.org
# -> 31611

The oracle staleness behaviour

The BTC/USD price comes from a native Mezo precompile (Skip Connect, secured by the validator set), not Chainlink or Pyth. PriceFeed.fetchPrice() reads it, and its behaviour shapes the whole app.

fetchPrice() reverts if the price is more than 60 seconds stale, and it is a view function with no lastGoodPrice() fallback. Every borrow, adjust, redeem, and liquidate path can revert for reasons unrelated to the user. Both Maren apps carry an explicit "price feed unavailable" state and never render a stale price as live. The keeper treats a price revert as a hold, not an error, and retries with backoff.

Reader caveats that are not optional

Two measured behaviours the log and receipt readers are built around:

A missing receipt is not a missing history

On matsnet the primary RPC has returned a Maren log and then null for that same transaction's receipt, while the fallback returned the full receipt. Both log readers absorb a per-transaction receipt failure and mark that row as awaiting a receipt, rather than failing the whole scan.

Log scans walk in 10,000-block windows

Mezo's public RPC answers a eth_getLogs range of at most 10,000 blocks (MEZO_MAX_LOG_RANGE). A wider range returns maximum [from, to] blocks distance: 10000. At matsnet's measured 4.1s blocks that is about 13 hours per request, which is why a reader walks backwards in windows rather than asking for everything at once.