# Table of Contents - [Introduction - Monad Documentation](#introduction-monad-documentation) - [Unknown](#unknown) - [Monad Architecture - Monad Documentation](#monad-architecture-monad-documentation) - [Asynchronous I/O - Monad Documentation](#asynchronous-i-o-monad-documentation) - [Pipelining - Monad Documentation](#pipelining-monad-documentation) - [Parallel Execution - Monad Documentation](#parallel-execution-monad-documentation) - [Execution - Monad Documentation](#execution-monad-documentation) - [JIT Compilation - Monad Documentation](#jit-compilation-monad-documentation) - [Transaction Lifecycle in Monad - Monad Documentation](#transaction-lifecycle-in-monad-monad-documentation) - [Concepts - Monad Documentation](#concepts-monad-documentation) - [Real-time Data - Monad Documentation](#real-time-data-monad-documentation) - [Speculative Real-Time Data - Monad Documentation](#speculative-real-time-data-monad-documentation) - [MonadDb - Monad Documentation](#monaddb-monad-documentation) - [Hardware Requirements - Monad Documentation](#hardware-requirements-monad-documentation) - [Node Operations - Monad Documentation](#node-operations-monad-documentation) - [Announcements - Monad Documentation](#announcements-monad-documentation) - [Solonet - Monad Documentation](#solonet-monad-documentation) - [Validator Installation - Monad Documentation](#validator-installation-monad-documentation) - [How Full Nodes Receive Blocks - Monad Documentation](#how-full-nodes-receive-blocks-monad-documentation) - [Blocksync - Monad Documentation](#blocksync-monad-documentation) - [Transport Protocol Usage - Monad Documentation](#transport-protocol-usage-monad-documentation) - [Local Mempool - Monad Documentation](#local-mempool-monad-documentation) - [Validator Delegation Program (VDP) - Monad Documentation](#validator-delegation-program-vdp-monad-documentation) - [General Operations - Monad Documentation](#general-operations-monad-documentation) - [Consensus - Monad Documentation](#consensus-monad-documentation) - [Peer Discovery - Monad Documentation](#peer-discovery-monad-documentation) - [VDP Policy on MEV Systems - Monad Documentation](#vdp-policy-on-mev-systems-monad-documentation) - [Statesync - Monad Documentation](#statesync-monad-documentation) - [Forkpoint - Monad Documentation](#forkpoint-monad-documentation) - [Asynchronous Execution - Monad Documentation](#asynchronous-execution-monad-documentation) - [Genesis Replay - Monad Documentation](#genesis-replay-monad-documentation) - [RaptorCast - Monad Documentation](#raptorcast-monad-documentation) - [Real-Time Data Sources - Monad Documentation](#real-time-data-sources-monad-documentation) - [The Data Waterfall - Monad Documentation](#the-data-waterfall-monad-documentation) - [Full Replay - Monad Documentation](#full-replay-monad-documentation) - [Node Migration (Promoting a Full Node to Validator) - Monad Documentation](#node-migration-promoting-a-full-node-to-validator-monad-documentation) - [Running an Archive Server - Monad Documentation](#running-an-archive-server-monad-documentation) - [Message Authentication - Monad Documentation](#message-authentication-monad-documentation) - [Staking - Monad Documentation](#staking-monad-documentation) - [Execution Events and WebSocket Setup - Monad Documentation](#execution-events-and-websocket-setup-monad-documentation) - [Configuring RPC to use archive data - Monad Documentation](#configuring-rpc-to-use-archive-data-monad-documentation) - [Hard Reset Instructions - Monad Documentation](#hard-reset-instructions-monad-documentation) - [Soft Reset Instructions - Monad Documentation](#soft-reset-instructions-monad-documentation) - [Archive Data Setup - Monad Documentation](#archive-data-setup-monad-documentation) - [MonadBFT - Monad Documentation](#monadbft-monad-documentation) - [Recovering a Node - Monad Documentation](#recovering-a-node-monad-documentation) - [Block States - Monad Documentation](#block-states-monad-documentation) - [Best Practices for Building High Performance Apps - Monad Documentation](#best-practices-for-building-high-performance-apps-monad-documentation) - [EIP-7702 on Monad - Monad Documentation](#eip-7702-on-monad-monad-documentation) - [Gas Pricing - Monad Documentation](#gas-pricing-monad-documentation) - [Full Node Installation - Monad Documentation](#full-node-installation-monad-documentation) - [Differences between Monad and Ethereum - Monad Documentation](#differences-between-monad-and-ethereum-monad-documentation) - [Changelog - Monad Documentation](#changelog-monad-documentation) - [v0.12.7 - Monad Documentation](#v0-12-7-monad-documentation) - [v0.14.2 Upgrade Instructions - Monad Documentation](#v0-14-2-upgrade-instructions-monad-documentation) - [v0.14.3 Upgrade Instructions - Monad Documentation](#v0-14-3-upgrade-instructions-monad-documentation) - [Authenticated UDP Checking - Monad Documentation](#authenticated-udp-checking-monad-documentation) - [v0.13.1 Upgrade Instructions - Monad Documentation](#v0-13-1-upgrade-instructions-monad-documentation) - [v0.14.0 Upgrade Instructions - Monad Documentation](#v0-14-0-upgrade-instructions-monad-documentation) - [v0.14.5 Upgrade Instructions - Monad Documentation](#v0-14-5-upgrade-instructions-monad-documentation) - [v0.14.4 Upgrade Instructions - Monad Documentation](#v0-14-4-upgrade-instructions-monad-documentation) - [v0.13.0 (MONAD_NINE) - Monad Documentation](#v0-13-0-monad-nine-monad-documentation) - [v0.14.1 Upgrade Instructions - Monad Documentation](#v0-14-1-upgrade-instructions-monad-documentation) - [Opcode Pricing - Monad Documentation](#opcode-pricing-monad-documentation) - [v0.12.6 - Monad Documentation](#v0-12-6-monad-documentation) - [v0.15.1 Upgrade Instructions - Monad Documentation](#v0-15-1-upgrade-instructions-monad-documentation) - [v0.12.3 - Monad Documentation](#v0-12-3-monad-documentation) - [v0.15.2 Upgrade Instructions - Monad Documentation](#v0-15-2-upgrade-instructions-monad-documentation) - [Developer Essentials - Monad Documentation](#developer-essentials-monad-documentation) - [Transactions - Monad Documentation](#transactions-monad-documentation) - [v0.12.5 - `testnet` re-genesis - Monad Documentation](#v0-12-5-testnet-re-genesis-monad-documentation) - [v0.15.0 Upgrade Instructions - Monad Documentation](#v0-15-0-upgrade-instructions-monad-documentation) - [Official Links - Monad Documentation](#official-links-monad-documentation) - [Why Blockchain? - Monad Documentation](#why-blockchain-monad-documentation) - [Upgrade Instructions - Monad Documentation](#upgrade-instructions-monad-documentation) - [Privacy - Monad Documentation](#privacy-monad-documentation) - [Payment Orchestrators - Monad Documentation](#payment-orchestrators-monad-documentation) - [Precompiles - Monad Documentation](#precompiles-monad-documentation) - [Tokens and Bridges - Monad Documentation](#tokens-and-bridges-monad-documentation) - [Earn/Yield Infrastructure - Monad Documentation](#earn-yield-infrastructure-monad-documentation) - [Block Explorers - Monad Documentation](#block-explorers-monad-documentation) - [Wallet Developer Integration Guide - Monad Documentation](#wallet-developer-integration-guide-monad-documentation) - [Tooling and Infrastructure - Monad Documentation](#tooling-and-infrastructure-monad-documentation) - [Authenticated UDP Migration - Monad Documentation](#authenticated-udp-migration-monad-documentation) - [Custody - Monad Documentation](#custody-monad-documentation) - [Oracles - Monad Documentation](#oracles-monad-documentation) - [MPP API Reference - Monad Documentation](#mpp-api-reference-monad-documentation) - [JSON-RPC Playground - Monad Documentation](#json-rpc-playground-monad-documentation) - [Analytics - Monad Documentation](#analytics-monad-documentation) - [Add Monad Testnet to Wallet - Monad Documentation](#add-monad-testnet-to-wallet-monad-documentation) - [EVM Resources - Monad Documentation](#evm-resources-monad-documentation) - [Add Monad Mainnet to Wallet - Monad Documentation](#add-monad-mainnet-to-wallet-monad-documentation) - [Reserve Balance - Monad Documentation](#reserve-balance-monad-documentation) - [RPC Providers - Monad Documentation](#rpc-providers-monad-documentation) - [Cross-Chain - Monad Documentation](#cross-chain-monad-documentation) - [Why Monad: Decentralization + Performance - Monad Documentation](#why-monad-decentralization-performance-monad-documentation) - [Frequently Asked Questions - Monad Documentation](#frequently-asked-questions-monad-documentation) - [Network Information - Mainnet - Monad Documentation](#network-information-mainnet-monad-documentation) - [Monad Solonet - Monad Documentation](#monad-solonet-monad-documentation) - [Toolkits - Monad Documentation](#toolkits-monad-documentation) - [Indexing Frameworks - Monad Documentation](#indexing-frameworks-monad-documentation) - [Monad for Users - Monad Documentation](#monad-for-users-monad-documentation) - [Verify a smart contract on Monad using Hardhat - Monad Documentation](#verify-a-smart-contract-on-monad-using-hardhat-monad-documentation) - [MPP Overview - Monad Documentation](#mpp-overview-monad-documentation) - [Guides - Monad Documentation](#guides-monad-documentation) - [Agentic Payments - Monad Documentation](#agentic-payments-monad-documentation) - [Network Information - Testnet - Monad Documentation](#network-information-testnet-monad-documentation) - [MIP-8 Activation and Page Storage Migration - Monad Documentation](#mip-8-activation-and-page-storage-migration-monad-documentation) - [Other Languages - Monad Documentation](#other-languages-monad-documentation) - [Yul - Monad Documentation](#yul-monad-documentation) - [Solidity Resources - Monad Documentation](#solidity-resources-monad-documentation) - [Multisig Wallets - Monad Documentation](#multisig-wallets-monad-documentation) - [Institutional Wallets - Monad Documentation](#institutional-wallets-monad-documentation) - [Hardware Wallets - Monad Documentation](#hardware-wallets-monad-documentation) - [Account Abstraction Providers - Monad Documentation](#account-abstraction-providers-monad-documentation) - [Onramps - Monad Documentation](#onramps-monad-documentation) - [Add Monad to Wallet - Monad Documentation](#add-monad-to-wallet-monad-documentation) - [Staking Overview - Monad Documentation](#staking-overview-monad-documentation) - [Deploy a smart contract on Monad using Remix - Monad Documentation](#deploy-a-smart-contract-on-monad-using-remix-monad-documentation) - [Smart Account Implementations - Monad Documentation](#smart-account-implementations-monad-documentation) - [Verify a Contract - Monad Documentation](#verify-a-contract-monad-documentation) - [EVM Behavior - Monad Documentation](#evm-behavior-monad-documentation) - [Indexers - Monad Documentation](#indexers-monad-documentation) - [Vyper - Monad Documentation](#vyper-monad-documentation) - [Deploy a smart contract on Monad using Hardhat - Monad Documentation](#deploy-a-smart-contract-on-monad-using-hardhat-monad-documentation) - [Common Data - Monad Documentation](#common-data-monad-documentation) - [How to accelerate your app with Execution Events - Monad Documentation](#how-to-accelerate-your-app-with-execution-events-monad-documentation) - [How to index every WMON transfer using QuickNode Streams - Monad Documentation](#how-to-index-every-wmon-transfer-using-quicknode-streams-monad-documentation) - [Monad Foundry - Monad Documentation](#monad-foundry-monad-documentation) - [Deploy a Contract - Monad Documentation](#deploy-a-contract-monad-documentation) - [Release notes - Monad Documentation](#release-notes-monad-documentation) - [How to Consume Execution Events in Rust - Monad Documentation](#how-to-consume-execution-events-in-rust-monad-documentation) - [How to build a transfer notification bot with Envio HyperIndex - Monad Documentation](#how-to-build-a-transfer-notification-bot-with-envio-hyperindex-monad-documentation) - [Deploy a smart contract on Monad using Monad Foundry - Monad Documentation](#deploy-a-smart-contract-on-monad-using-monad-foundry-monad-documentation) - [Embedded Wallets - Monad Documentation](#embedded-wallets-monad-documentation) - [Use an Indexer - Monad Documentation](#use-an-indexer-monad-documentation) - [Event rings in detail - Monad Documentation](#event-rings-in-detail-monad-documentation) - [Hardhat - Monad Documentation](#hardhat-monad-documentation) - [Advanced topics - Monad Documentation](#advanced-topics-monad-documentation) - [Software Wallets - Monad Documentation](#software-wallets-monad-documentation) - [JSON-RPC Overview - Monad Documentation](#json-rpc-overview-monad-documentation) - [Consensus events - Monad Documentation](#consensus-events-monad-documentation) - [C API - Monad Documentation](#c-api-monad-documentation) - [Huff - Monad Documentation](#huff-monad-documentation) - [Monad for Developers - Monad Documentation](#monad-for-developers-monad-documentation) - [How to use the Next.js Serwist Thirdweb embedded wallet template - Monad Documentation](#how-to-use-the-next-js-serwist-thirdweb-embedded-wallet-template-monad-documentation) - [Wallets - Monad Documentation](#wallets-monad-documentation) - [Wallet Infrastructure - Monad Documentation](#wallet-infrastructure-monad-documentation) --- # Introduction - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/#content-area) **Quick hits** * [Network Information](https://docs.monad.xyz/developer-essentials/network-information) * [Deployment Summary for Developers](https://docs.monad.xyz/developer-essentials/summary) * [Guide for Node Operators](https://docs.monad.xyz/node-ops) Monad is a Layer-1 blockchain delivering high performance, true decentralization, and EVM compatibility. Monad’s north star is making decentralization more powerful, and eliminating the perceived tradeoff between decentralization and performance. Monad supports a large globally distributed network (see the [validator map](https://www.gmonads.com/) ), with intentionally minimal [hardware requirements](https://docs.monad.xyz/node-ops/hardware-requirements) so that anyone may run a node. Performance comes from software architecture improvements rather than reliance on heavy hardware or node colocation. Monad’s codebase is fully open source ([consensus](https://github.com/category-labs/monad-bft) , [execution](https://github.com/category-labs/monad) ) and is built for extreme performance in C++ and rust. Monad introduces novel architectures in five major areas: * [MonadBFT](https://docs.monad.xyz/monad-arch/consensus/monad-bft) , a frontier BFT consensus mechanism solving the [tail-forking](https://www.category.xyz/blogs/monadbft-fast-responsive-fork-resistant-streamlined-consensus) problem * [RaptorCast](https://docs.monad.xyz/monad-arch/consensus/raptorcast) for efficient block transmission * [Asynchronous Execution](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution) for pipelining consensus and execution to raise the time budget for execution * [Parallel Execution](https://docs.monad.xyz/monad-arch/execution/parallel-execution) and [JIT Compilation](https://docs.monad.xyz/monad-arch/execution/native-compilation) for efficient transaction execution * [MonadDb](https://docs.monad.xyz/monad-arch/execution/monaddb) for efficient storage of Ethereum state Monad’s improvements address existing bottlenecks while preserving seamless compatibility for application developers (full EVM bytecode compatibility) and users (Ethereum [RPC API](https://docs.monad.xyz/reference/json-rpc) compatibility). The result is an Ethereum-compatible Layer-1 blockchain with 10,000 tps of throughput, 300ms block frequency, and 600ms finality. Select a level of detail by visiting either [Monad for Users](https://docs.monad.xyz/introduction/monad-for-users) or [Monad for Developers](https://docs.monad.xyz/introduction/monad-for-developers) . [​](https://docs.monad.xyz/#deploying-on-monad) Deploying on Monad --------------------------------------------------------------------- See [Deployment Summary for Developers](https://docs.monad.xyz/developer-essentials/summary) for everything you need to know as a developer deploying on Monad. Monad features first-class support for many leading Ethereum developer tools and infra providers. See [Tooling and Infrastructure](https://docs.monad.xyz/tooling-and-infra) for a summary. [​](https://docs.monad.xyz/#architecture) Architecture --------------------------------------------------------- Monad is designed with a focus on performance and scalability with commodity hardware. The subsequent pages survey the major [architectural changes](https://docs.monad.xyz/monad-arch) in Monad as well as the interface for users. The first Monad client is built by [Category Labs](https://www.category.xyz/) and is written from scratch in C++ and Rust. [`monad-bft`](https://github.com/category-labs/monad-bft) , Category Labs’s implementation of a Monad consensus client, and [`monad`](https://github.com/category-labs/monad) , Category Labs’s implementation of a Monad execution client, are both open-source under `GPL-3.0`. [​](https://docs.monad.xyz/#mainnet) Mainnet ----------------------------------------------- Public mainnet launched on Nov 24, 2025. See [Network Information](https://docs.monad.xyz/developer-essentials/network-information) for access, or check out the [MonadVision](https://monadvision.com/) block explorer, the [gmonads.com](https://gmonads.com/) network visualization, or [app.monad.xyz](https://app.monad.xyz/) . [Why Blockchain?\ \ Next](https://docs.monad.xyz/introduction/why-blockchain) Ctrl+I Assistant Responses are generated using AI and may contain mistakes. --- # Unknown \# Monad Documentation ## Docs - \[Best Practices for Building High Performance Apps\](https://docs.monad.xyz/developer-essentials/best-practices.md): Learn best practices for building high performance apps on Monad - \[Changelog\](https://docs.monad.xyz/developer-essentials/changelog/index.md) - \[Releases\](https://docs.monad.xyz/developer-essentials/changelog/releases.md) - \[Differences between Monad and Ethereum\](https://docs.monad.xyz/developer-essentials/differences.md) - \[EIP-7702 on Monad\](https://docs.monad.xyz/developer-essentials/eip-7702.md) - \[Gas Pricing\](https://docs.monad.xyz/developer-essentials/gas-pricing.md) - \[Historical Data\](https://docs.monad.xyz/developer-essentials/historical-data.md) - \[Developer Essentials\](https://docs.monad.xyz/developer-essentials/index.md) - \[Network Information - Mainnet\](https://docs.monad.xyz/developer-essentials/network-information/index.md) - \[Tokens and Bridges\](https://docs.monad.xyz/developer-essentials/network-information/tokens-and-bridges.md) - \[Opcode Pricing\](https://docs.monad.xyz/developer-essentials/opcode-pricing.md) - \[Precompiles\](https://docs.monad.xyz/developer-essentials/precompiles.md): How to use Monad's precompiled contracts - \[Reserve Balance\](https://docs.monad.xyz/developer-essentials/reserve-balance.md) - \[Deployment Summary for Developers\](https://docs.monad.xyz/developer-essentials/summary.md): Deployment Summary for Developers - \[Network Information - Testnet\](https://docs.monad.xyz/developer-essentials/testnet.md) - \[Transactions\](https://docs.monad.xyz/developer-essentials/transactions.md) - \[Wallet Developer Integration Guide\](https://docs.monad.xyz/developer-essentials/wallet-developers.md): Guidance and recipes for wallet teams improving Monad support - \[Advanced topics\](https://docs.monad.xyz/execution-events/advanced.md) - \[C API\](https://docs.monad.xyz/execution-events/c-api.md) - \[Consensus events\](https://docs.monad.xyz/execution-events/consensus-events.md) - \[Event rings in detail\](https://docs.monad.xyz/execution-events/event-ring.md) - \[Building the C example program\](https://docs.monad.xyz/execution-events/getting-started/c.md) - \[Running the example program on live data, and next steps\](https://docs.monad.xyz/execution-events/getting-started/final.md) - \[Getting started\](https://docs.monad.xyz/execution-events/getting-started/index.md) - \[Building the Rust example program\](https://docs.monad.xyz/execution-events/getting-started/rust.md) - \[Setting up your Monad node\](https://docs.monad.xyz/execution-events/getting-started/setup-node.md) - \[Running the example program on snapshot data\](https://docs.monad.xyz/execution-events/getting-started/snapshot.md) - \[Execution Events\](https://docs.monad.xyz/execution-events/index.md) - \[Execution events overview\](https://docs.monad.xyz/execution-events/overview.md) - \[Release notes\](https://docs.monad.xyz/execution-events/release-notes.md) - \[Rust API\](https://docs.monad.xyz/execution-events/rust-api.md) - \[Frequently Asked Questions\](https://docs.monad.xyz/faq.md) - \[Add Monad to Wallet\](https://docs.monad.xyz/guides/add-monad-to-wallet/index.md) - \[Add Monad Mainnet to Wallet\](https://docs.monad.xyz/guides/add-monad-to-wallet/mainnet.md) - \[Add Monad Testnet to Wallet\](https://docs.monad.xyz/guides/add-monad-to-wallet/testnet.md) - \[Custom Stablecoins on Monad with Brale\](https://docs.monad.xyz/guides/brale.md) - \[How to make your Monad contract clear-signable (ERC-7730)\](https://docs.monad.xyz/guides/clear-signing.md) - \[How to build custom deep links in an Expo-based mobile app\](https://docs.monad.xyz/guides/deeplinks-using-expo.md) - \[Deploy a smart contract on Monad using Monad Foundry\](https://docs.monad.xyz/guides/deploy-smart-contract/foundry.md) - \[Deploy a smart contract on Monad using Hardhat\](https://docs.monad.xyz/guides/deploy-smart-contract/hardhat.md) - \[Deploy a Contract\](https://docs.monad.xyz/guides/deploy-smart-contract/index.md) - \[Deploy a smart contract on Monad using Remix\](https://docs.monad.xyz/guides/deploy-smart-contract/remix.md) - \[How to register and build with ERC-8004 (Trustless Agents) on Monad\](https://docs.monad.xyz/guides/erc-8004.md) - \[EVM Behavior\](https://docs.monad.xyz/guides/evm-resources/evm-behavior.md) - \[EVM Resources\](https://docs.monad.xyz/guides/evm-resources/index.md) - \[Huff\](https://docs.monad.xyz/guides/evm-resources/other-languages/huff.md) - \[Other Languages\](https://docs.monad.xyz/guides/evm-resources/other-languages/index.md) - \[Vyper\](https://docs.monad.xyz/guides/evm-resources/other-languages/vyper.md) - \[Yul\](https://docs.monad.xyz/guides/evm-resources/other-languages/yul.md) - \[Solidity Resources\](https://docs.monad.xyz/guides/evm-resources/solidity-resources.md) - \[How to Consume Execution Events in Rust\](https://docs.monad.xyz/guides/execution-events/consume-rust.md) - \[How to accelerate your app with Execution Events\](https://docs.monad.xyz/guides/execution-events/index.md) - \[Set up Execution Events\](https://docs.monad.xyz/guides/execution-events/setup.md) - \[Guides\](https://docs.monad.xyz/guides/index.md) - \[How to index token transfers with GhostGraph\](https://docs.monad.xyz/guides/indexers/ghost.md) - \[Use an Indexer\](https://docs.monad.xyz/guides/indexers/index.md) - \[How to index every WMON transfer using QuickNode Streams\](https://docs.monad.xyz/guides/indexers/quicknode-streams.md) - \[How to build a transfer notification bot with Envio HyperIndex\](https://docs.monad.xyz/guides/indexers/tg-bot-using-envio.md) - \[How to query token data with Envio HyperSync\](https://docs.monad.xyz/guides/indexers/token-snapshot-hypersync.md) - \[How to add swaps to your app using Kuru Flow\](https://docs.monad.xyz/guides/kuru-flow.md) - \[How to create passkey accounts with Mera\](https://docs.monad.xyz/guides/mera.md): Create and recover Monad accounts from a passkey, with no seed phrase. - \[How to build an MCP server that can interact with Monad Testnet\](https://docs.monad.xyz/guides/monad-mcp.md) - \[How to build a portfolio viewer using Moralis API\](https://docs.monad.xyz/guides/moralis-api.md) - \[How to connect a wallet to your app with Reown AppKit\](https://docs.monad.xyz/guides/reown.md) - \[How to build a basic dApp with Scaffold-ETH\](https://docs.monad.xyz/guides/scaffold-eth.md) - \[Verify a smart contract on Monad using Foundry\](https://docs.monad.xyz/guides/verify-smart-contract/foundry.md) - \[Verify a smart contract on Monad using Hardhat\](https://docs.monad.xyz/guides/verify-smart-contract/hardhat.md) - \[Verify a Contract\](https://docs.monad.xyz/guides/verify-smart-contract/index.md) - \[How to set up an x402-enabled endpoint with Monad support\](https://docs.monad.xyz/guides/x402.md) - \[Introduction\](https://docs.monad.xyz/index.md): Monad is a Layer-1 blockchain delivering high performance, true decentralization, and EVM compatibility. - \[Monad for Developers\](https://docs.monad.xyz/introduction/monad-for-developers.md): Technical one-pager on Monad for developers - \[Monad for Users\](https://docs.monad.xyz/introduction/monad-for-users.md): One-pager on Monad for users - \[Why Blockchain?\](https://docs.monad.xyz/introduction/why-blockchain.md): A simple mental model for the 'what' and 'why'. - \[Why Monad: Decentralization + Performance\](https://docs.monad.xyz/introduction/why-monad.md): Monad addresses today's performance bottlenecks through optimization while preserving decentralization. - \[Asynchronous I/O\](https://docs.monad.xyz/monad-arch/concepts/asynchronous-io.md) - \[Concepts\](https://docs.monad.xyz/monad-arch/concepts/index.md) - \[Pipelining\](https://docs.monad.xyz/monad-arch/concepts/pipelining.md) - \[Asynchronous Execution\](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution.md): Pipelined consensus-execution staging - \[Message Authentication\](https://docs.monad.xyz/monad-arch/consensus/authentication.md) - \[Block States\](https://docs.monad.xyz/monad-arch/consensus/block-states.md): Block lifecycle - \[Blocksync\](https://docs.monad.xyz/monad-arch/consensus/blocksync.md): Mechanism for synchronizing missing blocks - \[Forkpoint\](https://docs.monad.xyz/monad-arch/consensus/forkpoint.md): How a node persists consensus state and resumes from it on startup - \[Consensus\](https://docs.monad.xyz/monad-arch/consensus/index.md) - \[Local Mempool\](https://docs.monad.xyz/monad-arch/consensus/local-mempool.md): Mempool local to each node - \[MonadBFT\](https://docs.monad.xyz/monad-arch/consensus/monad-bft.md): MonadBFT - Fast, Responsive, Fork-Resistant, Streamlined Consensus - \[Peer Discovery\](https://docs.monad.xyz/monad-arch/consensus/peer-discovery.md) - \[RaptorCast\](https://docs.monad.xyz/monad-arch/consensus/raptorcast.md): Multicast message delivery protocol used for block propagation - \[Staking\](https://docs.monad.xyz/monad-arch/consensus/staking.md): How Monad's staking system works - \[Statesync\](https://docs.monad.xyz/monad-arch/consensus/statesync.md): Mechanism for synchronizing MonadDb state - \[Transport Protocol Usage\](https://docs.monad.xyz/monad-arch/consensus/transport-protocols.md): Overview of transport protocol usage for node communication - \[Execution\](https://docs.monad.xyz/monad-arch/execution/index.md) - \[MonadDb\](https://docs.monad.xyz/monad-arch/execution/monaddb.md): High-performance database for storing blockchain data. - \[JIT Compilation\](https://docs.monad.xyz/monad-arch/execution/native-compilation.md): High-performance execution of EVM bytecode by compiling to machine code. - \[Parallel Execution\](https://docs.monad.xyz/monad-arch/execution/parallel-execution.md) - \[Monad Architecture\](https://docs.monad.xyz/monad-arch/index.md) - \[Real-Time Data Sources\](https://docs.monad.xyz/monad-arch/realtime-data/data-sources.md) - \[Real-time Data\](https://docs.monad.xyz/monad-arch/realtime-data/index.md) - \[Speculative Real-Time Data\](https://docs.monad.xyz/monad-arch/realtime-data/spec-realtime.md) - \[Transaction Lifecycle in Monad\](https://docs.monad.xyz/monad-arch/transaction-lifecycle.md) - \[Announcements\](https://docs.monad.xyz/node-ops/announcements.md) - \[Configuring RPC to use archive data\](https://docs.monad.xyz/node-ops/archive-data/configuring-rpc.md) - \[The Data Waterfall\](https://docs.monad.xyz/node-ops/archive-data/data-waterfall.md) - \[Genesis Replay\](https://docs.monad.xyz/node-ops/archive-data/genesis-replay.md): Re-execute historical blocks to reconstruct state - \[Archive Data Setup\](https://docs.monad.xyz/node-ops/archive-data/index.md) - \[Running an Archive Server\](https://docs.monad.xyz/node-ops/archive-data/running-an-archive-server.md) - \[Execution Events and WebSocket Setup\](https://docs.monad.xyz/node-ops/events-and-websockets.md) - \[How Full Nodes Receive Blocks\](https://docs.monad.xyz/node-ops/full-node-block-delivery.md) - \[Full Node Installation\](https://docs.monad.xyz/node-ops/full-node-installation.md) - \[General Operations\](https://docs.monad.xyz/node-ops/general-operations.md) - \[Hardware Requirements\](https://docs.monad.xyz/node-ops/hardware-requirements.md) - \[Node Operations\](https://docs.monad.xyz/node-ops/index.md) - \[Full Replay\](https://docs.monad.xyz/node-ops/node-recovery/full-replay.md) - \[Hard Reset Instructions\](https://docs.monad.xyz/node-ops/node-recovery/hard-reset.md) - \[Recovering a Node\](https://docs.monad.xyz/node-ops/node-recovery/index.md) - \[Node Migration (Promoting a Full Node to Validator)\](https://docs.monad.xyz/node-ops/node-recovery/node-migration.md) - \[Soft Reset Instructions\](https://docs.monad.xyz/node-ops/node-recovery/soft-reset.md) - \[Solonet\](https://docs.monad.xyz/node-ops/solonet.md): Run a complete Monad network locally in Docker for testing node operations and validator workflows. - \[Authenticated UDP Migration\](https://docs.monad.xyz/node-ops/upgrade-instructions/auth-udp.md) - \[Authenticated UDP Checking\](https://docs.monad.xyz/node-ops/upgrade-instructions/authenticated-udp-checking.md) - \[Upgrade Instructions\](https://docs.monad.xyz/node-ops/upgrade-instructions/index.md) - \[MIP-8 Activation and Page Storage Migration\](https://docs.monad.xyz/node-ops/upgrade-instructions/page-storage-mip-8-migration.md) - \[v0.12.3\](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.3.md) - \[v0.12.5 - \`testnet\` re-genesis\](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.5-testnet-regenesis.md) - \[v0.12.6\](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.6.md) - \[v0.12.7\](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.7.md) - \[v0.13.0 (MONAD\_NINE)\](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.13.0.md) - \[v0.13.1 Upgrade Instructions\](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.13.1.md) - \[v0.14.0 Upgrade Instructions\](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.0.md) - \[v0.14.1 Upgrade Instructions\](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.1.md) - \[v0.14.2 Upgrade Instructions\](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.2.md) - \[v0.14.3 Upgrade Instructions\](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.3.md) - \[v0.14.4 Upgrade Instructions\](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.4.md) - \[v0.14.5 Upgrade Instructions\](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.5.md) - \[v0.15.0 Upgrade Instructions\](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.0.md) - \[v0.15.1 Upgrade Instructions\](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.1.md) - \[v0.15.2 Upgrade Instructions\](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.2.md) - \[Validator Delegation Program (VDP)\](https://docs.monad.xyz/node-ops/validator-delegation-program/index.md) - \[VDP Policy on MEV Systems\](https://docs.monad.xyz/node-ops/validator-delegation-program/mev.md) - \[Validator Installation\](https://docs.monad.xyz/node-ops/validator-installation.md) - \[Official Links\](https://docs.monad.xyz/official-links.md) - \[JSON-RPC API Reference\](https://docs.monad.xyz/reference/json-rpc/api.md): Reference for Monad's JSON-RPC interface - \[JSON-RPC Overview\](https://docs.monad.xyz/reference/json-rpc/overview.md): JSON-RPC methods, differences from Ethereum, rate limits, and error codes - \[JSON-RPC Playground\](https://docs.monad.xyz/reference/json-rpc/playground.md): Interactive JSON-RPC request builder for all Monad RPC methods - \[MPP API Reference\](https://docs.monad.xyz/reference/mpp/api.md): Reference for the @monad-crypto/mpp package - \[MPP Overview\](https://docs.monad.xyz/reference/mpp/overview.md): Send and accept payments on Monad using the Machine Payments Protocol - \[Staking API Reference\](https://docs.monad.xyz/reference/staking/api.md): Reference for Monad's staking precompile - \[Staking Overview\](https://docs.monad.xyz/reference/staking/overview.md): How to interact with Monad's staking system - \[How to generate user specific images in the Farcaster Mini App\](https://docs.monad.xyz/templates/farcaster-miniapp/generating-custom-og-images.md) - \[How to build a Farcaster Mini App\](https://docs.monad.xyz/templates/farcaster-miniapp/getting-started.md) - \[How to add haptics to a Farcaster Mini App\](https://docs.monad.xyz/templates/farcaster-miniapp/haptics.md) - \[Farcaster Mini Apps\](https://docs.monad.xyz/templates/farcaster-miniapp/index.md) - \[How to publish a Farcaster Mini App\](https://docs.monad.xyz/templates/farcaster-miniapp/publishing-miniapp.md) - \[How to send notifications to users of the Farcaster Mini App\](https://docs.monad.xyz/templates/farcaster-miniapp/sending-notifications.md) - \[How to use the Next.js Serwist 0x Privy embedded wallet template\](https://docs.monad.xyz/templates/next-serwist-0x-privy-embedded-wallet.md) - \[How to use the Next.js PWA Privy embedded wallet template\](https://docs.monad.xyz/templates/next-serwist-privy-embedded-wallet.md) - \[How to use the Next.js PWA sponsored transactions template\](https://docs.monad.xyz/templates/next-serwist-privy-smart-wallet.md) - \[How to use the Next.js Serwist Thirdweb embedded wallet template\](https://docs.monad.xyz/templates/next-serwist-thirdweb.md) - \[How to use the React Native Privy embedded wallet template\](https://docs.monad.xyz/templates/react-native-privy-embedded-wallet.md) - \[How to use the React Native sponsored transactions template\](https://docs.monad.xyz/templates/react-native-privy-pimlico-sponsored-transactions.md) - \[How to use the React Native Thirdweb embedded wallet template\](https://docs.monad.xyz/templates/react-native-thirdweb-embedded-wallet.md) - \[Agentic Payments\](https://docs.monad.xyz/tooling-and-infra/agentic-payments.md) - \[Analytics\](https://docs.monad.xyz/tooling-and-infra/analytics.md) - \[Block Explorers\](https://docs.monad.xyz/tooling-and-infra/block-explorers.md) - \[Cross-Chain\](https://docs.monad.xyz/tooling-and-infra/cross-chain.md) - \[Custody\](https://docs.monad.xyz/tooling-and-infra/custody.md) - \[Earn/Yield Infrastructure\](https://docs.monad.xyz/tooling-and-infra/earn-yield.md) - \[Tooling and Infrastructure\](https://docs.monad.xyz/tooling-and-infra/index.md) - \[Common Data\](https://docs.monad.xyz/tooling-and-infra/indexers/common-data.md) - \[Indexers\](https://docs.monad.xyz/tooling-and-infra/indexers/index.md) - \[Indexing Frameworks\](https://docs.monad.xyz/tooling-and-infra/indexers/indexing-frameworks.md) - \[Onramps\](https://docs.monad.xyz/tooling-and-infra/onramps.md) - \[Oracles\](https://docs.monad.xyz/tooling-and-infra/oracles.md) - \[Payment Orchestrators\](https://docs.monad.xyz/tooling-and-infra/payment-orchestrators.md) - \[Privacy\](https://docs.monad.xyz/tooling-and-infra/privacy.md) - \[RPC Providers\](https://docs.monad.xyz/tooling-and-infra/rpc-providers.md) - \[Hardhat\](https://docs.monad.xyz/tooling-and-infra/toolkits/hardhat.md) - \[Toolkits\](https://docs.monad.xyz/tooling-and-infra/toolkits/index.md) - \[Monad Foundry\](https://docs.monad.xyz/tooling-and-infra/toolkits/monad-foundry.md) - \[Monad Solonet\](https://docs.monad.xyz/tooling-and-infra/toolkits/monad-solonet.md) - \[Account Abstraction Providers\](https://docs.monad.xyz/tooling-and-infra/wallet-infra/account-abstraction.md) - \[Embedded Wallets\](https://docs.monad.xyz/tooling-and-infra/wallet-infra/embedded-wallets.md) - \[Wallet Infrastructure\](https://docs.monad.xyz/tooling-and-infra/wallet-infra/index.md) - \[Smart Account Implementations\](https://docs.monad.xyz/tooling-and-infra/wallet-infra/smart-accounts.md) - \[Hardware Wallets\](https://docs.monad.xyz/tooling-and-infra/wallets/hardware-wallets.md) - \[Wallets\](https://docs.monad.xyz/tooling-and-infra/wallets/index.md) - \[Institutional Wallets\](https://docs.monad.xyz/tooling-and-infra/wallets/institutional-wallets.md) - \[Multisig Wallets\](https://docs.monad.xyz/tooling-and-infra/wallets/multisig-wallets.md) - \[Software Wallets\](https://docs.monad.xyz/tooling-and-infra/wallets/software-wallets.md) ## OpenAPI Specs - \[openapi\](https://docs.monad.xyz/api-reference/openapi.json) --- # Monad Architecture - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/monad-arch#content-area) This section surveys Monad’s major architectural innovations. Concepts -------- Explaining high level themes (async io and pipelining) that recur in Monad Consensus --------- Algorithms for maintaining a globally distributed, decentralized validator set Execution --------- Algorithms for executing EVM transactions efficiently Real-time Data -------------- Consuming recent blockchain data as quickly as possible Transaction Lifecycle --------------------- Mapping the path of a transaction in Monad The first Monad client is built by [Category Labs](https://www.category.xyz/) and is written from scratch in C++ and Rust. Check out the codebase: * [`monad-bft`](https://github.com/category-labs/monad-bft) (consensus client) * [`monad`](https://github.com/category-labs/monad) (execution client) [Concepts\ \ Next](https://docs.monad.xyz/monad-arch/concepts) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Asynchronous I/O - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/monad-arch/concepts/asynchronous-io#content-area) _Asynchronous I/O_ is a form of input/output processing that allows the CPU to continue executing concurrently while communication is in progress. Disk and network are orders of magnitude slower than the CPU. Rather than initiating an I/O operation and waiting for the result, the CPU can initiate the I/O operation as soon as it’s known that the data will be needed, and continue executing other instructions which do not depend on the result of the I/O operation. Some rough comparisons for illustration purposes: | Device | Latency | Bandwidth | | --- | --- | --- | | CPU L3 Cache | 10 ns | \>400 GB/s | | Memory | 100 ns | 100 GB/s | | Disk (NVMe SSD) | 400 us | 380 MB/s | | Network | 50 - 200 ms | 1 Gb/s (125 MB/s) | (actual disk stats as reported by fio for random reads of size 2KB - ~190k IOPS) Fortunately, SSD drives can perform operations concurrently, so the CPU can initiate several requests at the same time, continue executing, and then receive the results of multiple operations around the same time. Some databases (such as lmdb / mdbx) use memory-mapped storage to read and write to disk. Unfortunately, memory-mapped storage is implemented by the kernel (mmap) and is not asynchronous, so execution is blocked while waiting for the operation to complete. More about asynchronous I/O can be read [here](https://en.wikipedia.org/wiki/Asynchronous_I/O) . [Concepts\ \ Previous](https://docs.monad.xyz/monad-arch/concepts) [Pipelining\ \ Next](https://docs.monad.xyz/monad-arch/concepts/pipelining) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Pipelining - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/monad-arch/concepts/pipelining#content-area) _Pipelining_ is a technique for implementing parallelism by dividing tasks into a series of smaller tasks which can be processed in parallel. Pipelining is used in computer processors to increase the throughput of executing a series of instructions sequentially at the same clock rate. (There are other techniques used in processors to increase throughput as well.) More about instruction-level parallelism (ILP) can be read [here](https://en.wikipedia.org/wiki/Instruction_pipelining) . A simple example of pipelining: ![Pipelining, Laundry Day](https://mintcdn.com/monadfoundation-40611fb6/-TCPhWHMfGzx9j3a/static/img/pipelining.png?w=2500&fit=max&auto=format&n=-TCPhWHMfGzx9j3a&q=85&s=fc5d1dfbe3a6ed66c63833a65d59670d) Pipelining laundry day. Top: Naive; Bottom: Pipelined. Credit: [Prof. Lois Hawkes, FSU](https://www.cs.fsu.edu/~hawkes/cda3101lects/chap6/index.html?$$$F6.1.html$$$) When doing four loads of laundry, the naive strategy is to wash, dry, fold, and store the first load of laundry before starting on the second one. The pipelined strategy is to start washing load 2 when load 1 goes into the dryer. Pipelining gets work done more efficiently by utilizing multiple resources simultaneously. [Asynchronous I/O\ \ Previous](https://docs.monad.xyz/monad-arch/concepts/asynchronous-io) [Consensus\ \ Next](https://docs.monad.xyz/monad-arch/consensus) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Parallel Execution - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/monad-arch/execution/parallel-execution#content-area) [​](https://docs.monad.xyz/monad-arch/execution/parallel-execution#summary) Summary -------------------------------------------------------------------------------------- Monad executes transactions in parallel. While at first it might seem like this implies different execution semantics than exist in Ethereum, it actually does not. Monad blocks are the same as Ethereum blocks - a linearly ordered set of transactions. The result of executing the transactions in a block is identical between Monad and Ethereum. [​](https://docs.monad.xyz/monad-arch/execution/parallel-execution#optimistic-execution) Optimistic Execution ---------------------------------------------------------------------------------------------------------------- At a base level, Monad uses optimistic execution. This means that Monad will start executing transactions before earlier transactions in the block have completed. Sometimes (but not always) this results in incorrect execution. Consider two transactions (in this order in the block): 1. Transaction 1 reads and updates the balance of account A (for example, it receives a transfer from account B). 2. Transaction 2 also reads and updates the balance of account A (for example, it makes a transfer to account C). If these transactions are run in parallel and transaction 2 starts running before transaction 1 has completed, then the balance it reads for account A may be different than if they were run sequentially. This could result in incorrect execution. The way optimistic execution solves this is by tracking the inputs used while executing transaction 2 and comparing them to the outputs of transaction 1. If they differ, we have detected that transaction 2 used incorrect data while executing and it needs to be executed again with the correct data. While Monad executes transactions in parallel, the updated state for each transaction is “merged” sequentially in order to check the condition mentioned above. Related computer science topics are [optimistic concurrency control](https://en.wikipedia.org/wiki/Optimistic_concurrency_control) (OCC) and [software transactional memory](https://en.wikipedia.org/wiki/Software_transactional_memory) (STM). [​](https://docs.monad.xyz/monad-arch/execution/parallel-execution#optimistic-execution-implications) Optimistic Execution Implications ------------------------------------------------------------------------------------------------------------------------------------------ In a naïve implementation of optimistic execution, one doesn’t detect that a transaction needs to be executed again until earlier transactions in the block have completed. At that time, the state updates for all the earlier transactions have been merged so it’s not possible for the transaction to fail due to optimistic execution a second time. There are steps in executing a transaction that do not depend on state. An example is signature recovery, which is an expensive computation. This work does not need to be repeated when executing the transaction again. Furthermore, when executing a transaction again due to failure to merge, often the account(s) and storage accessed will not change. This state is still be cached in memory, so again this is expensive work that does not need to be repeated. [​](https://docs.monad.xyz/monad-arch/execution/parallel-execution#further-work) Further Work ------------------------------------------------------------------------------------------------ There are other opportunities to avoid re-executing transactions which are still being explored. [Execution\ \ Previous](https://docs.monad.xyz/monad-arch/execution) [MonadDb\ \ Next](https://docs.monad.xyz/monad-arch/execution/monaddb) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Execution - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/monad-arch/execution#content-area) Parallel Execution ------------------ Optimistic parallel execution MonadDb ------- Custom database for storing the Ethereum Merkle Patricia Trie natively on SSD JIT Compilation --------------- High-performance execution of EVM bytecode by compiling to machine code [Staking\ \ Previous](https://docs.monad.xyz/monad-arch/consensus/staking) [Parallel Execution\ \ Next](https://docs.monad.xyz/monad-arch/execution/parallel-execution) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # JIT Compilation - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/monad-arch/execution/native-compilation#content-area) [​](https://docs.monad.xyz/monad-arch/execution/native-compilation#summary) Summary -------------------------------------------------------------------------------------- Executing each EVM contract call to completion as quickly as possible is a key part of Monad’s overall performance. To do this, Monad uses both a highly optimized interpreter and a bespoke native-code compiler. The compiler analyzes frequently used contracts once and caches native code so subsequent calls execute more efficiently while preserving exact EVM semantics (including gas and error behavior). [​](https://docs.monad.xyz/monad-arch/execution/native-compilation#interpreting-vs-compiling) Interpreting vs. Compiling --------------------------------------------------------------------------------------------------------------------------- Most Ethereum clients execute smart contract code one instruction at a time, checking stack bounds and available gas before applying the instruction’s semantics. This is an _interpreter_. Interpreters are straightforward to build and maintain, have low startup latency, and can perform very well when implemented with modern techniques. An alternative is to _compile_ programs. Before execution begins, code is analyzed and transformed into a representation that executes more efficiently. Compilation adds upfront latency and complexity, but it happens once per contract version. If repeated executions are faster, overall system performance improves. For simplicity and portability, many compilers target a higher-level _intermediate representation_ (e.g., [LLVM IR](https://llvm.org/) or [Cranelift](https://cranelift.dev/) ). Because the Monad client targets a specific hardware configuration, the compiler emits native [x86-64](https://en.wikipedia.org/wiki/X86_assembly_language) directly to maximize control and performance while still matching EVM behavior exactly. [​](https://docs.monad.xyz/monad-arch/execution/native-compilation#eliminating-redundant-work) Eliminating Redundant Work ---------------------------------------------------------------------------------------------------------------------------- Compilation lets us precompute behavior ahead of time. Consider this straight-line fragment: JUMPDEST PUSH1 0x1 ADD PUSH0 JUMP Once execution reaches the `JUMPDEST`, it must proceed through `PUSH1`, `ADD`, `PUSH0` and `JUMP`. A pure interpreter would charge gas and perform checks for each instruction as it executes. A compiler can recognize the straight-line block and perform a single upfront gas check for the combined cost of the block (subject to EVM rules), then emit code that runs the block without per-instruction bookkeeping. The result is fewer CPU instructions while preserving identical gas accounting and out-of-gas semantics. [Constant folding](https://en.wikipedia.org/wiki/Constant_folding) is another example. Given: PUSH1 0x2 PUSH1 0x3 ADD the compiler can determine the stack state at ADD and fold it to: PUSH1 0x5 internally, while still charging the same total gas as the original sequence and maintaining 256-bit modular arithmetic semantics. [​](https://docs.monad.xyz/monad-arch/execution/native-compilation#optimizing-code) Optimizing Code ------------------------------------------------------------------------------------------------------ Beyond removing redundant work, the compiler chooses efficient implementations based on where operands reside. It maintains a _simulated EVM stack_ that maps each 256-bit stack word to a location on the machine: main memory, a set of general-purpose integer registers, or a single AVX vector register. This approach is a combination of [register allocation](https://en.wikipedia.org/wiki/Register_allocation) in a traditional optimizing compiler and [stack caching](https://dl.acm.org/doi/abs/10.1145/223428.207165) techniques for compiling stack-based languages. Each EVM instruction is then specialized to the operand locations it sees. For example, `AND` can be implemented with a single [x86 `vpand`](https://www.felixcloutier.com/x86/pand) when both arguments are already in AVX registers. Much of the compiler’s effectiveness comes from emitting specialized sequences for common operand-location combinations. [​](https://docs.monad.xyz/monad-arch/execution/native-compilation#compilation-performance) Compilation Performance ---------------------------------------------------------------------------------------------------------------------- Compiling every contract ahead of time is impractical. Instead, the compiler tracks contracts by cumulative gas consumed over all executions and caches native code for the “hottest” ones. As blocks execute, newly hot contracts enter a compile queue. Compilation runs asynchronously, and contracts that are not yet compiled (or never become hot) continue to run on the highly optimized interpreter. The cache ensures repeated calls to popular contracts benefit from compilation without blocking execution on compile latency. [MonadDb\ \ Previous](https://docs.monad.xyz/monad-arch/execution/monaddb) [Real-time Data\ \ Next](https://docs.monad.xyz/monad-arch/realtime-data) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Transaction Lifecycle in Monad - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/monad-arch/transaction-lifecycle#content-area) [​](https://docs.monad.xyz/monad-arch/transaction-lifecycle#transaction-submission) Transaction Submission ------------------------------------------------------------------------------------------------------------- The lifecycle of a transaction starts with a user preparing a signed transaction and submitting it to an RPC node. Transactions are typically prepared by an application frontend, then presented to the user’s wallet for signing. Most wallets make an `eth_estimateGas` RPC call to populate the gas **limit** for this transaction, although the user can also override this in their wallet. The user is also typically asked to choose a gas **price** for the transaction, which is a number of NativeTokens per unit of gas. After the user approves the signing in their wallet, the signed transaction is submitted to an RPC node using the `eth_sendTransaction` or `eth_sendRawTransaction` API call. [​](https://docs.monad.xyz/monad-arch/transaction-lifecycle#mempool-propagation) Mempool Propagation ------------------------------------------------------------------------------------------------------- As described in [Local Mempool](https://docs.monad.xyz/monad-arch/consensus/local-mempool) : The RPC node performs validity checks: * signature verification * nonce not too low * gas limit below transaction gas limit before forwarding the pending transaction to the next `N` leaders. Each of those leaders replicate those validity checks before adding the pending transaction to their local mempool. If the transaction isn’t included in any of the blocks proposed by those leaders, the RPC node repeats this process, sending to the next `N` leaders. The process is repeated up to `K` times. [​](https://docs.monad.xyz/monad-arch/transaction-lifecycle#block-inclusion) Block Inclusion ----------------------------------------------------------------------------------------------- Pending transactions are included in a block only if further dynamic checks pass: * account balance is sufficient to pay for gas (taking into account the [reserve balance rules](https://docs.monad.xyz/developer-essentials/reserve-balance) ) * nonce is contiguous * pays valid [base fee per gas](https://docs.monad.xyz/developer-essentials/gas-pricing#eip-1559-compatibility) * there is space in the block and the leader has chosen to include this transaction [​](https://docs.monad.xyz/monad-arch/transaction-lifecycle#block-propagation) Block Propagation --------------------------------------------------------------------------------------------------- Blocks are propagated through the network as discussed in [MonadBFT](https://docs.monad.xyz/monad-arch/consensus/monad-bft) , using the [RaptorCast](https://docs.monad.xyz/monad-arch/consensus/raptorcast) messaging protocol for outbound messages from the leader. Under MonadBFT, a block progresses from the Proposed phase to the Voted phase (after 1 block) and then to the Finalized phase (after 2 blocks). Once the block is Finalized, the transaction has officially “occurred” in the history of the blockchain. Since its order is determined, its truth value (i.e., whether it succeeds or fails, and what the outcome is immediately after that execution) is determined. [​](https://docs.monad.xyz/monad-arch/transaction-lifecycle#local-execution) Local Execution ----------------------------------------------------------------------------------------------- As soon as a node receives a block, it begins executing the transactions from that block. For efficiency reasons, transactions are executed [optimistically in parallel](https://docs.monad.xyz/monad-arch/execution/parallel-execution) , but it is as if the transactions were executed serially, since results are always committed in the original order. [​](https://docs.monad.xyz/monad-arch/transaction-lifecycle#querying-the-outcome) Querying the Outcome --------------------------------------------------------------------------------------------------------- The user can query the result of the transaction by calling `eth_getTransactionByHash` or `eth_getTransactionReceipt` on any RPC node. The RPC node will return as soon as execution completes locally on the node. [Speculative Real-Time Data\ \ Previous](https://docs.monad.xyz/monad-arch/realtime-data/spec-realtime) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Concepts - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/monad-arch/concepts#content-area) Key concepts that underpin Monad’s architecture. Asynchronous I/O ---------------- How Monad uses async I/O to keep the CPU productive while communication is in progress Pipelining ---------- Dividing tasks into smaller stages that can be processed in parallel [Monad Architecture\ \ Previous](https://docs.monad.xyz/monad-arch) [Asynchronous I/O\ \ Next](https://docs.monad.xyz/monad-arch/concepts/asynchronous-io) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Real-time Data - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/monad-arch/realtime-data#content-area) Real-Time Data Sources ---------------------- How Monad reports real-time blockchain data Speculative Real-Time Data -------------------------- An optimization for reporting real-time data with very low latency [JIT Compilation\ \ Previous](https://docs.monad.xyz/monad-arch/execution/native-compilation) [Real-Time Data Sources\ \ Next](https://docs.monad.xyz/monad-arch/realtime-data/data-sources) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Speculative Real-Time Data - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/monad-arch/realtime-data/spec-realtime#content-area) The Monad architectural overview explains the [asynchronous execution](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution) feature. It is essential to have a basic understanding of how this feature works before you consume Monad’s fastest real-time data feeds, especially the [speculative execution](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution#speculative-execution) and [block states](https://docs.monad.xyz/monad-arch/consensus/block-states) sections. [​](https://docs.monad.xyz/monad-arch/realtime-data/spec-realtime#why-do-i-need-to-understand-speculative-execution) Why do I need to understand speculative execution? -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Monad’s design has considerably more parallelism than a typical EVM-compatible blockchain. This includes nodes speculatively executing the transactions in a newly-received block before being certain that that block will finalize. The real-time data feeds are created during speculative execution, so if you consume them, you might see data about transactions and their effects (e.g., logs and balance changes), but _those transactions may never really happen!_ To avoid reacting to blockchain data that is not “real”, you need to know how Monad real-time data feeds express speculative execution, and how they inform you later whether blocks (and their transactions and state effects) were ultimately added to the blockchain (or not). Given this additional complexity, why would you consume these real-time feeds? The answer is so that _your_ software can get the same performance benefits from speculative execution that Monad itself gets [(explained below)](https://docs.monad.xyz/monad-arch/realtime-data/spec-realtime#what-benefits-do-i-get-from-speculative-execution) . The cost you pay for this benefit is that you need to understand more about how Monad works, so that you can write your data processing code correctly. [​](https://docs.monad.xyz/monad-arch/realtime-data/spec-realtime#can-i-consume-real-time-data-without-dealing-with-speculative-execution) Can I consume real-time data without dealing with speculative execution? ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Yes. Monad’s JSON-RPC interface supports the `"safe"` and `"finalized"` block tags, which return data only from blocks that have reached stronger commitment levels (`Voted` and `Finalized` respectively). See [block states](https://docs.monad.xyz/monad-arch/consensus/block-states) for details on what each commitment level guarantees. Geth-style reorganizations don’t occur in the `monadNewHeads` or `monadLogs` subscriptions. Instead, you are explicitly told what the consensus algorithm is doing with the blocks you have already seen, so you know what blockchain data gets committed or not. The purpose of this document is to explain exactly what this information means, so you know how to react to it. [​](https://docs.monad.xyz/monad-arch/realtime-data/spec-realtime#what-benefits-do-i-get-from-speculative-execution) What benefits do I get from speculative execution? -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Realtime data generated by speculative execution is valuable to a consumer for two reasons: 1. It allows you to use the same pipelining tricks that Monad itself uses 2. Sometimes it’s valuable to react as soon as possible, even when the data you’re seeing is not a sure thing ### [​](https://docs.monad.xyz/monad-arch/realtime-data/spec-realtime#advantage-#1-pipelining) Advantage #1: pipelining Monad’s pipelining tricks are explained [here](https://docs.monad.xyz/monad-arch/concepts/pipelining) and [here](https://docs.monad.xyz/introduction/monad-for-users#whats-different-about-monad) . You may recall the below illustration of the laundry analogy, which helps explain the concept in both places: ![Pipelining, Laundry Day](https://mintcdn.com/monadfoundation-40611fb6/-TCPhWHMfGzx9j3a/static/img/pipelining.png?w=2500&fit=max&auto=format&n=-TCPhWHMfGzx9j3a&q=85&s=fc5d1dfbe3a6ed66c63833a65d59670d) Pipelining laundry day. Top: Naive; Bottom: Pipelined. Credit: [Prof. Lois Hawkes, FSU](https://www.cs.fsu.edu/~hawkes/cda3101lects/chap6/index.html?$$$F6.1.html$$$) Here’s a concrete example of how you can use pipelining yourself: Suppose you are writing a automated trading application. Further suppose that when a certain contract (e.g., a CLOB contract) emits a particular log event, your trading algorithm uses data from that log event as a signal to buy or sell. Before actually trading, you may need to perform additional actions first. Some of the things you might do are: * Check your risk limits, to see if increasing the position will give you too much exposure, or bring you too close to a potential liquidation * Run a more complex mathematical model, if your strategy needs to perform complex computations based on the input in the trading signal * Create and cryptographically sign the transaction for your buy/sell order All these things take time, and you can do them _in preparation_ for your eventual trade, while you wait to find out if the block containing the market signal was actually finalized. If the block _is_ finalized, you’ve already completed the essential work and can just “pull the trigger” (i.e., send the presigned trade transaction message). If the block is _not_ finalized, you just throw the preparatory work away and never do the trade. ### [​](https://docs.monad.xyz/monad-arch/realtime-data/spec-realtime#advantage-#2-reacting-before-we-know-it%E2%80%99s-%E2%80%9Creal%E2%80%9D) Advantage #2: reacting before we know it’s “real” Consider a UI component which wants to keep users informed about the progress of their transaction. When the transaction is speculatively executed, it can be marked as `Pending` in the UI, so that the user knows it has been seen and there’s a very good chance it will go through. Even if it fails to progress to a later commit state, seeing a bit of instant feedback tends to be a superior user experience. Also, consider again the example of our automated trading application. Timing is very important in financial markets. When prices are changing rapidly, a trade _right now_ could be much more valuable than a trade a few seconds later. It might make sense to initiate a trade _immediately_ off of speculative data, even knowing that some tiny percentage of the time, the trade is based on a false premise. You may lose money sometimes, i.e., when your strategy reacts to “not real” market data in a block that fails to finalize. But _usually_ this does not happen, and the gains from being early most of the time could outweigh the occasional losses when you react to “false” data. There are also other kinds of applications, e.g., on-chain games, where being more interactive is better than being perfectly accurate all the time. [​](https://docs.monad.xyz/monad-arch/realtime-data/spec-realtime#block-commit-states) Block commit states ============================================================================================================= Elsewhere in the [documentation](https://docs.monad.xyz/monad-arch/consensus/block-states) , we learned that a block can be in one of four states: `Proposed`, `Voted`, `Finalized`, and `Verified`. These are sometimes called “commit states” or “consensus states” in the documentation. In speculative real-time data feeds, whenever you are given blockchain data, you will also be told: * What commit state the associated block is in * If the initial state was not _verified_, you will be notified at some point later when the block transitions to a different state Later in this article, we’ll walk through exactly how the process happens in the current version of the software. [​](https://docs.monad.xyz/monad-arch/realtime-data/spec-realtime#block-numbers-and-block-ids) Block numbers and block ids ----------------------------------------------------------------------------------------------------------------------------- Once a block is canonically appended to the blockchain, it becomes uniquely identified by a (sequentially increasing) block number, also called a “block height.” The inclusion of a block on the blockchain is the goal of the consensus algorithm, and is called “finalization.” When a block is first constructed, it is constructed assuming it will become the next block number, `N`. But prior to finalization, consensus nodes are still trying to agree whether or not this candidate block will actually become block `N`. In consensus terminology, a leader constructs a block and _proposes_ it to the Monad network. Consensus nodes vote on the proposal of a particular candidate block `B` to become the finalized block with number `N`. We call this candidate block a “proposed block.” It’s not part of the blockchain yet, but it probably will be soon. It’s possible for the proposal to fail for many reasons. In the most common case, the proposed block does not reach enough other nodes before the timeout period expires, due to network issues. In that case, you would see another candidate to become the same block number `N` later on. Because the real-time data feeds are fed by speculative execution, you might see blockchain data for _both_ of the block `N` candidates, and will be told later which one was correct. The critical thing to understand is that this blockchain data may claim to be for “block number `N`”, but it’s not be the “real” block `N` yet: it’s just a _proposal_ to become block `N`. Consequently, when you see real-time data for a block _before_ it finalizes, the block number alone is not enough to uniquely identify it. This is only the block number that the block _will_ have, if it eventually gets finalized. Instead, consensus uses a “block id” to uniquely identify proposed blocks. The id can be used to track a specific block through its commit state lifecycle. Consider the following situation: ■ ║ ┌─────────────┐ ┌─────────────┐ ║ │ │ │ │ ┌─────────╬──┤ Block 102 ◀───┤ Block 103 │ │ ║ │ id: 79c25 │ │ id: 13a33 │ ┌─────────────┐ ┌──────▼──────┐ ║ │ │ │ │ │ │ │ │ ║ └─────────────┘ └─────────────┘ │ Block 100 ◀───┤ Block 101 │ ║ │ id: 5b3a6 │ │ id: 6d585 │ ║ │ │ │ │ ║ └─────────────┘ └──────▲──────┘ ║ ┌─────────────┐ │ ║ │ │ └─────────╬──┤ Block 102 │ ║ │ id: 3ed4d │ ║ │ │ ║ └─────────────┘ ║ ║ ◀ ║ ▶ Finalized blocks ║ Proposed blocks (committed to ║ (may not become blockchain) ║ committed to ║ blockchain) ║ ■ In this diagram: * Block 101 is the latest block to be finalized * There are two competing proposed blocks vying to become block 102; they can be distinguished by their block ids * One of the proposed blocks (`13a33`) is the parent of another proposed block * You might see real-time data for _all_ of these blocks; for those which are not finalized, you can start your pipeline processing right away, but you _may_ want to wait until they reach a better commitment state before acting The above situation is very rare in practice, but you should be aware that it is possible. [​](https://docs.monad.xyz/monad-arch/realtime-data/spec-realtime#consensus-execution-and-commit-states) Consensus, execution, and commit states =================================================================================================================================================== Monad’s real-time data stream is emitted directly by the EVM. In Category Labs’ implementation of a Monad node, execution and consensus are decoupled, as they are in most Ethereum-compatible blockchain software. That is, consensus and execution are not _just_ different algorithms, but completely separate programs that communicate with each other. Consensus is the algorithm (and the daemon) which decides whether or not a potential block will become part of the blockchain. Execution hosts the EVM, and executes blocks on a speculative basis, before it is told the fate of the block by the consensus algorithm. Meanwhile, consensus is in the “driver’s seat”: it is the primary driver in the creation of new blocks, and execution acts as service that consensus uses. However, only execution produces real-time data and maintains the state database, because it is the only thing that sees the details of every log, every call frame, etc. The exact way that blocks progress from one state to the next is explained below. Note that a block’s state is from the perspective of a particular observer — for example if you receive a [QC](https://docs.monad.xyz/monad-arch/consensus/monad-bft#quorum-certificate-qc) for a block, then you can move that block to the `Voted` state, but if your friend didn’t receive that QC yet, then she would still consider that block to be in the `Proposed` state. The challenge of building a distributed consensus mechanism lies in defining rules that allow nodes to individually update their state machines in response to messages even while assuming the worst, i.e. even while assuming that they might be the only one that received that message. [​](https://docs.monad.xyz/monad-arch/realtime-data/spec-realtime#first-commit-state-proposed) First commit state: `Proposed` -------------------------------------------------------------------------------------------------------------------------------- When a new block is proposed by a leader (a Monad validator node), it is sent from that leader’s consensus node to all other consensus nodes to be voted on. From the perspective of each of those nodes (as well as any observers), if the block is valid (i.e., follows all protocol rules), it is in the [`Proposed`](https://docs.monad.xyz/monad-arch/consensus/block-states#proposed) state. Upon receiving a valid block, each consensus node will send a “yes” vote to the next leader, while also scheduling it for immediate [speculative execution](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution#speculative-execution) by its local execution daemon. Shortly after this happens — even as the “yes” vote is starting to be transmitted over the Internet — the execution daemon begins executing the proposed block in the EVM. A few milliseconds later, the EVM will begin publishing real-time data for this block. In the current implementation of the software, _all_ blockchain data is first observed in the `Proposed` state. A `Proposed` block is a tricky thing. Nearly 100% of proposals that are received do eventually become finalized. In a statistical sense then, seeing a `Proposed` block seems quite good. However, that is because usually the global Monad network is functioning properly: the vast majority of the time, there are no major telecom outages on the Internet and there is no attempted malicious activity going on. You are seeing the block so early, that no one has voted for it except you (if you are a validator), and the leader that proposed it. The first stage vote is occurring in parallel, at roughly the same time that you are watching real-time data from its execution. This is the paradox of a `Proposed` block: the transactions within it are almost certainly going to happen. And yet if you need very high levels of assurance before acting, it would be foolish to assume they definitely will: the blockchain’s primary defense against errors, outages, and attacks (its consensus algorithm) has not weighed in yet. Make sure you understand the implications of a block being in the `Proposed` state: it’s very early, but has no defense against network problems, software errors, or malicious behavior. Each later stage reduces the likelihood of problems occurring, and the kinds of problems that can occur. [​](https://docs.monad.xyz/monad-arch/realtime-data/spec-realtime#second-commit-state-voted) Second commit state: `Voted` ---------------------------------------------------------------------------------------------------------------------------- As mentioned above, the consensus algorithm is conducting a first round vote on whether or not that block will be appended to the blockchain. The goal of this referendum is to produce a “quorum (minimum number of required votes for referendum to pass) of “yes” votes. The vote is coordinated by the second-round leader, who gathers a quorum of cryptographically-signed “yes” votes into an aggregate signature called a “quorum certificate” ([QC](https://docs.monad.xyz/monad-arch/consensus/monad-bft#quorum-certificate-qc) ). The second round leader sends out that QC to all consensus nodes. If you have received a QC on a block, that means that you have proof that the block passed the first round of voting. When this happens, you may consider the block to be in the [`Voted`](https://docs.monad.xyz/monad-arch/consensus/block-states#voted) state. A few things to note about the voted state: ### [​](https://docs.monad.xyz/monad-arch/realtime-data/spec-realtime#voted-does-not-mean-it%E2%80%99s-on-the-blockchain) `Voted` does not mean it’s on the blockchain A block _cannot_ yet be definitively appended to the blockchain when it reaches the `Voted` state. Monad’s consensus algorithm uses two rounds of voting. Possession of a QC (i.e. proof that the first round concluded in most participants voting yes) removes the most common kinds of risks, but some risk of being reverted remains. Possessing a QC removes the risk that a block will be “lost” due to the most common issues such as network outages and latency issues. Even if it turned out that you were the only observer with this QC due to a severe network outage, Monad’s consensus algorithm has a fallback mechanism that ensures that the original block will be reproposed and ultimately finalized under almost all conditions. Under what conditions is the existence of a QC not enough? [Several things must have happened](https://docs.monad.xyz/monad-arch/consensus/monad-bft#the-only-loophole) , but the most notable is that the original leader must have _equivocated_, i.e. proposed two different blocks at the same block height, sending each to a different set of nodes. Equivocation is an unlikely thing for a leader to do, since it is an easily attributable fault (proof is just the pair of conflicting blocks signed by the same leader), and since the leader only hurts themselves by invalidating their own proposal. This is why a block that has reached the `Voted` stage is very likely to be finalized. ### [​](https://docs.monad.xyz/monad-arch/realtime-data/spec-realtime#a-block-might-never-enter-the-voted-state) A block might never enter the `Voted` state A proposed block might never receive a QC, if its first consensus vote fails. The most common reason that a block does not get voted in is network latency issues. Suppose, for example, that both your node and the leader are in Australia, and there is significant congestion with the cross-continental network traffic. In that case, most of the blockchain nodes may not learn about the proposal before the timeout period expires, and the vote will fail. Note that you will _not_ be told that the vote fails. The failure of the vote is _implicit_, but you can tell it happened because of the next property. ### [​](https://docs.monad.xyz/monad-arch/realtime-data/spec-realtime#for-some-block-number-n-some-proposed-block-will-eventually-be-voted-in) For some block number `N`, _some_ proposed block will eventually be voted in If you do not receive a QC for a particular block with block number `N`, then at some other time you will receive a _different_ proposed block to become block `N` and that _will_ receive a QC. A sequence like the following may occur: * You see all of real-time data for some block `B1`, which is proposed to become block number `N` * You see a _different_ block, `B2` (and all of its execution events) also competing to become block `N` * `B2` receives a QC, and this is the only thing that happens. Namely, `B1` does _not_ receive an explicit “abandonment” event: it is just never mentioned again, and is implicitly abandoned by the network endorsing another block with the same number [​](https://docs.monad.xyz/monad-arch/realtime-data/spec-realtime#third-commit-state-finalized) Third commit state: `Finalized` ---------------------------------------------------------------------------------------------------------------------------------- [`Finalized`](https://docs.monad.xyz/monad-arch/consensus/block-states#finalized) means the block is now part of the canonical blockchain and cannot be reverted without a hard fork. From this point forward, we no longer need the block id and can refer to a block solely by its block number. When a block number `N` is finalized, it _implicitly_ abandons all other proposed blocks with the same block number `N`. Such blocks could be in either the proposed or the voted state. We say the abandonment is implicit because no event will be recorded to explicitly announce the abandonment of previously seen block id. If you are using pipelining programming techniques when you consume real-time data, then you are probably keeping track of some state associated with unfinalized blocks. In our trading example, this would be the pre-prepared buy or sell order transaction message. Every time a block is finalized, you read must check for any blocks (1) with the same block number, but (2) with a different id, and abort your pipelined processing for those blocks. They will never be appended to the blockchain and the associated transactions and their effects — whose execution events you have already seen — will never occur. ### [​](https://docs.monad.xyz/monad-arch/realtime-data/spec-realtime#why-are-there-two-different-stages-of-voting) Why are there two different stages of voting? This is because the _subject_ of the vote — the thing we are trying to get agreement on — is different. 1. In the _first_ vote, the network wants to verify that a block satisfies all the protocol rules. If a QC is obtained, we know that a majority of the honest nodes agree that the block _should_ be added. This first vote is called the “voted” stage since _the block itself_ has been voted for. 2. In the _second_ vote, we want to get cryptographically secure agreement that _enough of the network has actually seen the result of the first vote_. This second vote is called the “finalized” stage since, now that everyone knows the first vote succeeded, they can also agree that it must be the next block on the blockchain. The second vote is trying to answer the question posed by the old saying “If a tree falls in a forest and no one is around to hear it, does it make a sound?” Consider how the “fan-in, fan-out” [linear communication pattern](https://docs.monad.xyz/monad-arch/consensus/monad-bft#happy-path) of the BFT protocol works. We talk about nodes “having a QC”, but the QC is computed by the leader of the next round — this leader is the one actually “conducting” the vote. Even if the leader is dishonest, it cannot forge the vote because it cannot forge other nodes’ cryptographic signatures. But it _can_ fail to successfully tell enough of its peers about the QC, since it must communicate the QC to everyone. Network problems are common, so communication can always fail. Thus we need a second round of voting, for validators to reach distributed agreement about the fact that they’ve seen the first QC. Now it’s safe to assume that everyone (or at least the honest majority) will have the same canonical blockchain. The reason that `Voted` is a very reliable commit state on Monad is that if common problems occur during the _second_ stage vote, the algorithm will continue trying to conduct the second stage vote, failing only in some narrow corner cases involving equivocation. [​](https://docs.monad.xyz/monad-arch/realtime-data/spec-realtime#fourth-commit-state-verified) Fourth commit state: `Verified` ---------------------------------------------------------------------------------------------------------------------------------- The consensus algorithm produces one last state transition for a block, called [`Verified`](https://docs.monad.xyz/monad-arch/consensus/block-states#verified) . The `Verified` state is a consequence of Monad’s [asynchronous execution](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution) . Recall that a consensus node votes on a block _before_ its execution is complete. This implies that consensus must be voting on the block’s execution inputs, but _not_ on the block’s execution outputs. Consensus nodes cannot be voting, for example, on the correct value of the state root produced by the execution of the block, because they don’t know what it is (remember, it is being computed in parallel with the vote occurring). This means that the `Voted` state does not certify the correctness of any output fields in the Ethereum block header such as `state_root`, `receipts_root`, etc. This is possible because any well-formed Ethereum block will have completely deterministic effects on the blockchain state, when executed by a conforming EVM implementation. Thus, it is safe to append a block onto the blockchain, knowing that everyone will agree on its behavior, even if we don’t know exactly what the behavior will be. Clearly though, for the blockchain to be reliable, consensus nodes _must_ eventually vote on the correctness of the execution outputs. Suppose they did not, and further suppose that a bug existed in some execution nodes but not in others (perhaps running a different version of the client software). If there were no mechanism to feed the execution outputs back into consensus decisions, the state could become forked without anyone noticing. Consensus proposals _start_ by assuming that all execution nodes will compute the correct state, but to prevent bugs and malicious actions from compromising the network, it must check that this happens eventually. Here is how Monad solves this issue: To give execution ample time to finish, execution outputs for block `B` are not incorporated into the consensus protocol until three rounds in the future, alongside the proposal of block `B+3`. When _this_ proposal is finalized (ideally two rounds later, during the proposal of block `B+5`), then a supermajority of nodes will have voted for the correct values of the execution outputs. To roughly summarize the difference: * `Finalized` means the block’s definition (i.e., its transactions) are definitely part of the blockchain * `Verified` means that a supermajority stake’s worth of other nodes have verified that your local node’s computation of the state changes of these transactions match the supermajority’s To understand more, read [here](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution#delayed-merkle-root) . Does this imply that verified state is the gold standard for “100%, can never fail” transaction reporting? Also no, if you are trusting a data feed produced by a single node. Who is to say, for example, that the node producing the data in not suffering from a bug, or has been hacked? As always in the blockchain universe, critical transactions that demand _total_ peace of mind can only be verified by widespread agreement, _broadly_ defined. This includes explicitly checking with other nodes, to ensure no hosts or network intermediaries have been compromised and the software is working properly. In practice, the `Voted` state is usually good enough for most things: it should _very_ rarely revert in practice, so it is also used as the `"safe"` block tag in Monad’s RPC implementation. [Real-Time Data Sources\ \ Previous](https://docs.monad.xyz/monad-arch/realtime-data/data-sources) [Transaction Lifecycle in Monad\ \ Next](https://docs.monad.xyz/monad-arch/transaction-lifecycle) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # MonadDb - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/monad-arch/execution/monaddb#content-area) [​](https://docs.monad.xyz/monad-arch/execution/monaddb#summary) Summary --------------------------------------------------------------------------- MonadDb is a critical component in Monad for maintaining full Ethereum compatibility while delivering high performance. It is a custom-built key-value database designed for storing authenticated blockchain data. MonadDb, specifically, is optimized for efficiently storing Merkle Patricia Trie nodes on disk. [​](https://docs.monad.xyz/monad-arch/execution/monaddb#merkle-patricia-trie-structured-database) Merkle Patricia Trie Structured Database --------------------------------------------------------------------------------------------------------------------------------------------- Most Ethereum clients use generic key-value databases that are implemented as either B-Tree (e.g. [LMDB](https://www.symas.com/lmdb) ) or LSM-Tree (e.g. [LevelDB,](https://github.com/google/leveldb) [RocksDB](https://rocksdb.org/) ) data structures. However Ethereum uses the [Merkle Patricia Trie](https://ethereum.org/en/developers/docs/data-structures-and-encoding/patricia-merkle-trie/) (MPT) data structure for storing state and other authenticated fields like receipts and transactions. This results in a suboptimal solution where one data structure is embedded into another data structure. MonadDb implements a [Patricia Trie](https://en.wikipedia.org/wiki/Radix_tree) (a specific variant of radix tree) data structure natively, both on-disk and in-memory. Despite the opinionated design, MonadDb is a flexible key-value store capable of storing any type of data. For instance, MonadDb is also used to store block headers and payloads for Monad. [​](https://docs.monad.xyz/monad-arch/execution/monaddb#asynchronous-io) Asynchronous IO ------------------------------------------------------------------------------------------- Monad executes multiple transactions in [parallel](https://docs.monad.xyz/monad-arch/execution/parallel-execution) . In order to enable this, reads should not block continued operation, and this goal motivates [asynchronous I/O](https://docs.monad.xyz/monad-arch/concepts/asynchronous-io) (async I/O) for the database. The above-mentioned key-value databases lack proper async I/O support (although there are some efforts to improve in this area). MonadDb fully utilizes the latest kernel support for async I/O (on Linux this is [io\_uring](https://unixism.net/loti/index.html) ). This avoids spawning a large number of kernel threads to handle pending I/O requests in an attempt to perform work asynchronously. [​](https://docs.monad.xyz/monad-arch/execution/monaddb#filesystem-bypass) Filesystem bypass ----------------------------------------------------------------------------------------------- Modern filesystems provide a convenient abstraction for applications, but introduce overhead when building high-throughput I/O software. These often hidden costs include block allocation, fragmentation, read/write amplification, and metadata management. The abstraction of files and a set of system calls allows applications to interact with the file data as if it were stored contiguously. The complexity of managing exact physical disk locations is abstracted away from the applications (and their developers). However, the actual content on disk might be fragmented into multiple non-contiguous pieces.  Accessing or writing to such a file usually involves more than one simple I/O operation. To minimize overhead, MonadDb provides operators the option to bypass the filesystem. MonadDb implements its own indexing system based on the Patricia trie data structure, eliminating filesystem dependencies. Users have the flexibility to operate MonadDb on either regular files or block devices. For optimal performance, it is recommended to run MonadDb directly on block devices. This approach avoids all filesystem-related overhead, allowing MonadDb to fully unlock SSD performance. [​](https://docs.monad.xyz/monad-arch/execution/monaddb#concurrency-control) Concurrency Control --------------------------------------------------------------------------------------------------- The Monad blockchain consists of multiple clients, each interacting with the database as either reader or writer. To support this functionality, MonadDb must efficiently synchronize between a single writer (execution) and multiple readers (consensus and RPC). MonadDb implements a persistent (or immutable) Patricia trie. When a branch in the trie is updated, new versions of the nodes on that branch are created, and the previous version of the trie is preserved. This approach facilitates versioning within the database and significantly simplifies synchronization between readers and the writer. It ensures that all reads are accurate and consistent while guaranteeing that writes are both complete and atomic from the perspective of the readers. [​](https://docs.monad.xyz/monad-arch/execution/monaddb#write-performance-on-modern-ssd) Write Performance on Modern SSD --------------------------------------------------------------------------------------------------------------------------- The usage of a persistent data structure also allows us to perform sequential writes, which offers better performance than random writes on modern SSDs. Modern SSD garbage collection occurs at the block level. On sequential writes, an entire block gets filled before the next one, which dramatically simplifies garbage collection. Garbage collection is much more expensive for random writes. Sequential writes also distribute data more efficiently, thereby reducing write amplification and increasing SSD longevity. [​](https://docs.monad.xyz/monad-arch/execution/monaddb#compaction) Compaction --------------------------------------------------------------------------------- As historical versions accumulate, the amount of data written to disk will grow. Given the limited disk capacity it operates on, it is impossible to retain complete historical records. MonadDb stores recent versions of blockchain data and state and dynamically adjusts the history length based on available disk space. As newer versions are stored and older versions are pruned, the underlying storage space becomes fragmented. To address this, MonadDb performs compaction inline with updates, consolidating active data and releasing unused storage for recycling. This reduces fragmentation while maintaining performance and data integrity. [Parallel Execution\ \ Previous](https://docs.monad.xyz/monad-arch/execution/parallel-execution) [JIT Compilation\ \ Next](https://docs.monad.xyz/monad-arch/execution/native-compilation) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Hardware Requirements - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/hardware-requirements#content-area) Cloud-based environments are not officially supported. [​](https://docs.monad.xyz/node-ops/hardware-requirements#requirements) Requirements --------------------------------------------------------------------------------------- All requirements are the same between validators (consensus participants) and full nodes aside from bandwidth: * **CPU**: 16 core CPU with 4.5 GHz+ base clock speed, e.g. AMD Ryzen 9950x, AMD Ryzen 7950x, AMD EPYC 4584PX, etc. * **Memory**: 32 GB+ RAM * **Storage**: * 2TB dedicated disk for TrieDB (Execution) * 500GB Disk for MonadBFT / OS * PCIe Gen4x4 NVME SSD or better for both * **Bandwidth**: * 300 Mbit/s (Validators) * 100 Mbit/s (Full Nodes) Hard drive performance can vary dramatically by manufacturer. Below are results from internal testing:**Ranked performance** 1. Samsung 980 / 990 Pro - PCIe 4.0, top class performance 2. Samsung PM9A1 - PCIe 4.0, pretty good performance and stable performance under load 3. Micron 7450 - PCIe 4.0, pretty good performance BUT has weird random slowdowns under a lot of load **Known unreliable** 1. Nextorage SSDs - can become unresponsive under load due to overheating, requiring a system reboot. A community-driven set of hardware recommendations and notes can be found [here](https://monadhcl.xyz/#recommended-hardware) . [​](https://docs.monad.xyz/node-ops/hardware-requirements#why-bare-metal) Why Bare Metal? -------------------------------------------------------------------------------------------- Monad nodes must operate on bare metal servers rather than virtualized or cloud-based environments (e.g., AWS EC2, GCP, Azure) due to the system’s strict performance and timing requirements. A bare metal server gives the node direct, stable access to hardware, ensuring smooth operation and synchronization with the network: * Monad’s consensus protocol enforces tight time windows—blocks are proposed and voted on in sub-second intervals, and the network assumes nodes can validate and execute blocks within this budget. In such a situation, cloud-based environments may introduce latency and unpredictability, which can cause nodes to miss deadlines, fall behind in block processing, or become unstable during high-throughput periods. * Even when resources appear sufficient on paper, virtualization adds an additional layer of software between the node and physical hardware. This layer introduces context switching overhead and restricts direct I/O access to SSDs and network interfaces. These effects are negligible for average compute tasks but become significant when sustained high-throughput and low-latency operations are required, as in Monad’s consensus and execution loops. In summary, a bare metal server provides predictability and determinism, which are crucial for maintaining synchronization and throughput across the network. Cloud-hosted VMs may work under light loads, but they cannot guarantee consistent real-time performance required by Monad consensus at scale. [Node Operations\ \ Previous](https://docs.monad.xyz/node-ops) [Full Node Installation\ \ Next](https://docs.monad.xyz/node-ops/full-node-installation) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Node Operations - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops#content-area) [​](https://docs.monad.xyz/node-ops#setup) Setup --------------------------------------------------- Hardware Requirements --------------------- High performance on commodity hardware Full Node Installation ---------------------- How to run a full node Validator Installation ---------------------- How to run a validator [​](https://docs.monad.xyz/node-ops#operations) Operations ------------------------------------------------------------- General Operations ------------------ Command-line tools for debugging or checking node status Upgrade Instructions -------------------- Instructions for specific upgrade sequences Recovering a node ----------------- Procedures for recovering node operation [​](https://docs.monad.xyz/node-ops#advanced) Advanced --------------------------------------------------------- How Full Nodes Receive Blocks ----------------------------- How to configure node.toml to receive blocks from validators Execution Events and WebSockets ------------------------------- Additional setup instructions if you need real-time data Archive Data Setup ------------------ How to configure your node to serve historical transactional data Validator Delegation Program ---------------------------- Foundation delegation framework for validators [Hardware Requirements\ \ Next](https://docs.monad.xyz/node-ops/hardware-requirements) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Announcements - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/announcements#content-area) [​](https://docs.monad.xyz/node-ops/announcements#channels) Channels ----------------------------------------------------------------------- Subscribe to the following channels to receive Monad Foundation announcements: | Channel | Link | | --- | --- | | Email | Delivered to the address associated with your validator registration | | Discord | [#mainnet-validator-announcements](https://discord.gg/monaddev) | | Telegram | [Node Announcements](https://t.me/MonadNodeAnnouncements) | [​](https://docs.monad.xyz/node-ops/announcements#severity-system) Severity System ------------------------------------------------------------------------------------- In order to provide a standardized framework for network-related communications, the Monad Foundation uses the following color-coded categories to preface announcements. These categories are directly attributed to level of severity, recommended action, and timeframe. Ecosystem participants can use this framework to set up alerts (e.g. PagerDuty) for “CODE RED” in email subjects or social channels, further assisting in the dissemination of time-critical information. Announcements may be reclassified as more information becomes available. In an emergency, the Foundation may use any available communication channel regardless of the classification below. ### [​](https://docs.monad.xyz/node-ops/announcements#green-) Green 🟢 **Subject contains “CODE GREEN”** — informational, no action required. Examples: * Optional upgrades * Validator info updates * Social coordination messaging * Non-critical additions to the operations layer ### [​](https://docs.monad.xyz/node-ops/announcements#orange-) Orange 🟠 **Subject contains “CODE ORANGE”** — action recommended within 24–48 hours. Examples: * Upcoming non-emergency upgrades Communication will be shared over email, Discord, and the Telegram Node Announcements channel. ### [​](https://docs.monad.xyz/node-ops/announcements#red-) Red 🔴 **Subject contains “CODE RED”** — action recommended immediately upon receiving communication. Examples: * Critical emergency upgrades * Chain halts * Staking protocol compromises Communication channels depend on the nature of the incident: * **Resetricted rollout** (emergency and sensitive, e.g. security vulnerability) — to minimize the risk of exploitation before a patch is widely deployed, communication may initially be shared **exclusively over email** to known validators. * **Unrestricted rollout** (emergency but not sensitive, e.g. emergency upgrade affecting chain liveness) — communication will generally be shared over email, Discord, and the Telegram Node Announcements channel. [General Operations\ \ Previous](https://docs.monad.xyz/node-ops/general-operations) [Upgrade Instructions\ \ Next](https://docs.monad.xyz/node-ops/upgrade-instructions) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Solonet - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/solonet#content-area) [Solonet](https://github.com/monad-crypto/monad-solonet) lets you spin up a private Monad network on your laptop in seconds. It runs a self-contained chain in Docker — validator nodes, execution client, and RPC endpoint — booted from genesis with unlimited tokens. It uses the same binaries that run on testnet and mainnet, so node behavior closely matches production. Linux is supported natively, and macOS works through a small VM layer. [​](https://docs.monad.xyz/node-ops/solonet#when-to-use-solonet) When to use Solonet --------------------------------------------------------------------------------------- Solonet gives node operators a fast feedback loop without depending on a public network: * **Practice node operations**: rehearse upgrades, recoveries, and configuration changes against a disposable local chain. * **Test validator workflows**: run `staking-cli` operations against your own validator without spending testnet MON or waiting for finality. * **Develop tooling**: validate scripts, monitoring dashboards, or block-delivery integrations against a chain whose state you fully control. * **Reproduce issues**: spin up a multi-validator topology to investigate consensus or block-sync edge cases. For application development that only needs a fast EVM endpoint, `anvil --monad` starts faster and is usually sufficient. Reach for Solonet when you need full node behavior: consensus, staking, archive RPC, or production-like timing. [​](https://docs.monad.xyz/node-ops/solonet#prerequisites) Prerequisites --------------------------------------------------------------------------- * Linux x86\_64 host, or macOS (Apple Silicon) * 4+ CPU cores and 16 GB RAM * Docker on Linux; Homebrew on macOS (used to install the Lima + Colima setup below) [​](https://docs.monad.xyz/node-ops/solonet#macos-setup-apple-silicon) macOS setup (Apple Silicon) ----------------------------------------------------------------------------------------------------- Solonet’s containers are x86\_64 Linux, so on Apple Silicon you need a small Linux VM to host Docker. [Lima](https://lima-vm.io/) and [Colima](https://github.com/abiosoft/colima) handle this: brew install lima colima lima-additional-guestagents Start an x86\_64 Linux VM with enough resources: colima start \ --arch x86_64 \ --cpu-type max \ --cpu 8 \ --memory 16 \ --disk 300 \ --foreground Verify Docker is wired to the VM (output should show `Architecture: x86_64`): docker info The Docker CLI automatically points at the Colima VM, so every `docker compose` command below works identically on macOS and Linux. To tear everything down later: colima delete --data [​](https://docs.monad.xyz/node-ops/solonet#quick-start) Quick start ----------------------------------------------------------------------- Clone the repository and bring up a single-validator network: git clone https://github.com/monad-crypto/monad-solonet cd monad-solonet docker compose up --build Once the network is up: * RPC: `http://localhost:8080` * WebSocket: `ws://localhost:8081` * CORS RPC: `http://localhost:8082/rpc/` * Dashboard: `http://localhost:8082` [​](https://docs.monad.xyz/node-ops/solonet#other-network-configurations) Other network configurations --------------------------------------------------------------------------------------------------------- Multi-validator network: docker compose -f networks/multi-validators.yaml up --build Full-components network (validators plus auxiliary services): docker compose -f networks/full-network.yaml up --build [​](https://docs.monad.xyz/node-ops/solonet#included-tooling) Included tooling --------------------------------------------------------------------------------- The Solonet containers come with the tools most commonly used for node operations: * `forge` and `cast` ([Foundry](https://book.getfoundry.sh/) ) * `staking-cli` for validator staking operations * `monad-status` for inspecting node health [​](https://docs.monad.xyz/node-ops/solonet#notes) Notes ----------------------------------------------------------- * Solonet boots a fresh chain from genesis. State and validator sets are independent of testnet and mainnet, so it is suited for verifying your operational processes against a chain you control. * Because the chain is local, finality is fast and gas is effectively free. Realistic latency or load tests still require a deployed network. For installation details, environment variables, and configuration options, see the [Solonet README](https://github.com/monad-crypto/monad-solonet#readme) . [VDP Policy on MEV Systems\ \ Previous](https://docs.monad.xyz/node-ops/validator-delegation-program/mev) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Validator Installation - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/validator-installation#content-area) Setting up a validator is very similar to setting up a full node with a few extra steps. Start by configuring a node according to the full node installation [instructions](https://docs.monad.xyz/node-ops/full-node-installation) . When the full node is fully operational and synced to the network tip, you can register your node as a prospective validator by calling [`addValidator`](https://docs.monad.xyz/reference/staking/api#addvalidator) on the staking precompile. This function requires passing at least `MIN_VALIDATE_STAKE = 100_000 MON` (the minimum self-stake). After registering, your validator must also satisfy the following conditions, described in greater depth in the staking [docs](https://docs.monad.xyz/monad-arch/consensus/staking) : 1. Must have a total stake of at least `ACTIVE_VALIDATOR_STAKE = 10_000_000 MON` 2. Must be in the top `ACTIVE_VALSET_SIZE = 200` validators by stake weight 3. Must continue to have a self-stake of `MIN_VALIDATE_STAKE = 100_000 MON` When all three conditions are achieved, the validator will become active in the next epoch. [​](https://docs.monad.xyz/node-ops/validator-installation#staking-cli) Staking CLI -------------------------------------------------------------------------------------- [`staking-sdk-cli`](https://github.com/monad-developers/staking-sdk-cli) is an open-source staking CLI tool for interfacing with the staking precompile. Start with the [onboarding workflow](https://github.com/monad-developers/staking-sdk-cli/blob/main/docs/validator-onboarding.md) . [​](https://docs.monad.xyz/node-ops/validator-installation#configure-node-toml) Configure `node.toml` -------------------------------------------------------------------------------------------------------- When following the full node instructions, when you got to [this section](https://docs.monad.xyz/node-ops/full-node-installation#download-a-collection-of-chain-related-configuration-files-and-scripts) you should have downloaded the Validator-themed `node.toml`. From that template, the following should be configured: 1. (Important) Review the `beneficiary` address. This is the address that will receive block rewards. beneficiary = "0x" 2. (Optional) - Double check `node_name` makes sense after transition from full node (for example, remove any `full_` prefix). Please choose a unique identifier to avoid confusion. 3. (Optional) - Configure [dedicated](https://docs.monad.xyz/node-ops/full-node-block-delivery#dedicated-upstream) or [prioritized](https://docs.monad.xyz/node-ops/full-node-block-delivery#prioritized-secondary-raptorcast-inclusion) connections: * **Dedicated full node** # Use the following to broadcast blocks to downstream full nodes # [[bootstrap.peers]] # address = ":" # record_seq_num = "" # name_record_sig = "" # secp256k1_pubkey = "" # [[fullnode_dedicated.identities]] # secp256k1_pubkey = "" * **Prioritized full node** # Use the following to broadcast blocks to downstream full nodes # [[bootstrap.peers]] # address = ":" # record_seq_num = "" # name_record_sig = "" # secp256k1_pubkey = "" # [[fullnode_raptorcast.full_nodes_prioritized.identities]] # secp256k1_pubkey = "" To apply these full node configuration changes without restarting `monad-bft`, run the following command: monad-debug-node --control-panel-ipc-path /home/monad/monad-bft/controlpanel.sock reload-config [Full Node Installation\ \ Previous](https://docs.monad.xyz/node-ops/full-node-installation) [General Operations\ \ Next](https://docs.monad.xyz/node-ops/general-operations) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # How Full Nodes Receive Blocks - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/full-node-block-delivery#content-area) See [here](https://docs.monad.xyz/node-ops/full-node-installation) for instructions on how to set up a full node. The [RaptorCast](https://docs.monad.xyz/monad-arch/consensus/raptorcast) protocol is a novel method of one-to-many block propagation that uses an erasure-coded two-level broadcast tree to propagate large blocks from a message originator to many listeners. There are two usages of RaptorCast in the Monad network: primary and secondary: * In its **primary** usage, RaptorCast is utilized by each leader to share its block proposal to all other validators in the active set. There is one primary RaptorCast group, consisting of all validators in the active set, with a leader that rotates. * In its **secondary** usage, one validator from the active set supports a number of downstream full nodes, propagating every block proposal (received by it via primary RaptorCast) to its downstream listeners. There are many secondary RaptorCast groups - one per validator in the active set - and for each one, the leader is static. Secondary RaptorCast allows the network to support a huge set of full nodes. In the recommended configuration, each validator has a secondary RaptorCast group of size 150. Given a network of 200 active set validators, even after accounting for a redundancy factor of 2 (full nodes may register for multiple secondary RaptorCast groups), there is still capacity for 150 \* 200 / 2 = 15,000 full nodes. The rest of this page documents the behavior of secondary RaptorCast, as well as how full node operators should configure it. Validators may find the configuration helpful as well, since validators usually start as full nodes. [​](https://docs.monad.xyz/node-ops/full-node-block-delivery#differences-between-primary-and-secondary-raptorcast) Differences between primary and secondary RaptorCast -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Secondary RaptorCast follows the same mechanism as primary RaptorCast. There are some differences, however. In Primary RaptorCast: * The participants are all validators * The originator changes given that the leader can change (due to leader election) * The “weights” on the other nodes are based on stake In Secondary RaptorCast: * The originator of a group is fixed and always a validator * Other than the above, the other participants are full nodes * All nodes are equally weighted [​](https://docs.monad.xyz/node-ops/full-node-block-delivery#how-full-nodes-register-for-secondary-raptorcast) How full nodes register for secondary RaptorCast ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1. Full nodes start by peering with some of the validators. They do this by peering with the bootstrap peers (aka other full nodes) specified in `node.toml` (see later in this document for more details), then asking them for their peers, and repeating until they have the name records of the full validator set. 2. If a validator has `enable_publisher = true` in its `node.toml`, it will routinely send invites to the full nodes in its routing table (up to `max_group_size`). These invites will request the full node to join the validator’s secondary RaptorCast group. 3. A full node has the option to accept or reject. If a full node is in too many groups, it will reject. This is controlled by the `max_num_group` parameter. 4. The validator will collect these accept/reject responses and confirm a group. 5. The group will last for `round_span` specified in the validator’s `node.toml` (default: 240 rounds). As the group’s age approaches `round_span`, the validator will start sending invites for its next secondary RaptorCast group. 6. Full nodes can (and should) join multiple secondary RaptorCast groups for redundancy. A full node can join a group even if it hasn’t finished syncing the state. Joining a group is how a full node becomes aware of the current round. That information can, in turn, be used to adjust the statesync target. [​](https://docs.monad.xyz/node-ops/full-node-block-delivery#configuring-raptorcast) Configuring RaptorCast -------------------------------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/node-ops/full-node-block-delivery#general-recommendation) General Recommendation It is highly suggested that operators of validators have the node: * First be a full node with `enable_client = true` * AND also configure the validator specific settings in `node.toml` * Then convert to a validator via staking ### [​](https://docs.monad.xyz/node-ops/full-node-block-delivery#important-considerations) Important Considerations * Several of the settings below only apply to nodes that are operating as a validator * Other apply only if the node is running as a full node * That being said, it’s recommended that BOTH sets of settings be in the `node.toml` Why do we recommend the above? Because it’s possible for a node to “begin life” as a full node, become a validator (via staking) and then become a full node again (if staking is pulled back). Having settings for both modes (validator and full node) ensures that the node can keep up with the chain tip. For example, if a validator becomes a full node and is NOT part of a secondary RaptorCast group (aka `enable_client = true`) then it will miss block updates and fall behind the ledger tip. ### [​](https://docs.monad.xyz/node-ops/full-node-block-delivery#node-toml) `node.toml` Below is a snippet of a `node.toml` that applies to RaptorCast. We’ve grouped the settings as “full node only”, “validator only” or “both” We’ve also added comments to explain what each setting does `node.toml` contains the following settings: [fullnode_raptorcast] # VALIDATOR ONLY # "enable_publisher = true" means that if the full node becomes a validator, it will participate # as a secondary RaptorCast originator. enable_publisher = true # maximum number of rounds that a validator will wait for invite response from the full node max_invite_wait = 10 # number of rounds that a group lasts for round_span = 240 # how far ahead (in rounds) validator sends invites to full nodes before the start of the round # e.g. if the round_span is 240, the invites will go out at round 220 invite_lookahead = 20 # FULL NODE ONLY # this needs to be "true" for full nodes to participate in secondary RaptorCast enable_client = true # upper limit on how many groups the full node will join max_num_group = 3 # indicates the time range (in rounds) that the full node will accept group invites invite_future_dist_min = 1 invite_future_dist_max = 600 # a heartbeat which is used to determine whether the full node is receiving proposals invite_accept_heartbeat_ms = 10000 # BOTH MODES # maximum number of nodes in a group max_group_size = 150 raptor10_fullnode_redundancy_factor = 2.0 deadline_round_dist = 10 init_empty_round_span = 23 [fullnode_raptorcast.full_nodes_prioritized] identities = [] [​](https://docs.monad.xyz/node-ops/full-node-block-delivery#additional-options) Additional options ------------------------------------------------------------------------------------------------------ ### [​](https://docs.monad.xyz/node-ops/full-node-block-delivery#prioritized-secondary-raptorcast-inclusion) Prioritized secondary RaptorCast inclusion A full node may coordinate with a validator to be explicitly and consistently invited to that validator’s secondary RaptorCast group. To do this, the full node provides some information for the validator to include in its `[fullnode_raptorcast.full_nodes_prioritized.identities]` section. See [Validator Installation](https://docs.monad.xyz/node-ops/validator-installation#configure-nodetoml) for details on what needs to be provided. Note that this means the full node doesn’t have to rely on peer discovery to peer with that validator. ### [​](https://docs.monad.xyz/node-ops/full-node-block-delivery#dedicated-upstream) Dedicated upstream Validators also have the option of specifying full nodes to which they wish to directly forward all primary RaptorCast chunks. This utilizes a lot of validator bandwidth, since each registered downstream requires another copy of all chunks to be sent. It is potentially more reliable for the downstream node than subscribing via secondary RaptorCast, although in practice secondary RaptorCast is quite reliable. Note that if a full node is designated by one or more validators for dedicated chunk forwarding, then it could be configured with `enable_client = false`. This turns off attempting to participate in secondary RaptorCast. ### [​](https://docs.monad.xyz/node-ops/full-node-block-delivery#comparison) Comparison | Configuration | Requires validator to whitelist full node | RaptorCast mode | Data Source | | --- | --- | --- | --- | | **Normal** | No | `enable_client = true` | Secondary RaptorCast | | **Prioritized secondary RaptorCast** | Yes | `enable_client = true` | Secondary RaptorCast | | **Chunk forwarding** | Yes | `enable_client = false` | Primary RaptorCast | Note that these configurations are properties of a **relationship** between a full node and a validator, rather than properties of the full node itself. A full node could coordinate with multiple validators to treat it specially, while also participating in normal secondary RaptorCast with other validators that it automatically peers with. [​](https://docs.monad.xyz/node-ops/full-node-block-delivery#raptorcast-configurations-for-validators) RaptorCast configurations for validators -------------------------------------------------------------------------------------------------------------------------------------------------- Validators can toggle off their participation in secondary RaptorCast by setting `enable_publisher = false`. Although turning secondary RaptorCast off will reduce bandwidth usage, note that the bandwidth cost of secondary RaptorCast is relatively low; for example, even at 10,000 transactions per second, the expected usage will be about 6 MB per second (3 MB of block data with 2x redundancy). Therefore, it is recommended to keep `enable_publisher = true`. For more technical details about the RaptorCast, see the [RaptorCast documentation](https://docs.monad.xyz/monad-arch/consensus/raptorcast) . [Node Migration (Promoting a Full Node to Validator)\ \ Previous](https://docs.monad.xyz/node-ops/node-recovery/node-migration) [Execution Events and WebSocket Setup\ \ Next](https://docs.monad.xyz/node-ops/events-and-websockets) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Blocksync - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/monad-arch/consensus/blocksync#content-area) [​](https://docs.monad.xyz/monad-arch/consensus/blocksync#summary) Summary ----------------------------------------------------------------------------- Blocksync is a mechanism that nodes can use to acquire missing blocks. A block is considered missing when a Quorum Certificate is observed that references an unknown block. Blocks can be missing from a node in one of two scenarios: 1. After the node completes statesync and its local block height is close enough to the network tip. 2. During ordinary consensus operations, the node does not receive enough RaptorCast chunks to decode the block. This can be due to packet loss or a network partition. [​](https://docs.monad.xyz/monad-arch/consensus/blocksync#blocksync-procedure) Blocksync procedure ----------------------------------------------------------------------------------------------------- 1. A single header request is made for a range of `num_blocks` blocks, starting with `last_block_id`. 2. A chain of `num_blocks` headers are received, forming a cryptographically verifiable chain back to `last_block_`. 3. For each of the `num_blocks` headers received, concurrent (up to a max concurrency factor) body requests are made containing the `body_id` included in the header. 4. Each body response is cryptographically verifiable by comparing against the corresponding header `body_id`. ![Blocksync procedure](https://mintcdn.com/monadfoundation-40611fb6/asJraP9TfdYeo6NL/static/img/monad-arch/consensus/blocksync/blocksync_procedure.svg?w=2500&fit=max&auto=format&n=asJraP9TfdYeo6NL&q=85&s=2558fdd3e662f1c4a922c644ee088a32) [Statesync\ \ Previous](https://docs.monad.xyz/monad-arch/consensus/statesync) [Forkpoint\ \ Next](https://docs.monad.xyz/monad-arch/consensus/forkpoint) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Transport Protocol Usage - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/monad-arch/consensus/transport-protocols#content-area) Monad nodes use both TCP and UDP protocols for different types of communication. | Traffic Type | Protocol | | --- | --- | | [Primary RaptorCast](https://docs.monad.xyz/monad-arch/consensus/raptorcast) | UDP | | [Secondary RaptorCast](https://docs.monad.xyz/monad-arch/consensus/raptorcast#secondary-raptorcast---full-node-block-propagation) | UDP | | [Peer Discovery](https://docs.monad.xyz/monad-arch/consensus/peer-discovery) | UDP | | [Transaction Forwarding](https://docs.monad.xyz/monad-arch/consensus/local-mempool) | UDP | | [Block Forwarding to Dedicated Full Nodes](https://docs.monad.xyz/node-ops/full-node-block-delivery#dedicated-upstream) | UDP | | [Blocksync](https://docs.monad.xyz/monad-arch/consensus/blocksync) | TCP | | [Statesync](https://docs.monad.xyz/monad-arch/consensus/statesync) | TCP | [Message Authentication\ \ Previous](https://docs.monad.xyz/monad-arch/consensus/authentication) [Staking\ \ Next](https://docs.monad.xyz/monad-arch/consensus/staking) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Local Mempool - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/monad-arch/consensus/local-mempool#content-area) [​](https://docs.monad.xyz/monad-arch/consensus/local-mempool#summary) Summary --------------------------------------------------------------------------------- Most blockchains use a global mempool with peer-to-peer gossipping for transaction propagation. This approach is not suitable for high-performance distributed consensus for a few reasons: 1. It is slow because it may involve many hops for a transaction to reach a leader, increasing time to inclusion. 2. It is wasteful on bandwidth because the gossip protocol involves many retransmissions. 3. It ignores the leader schedule which is typically known well in advance. In Monad, there is no global mempool; instead, each validator maintains a local mempool, and RPC nodes forward transactions to the next few leaders for inclusion in their local mempool. This is much more efficient on bandwidth usage and allows transactions to be included more quickly. [​](https://docs.monad.xyz/monad-arch/consensus/local-mempool#background) Background --------------------------------------------------------------------------------------- A mempool is a collection of pending transactions. Many blockchain networks use a global mempool design, using peer-to-peer gossip protocols to keep roughly the same mempool state across all nodes in the network. A primary motivation of a global mempool design is that no matter who is leader, they will have access to the same set of pending transactions to include in the next block. A global mempool is effective for low-throughput networks, where network bandwidth is typically not a bottleneck. However, at thousands of transactions per second, the gossip protocols (and especially the required retransmission at each node) can easily consume the entire network bandwidth budget. Moreover, a global mempool is wasteful since the leader schedule is typically known well in advance. [​](https://docs.monad.xyz/monad-arch/consensus/local-mempool#transaction-lifecycle-in-monad) Transaction Lifecycle in Monad ------------------------------------------------------------------------------------------------------------------------------- There is no global mempool in Monad. Validators maintain local mempools; RPC nodes forward transactions to upcoming leaders to ensure that those transactions are available for inclusion. More precisely, transaction flow is as follows: 1. A transaction is submitted to the RPC process of a node (typically a full non-validator node). We’ll call this node the **“owner node”** of the transaction, since it assumes responsibility for communicating the status with the user. 2. The RPC process performs some static checks on the transaction. 3. The RPC process passes the transaction to the consensus process. 4. The consensus process performs static checks and dynamic checks against local state in MonadDb, such as checking the sender’s account balance and nonce. 5. If the transaction is valid, the consensus process forwards the transaction to `N` upcoming leader validator nodes. Currently, `N` is set to 3 in Monad testnet and mainnet. 6. Each of those `N` validators performs the same checks before inserting valid transactions into their local mempools. 7. When it is a leader’s turn to create a proposal, it selects transactions from its local mempool. 8. The owner node of the transaction monitors for that transaction in subsequent blocks. If it doesn’t see the transaction in the next `N` blocks, it will re-send to the next `N` leaders. It repeats this behavior for a total of `K` times. Currently, `K` is set to 3 in Monad testnet and mainnet. The behavior of this transaction flow is chosen to reduce time-to-inclusion while minimizing the number of messages. ![Transaction path to leader](https://mintcdn.com/monadfoundation-40611fb6/5Mt9_Scj9fq4fC68/static/img/monad-arch/consensus/local-mempool/tx_path.png?w=2500&fit=max&auto=format&n=5Mt9_Scj9fq4fC68&q=85&s=29b6260cd576c3ed735ef9ae5aa9fc77) Transaction path from RPC to leader (through the local mempool). [​](https://docs.monad.xyz/monad-arch/consensus/local-mempool#local-mempool-eviction) Local mempool eviction --------------------------------------------------------------------------------------------------------------- Transactions are evicted from a validator’s local mempool for the following reasons: 1. Whenever a validator finalizes a block, any replicas of transactions in that block are pruned from the local mempool. 2. Validators periodically check the validity of each transaction in the mempool and evict invalid transactions (e.g. nonces are too low, account balances are insufficient). 3. If the local mempool’s size reaches a soft limit, older transactions will be evicted. [Block States\ \ Previous](https://docs.monad.xyz/monad-arch/consensus/block-states) [Statesync\ \ Next](https://docs.monad.xyz/monad-arch/consensus/statesync) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Validator Delegation Program (VDP) - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/validator-delegation-program#content-area) _Last updated April 22, 2026_ The Monad Validator Delegation Program (VDP) is a framework for strengthening the validator set for the Monad network. [​](https://docs.monad.xyz/node-ops/validator-delegation-program#core-objectives) Core Objectives ---------------------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/node-ops/validator-delegation-program#promote-decentralization) Promote decentralization * Promote decentralized block building/proposing * Promote a wide distribution of stake * Promote geographic diversity and infrastructure provider diversity * Oppose forces that centralize authority over block building ### [​](https://docs.monad.xyz/node-ops/validator-delegation-program#promote-network-performance-and-resilience) Promote network performance and resilience * Encourage a validator set that is reliable, responsive and timely with respect to network operations * Encourage a validator set that exhibits honest behavior relative to the protocol specification ### [​](https://docs.monad.xyz/node-ops/validator-delegation-program#promote-a-healthy-diverse-validator-community) Promote a healthy, diverse validator community * Support emerging node operators who demonstrate exceptional ability and contributions to the validator community ### [​](https://docs.monad.xyz/node-ops/validator-delegation-program#promote-value-capture-to-mon) Promote value capture to MON * Oppose forces that would give systems governed by third parties or alternative tokens the power to control block production * Oppose forces that would give systems governed by third parties or alternative tokens the power to direct order flow ### [​](https://docs.monad.xyz/node-ops/validator-delegation-program#promote-overall-ecosystem-health) Promote overall ecosystem health * Promote a validator set that prioritizes user welfare and longer-term ecosystem health over short-term value optimization * Promote a validator set that does not engage in forms of toxic MEV such as frontrunning or sandwiching [​](https://docs.monad.xyz/node-ops/validator-delegation-program#evaluation-and-intake) Evaluation and Intake ---------------------------------------------------------------------------------------------------------------- The Monad Foundation will evaluate the participation and uptime of every validator in the VDP on a six-month rolling basis. Validators who have performed well and who meet the general requirements of the program will be considered for further delegation over another six month period. Validators who have contributed significantly to the ecosystem in this period may receive additional delegation at the Foundation’s discretion. ### [​](https://docs.monad.xyz/node-ops/validator-delegation-program#intake) Intake The VDP is open to validators who join the network and wish to receive delegation support from the Foundation. Prospective validators are evaluated on: * Testnet uptime (minimum of 4 weeks active operations for evaluation) * Industry experience * Monitoring / security processes * Geographic decentralization * Ecosystem contributions A new application form is soon to be made available here. ### [​](https://docs.monad.xyz/node-ops/validator-delegation-program#eligibility-criteria) Eligibility Criteria * Complete KYC/KYB successfully prior to receiving delegation * Maintain uptime above 98% * The Monad Foundation reserves the right to remove delegation at any given time if performance does not meet desired standards - see below for demerit criteria/considerations * Have track record of operating on Monad Testnet * Set a commission fee of 10% or less ([temporarily raised to 15%](https://docs.monad.xyz/node-ops/validator-delegation-program#temporary-commission-adjustment) ) * Allow node metrics to be accessed by the Monad Foundation * Comply with the [policy on MEV and centralization](https://docs.monad.xyz/node-ops/validator-delegation-program/mev) * Operate a validator on Testnet at all times while in the VDP * Not use a validator node to service external RPCs (Axelar, Wormhole, etc.) * If validators wish to do this, they can spin up a separate Full Node Teams building a MON LST/LRT or an MEV system are ineligible for the VDP. Eligibility is monitored on a continuous basis. ### [​](https://docs.monad.xyz/node-ops/validator-delegation-program#temporary-commission-adjustment) \*Temporary Commission Adjustment _Stage 1 - Update as of January 23, 2026_ In light of the early stage of the Monad ecosystem, the Foundation temporarily increased the maximum commission cap for validators participating in the VDP from 10% to 20% for an initial period of approximately six months. This adjustment is intended to: * Improve validator sustainability during the network’s early growth phase * Support continued geographic and operator diversity * Reduce reliance on Foundation-delegated stake over time To ensure this change did not negatively impact non-Foundation delegating tokenholders, the Foundation proportionally reduced its own delegated stake in late January. As a result, delegating tokenholders should see no material change in net rewards, while validators benefit from improved economics. _Stage 2 - Update as of April 24, 2026_ Following the temporary increase of the maximum validator commission cap from 10% to 20% in late January 2026, the cap has been adjusted to 15%. The initial temporary increase was implemented to support validator sustainability during the early stages of the Monad ecosystem, encourage geographic and operator diversity, and reduce reliance on Foundation-delegated stake. As the network continues to mature and validator economics improve, this adjustment reflects a step toward a more steady-state commission structure. This change coincides with the addition of a new wave of participants to the Validator Delegation Program (VDP), further expanding and diversifying the validator set. All validators participating in the VDP are required to be in compliance with the updated 15% maximum commission cap by Friday, April 24, 2026 at 11:59 PM UTC. In addition, the Foundation increased the delegated amount to Tier 4 VDP participants by 10,000,000 MON, for a total delegation of 25,000,000 MON. ### [​](https://docs.monad.xyz/node-ops/validator-delegation-program#criteria-for-removal-of-delegation) Criteria for Removal of Delegation These criteria apply to nodes receiving delegation from the VDP: * Failure to upgrade in a timely manner (within 48 hours of announcement unless otherwise specified) * Unresponsiveness within 24 hours of outreach in the case of node performance * Failure to adhere to 98% uptime minimum\* * Running any alt binary in contravention of the [MEV policy](https://docs.monad.xyz/node-ops/validator-delegation-program/mev) * Peering with centralized flow routers in contravention of the [MEV policy](https://docs.monad.xyz/node-ops/validator-delegation-program/mev) * Failure to maintain regulatory compliance \*If a validator’s weekly uptime is flagged as less than 98% three times within a 3 month period, this warrants removal from the VDP, barring extenuating circumstances. This will be evaluated at Monad Foundation discretion.For example, if a validator’s total uptime in Week 1 is 97%, that constitutes 1 of 3 weeks allowed under the benchmark in a 3 month period. If that validator’s uptime for Week 4 is 97%, that constitutes a second violation in the 3 month period. That validator now has to ensure its adherence is above 98% in all weeks remaining in that 3 month period to avoid being removed from the program. ### [​](https://docs.monad.xyz/node-ops/validator-delegation-program#maximum-stake-within-the-vdp) Maximum Stake within the VDP If a validator reaches 1 billion MON of non-VDP delegation, the Monad Foundation will remove the VDP allocation delegation, as one of the goals of the VDP is to promote a distributed stake weight. [​](https://docs.monad.xyz/node-ops/validator-delegation-program#vdp-delegations) VDP Delegations ---------------------------------------------------------------------------------------------------- * The Monad Foundation delegated 9.3B MON (~9.3% of total supply) through the VDP in Wave 1 * The delegation was spread across 170 validators. The Monad Foundation provided the `MIN_AUTH_ADDRESS_STAKE` (100,000 MON) as a one-time grant to all successful applicants * The VDP delegated at least `ACTIVE_VALIDATOR_STAKE` (10,000,000 MON), to all successful applicants ### [​](https://docs.monad.xyz/node-ops/validator-delegation-program#plans-for-reduction-of-foundation-stake-over-time) Plans for Reduction of Foundation Stake Over Time A purpose of the VDP is to support the initial security and functionality of the Monad network by facilitating early validator participation. Over time, as network participation evolves and third-party stake increases, the Foundation may determine that a reduced level of Foundation-delegated stake is appropriate. Any adjustment to the Foundation’s staking participation will be made at its discretion, based on its assessment of network conditions, and may occur at any time or not at all. ### [​](https://docs.monad.xyz/node-ops/validator-delegation-program#delegation-tiers) Delegation Tiers The VDP will **initially** be split into 4 tiers that correspond with performance and ecosystem contribution. | **Tier** | **Criteria**\* | **Delegation** | | --- | --- | --- | | 1 | Highest performance across high throughput networks in the industry, and/or strong level of experience operating in high throughput networks. Potential to have high impact in offering ecosystem contributions. | 90,000,000 MON | | 2 | Strong performance across high throughput networks in the industry, and/or solid level of experience operating in high throughput networks. Potential to have a strong level of impact in contribution to the ecosystem. | 75,000,000 MON | | 3 | Good performance across high throughput networks in the industry. Potential to have a good level of impact in contribution to the ecosystem. | 52,500,000 MON | | 4 | Entities that can attract significant stake without the assistance of the foundation, or fair performance across high throughput networks in the industry. No extra ecosystem contributions planned beyond node operations. | 25,000,000 MON | \*These categories and levels are provided to outline the general framework, but are not definitive. Validators can work toward increasing their allocation through ecosystem contributions. This will be evaluated based on the impact an validator’s contributions have had on the ecosystem. [​](https://docs.monad.xyz/node-ops/validator-delegation-program#changelog) Changelog ---------------------------------------------------------------------------------------- The VDP launched alongside Monad Public Mainnet on November 24, 2025. The initial cohort comprised validators who had proven themselves through Monad’s pre-Mainnet networks (Testnet-1 and Testnet-2), and were selected and tiered based on: * Performance in Monad’s pre-Mainnet testnets * Contribution to geographic decentralization * Contribution to the Monad ecosystem, including tools, dashboards, snapshots, integrations, support for other validators, and community activation / support | Date | Change | | --- | --- | | Nov 24, 2025 | VDP launched with Monad Public Mainnet; initial delegation spread across 170 validators:
Tier 1: 120,000,000 MON
Tier 2: 90,000,000 MON
Tier 3: 70,000,000 MON
Tier 4: 20,000,000 MON | | Jan 23, 2026 | Raise max VDP commission from 10% to 20% | | Jan 23, 2026 | Reduce delegations:
Tier 1: 120,000,000 → 90,000,000 MON
Tier 2: 100,000,000 → 75,000,000 MON
Tier 3: 70,000,000 → 52,500,000 MON
Tier 4: 20,000,000 → 15,000,000 MON | | April 24, 2026 | Lower max VDP commission from 20% to 15% | | April 24, 2026 | Tier 4 delegation increased from 15,000,000 MON to 25,000,000 MON | [​](https://docs.monad.xyz/node-ops/validator-delegation-program#faq) FAQ ---------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/node-ops/validator-delegation-program#does-a-delegation-guarantee-active-set-inclusion-in-every-epoch) Does a delegation guarantee active set inclusion in every epoch? All participants will have been delegated sufficient stake to exceed the `ACTIVE_VALIDATOR_STAKE` requirement. There are [multiple requirements](https://docs.monad.xyz/monad-arch/consensus/staking) , namely the validator must also rank in the top `ACTIVE_VALSET_SIZE` (200) by stake weight as well. Thus, VDP delegation does not guarantee inclusion in every epoch. Delegated entities are expected to attract their own stake, and not solely rely on the foundation stake. ### [​](https://docs.monad.xyz/node-ops/validator-delegation-program#after-receiving-a-delegation-can-i-stop-my-testnet-validator) After receiving a delegation, can I stop my Testnet Validator? No, to remain compliant with the VDP requirements, all mainnet validators must operate a testnet validator for the duration of their participation in the VDP. [Genesis Replay\ \ Previous](https://docs.monad.xyz/node-ops/archive-data/genesis-replay) [VDP Policy on MEV Systems\ \ Next](https://docs.monad.xyz/node-ops/validator-delegation-program/mev) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # General Operations - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/general-operations#content-area) [​](https://docs.monad.xyz/node-ops/general-operations#version-information) Version Information -------------------------------------------------------------------------------------------------- View the version and build information for your Monad binaries: monad-node --version # Example output: monad-node {"commit":"c0cdcaae8eb527e44d72c4638c1f1335025a5132","tag":"v0.12.2-rc","branch":"","modified":true} [​](https://docs.monad.xyz/node-ops/general-operations#cli-help) CLI Help ---------------------------------------------------------------------------- View available command-line arguments for any Monad binary: monad-rpc --help monad --help monad-bft --help CLI arguments should not be changed arbitrarily as some configurations may result in unexpected behavior or crashes. [​](https://docs.monad.xyz/node-ops/general-operations#service-management) Service Management ------------------------------------------------------------------------------------------------ Check the status of Monad services: # Check all services at once systemctl status monad-bft monad-execution monad-rpc --no-pager -l # Check individual service status systemctl status monad-bft systemctl status monad-execution systemctl status monad-rpc # View logs for a specific service journalctl -u monad-bft -f journalctl -u monad-execution -f journalctl -u monad-rpc -f [​](https://docs.monad.xyz/node-ops/general-operations#monitoring-block-height) Monitoring Block Height ---------------------------------------------------------------------------------------------------------- The RPC service will start listening on port `8080` when the statesync is completed. Check the current block height via RPC: curl http://localhost:8080/ \ -X POST \ -H "Content-Type: application/json" \ --data '{"method":"eth_blockNumber","params":[],"id":1,"jsonrpc":"2.0"}' [​](https://docs.monad.xyz/node-ops/general-operations#viewing-monaddb-disk-usage) Viewing MonadDB Disk Usage ---------------------------------------------------------------------------------------------------------------- Note that MonadDB (TrieDB) will automatically compact when at 80% capacity to preserve optimal SSD performance. To check MonadDB disk usage and retained block history: monad-mpt --storage /dev/triedb Example output: MPT database on storages: Capacity Used % Path 3.49 Tb 24.30 Gb 0.68% "/dev/nvme1n1p1" MPT database internal lists: Fast: 94 chunks with capacity 23.50 Gb used 23.40 Gb Slow: 3 chunks with capacity 768.00 Mb used 658.72 Mb Free: 14207 chunks with capacity 3.47 Tb used 0.00 bytes MPT database has 599928 history, earliest is 36784905 latest is 37384832. It has been configured to retain no more than 33554432. Latest proposed is (37384832, 88a5550ba067c2f21cef6b6e8953fbf700fe300905952e5621335fe2bd58729c). Latest voted is (37384831, 56074c2429909c2966bfe8df55810ec3b8f4f4f599b407ff89ec92b090656ab1). Latest finalized is 37384830, latest verified is 37384827, auto expire version is 36784905 [​](https://docs.monad.xyz/node-ops/general-operations#log-analysis-with-monlog) Log Analysis with `monlog` -------------------------------------------------------------------------------------------------------------- `monlog` is a lightweight tool maintained by [Category Labs](https://www.category.xyz/) that scrapes BFT logs and provides useful status information and suggestions. It examines logs from the last 60 seconds. **Setup (as root user):** First, grant the monad user access to read systemd journal logs: # Add monad user to systemd-journal group usermod -a -G systemd-journal monad **Download monlog (as monad user):** cd /home/monad curl -sSL https://pub-b0d0d7272c994851b4c8af22a766f571.r2.dev/scripts/monlog -O chmod u+x ./monlog # confirm sha sha256sum ./monlog f8a1066d8c093bbdb5f722f5b3d89904c17a76fa01fa1dd62e950f445e88327f ./monlog If you’re already logged in as the monad user when the group is added, you’ll need to log out and log back in for the group membership to take effect. Alternatively, you can run `su - monad` to start a new session. **Run monlog (as monad user):** ./monlog # For live updates watch -d "./monlog" # Show last 10 lines of grabbed logs ./monlog -r # Show secp keys mapped to validator names ./monlog -n e.g. 0123123ae (validator name) # Show with no color coding ./monlog --no-color Example output for a healthy node: # FYI this is without color coding Installed version: ii monad 0.12.1~rc amd64 Monad BFT stack (symbols stripped) No StateSync messages. --- No BlockSync messages. --- Most recent round: 52268965 Most recent epoch: 1001 Most recent block: 50041845 Blocks processing and being committed ✅ [​](https://docs.monad.xyz/node-ops/general-operations#consensus-information-with-ledger-tail) Consensus Information with `ledger-tail` ------------------------------------------------------------------------------------------------------------------------------------------ `monad-ledger-tail` exposes consensus information by directly parsing ledger artifacts and streams the data in JSON format. Start the service: systemctl start monad-ledger-tail # View output journalctl -fu monad-ledger-tail Example output: // the real output is all on one line, but we've prettified this for legibility: { "timestamp": "2025-11-23T03:09:09.534974Z", "level": "INFO", "fields": { "message": "proposed_block", "round": "53449032", "parent_round": "53449031", "epoch": "1024", "seq_num": "51203516", "num_tx": "3", "author": "036daee7750e29e46eb64d86ad1cc7b235d7f1ad9597941a3a77cdd641cead4528", "block_ts_ms": "1763867349470", "now_ts_ms": "1763867349534", "author_address": "" }, "target": "ledger_tail" } [​](https://docs.monad.xyz/node-ops/general-operations#node-status-with-monad-status) Node Status with `monad-status` ------------------------------------------------------------------------------------------------------------------------ Install `monad-status`: curl -sSL https://bucket.monadinfra.com/scripts/monad-status.sh -o /usr/local/bin/monad-status chmod +x /usr/local/bin/monad-status Run `monad-status` to get the status of the node. This should print similar output: ### Monad Node Status hostname: monad-node date: Wed Nov 26 10:48:26 PM CET 2025 uptime: 0d 00h 41m 49s version: 0.12.2 config: network: mainnet chain: monad_mainnet chainId: 143 secpPublicKey: 03831b36b50261011d82f94d58f8aa0edfe058359e2c365c37cce678436b9eb371 blsPublicKey: b9c1905e11e8395a789bece454ec24bed98b96cf9dc04c02c9512fb94900d3e0355383e542c44a0eb1be4d2780a1fb2f nodeSignature: 4f6e3e47af0e8ff3614e1eb53f9015ef4fc8593e60c13d52c2b458d05385b5f94cff8776ceb8b9401c3647148637d599622353d0631864a23b07f6d7fb55e84f00 selfAddress: 65.109.145.172:8000 recordSeqNum: 0 services: monad-bft: running monad-execution: running monad-rpc: running otelcol: running monad-cruft: activated: true previous: 48min ago next: 11min peers: peersNumber: 1146 consensus: status: in-sync mode: live epoch: 764 round: 38259075 blockNumber: 38200041 blockNumberFromExternal: 38200040 blockDifference: 0 statesync: percentage: 100.0000% progress: 38193694 target: 38193694 rpc: status: active clientVersion: Monad/0.12.2 netVersion: 143 blockNumber: 38200041 [​](https://docs.monad.xyz/node-ops/general-operations#exporting-key-backups) Exporting Key Backups ------------------------------------------------------------------------------------------------------ If you followed the [full node installation](https://docs.monad.xyz/node-ops/full-node-installation#generate-keystores) guide, backup files for your keys were automatically created at: * `/opt/monad/backup/secp-backup` * `/opt/monad/backup/bls-backup` If those files are missing or you need to re-export your keys, use the commands below to recreate them. Any existing backup files will be preserved with a timestamp suffix before being overwritten. source /home/monad/.env [ -f /opt/monad/backup/secp-backup ] && mv /opt/monad/backup/secp-backup "/opt/monad/backup/secp-backup.$(date +%Y%m%d%H%M%S).bak" [ -f /opt/monad/backup/bls-backup ] && mv /opt/monad/backup/bls-backup "/opt/monad/backup/bls-backup.$(date +%Y%m%d%H%M%S).bak" monad-keystore recover \ --password "$KEYSTORE_PASSWORD" \ --keystore-path /home/monad/monad-bft/config/id-secp \ --key-type secp > /opt/monad/backup/secp-backup monad-keystore recover \ --password "$KEYSTORE_PASSWORD" \ --keystore-path /home/monad/monad-bft/config/id-bls \ --key-type bls > /opt/monad/backup/bls-backup These files contain your node’s private keys — they define your node identity. Anyone with access to them can take over your node’s identity.**Ensure that these backup files are stored in an external location outside of the node (e.g. a password manager or secrets vault). They are required to restore your full node or validator identity in the event of hardware failure or system loss:** * `/opt/monad/backup/secp-backup` * `/opt/monad/backup/bls-backup` For validators, this is especially important: losing your keys means you cannot migrate your validator, and re-registering with a new identity requires moving all delegations manually. [​](https://docs.monad.xyz/node-ops/general-operations#importing-keys-from-backups) Importing Keys from Backups ------------------------------------------------------------------------------------------------------------------ To restore your node identity from a backup, extract the IKM secret from each backup file and import it using `monad-keystore import`: source /home/monad/.env [ -f /home/monad/monad-bft/config/id-secp ] && mv /home/monad/monad-bft/config/id-secp "/home/monad/monad-bft/config/id-secp.$(date +%Y%m%d%H%M%S).bak" [ -f /home/monad/monad-bft/config/id-bls ] && mv /home/monad/monad-bft/config/id-bls "/home/monad/monad-bft/config/id-bls.$(date +%Y%m%d%H%M%S).bak" SECP_IKM=$(grep -E "Keystore secret:|Keep your IKM secure:" /opt/monad/backup/secp-backup | awk '{print $NF}') BLS_IKM=$(grep -E "Keystore secret:|Keep your IKM secure:" /opt/monad/backup/bls-backup | awk '{print $NF}') monad-keystore import \ --ikm "$SECP_IKM" \ --password "$KEYSTORE_PASSWORD" \ --keystore-path /home/monad/monad-bft/config/id-secp \ --key-type secp monad-keystore import \ --ikm "$BLS_IKM" \ --password "$KEYSTORE_PASSWORD" \ --keystore-path /home/monad/monad-bft/config/id-bls \ --key-type bls [​](https://docs.monad.xyz/node-ops/general-operations#keeping-updated) Keeping Updated ------------------------------------------------------------------------------------------ To stay updated on new releases: * join the [Monad Node Announcements](https://t.me/MonadNodeAnnouncements) telegram group, or * join the [Monad Developer Discord](https://discord.gg/monaddev) and follow the `#mainnet-fullnode-announcements` channel [Validator Installation\ \ Previous](https://docs.monad.xyz/node-ops/validator-installation) [Announcements\ \ Next](https://docs.monad.xyz/node-ops/announcements) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Consensus - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/monad-arch/consensus#content-area) MonadBFT -------- Tail-fork-resistant pipelined consensus RaptorCast ---------- Efficient block propagation of large blocks, utilized by leaders in MonadBFT Asynchronous Execution ---------------------- Moving execution out of the hot path of consensus so it can use the full block time Block States ------------ Summarizing the progression of Monad blocks from proposal to verification Local Mempool ------------- Policies for sharing pending transactions to leaders while minimizing bandwidth Statesync --------- Algorithms for bootstrapping a node from peers Blocksync --------- Algorithms for catching up on missed traffic Peer Discovery -------------- How nodes know where to find each other Message Authentication ---------------------- Signature schemes used in Monad Transport Protocol Usage ------------------------ TCP and UDP usage for node communication [Pipelining\ \ Previous](https://docs.monad.xyz/monad-arch/concepts/pipelining) [MonadBFT\ \ Next](https://docs.monad.xyz/monad-arch/consensus/monad-bft) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Peer Discovery - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/monad-arch/consensus/peer-discovery#content-area) [​](https://docs.monad.xyz/monad-arch/consensus/peer-discovery#summary) Summary ---------------------------------------------------------------------------------- Peer discovery enables a new validator or full node to join the network by connecting with other existing nodes, in order to receive consensus messages necessary to validate and keep up to the chain tip. To participate in peer discovery, a node needs to generate a `MonadNameRecord`, which contains a name record and a signature over that record using its secp key. struct MonadNameRecord { name_record: NameRecord, signature: SecpSignature, } A `NameRecord` contains the node’s IPv4 address, port information, and a sequence number. Currently only IPv4 addresses are supported. There are two wire formats: a legacy format with a single port shared across protocols, and a newer format that supports multiple ports tagged by protocol (TCP, UDP, AuthenticatedUDP) along with a capabilities field. The newer format is used by nodes that have opted into [authenticated UDP](https://docs.monad.xyz/node-ops/upgrade-instructions/auth-udp) . The IP address and ports describe the network endpoints at which other nodes in the network may contact it. A sequence number is necessary to ensure newer name records take priority over older name records. For example, when a node sees a peer’s name records with a higher sequence number, it will update its routing table with the new name record. A node specifies a few bootstrap nodes and their name records when starting up. Bootstrap nodes are not specialized nodes; any node in the network can be a bootstrap node. The node will then advertise its own name record by sending pings to other peers, where the ping message contains its own name record. The node also sends lookup request to its peers when it is missing name records of current active validators. Periodically, the node looks for new nodes or prunes excessive nodes depending on the min and max number of peers configured. [Forkpoint\ \ Previous](https://docs.monad.xyz/monad-arch/consensus/forkpoint) [Message Authentication\ \ Next](https://docs.monad.xyz/monad-arch/consensus/authentication) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # VDP Policy on MEV Systems - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/validator-delegation-program/mev#content-area) The Monad Foundation is aware that several ecosystem teams are building extra-protocol systems that enable participants to express transaction ordering preferences. The Foundation recognizes that there may be some benefits to the presence of such systems, such as reducing spam and allowing participants to express ordering preferences that economically benefits stakers. At the same time, it is extremely early in the life of the public Monad network; none of these systems are battle-tested; and there is a wide variety of possible system designs with different implications on decentralization and risks to network robustness. In light of the VDP’s [Objectives](https://docs.monad.xyz/node-ops/validator-delegation-program#core-objectives) , the Monad Foundation has adopted the following policy: * Systems that centralize order flow, giving a third party power to route the order flow to the highest bidder, are counter to the objectives of the VDP. The VDP will not delegate to validators that peer with centralized order flow routers. * Systems that give a third party authority over block building are counter to the objectives of the VDP. The VDP will not delegate to validators that give authority to a third-party block builder. * Third parties might be tempted to build modified versions of the Category Labs client to facilitate integration with their systems. At this early stage in the network’s life, the VDP is not prepared to accept risks to network liveness or security that arise from validators running a modified version of the Category Labs client. Consequently, the VDP will not delegate to validators running a version of the client software modified by a third party. [Validator Delegation Program (VDP)\ \ Previous](https://docs.monad.xyz/node-ops/validator-delegation-program) [Solonet\ \ Next](https://docs.monad.xyz/node-ops/solonet) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Statesync - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/monad-arch/consensus/statesync#content-area) [​](https://docs.monad.xyz/monad-arch/consensus/statesync#summary) Summary ----------------------------------------------------------------------------- Statesync is the process for synchronizing state to a target block close to the current tip. A synchronizing node (“client”) requests data from other up-to-date validators (“servers”) to help it progress from its current view to its target view; the servers rely on metadata in MonadDb to efficiently respond to the request. Since the current tip is a moving target, following completion of statesync, the client makes another statesync request to get closer to the current tip, or replays queued blocks if within striking distance. [​](https://docs.monad.xyz/monad-arch/consensus/statesync#approach) Approach ------------------------------------------------------------------------------- Statesync is the process of synchronizing state stored in [MonadDb](https://docs.monad.xyz/monad-arch/execution/monaddb) to a target block close to the current tip. The current tip is a moving target, so as statesync is running, the syncing node stores new blocks beyond the target block and, upon completion of statesync, replays these additional blocks through normal execution to catch up to the current tip. The target block may be updated several times during this process. Statesync follows a client-server model, where the statesync requester is the client and the validator node servicing a statesync request is the server. [​](https://docs.monad.xyz/monad-arch/consensus/statesync#data-included-in-statesync) Data included in statesync ------------------------------------------------------------------------------------------------------------------- MonadDb stores a variety of data relating to the execution of blocks. However, only a subset is required for full participation in the active set and thus included in statesync: * accounts, including balances, code, and storage * the last 256 block headers (to verify correctness) In an effort to evenly distribute load, each of the aforementioned is spliced into chunks. The client assigns each chunk to a server who remains the peer for that chunk until synchronization is complete. Servers are randomly selected from the list of available peers. The client maintains a certain number of sessions up to a configured maximum. In the event that servers are unresponsive, the client’s statesync request will timeout and request from a different server. [​](https://docs.monad.xyz/monad-arch/consensus/statesync#versioning-and-verification) Versioning and verification --------------------------------------------------------------------------------------------------------------------- For efficiency, the client requests state from least- to most-recently updated, converging on the tip near the end of the process. Servers serve diffs relative to the client’s latest block. ![statesync_requests](https://mintcdn.com/monadfoundation-40611fb6/-TCPhWHMfGzx9j3a/static/img/monad-arch/consensus/statesync/statesync_requests.png?w=2500&fit=max&auto=format&n=-TCPhWHMfGzx9j3a&q=85&s=042679201fb063af3e694e07394513db) In the example above, the statesync client makes three consecutive requests to the statesync server assigned to prefix p. For each request, there are five parameters specified: * `prefix` - the prefix of the Merkle Patricia Trie * `i` - the start block number * `j` - the end block number * `target` - the target block number * `last_target` - last target block number, this is used to deduce deletions to send Because there may be multiple rounds of statesync (as statesync occurs, the chain is progressing and the target block may need to adjust), `j` is buffered by some offset B from the target block to avoid retransmitting most recently used nodes in the MPT. When `i` and `target` block are sufficiently close, as in the last round above, the statesync client will request `j = target`. At this point, if `target` is less than `statesync_threshold` (600 blocks by default) from the tip of the chain, statesync is concluded and the state root will be validated. Any remaining blocks between `target` and tip are then synced via [blocksync](https://docs.monad.xyz/monad-arch/consensus/blocksync) . If `target` is greater than `statesync_threshold` blocks from the tip of the chain, a new round of statesync will begin. During block execution, the server stores the version alongside node contents. As such, upon receipt of a statesync request, the server is able to quickly narrow down the relevant subtrie and submit read requests, which are embarrassingly parallel. [​](https://docs.monad.xyz/monad-arch/consensus/statesync#trust-assumptions) Trust assumptions ------------------------------------------------------------------------------------------------- Statesync clients trust that the requested data (including state root and parent hash) from statesync servers is correct. This is currently sampled randomly from the validator set according to stakeweight, but clients can optionally whitelist specific known providers as statesync servers. The current implementation validates the data transmitted when the whole transfer is complete by comparing the state root. Because the work is split between multiple servers, a single server sending invalid data can cause a state root mismatch, without attribution to the faulty server. The only recourse in this situation is to retry the whole transfer, giving the faulty server an opportunity to fail the operation again. Changes are currently being implemented to verify the data transmitted on a per-server basis. In the event of a faulty server sending invalid data, the statesync client can discard and retry _only_ the affected prefix. Further, it can identify the faulty server, log the error and potentially blacklist it from subsequent requests. [Local Mempool\ \ Previous](https://docs.monad.xyz/monad-arch/consensus/local-mempool) [Blocksync\ \ Next](https://docs.monad.xyz/monad-arch/consensus/blocksync) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Forkpoint - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/monad-arch/consensus/forkpoint#content-area) [​](https://docs.monad.xyz/monad-arch/consensus/forkpoint#summary) Summary ----------------------------------------------------------------------------- A forkpoint is a saved snapshot of consensus state. It lets a node restart from a known-good point instead of replaying the chain from genesis. It holds everything the node needs to rejoin consensus: where it was in the blocktree, the proof it needs to enter the next round, and the validator sets that check that proof. On disk, a forkpoint is the `forkpoint.rlp` and `forkpoint.toml` pair you handle during installation and [recovery](https://docs.monad.xyz/node-ops/node-recovery) . This page covers what those files hold and how a node uses them to sync on startup. [​](https://docs.monad.xyz/monad-arch/consensus/forkpoint#what-a-forkpoint-contains) What a forkpoint contains ----------------------------------------------------------------------------------------------------------------- A forkpoint holds three fields: * **`root`** — the root of the node’s blocktree, which points to its highest committed block. Syncing starts here. * **`high_certificate`** — the highest quorum certificate (QC) or timeout certificate (TC) the node has seen. It’s the proof the node needs to enter the next round. * **`validator_sets`** — the validator sets that check those certificates. There’s usually one, for the current epoch. During an epoch change there are two, so the node can check certificates on both sides of the boundary. When a node loads a forkpoint, it checks that the `high_certificate` verifies against the `validator_sets` before using it. [​](https://docs.monad.xyz/monad-arch/consensus/forkpoint#startup-sync) Startup sync --------------------------------------------------------------------------------------- A node loads its forkpoint and then syncs to the network tip in three steps. 1. **Fetch the blocks up to the root.** The node uses [blocksync](https://docs.monad.xyz/monad-arch/consensus/blocksync) to pull the `2 × execution_delay` committed blocks up to and including `root`. These are needed for reserve-balance checking under the transaction fee mechanism, and they have to be in place before state can sync. 2. **Statesync.** The node brings [MonadDb](https://docs.monad.xyz/monad-arch/execution/monaddb) up to version `root − execution_delay`. While this runs, it listens for new proposals and sets them aside in a buffer. See [statesync](https://docs.monad.xyz/monad-arch/consensus/statesync) . 3. **Replay.** Once both syncs finish, the node builds its blocktree from `root` and `high_certificate`, then replays the buffered proposals to reach the tip. One thing to keep straight: blocksync does two different jobs. * **On startup**, it pulls blocks that sit _behind_ the root, and it runs before statesync (step 1 above). * **During normal operation**, it does the reverse: statesync gets the node close to the tip, and blocksync fetches the last few blocks to close the gap, the way getting into the stadium comes before finding your seat. This catch-up role is the one the [blocksync](https://docs.monad.xyz/monad-arch/consensus/blocksync) page describes. Consensus resumes at `high_certificate.round() + 1`, so a node never votes at or below a round it already voted in. That’s what makes restarting from a forkpoint safe instead of a source of double votes. [​](https://docs.monad.xyz/monad-arch/consensus/forkpoint#how-forkpoints-are-persisted) How forkpoints are persisted ----------------------------------------------------------------------------------------------------------------------- A node writes a new forkpoint each time it enters a new round or finalizes a block. New rounds come constantly, so `forkpoint.toml` changes roughly every round. Each write produces two files: * **`forkpoint.rlp`** — the canonical, RLP-encoded form. * **`forkpoint.toml`** — a human-readable, TOML-encoded form. The node loads whichever file its `--forkpoint-config` path points at; the bundled systemd unit points at `forkpoint.toml`. Both are written to a temporary file first and then renamed, so a process crash mid-write doesn’t corrupt the forkpoint. Each write also keeps a backup copy, keyed by the root sequence number and round, so earlier forkpoints stay around for recovery. [Blocksync\ \ Previous](https://docs.monad.xyz/monad-arch/consensus/blocksync) [Peer Discovery\ \ Next](https://docs.monad.xyz/monad-arch/consensus/peer-discovery) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Asynchronous Execution - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution#content-area) [​](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution#summary) Summary ------------------------------------------------------------------------------------------ Asynchronous Execution is a technique that allows Monad to substantially increase execution throughput by decoupling consensus from execution. Decoupling consensus from execution allows Monad to substantially increase the execution budget, since execution goes from occupying a small fraction of the block time to occupying the full block time. [​](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution#background-interleaved-execution-is-inefficient) Background: interleaved execution is inefficient --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Consensus is the process where nodes come to agreement about the official ordering of transactions. Execution is the process of actually executing those transactions and updating the state. In Ethereum and most other blockchains, execution is a prerequisite to consensus. When nodes come to consensus on a block, they are agreeing on both (1) the list of transactions in the block, and (2) the merkle root summarizing all of the state after executing that list of transactions. As a result, the leader must execute all of the transactions in the proposed block _before_ sharing the proposal, and the validating nodes must execute those transactions _before_ responding with a vote. We refer to this style of blockchain as one that has execution **interleaved** with consensus. In this paradigm, the time budget for execution is extremely limited, since it has to happen twice _and_ leave enough time for multiple rounds of cross-globe communication for consensus. Additionally, since execution will block consensus, the per-block gas limit must be chosen extremely conservatively to ensure that the computation completes on all nodes within the budget even in the worst-case scenario. The result is that the per-block gas limit is a tiny fraction of the block time. In particular, in Ethereum, the gas limit (30M worst-case gas) corresponds to a roughly 100ms time budget, even though the the block time is 12 seconds: ![](https://mintcdn.com/monadfoundation-40611fb6/5Mt9_Scj9fq4fC68/static/img/monad-arch/consensus/asynchronous-execution/time_budget_for_execution.png?w=2500&fit=max&auto=format&n=5Mt9_Scj9fq4fC68&q=85&s=d2e1121d1239cebeaafe69213eeaa092) Comparing Ethereum execution budget to block time That’s 1% of the block time! In short, interleaving consensus and execution has a massive time-shrinking effect. What if it didn’t have to be this way? [​](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution#asynchronous-execution) Asynchronous Execution ------------------------------------------------------------------------------------------------------------------------ Monad decouples consensus from execution, moving execution out of the hot path of consensus into a separate, slightly-lagged swim lane. **In Monad, nodes come to consensus (i.e. agreement about the official ordering of transactions), without ever executing those transactions.** That is, the leader proposes an ordering without knowing the resultant state root, and the validating nodes vote on block validity without knowing (for example) whether all of the transactions in the block execute without reverting. When a block is finalized, every node in the network (validators and full nodes) can execute the block’s transactions to produce the latest, agreed-upon state. As a result of this change, execution can be budgeted the full block time. To see why, consider the somewhat stylized diagrams, in which blue rectangles correspond to execution, and orange rectangles correspond to consensus: **Interleaved execution** In interleaved execution, the sum of the execution and consensus budgets equals the block time, and consensus occupies most of the block time. ![](https://mintcdn.com/monadfoundation-40611fb6/5Mt9_Scj9fq4fC68/static/img/monad-arch/consensus/asynchronous-execution/interleaved.png?w=2500&fit=max&auto=format&n=5Mt9_Scj9fq4fC68&q=85&s=f94e0d7fe90c730849d90e5239127d1a) Interleaved execution **Asynchronous execution** In asynchronous execution, consensus occupies the full block time - and so does execution, because they are occurring in separate swim lanes, _at the same time_: ![](https://mintcdn.com/monadfoundation-40611fb6/5Mt9_Scj9fq4fC68/static/img/monad-arch/consensus/asynchronous-execution/async.png?w=2500&fit=max&auto=format&n=5Mt9_Scj9fq4fC68&q=85&s=a301db0dc596bbb0f5e09d42da1a1e9a) Asynchronous execution **Comparison** Comparing the two styles side by side, you can see the benefit of the asynchronous style: the execution budget can be significantly expanded to occupy the full block time: ![](https://mintcdn.com/monadfoundation-40611fb6/5Mt9_Scj9fq4fC68/static/img/monad-arch/consensus/asynchronous-execution/interleaved-vs-async.png?w=2500&fit=max&auto=format&n=5Mt9_Scj9fq4fC68&q=85&s=bdb1bb8fd11c177756539b6a5fcf4cd0) Top: interleaved; bottom: asynchronous. [​](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution#determined-ordering-implies-state-determinism) Determined ordering implies state determinism ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- Although execution lags consensus, the true state of the world is determined as soon as the ordering is determined. Execution is required to unveil the truth, but the truth is already determined. It’s worth noting that in Monad, like in Ethereum, it is fine for transactions in a block to “fail” in the sense that the intuitive outcome did not succeed.(For example, there could be a transaction included in a block in which Bob tries to send 10 tokens to Alice but only has 1 token in his account. The transfer ‘fails’ but the transaction is still valid. The outcome of any transaction, including failure, is deterministic. ![](https://mintcdn.com/monadfoundation-40611fb6/5Mt9_Scj9fq4fC68/static/img/monad-arch/consensus/asynchronous-execution/transaction_ordering.png?w=2500&fit=max&auto=format&n=5Mt9_Scj9fq4fC68&q=85&s=ac2c1011503af6e450e534e317d75835) Example of transaction determinism even when some transactions fail [​](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution#finer-details) Finer details ------------------------------------------------------------------------------------------------------ ### [​](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution#delayed-merkle-root) Delayed Merkle Root As mentioned above, Monad block proposals don’t include the merkle root of the state trie, since that would require execution to have already completed. All nodes should stay in sync because they’re all doing the same work. But it’d be nice to be sure! As a precaution, proposals also includes a merkle root from `D` blocks ago, allowing nodes to detect if they’re diverging. `D` is a systemwide parameter (currently set in testnet and mainnet to `3`). Delayed merkle root validity is part of block validity, so if the leader proposes a block but the delayed merkle root is wrong, the block will be rejected. As a result of this delayed merkle root: 1. After the network comes to consensus (2/3 majority vote) on block `N` (typically upon receiving block `N+2`, which contains a QC-on-QC for block `N`), it means that the network has agreed that the official consequence of block `N-D` is a state rooted in merkle root `M`. Light clients can then query full nodes for merkle proofs of state variable values at block `N-D`. 2. Any node with an error in execution at block `N-D` will fall out of consensus starting at block `N`. This will trigger a rollback on that node to the end state of block `N-D-1`, followed by re-execution of the transactions in block `N-D` (hopefully resulting in the merkle root matching), followed by re-execution of the transactions in block `N-D+1`, `N-D+2`, etc. Ethereum’s approach uses consensus to enforce _state machine replication_ in a very strict way: after nodes come to consensus, we know that the supermajority agrees about the official ordering and the state resulting from that ordering. However, this strictness comes at great cost because interleaved execution limits execution throughput. Asynchronous execution achieves state machine replication without this limitation, and the delayed merkle root serves an additional precaution. ![](https://mintcdn.com/monadfoundation-40611fb6/5Mt9_Scj9fq4fC68/static/img/monad-arch/consensus/asynchronous-execution/state_root_delay.png?w=2500&fit=max&auto=format&n=5Mt9_Scj9fq4fC68&q=85&s=806bdc7bb6ccff7f4b1e44aaf611901b) Delayed merkle root ### [​](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution#reserve-balance) Reserve balance Because consensus can only be assumed to have up to the `D`\-block delayed view of the global state, it is necessary to adjust the consensus and execution rules slightly to allow consensus to safely build blocks that include only transactions whose gas costs can be paid for. Monad introduces the [Reserve Balance](https://docs.monad.xyz/developer-essentials/reserve-balance) rules to ensure this. The rules place light restrictions on when transactions can be included at consensus time, and imposes some conditions under which transactions will revert at execution time. ### [​](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution#speculative-execution) Speculative execution In MonadBFT, nodes receive a proposed block `N` at slot `N`, but it is not finalized until slot `N+2`. During the intervening time, a node can still locally execute the proposed block (without the guarantee that it will become voted or finalized). This allows a few nice properties: 1. In the likely event that the proposed block is finalized, the validator node has already done the work and can immediately update its merkle root pointer to the result. 2. Transactions can be simulated (in `eth_call` or `eth_estimateGas`) against the speculative state which is likely more up-to-date. ### [​](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution#transactions-from-newly-funded-accounts) Transactions from newly-funded accounts Because consensus runs slightly ahead of execution, newly-funded accounts which previously had zero balance cannot send transactions until the transfer that credits them with tokens is `D` blocks old. In practice, this means that if you send tokens from account `A` into an account `B` (which has 0 balance), then you should wait until seeing the transaction receipt (indicative that that block has reached [`Proposed`](https://docs.monad.xyz/monad-arch/consensus/block-states#Proposed) state), and then wait another 1.2 seconds. Alternatively, depending on the nature of intended transaction from `B`, it may be possible to write a smart contract callable by `A` which combines the funding operation and whatever `B` was intending to do, requiring no delay between funding and spending. [​](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution#block-states) Block states ---------------------------------------------------------------------------------------------------- See [block states](https://docs.monad.xyz/monad-arch/consensus/block-states) for a summary of the states through which each block progresses. [RaptorCast\ \ Previous](https://docs.monad.xyz/monad-arch/consensus/raptorcast) [Block States\ \ Next](https://docs.monad.xyz/monad-arch/consensus/block-states) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Genesis Replay - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/archive-data/genesis-replay#content-area) Genesis replay re-executes historical blocks so that additional copies of state are available at any given point in time. Historically, blocks have been stored in a static archive format. This process downloads those blocks and replays them through the EVM to reconstruct full state. [​](https://docs.monad.xyz/node-ops/archive-data/genesis-replay#prerequisites) Prerequisites ----------------------------------------------------------------------------------------------- * monad version `0.12.3` or later * Credentials and configuration to read from your chosen archive source (AWS, R2, MongoDB, MinIO, etc.). These are the same credentials used by `monad-archiver`; see [Running an Archive Server](https://docs.monad.xyz/node-ops/archive-data/running-an-archive-server) for details. [​](https://docs.monad.xyz/node-ops/archive-data/genesis-replay#setup) Setup ------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/node-ops/archive-data/genesis-replay#1-prepare-the-block-database-directory) 1\. Prepare the block database directory Choose a directory to store EVM-format historical blocks. This guide refers to it as `block-db`. ### [​](https://docs.monad.xyz/node-ops/archive-data/genesis-replay#2-initialize-triedb) 2\. Initialize triedb Create an empty `triedb`: monad-mpt \ --storage /dev/triedb \ --root-offsets-chunk-count 16 \ --create-empty ### [​](https://docs.monad.xyz/node-ops/archive-data/genesis-replay#3-start-the-block-writer) 3\. Start the block writer Run inside `tmux` or create a systemd service to download blocks continuously: monad-block-writer stream \ --block-data-source \ --dest-path The source string follows the same format used by `monad-archiver`, for example `"aws mainnet-deu-009-0"` or `"mongodb ..."`. The block writer will: 1. Download all blocks from the source 2. Transform them into EVM format 3. Brotli-compress the data 4. Write blocks into subdirectories of the form `block-db/XM/`, where `X = block_number / 1_000_000` (one million blocks per directory) **Resumption behavior:** The writer saves a `latest` file in the `block-db` directory. If the process stops, on the next startup it reads `latest` and compares it against the latest block available from the `--block-data-source`, then continues from that point. If you only need a specific range of blocks, run `monad-block-writer stream --help` for range options. ### [​](https://docs.monad.xyz/node-ops/archive-data/genesis-replay#4-configure-the-replay-service) 4\. Configure the replay service While `monad-block-writer` is running, add the following systemd override for `monad-execution` in a separate terminal: sudo systemctl edit monad-execution [Service] ExecStart= ExecStart=/usr/local/bin/monad \ --chain "$CHAIN" \ --as_eth_blocks \ --block_db \ --nblocks 0 \ --db /dev/triedb \ --no-compaction \ --trace_calls \ --block-db-timeout 60 AllowedCPUs= CPUAffinity= Restart= Restart=always Ensure `$CHAIN` is defined in your environment. Valid options: * `ethereum_mainnet` * `monad_devnet` * `monad_testnet` * `monad_mainnet` **`--block-db-timeout`** sets the number of seconds the replay service will wait for new blocks to appear in the block database. If the timeout is reached without new blocks, the replay service will crash and be restarted by systemd. If this happens, verify that the block writer from step 3 is still running and writing blocks to disk. Set to `0` to disable retries. ### [​](https://docs.monad.xyz/node-ops/archive-data/genesis-replay#5-reload-and-start) 5\. Reload and start sudo systemctl daemon-reload sudo systemctl restart monad-execution [​](https://docs.monad.xyz/node-ops/archive-data/genesis-replay#running-rpc-on-a-replay-host) Running RPC on a replay host ----------------------------------------------------------------------------------------------------------------------------- If you want to run `monad-rpc` on this host, you must remove the `--ipc-path` flag from the `monad-rpc` systemd configuration. [Configuring RPC to use archive data\ \ Previous](https://docs.monad.xyz/node-ops/archive-data/configuring-rpc) [Validator Delegation Program (VDP)\ \ Next](https://docs.monad.xyz/node-ops/validator-delegation-program) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # RaptorCast - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/monad-arch/consensus/raptorcast#content-area) [​](https://docs.monad.xyz/monad-arch/consensus/raptorcast#summary) Summary ------------------------------------------------------------------------------ RaptorCast is a specialized multicast message delivery protocol used in [MonadBFT](https://docs.monad.xyz/monad-arch/consensus/monad-bft) to send block proposals from leaders to validators. Block proposals are converted into erasure-coded chunks using the Raptor code in [RFC 5053](https://datatracker.ietf.org/doc/html/rfc5053) . Each chunk is sent to all validators through a two-level broadcast tree, where the first level is a single non-leader node. Each non-leader node is responsible for serving as the first-level node for a different set of chunks; the proportion of chunk assignments is equal to the validator’s stake weight. RaptorCast thus utilizes the full upload bandwidth of the entire network to propagate block proposals to all validators, while preserving Byzantine fault tolerance. Check out this [**blog post**](https://www.category.xyz/blogs/raptorcast-designing-a-messaging-layer) by Category Labs for a full briefing on RaptorCast’s data transmission, erasure coding, and broadcast strategy. [​](https://docs.monad.xyz/monad-arch/consensus/raptorcast#introduction) Introduction ---------------------------------------------------------------------------------------- The technical description of RaptorCast below relates to block propagation amongst **validator** nodes participating in consensus. In particular, [block propagation to full nodes](https://docs.monad.xyz/monad-arch/consensus/raptorcast#secondary-raptorcast---full-node-block-propagation) is handled differently. In MonadBFT, leaders need to send block proposals to every validator. Getting block proposals from a leader to the rest of the network is one of the challenging problems in high-performance distributed consensus because block proposals are large and the network is not reliable. Consider the following two naive approaches to addressing this problem: 1. Sending messages directly from the leader to each validator. This is the simplest approach, but it would impose very high upload bandwidth requirements for a leader because block proposals are large - for example, 10,000 transactions at 200 bytes per transaction is 2MB. 2. Sending messages from the leader to a few peers, who each re-broadcast to a few peers. This approach would reduce the upload bandwidth requirements for the leader, but it would increase maximum latency to all of the nodes, and it risks message loss if some of the peers are Byzantine and fail to forward the message. RaptorCast is the multicast message delivery protocol that solves this problem, offering the best tradeoff between bandwidth requirements, latency, and fault-tolerance. RaptorCast was developed specifically for MonadBFT, and satisfies the following requirements. In the below discussion, the “message” is the block proposal, and the “message originator” is the leader. [​](https://docs.monad.xyz/monad-arch/consensus/raptorcast#design-requirements) Design requirements ------------------------------------------------------------------------------------------------------ * Reliable message delivery to all participating consensus nodes is guaranteed if a `2/3` supermajority of the stake weight is non-faulty (honest and online). * Upload bandwidth requirements for a validator are linearly proportional to message size and are independent of the total number of participating validators.[1](https://docs.monad.xyz/monad-arch/consensus/raptorcast#user-content-fn-1) * The worst-case message propagation time is twice the worst-case one-way latency between any two nodes. In other words, the propagation of a message to all intended recipients happens within the round-trip time (RTT) between the two most distant nodes in the network. * Messages are transmitted with a configurable amount of redundancy (chosen by the node operator). Increased redundancy mitigates packet loss and reduces message latency (recipient can decode sooner and more quickly). [​](https://docs.monad.xyz/monad-arch/consensus/raptorcast#how-raptorcast-works) How RaptorCast works -------------------------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/monad-arch/consensus/raptorcast#erasure-coding) Erasure coding Messages are erasure-coded by the message originator. Erasure coding means that the message is encoded into a set of chunks, and the message can be decoded from any sufficiently-large subset of the chunks. The specific code used by RaptorCast is a variant of the Raptor code documented in [RFC 5053](https://datatracker.ietf.org/doc/html/rfc5053) , with some Monad-specific modifications to * improve the encoding efficiency of small messages * reduce the computational complexity of message encoding (at the cost of a slight increase in decoding complexity) ### [​](https://docs.monad.xyz/monad-arch/consensus/raptorcast#message-and-chunk-distribution-model) Message and chunk distribution model RaptorCast uses a two-level broadcast tree for each chunk. The message originator is the root of the tree, a single non-originator node lives at level 1, and every other node lives at level 2. Each chunk of the encoded message potentially corresponds to a different broadcast tree, but the current implementation uses the same broadcast tree for contiguous ranges of the encoded message chunk space. The following diagram illustrates this chunk distribution model: ![RaptorCast Broadcast Tree](https://mintcdn.com/monadfoundation-40611fb6/-TCPhWHMfGzx9j3a/static/img/monad-arch/consensus/raptorcast/raptorcast_generic.png?w=2500&fit=max&auto=format&n=-TCPhWHMfGzx9j3a&q=85&s=0f55982d4fd175aac713f8a5a9850b18) Generic view of the two-hop Raptorcast broadcast tree. Using a two-level broadcast tree minimizes latency for message delivery. Each level of the tree has worst-case latency of the one-way latency between any two nodes in the network (the network’s “latency diameter”), so the worst case delivery time under RaptorCast is the round-trip-time of the network. ### [​](https://docs.monad.xyz/monad-arch/consensus/raptorcast#fault-tolerance) Fault tolerance RaptorCast runs directly over UDP, with a single message chunk per UDP packet. Note that the broadcast tree is unidirectional. Unlike TCP, RaptorCast does not include a recovery mechanism for downstream nodes in the tree to detect packet loss and request retransmission, since this would violate latency expectations. To compensate, RaptorCast transmits the message in a redundant fashion, with a redundancy factor chosen by the message originator based on the network’s expected packet loss. For example, under the following assumptions: * 20% network packet loss * maximum 33% of the network is faulty or malicious then the message originator should expect in the worst case that (1 - 0.2) \* (1 - 0.33) or ~53.6% of chunks reach the intended destination. To offset that worst case loss, the originator should send 1 / 0.536 - 1 or roughly 87% _additional_ chunks. The default [MTU](https://en.wikipedia.org/wiki/Maximum_transmission_unit) used is 1480 bytes. After subtracting RaptorCast header overhead for the default Merkle tree depth of 6, this leaves 1220 bytes per packet for an encoded Raptor payload. A 2 MB block maps to 2e6 / 1220 = 1640 source chunks. Using the current redundancy factor of 2.5, 4100 encoded chunks will then be distributed to other validators by proportionate stake weight. If there are 100 validators, those 4100 encoded chunks will be divided into 99 (the originator is excluded) distinct chunk ranges and the leader will initiate a broadcast tree for each validator corresponding to its unique chunk range (and payload). If the validators had equal stake, each would receive 4100 / 99 = 41 chunks in contiguous ranges. ![RaptorCast encoding and redundancy](https://mintcdn.com/monadfoundation-40611fb6/-TCPhWHMfGzx9j3a/static/img/monad-arch/consensus/raptorcast/raptorcast_expansion.png?w=2500&fit=max&auto=format&n=-TCPhWHMfGzx9j3a&q=85&s=fe3c23007836402a713ef9a44445ed43) A 2 MB block is split into chunks, expanded and disseminated. Note that the two-stage distribution model allows participating consensus nodes to receive a copy of a message even if direct network connectivity with the message originator is intermittently or entirely faulty. ![Block proposal](https://mintcdn.com/monadfoundation-40611fb6/-TCPhWHMfGzx9j3a/static/img/monad-arch/consensus/raptorcast/raptorcast_monad.png?w=2500&fit=max&auto=format&n=-TCPhWHMfGzx9j3a&q=85&s=401c948b35eb5ae3197f230cb19c0317) RaptorCast used to send erasure-encoded chunks from a leader to each validator. The message originator (leader) typically[2](https://docs.monad.xyz/monad-arch/consensus/raptorcast#user-content-fn-2) distributes generated chunks to the first-hop recipients according to stake weight. For example: * Validator 1 has stake 1 * Validator 2 has stake 2 * Validator 3 has stake 3 * Validator 4 has stake 4 When Validator 1 is the leader, they will send: * 2 / (2 + 3 + 4) of generated chunks to validator 2 * 3 / (2 + 3 + 4) of generated chunks to validator 3 * 4 / (2 + 3 + 4) of generated chunks to validator 4 The leader _currently_ sends chunks in contiguous ranges but development work is currently being done to enable dissemination at a more granular level. With the new algorithm, individual or much smaller sets of chunks would be sent randomly to first-hop validators without replacement, weighted by stake. This approach produces better utilization of the network as all validators can start processing chunks as they arrive and send for redistribution (start the second-hop). ### [​](https://docs.monad.xyz/monad-arch/consensus/raptorcast#chunk-transport-integrity) Chunk transport integrity The originator signs every encoded chunk, so intermediate nodes (level one) in the broadcast tree can verify the integrity of an encoded chunk before forwarding it. Furthermore, the number of source chunks `K` is encoded in the message. For given `K`, the recipient currently accepts encoded chunks in the range of 0 to `7 * K - 1`. This gives the originator sufficient freedom to specify a high degree of redundancy (up to 7), while also limiting the potential for network spam by a rogue validator. To amortize the cost of generating and verifying these signatures over many chunks, RaptorCast aggregates contiguous ranges of encoded message chunks in variable-depth Merkle trees, and produces a single signature for every Merkle tree root. [​](https://docs.monad.xyz/monad-arch/consensus/raptorcast#other-uses-of-raptorcast) Other uses of RaptorCast ---------------------------------------------------------------------------------------------------------------- RaptorCast is not only used for broadcasting a block in chunks from the leader. ### [​](https://docs.monad.xyz/monad-arch/consensus/raptorcast#transaction-forwarding) Transaction forwarding Transaction forwarding, e.g. from a full node to the next three validator hosts, is performed via RaptorCast, benefiting from its properties of speed and robustness. In this context, only one hop is required - the receiver should not rebroadcast. ### [​](https://docs.monad.xyz/monad-arch/consensus/raptorcast#secondary-raptorcast-full-node-block-propagation) Secondary RaptorCast - full node block propagation RaptorCast is also used to disseminate block proposals to full nodes. As described in [full node configurations](https://docs.monad.xyz/node-ops/full-node-block-delivery) , each participating validator creates a secondary RaptorCast network rooted in itself, utilizing full nodes as the recipients. Full nodes are added to a validator’s secondary RaptorCast group if they are **prioritized** by the validator, or if they are running in **public** mode and are selected by the selection algorithm. ![Dissemination to full nodes](https://mintcdn.com/monadfoundation-40611fb6/-TCPhWHMfGzx9j3a/static/img/monad-arch/consensus/raptorcast/raptorcast_full_node.png?w=2500&fit=max&auto=format&n=-TCPhWHMfGzx9j3a&q=85&s=5f789fccf997dd4277d00310de0fe95a) Each validator, after reconstructing the proposal, can disseminate all received (or produced) chunks to full nodes via dedicated relationship or secondary RaptorCast. Secondary RaptorCast mirrors the primary RaptorCast diagram above. Under secondary RaptorCast, the originator is now _any_ validator, and the group receiving chunks is a collection of public and prioritized full nodes, rather than the stake-weighted validator set. All full nodes in secondary RaptorCast receive an equal number of chunks (no stake-weight applicable). In terms of bandwidth, secondary RaptorCast is much more efficient than dedicated full nodes, because the upload bandwidth requirement for the validator is constant, rather than scaling linearly for the number of dedicated full nodes. Similar to primary RaptorCast, by adding a second hop, the burden of dissemination is borne more evenly by the participants in the group. Footnotes --------- 1. This holds when participating validators are (approximately) equally staked. In situations with (very) unevenly distributed stake weights, we need to deviate from the equal-upload property in order to maintain reliable message delivery for every possible scenario where two-thirds of the stake weight corresponds to non-faulty nodes. [↩](https://docs.monad.xyz/monad-arch/consensus/raptorcast#user-content-fnref-1) 2. The pure stake-weighted distribution scheme can break down when the number of required chunks is sufficiently small, e.g. 12 chunks distributed to 100 validators. This corner case is actively being addressed. [↩](https://docs.monad.xyz/monad-arch/consensus/raptorcast#user-content-fnref-2) [MonadBFT\ \ Previous](https://docs.monad.xyz/monad-arch/consensus/monad-bft) [Asynchronous Execution\ \ Next](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Real-Time Data Sources - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/monad-arch/realtime-data/data-sources#content-area) For many use cases, developers and users can access current and historical data for the Monad blockchain via the JSON-RPC interface. This is not the most efficient way to receive data about the latest blocks, however. The traditional JSON-RPC access methods use a request/response model (which requires polling) instead of a notification model, where new updates are pushed to you as soon as they happen. Because the Monad blockchain is much faster than other EVM-compatible L1 blockchains, the traditional JSON-RPC methods may not provide enough performance if you consume a _lot_ of data, even if they’ve worked for you on other EVM ecosystems. The next section explains why in detail. [​](https://docs.monad.xyz/monad-arch/realtime-data/data-sources#why-might-i-need-real-time-data-even-if-i-didn%E2%80%99t-before) Why might I need real-time data, even if I didn’t before? ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Monad is a fast blockchain capable of thousands of transactions per second: when the Monad ecosystem runs at peak rates there is much more data per second than in other L1 EVM-compatible blockchains such as mainnet Ethereum. The data ecosystem of original Ethereum evolved around a network that ran at less than 100 TPS, so certain data query patterns that work there might not perform well enough when the amount of data is almost 100 times larger. A classic example is an indexer workflow of fetching data about every transaction and every log in a block, using JSON-RPC methods like [`eth_getLogs`](https://docs.monad.xyz/reference/json-rpc/eth_getLogs) . A typical Ethereum block will have hundreds of transactions in it, and there will be one new block every 12 seconds or so. For Monad, there are 2.5 blocks every second, and each block can contain thousands of transactions. The number of `eth_getLogs` requests would be almost 100 times greater, putting a strain on the JSON-RPC service provider. Using real-time data services can help. Such services exist on other EVM blockchains too, but they’re essential in more situations for Monad. [​](https://docs.monad.xyz/monad-arch/realtime-data/data-sources#how-do-i-receive-real-time-data) How do I receive real-time data? ------------------------------------------------------------------------------------------------------------------------------------- Monad currently offers three sources of real-time data, which offer different trade-offs in latency vs. complexity. ### [​](https://docs.monad.xyz/monad-arch/realtime-data/data-sources#source-#1-geth-compatible-real-time-events) Source #1: Geth-compatible real-time events This is a [WebSocket-based protocol](https://geth.ethereum.org/docs/interacting-with-geth/rpc/pubsub) that originated in the Geth Ethereum client but is widely supported by other EVM-compatible blockchains. Monad implements the `eth_subscribe` method and the `newHeads` and `logs` subscription types. The `syncing` and `newPendingTransactions` subscription types are not supported. This real-time data feed is published by the Monad RPC server component. ### [​](https://docs.monad.xyz/monad-arch/realtime-data/data-sources#source-#2-monad-extensions-to-geth-real-time-events) Source #2: Monad extensions to Geth real-time events The Monad RPC server also offers an extension to the Geth protocol; it provides `eth_subscribe` subscriptions called `monadNewHeads` and `monadLogs`. These publish almost the same data as the Geth real-time events protocol, but include extra data for tracking each block’s progression through consensus. This requires the user to understand speculative execution and [how it affects real-time data](https://docs.monad.xyz/monad-arch/realtime-data/spec-realtime) . You can read more about these subscriptions in the [WebSocket Guide](https://docs.monad.xyz/reference/websockets#monadnewheads-and-monadlogs) . ### [​](https://docs.monad.xyz/monad-arch/realtime-data/data-sources#source-#3-execution-events-sdk) Source #3: Execution events SDK This is the fastest way to consume real-time data. It requires you to write your own real-time data processing software using the Monad client SDK in C, C++, or Rust — and then run it alongside your own Monad node. This is the source of data that powers the other two access methods: it is what the RPC server itself is listening to, to create the WebSocket feeds. It has its own [documentation](https://docs.monad.xyz/execution-events) . [​](https://docs.monad.xyz/monad-arch/realtime-data/data-sources#comparison-of-data-offerings) Comparison of data offerings ------------------------------------------------------------------------------------------------------------------------------ | Data offering | How to consume | Published by | Granularity | Transaction-level info | When data is published | | --- | --- | --- | --- | --- | --- | | Geth real-time events | [WebSocket](https://docs.monad.xyz/reference/websockets) | RPC server | Block commit | Logs only | When a block reaches `Voted` state | | Geth real-time events (with Monad extensions) | [WebSocket](https://docs.monad.xyz/reference/websockets) | RPC server | Block commit | Logs only | When a block reaches `Proposed` state | | Execution event SDK | C/C++ or Rust SDK | Execution daemon | Tx commit | Logs, call frames, state reads/writes | As soon as proposal is received | The first two offerings are consumed using `eth_subscribe` method over a WebSocket. They are available from third-party data providers if you don’t wish to run your own Monad node. The SDK offering requires you to write your own third-party program using the C/C++ or Rust SDK. These programs are not plugins that run inside the node software — they are free-standing programs written entirely by you. As events occur inside the EVM (in the execution daemon), they are recorded to shared memory. Your program also is reading this same shared memory. Therefore, your program must run on the same host as a Monad node. [Real-time Data\ \ Previous](https://docs.monad.xyz/monad-arch/realtime-data) [Speculative Real-Time Data\ \ Next](https://docs.monad.xyz/monad-arch/realtime-data/spec-realtime) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # The Data Waterfall - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/archive-data/data-waterfall#content-area) [​](https://docs.monad.xyz/node-ops/archive-data/data-waterfall#background) Background ----------------------------------------------------------------------------------------- As a high throughput blockchain with frequent blocks, Monad generates a lot of data - both **transactional data** (blocks, transactions, receipts, logs, and traces), and **state data** (the full state trie at the end of each block). Full nodes and validators store as much of both kinds of data as possible in MonadDB, overwriting the oldest data when the storage capacity hits 80%. If an RPC call requests data older than whatever is locally available, the node must reference an external source. For transactional data, the waterfall is: 1. Chain State Buffer (in-memory cache) 2. MonadDb 3. Archive Server (if configured) 4. Object Storage (if configured) [​](https://docs.monad.xyz/node-ops/archive-data/data-waterfall#monaddb) MonadDB ----------------------------------------------------------------------------------- MonadDB, also called TrieDB, is a local state database run by each full node and validator. It maintains the most recent state tries, as well as the corresponding transactional data. Once the storage capacity of MonadDB reaches 80%, the node begins overwriting the oldest data. Because of this mechanism, and because of frequent blocks and high chain throughput, most MonadDB instances don’t store the entire blockchain history. [​](https://docs.monad.xyz/node-ops/archive-data/data-waterfall#archive-server-mongodb) Archive Server (MongoDB) ------------------------------------------------------------------------------------------------------------------- An Archive Server is a standalone server that stores historical transactional data in MongoDB. Note that Archive Servers don’t store state data - see [here](https://docs.monad.xyz/developer-essentials/historical-data) for a discussion why. An Archive Server is fed this data by an ordinary full node running an additional process called the Archive Writer. ![](https://mintcdn.com/monadfoundation-40611fb6/-TCPhWHMfGzx9j3a/static/img/node-ops/archive-data/archive-server-architecture.png?w=2500&fit=max&auto=format&n=-TCPhWHMfGzx9j3a&q=85&s=7b6ed3cf84335906d06ef15d7baef5c3) Monad Archive Server architecture Many full nodes and validators can point to the same Archive Server. For instructions on running an Archive Server, please refer to [Running an Archive Server](https://docs.monad.xyz/node-ops/archive-data/running-an-archive-server) . Archive Servers store the following data types: * blocks * transactions * receipts * logs * traces Note: We call this an “Archive Server” rather than an “Archive Node” to reduce confusion. Archive Servers typically don’t host a Monad full node (consensus and execution). [​](https://docs.monad.xyz/node-ops/archive-data/data-waterfall#object-storage) Object Storage ------------------------------------------------------------------------------------------------- Archive data can also be stored in an object storage service (e.g., AWS S3). While MongoDB is preferred for performance and query efficiency, object storage provides a viable fallback option for users who prefer off-site or cloud-based data retention. Like ArchiveDB, the object storage can also be configured in the RPC client as a source of historical data. Object Storage stores the following data types: * blocks * transactions * receipts * logs * traces Archive Server is given preference over Object Storage if both are configured. Configuring both is recommended to ensure that there is a fallback mechanism in case of any issues with the Archive Server instance. For more details about historical data, see the [Historical Data](https://docs.monad.xyz/developer-essentials/historical-data) page. [Archive Data Setup\ \ Previous](https://docs.monad.xyz/node-ops/archive-data) [Running an Archive Server\ \ Next](https://docs.monad.xyz/node-ops/archive-data/running-an-archive-server) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Full Replay - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/node-recovery/full-replay#content-area) Full Replay allows a node to catch up on missed blocks by simply retrieving and replaying them serially. This is helpful for nodes that want all intermediary state and transactional artifacts to be generated. For example, an RPC provider would probably want this to ensure that they can respond to requests like `eth_call`, `eth_getBalance`, or `eth_estimateGas` for blocks that were skipped. [​](https://docs.monad.xyz/node-ops/node-recovery/full-replay#context) Context --------------------------------------------------------------------------------- A node that has not locally executed block `forkpoint.root - delay` will statesync on startup (see [forkpoint startup sync](https://docs.monad.xyz/monad-arch/consensus/forkpoint#startup-sync) ). Also, nodes don’t serve blocksync requests more than statesync\_threshold (600) blocks ago. Statesync is the only in-protocol way for that node to recover. This document describes an _alternate_ way to recover a node while backfilling historical state in the event that a node has been down for longer than the blocksync provision window (600 blocks). Note that if `statesync_threshold` in `node.toml` is set to a value larger than that, blocksync will fail. In order to recover the faulty node with complete historical state, the below procedure _requires SSH access to a node that was healthy_ throughout the faulty node’s downtime.Let `REMOTE_HOST` be the healthy node that can be used for recovery. [​](https://docs.monad.xyz/node-ops/node-recovery/full-replay#procedure) Procedure ------------------------------------------------------------------------------------- 1. SSH into the faulty node as `monad` user. 2. Ensure `statesync_threshold = 600` in `node.toml` $ grep statesync_threshold /home/monad/monad-bft/config/node.toml statesync_threshold = 600 1. Stop the monad services sudo systemctl stop monad-bft monad-execution monad-rpc 1. Run this script to copy missing blocks, then run execution up to that point. You will need to run it several times since the tip of the chain will continue advancing while this script is executing. 1. NOTE: You will need to manually interrupt the process (Ctrl - C) once output stops. 2. Copy this script and name it `manual-sync.sh` #!/usr/bin/env bash set -euo pipefail # Load config first so SSH_PORT, REMOTE_HOST, CHAIN etc are set source .env : "${SSH_PORT:?SSH_PORT must be set}" : "${REMOTE_HOST:?REMOTE_HOST must be set}" : "${CHAIN:?CHAIN must be set}" echo "Reading files from $REMOTE_HOST" echo "Using ssh port: $SSH_PORT" # Copy proposed and finalized header symlinks first rsync -avP -e "ssh -p $SSH_PORT" \ "monad@$REMOTE_HOST:/home/monad/monad-bft/ledger/headers/*_head" \ /home/monad/monad-bft/ledger/headers/ # Copy new headers and bodies, but don't overwrite existing ones rsync -avP --ignore-existing -e "ssh -p $SSH_PORT" \ "monad@$REMOTE_HOST:/home/monad/monad-bft/ledger/" \ /home/monad/monad-bft/ledger/ # Note: the --state-sync flag is NOT present /usr/local/bin/monad \ --chain "$CHAIN" \ --db /dev/triedb \ --block_db /home/monad/monad-bft/ledger \ --sq_thread_cpu 1 \ --log_level INFO 3. Run the script REMOTE_HOST=node1..com SSH_PORT=22 CHAIN=monad_mainnet bash manual-sync-step-1.sh 2. Once the first script completes in under 1 min, run this script: 1. Copy this and name it `manual-sync-step-2.sh` #!/usr/bin/env bash set -euo pipefail # Load config first so SSH_PORT, REMOTE_HOST, CHAIN etc are set source .env : "${SSH_PORT:?SSH_PORT must be set}" : "${REMOTE_HOST:?REMOTE_HOST must be set}" : "${CHAIN:?CHAIN must be set}" # Copy current forkpoint rsync -av -e "ssh -p $SSH_PORT" \ "monad@$REMOTE_HOST:/home/monad/monad-bft/config/forkpoint/forkpoint.rlp" \ /home/monad/monad-bft/config/forkpoint/ rsync -av -e "ssh -p $SSH_PORT" \ "monad@$REMOTE_HOST:/home/monad/monad-bft/config/forkpoint/forkpoint.toml" \ /home/monad/monad-bft/config/forkpoint/forkpoint.toml rsync -av -e "ssh -p $SSH_PORT" \ "monad@$REMOTE_HOST:/home/monad/monad-bft/config/validators/validators.toml" \ /home/monad/monad-bft/config/validators/validators.toml systemctl start monad-bft monad-execution monad-rpc 2. Run the script REMOTE_HOST=node1..com SSH_PORT=22 CHAIN=monad_mainnet bash manual-sync-step-2.sh [​](https://docs.monad.xyz/node-ops/node-recovery/full-replay#check) Check ----------------------------------------------------------------------------- To check that statesync has been avoided, send an `eth_getBlockByNumber` RPC request for blocks finalized while the node was down. curl http://localhost:8080 \ -X POST \ -H "Content-Type: application/json" \ --data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["0xdedbeef", false],"id":1}' [Hard Reset Instructions\ \ Previous](https://docs.monad.xyz/node-ops/node-recovery/hard-reset) [Node Migration (Promoting a Full Node to Validator)\ \ Next](https://docs.monad.xyz/node-ops/node-recovery/node-migration) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Node Migration (Promoting a Full Node to Validator) - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/node-recovery/node-migration#content-area) Backup Recommendation: We highly recommend backing up all validator configuration files and keys. This ensures you can recover quickly in the event of a node crash or unexpected failure. There are several ways to achieve high availability for your validator node. This document specifically provides instructions for running a full node and promoting it to a validator using the proper configuration files and keys. In situations of planned or unplanned maintenance, validators can migrate their node keys with minimal downtime by running a full node. This node can be seamlessly converted into a validator, allowing for continuous participation in consensus. At the moment downtime results in the loss of rewards for validators and their delegators. However there is **no slashing** live on the chain as of now. Follow these steps to safely migrate your validator role, minimize downtime, and maintain network health. [​](https://docs.monad.xyz/node-ops/node-recovery/node-migration#prerequisites) Prerequisites ------------------------------------------------------------------------------------------------ 1. Monad version >= `0.12.x`. 2. `id-secp` and `id-bls` keys of the validator. 3. `node.toml` configuration file of the validator. 4. `KEYSTORE_PASSWORD` value from the `.env` file. [​](https://docs.monad.xyz/node-ops/node-recovery/node-migration#instructions) Instructions ---------------------------------------------------------------------------------------------- 1. Follow the [full node instructions](https://docs.monad.xyz/node-ops/full-node-installation) to sync a full node to the tip of the network. 2. Backup existing configuration files on the full node from `/home/monad/monad-bft/config` and move them to `/opt/monad/backup`. * `/home/monad/monad-bft/config/node.toml` * `/home/monad/monad-bft/config/id-secp` * `/home/monad/monad-bft/config/id-bls` 3. Copy `id-secp`,`id-bls` and `node.toml` from the validator to the full node. 4. From the full node, run the `monad-sign-name-record` utility to generate a name-record signature for the new IP address. # Source the .env file to load the keystore password env variable source /home/monad/.env # Generate a name record and signature monad-sign-name-record --ip $(curl -s4 ifconfig.me) \ --tcp-port 8000 \ --udp-port 8000 \ --node-config /home/monad/monad-bft/config/node.toml \ --authenticated-udp-port 8001 \ --self-record-seq-num 1 \ --keystore-path /home/monad/monad-bft/config/id-secp \ --password "$KEYSTORE_PASSWORD" **Monad v0.15.1 and earlier:**Older versions use the `--address ip:port` flag instead of separate `--ip`, `--tcp-port`, and `--udp-port` flags: monad-sign-name-record --address $(curl -s4 ifconfig.me):8000 \ --node-config /home/monad/monad-bft/config/node.toml \ --authenticated-udp-port 8001 \ --self-record-seq-num 1 \ --keystore-path /home/monad/monad-bft/config/id-secp \ --password "$KEYSTORE_PASSWORD" **Example Output:** self_address = ":8000" self_record_seq_num = 1 # Incremented by 1 from the previous value self_name_record_sig = "" 1. From the full node, replace the `[peer_discovery]` block in `node.toml` with the output of the above command (3 lines). * The `self_record_seq_num` is incremented each time the node undergoes a migration process. * This value is crucial as it is directly linked to the `self_name_record_sig`, ensuring consistency and integrity of the node’s identity during transitions. 1. If the original validator had (other) custom configuration related to dedicated full nodes, e.g. `[[fullnode_dedicated.identities]]`, those will need to be added to the full node’s `node.toml`. To maintain connectivity with downstream nodes all downstream peers must update the name record for the validator in their `node.toml` configuration. 2. Ensure `enable_publisher = true`, `enable_client = true` and `expand_to_group = true`. In `expand_to_group = true` mode, full nodes support relies on secondary raptorcast peers specified in the full node’s `node.toml` 3. Double-check and ensure if the **`beneficiary =`** values are copied from the validator’s `node.toml` to full node’s `node.toml`. 4. From the validator node, run `systemctl` commands to stop the services. systemctl stop monad-bft monad-rpc monad-execution 1. Verify the validator services are stopped. systemctl status monad-bft monad-rpc monad-execution 1. Stop the **full node** services and restart the services as a **validator**. systemctl stop monad-bft monad-rpc monad-execution sleep 1 systemctl start monad-bft monad-rpc monad-execution 1. Verify the systemd services are running: systemctl status monad-bft monad-execution monad-rpc # Check logs for each service journalctl -fu monad-bft journalctl -fu monad-execution journalctl -fu monad-rpc [​](https://docs.monad.xyz/node-ops/node-recovery/node-migration#restoring-the-original-validator) Restoring the original validator -------------------------------------------------------------------------------------------------------------------------------------- If you would like to restore the original validator (A) to its original role, you will need to perform one of two procedures: 1. Re-sync A - this will result in some downtime based on the time to statesync / blocksync 1. Copy the `node.toml` from node B to node A 2. From A, run `monad-sign-name-record` using node B’s `node.toml` with incremented `self_record_seq_num` 3. Update the corresponding two fields in `node.toml` 4. From the temporary validator (B), stop the services. 5. Soft or hard reset (A) 2. Run A as a full node, then perform steps above 1. For A, generate [new keys](https://docs.monad.xyz/node-ops/full-node-installation#Generate-Keystores) 2. Sign a new name record (see instructions above) and [setup as a dedicated node](https://docs.monad.xyz/node-ops/full-node-installation) to a validator, e.g. your temporary validator (B) 3. Perform the steps above with roles reversed. Always ensure that each node maintains distinct `node_name` values in their respective `node.toml` files. * If node B was originally a full node with `node_name = "node_B"`, it should retain this name when returning to full node operation * Node B should only temporarily use node A’s `node_name` during the migration procedure * After restoration, each node must return to its original `node_name` to avoid conflicts [Full Replay\ \ Previous](https://docs.monad.xyz/node-ops/node-recovery/full-replay) [How Full Nodes Receive Blocks\ \ Next](https://docs.monad.xyz/node-ops/full-node-block-delivery) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Running an Archive Server - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/archive-data/running-an-archive-server#content-area) Please see [The Data Waterfall](https://docs.monad.xyz/node-ops/archive-data/data-waterfall) for an overview of the different sources of archive data. This page is dedicated to operational details on running an Archive Server. [​](https://docs.monad.xyz/node-ops/archive-data/running-an-archive-server#recommended-footprint) Recommended footprint -------------------------------------------------------------------------------------------------------------------------- For anyone looking to reliably serve historical transactional data, it is recommended to run multiple Archive Servers, fed by multiple full nodes running the Archive Writer process. Suggested configuration: * 2 Archive Servers running MongoDB + monad-indexer * 2 Archive Writer nodes, aka full node + monad-archiver * Many full nodes serving RPC requests, connected to both Archive Servers for historical transactional data [​](https://docs.monad.xyz/node-ops/archive-data/running-an-archive-server#recommended-archive-server-host-specs) Recommended Archive Server host specs ---------------------------------------------------------------------------------------------------------------------------------------------------------- * CPU: 16 cores * RAM: minimum 64GB; prefer >512GB for best performance * Storage: minimum recommended 16TB; preferred 32TB+ * NVMe SSD * RAID 10 * Minimum 10K IOPS sustained * Network: >1GbE, scale higher as needed when serving more RPC servers [​](https://docs.monad.xyz/node-ops/archive-data/running-an-archive-server#fresh-installation) Fresh installation -------------------------------------------------------------------------------------------------------------------- These instructions assume an existing full node (for Archive Writer) and a new host (for Archive Server). ### [​](https://docs.monad.xyz/node-ops/archive-data/running-an-archive-server#on-your-archive-server) On your Archive Server: 1. Add the following section to `/home/monad/.env` # Replace and with your actual values DB_USER="" DB_PWD="" DB_VOLUME="~/archive-db-data" # Note: source and sink should generally be the same local MongoDB. # Indexer reads from: BLOCK_DATA_SOURCE="mongodb mongodb://${DB_USER}:${DB_PWD}@0.0.0.0:27017 archive-db" # Indexer writes to: ARCHIVE_SINK="mongodb mongodb://${DB_USER}:${DB_PWD}@0.0.0.0:27017 archive-db" OTEL_ENDPOINT="http://0.0.0.0:4317" 2. Run mongodb. Instructions show how to run in Docker, but operators can run however they choose. archive-db: image: mongo:latest command: mongod --bind_ip 0.0.0.0 networks: - host environment: MONGO_INITDB_ROOT_USERNAME: ${DB_USER} MONGO_INITDB_ROOT_PASSWORD: ${DB_PWD} ports: - "27017:27017" volumes: - ${DB_VOLUME}:/data/db logging: driver: journald options: tag: "mongo" 3. Start the db # create directory from .env db volume source /home/monad/.env sudo mkdir -p $DB_VOLUME sudo chown -R monad:monad $DB_VOLUME sudo chmod 700 $DB_VOLUME docker compose up archive-db -d ### [​](https://docs.monad.xyz/node-ops/archive-data/running-an-archive-server#on-your-archive-writer-host) On your Archive Writer host: 4. Add the following section to `/home/monad/.env` ############################################################### ################### Vars that do not change ################### ############################################################### # Replace with your Archive Server credentials ARCHIVE_DB_USER="" ARCHIVE_DB_PWD="" ARCHIVE_DB_HOST="" ## Where block data gets written (your Archive Server) ARCHIVE_SINK="mongodb mongodb://${ARCHIVE_DB_USER}:${ARCHIVE_DB_PWD}@${ARCHIVE_DB_HOST}:27017 archive-db" ## Change this if your ledger folder is in a different location BFT_BLOCK_PATH=~/monad-bft/ledger OTEL_ENDPOINT=http://0.0.0.0:4317 ## This can be significantly higher during backfill MAX_CONCURRENT_BLOCKS=50 ############################################################### ####### Backfill from Genesis (initial configuration) ######### ############################################################### BLOCK_DATA_SOURCE="aws testnet-can-004-0-aavn9ll 50" # testnet BLOCK_DATA_SOURCE="aws mainnet-deu-010-0 50" # mainnet ## Alternatively you can use your other ArchiveDB if it has already been backfilled ## If using another Archive Server, define variables for it and use them: #OTHER_DB_USER="" #OTHER_DB_PWD="" #OTHER_DB_HOST="" #BLOCK_DATA_SOURCE="mongodb mongodb://${OTHER_DB_USER}:${OTHER_DB_PWD}@${OTHER_DB_HOST}:27017 archive-db" FALLBACK_BLOCK_DATA_SOURCE="aws testnet-can-004-0-aavn9ll-0 50" # testnet FALLBACK_BLOCK_DATA_SOURCE="aws mainnet-deu-010-0 50" # mainnet ############################################################### ###################### Normal Operation ####################### ############################################################### ## Archiver checks triedb first for block data BLOCK_DATA_SOURCE="triedb /dev/triedb 5000" ### FALLBACK_BLOCK_DATA_SOURCE ### ## This is used whenever data is missing from BLOCK_DATA_SOURCE ## Normally used after state-sync ## If you have another Archive Server for redundancy, configure it here: #OTHER_DB_USER="" #OTHER_DB_PWD="" #OTHER_DB_HOST="" #FALLBACK_BLOCK_DATA_SOURCE="mongodb mongodb://${OTHER_DB_USER}:${OTHER_DB_PWD}@${OTHER_DB_HOST}:27017 archive-db" ## Alternatively you can use category-labs aws bucket ## Note: YOU pay for S3 egress costs if pulling from this bucket FALLBACK_BLOCK_DATA_SOURCE="aws testnet-can-004-0-aavn9ll 50" # testnet FALLBACK_BLOCK_DATA_SOURCE="aws mainnet-deu-010-0 50" # mainnet 5. Backfilling: As of v0.12.3, `--start-block` is no longer supported as a daemon argument. Instead, use the `set-start-block` subcommand to set the starting block marker imperatively before starting the daemon. This prevents accidental progress loss from systemd overrides. # [Optional] Set a specific start block if needed # This is typically only needed for initial setup or recovery scenarios # Example: start archiving from block 1000000 monad-archiver set-start-block --block 1000000 --archive-sink "${ARCHIVE_SINK}" # For async backfill marker, add the --async-backfill flag: # monad-archiver set-start-block --block 1000000 --archive-sink "${ARCHIVE_SINK}" --async-backfill # Start the archiver daemon sudo systemctl start monad-archiver # Should show it running # Double check the arguments look correct based on the above ^ systemctl status monad-archiver # Expect many: # > INFO: Successfully archived block block_num=X journalctl -u monad-archiver -o cat 6. Once `monad-archiver` has caught up to the chain tip you will see: > `INFO: Nothing to process` 7. This means backfilling is done and you should 1. Comment out `BACKFILL` section in your `.env` and uncomment `Normal Operation` 2. Restart: `systemctl restart monad-archiver` 3. Verify status and logs as above ### [​](https://docs.monad.xyz/node-ops/archive-data/running-an-archive-server#on-your-archivedb-host) On your ArchiveDB host 8. Start `monad-indexer` sudo systemctl start monad-indexer systemctl status monad-indexer # Expect many: # > INFO: Indexing block... # > INFO: Index spot-check successful journalctl -u monad-indexer -o cat [​](https://docs.monad.xyz/node-ops/archive-data/running-an-archive-server#optional-set-up-monad-archive-checker) \[Optional\] Set up `monad-archive-checker` ---------------------------------------------------------------------------------------------------------------------------------------------------------------- Typically only 1 checker is run per organization, but more can be run if desired 1. Add the following systemd override to `monad-archive-checker` sudo systemctl edit monad-archive-checker [Service] ExecStart= ExecStart=/usr/local/bin/monad-archive-checker \ # Example --bucket my-org-mainnet-checker # Note: storing checker state in local mongo or filesystem # will be supported in a future release --bucket checker # Example of comparing a local self-hosted mongo against a Category Labs aws bucket # --init-replicas ":@:27017 archive-db>,mongodb mongodb://:@:27017 archive-db>" --init-replicas "," 2. Reload and Restart sudo systemctl daemon-reload sudo systemctl restart monad-archive-checker systemctl status monad-archive-checker # Check for errors journalctl -u monad-archive-checker -o cat -f [The Data Waterfall\ \ Previous](https://docs.monad.xyz/node-ops/archive-data/data-waterfall) [Configuring RPC to use archive data\ \ Next](https://docs.monad.xyz/node-ops/archive-data/configuring-rpc) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Message Authentication - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/monad-arch/consensus/authentication#content-area) [​](https://docs.monad.xyz/monad-arch/consensus/authentication#bls-multi-signatures) BLS Multi-Signatures ------------------------------------------------------------------------------------------------------------ Certificates (QCs and TCs) can be naively implemented as a vector of ECDSA signatures on the secp256k1 curve. These certificates are explicit and easy to construct and verify. However, the size of the certificate is linear with the number of signers. It poses a limit to scaling because the certificate is included in almost every consensus message, except vote message. Pairing-based BLS signature on the BLS12-381 curve helps with solving the scaling issue. The signatures can be incrementally aggregated into one signature. Verifying the single valid aggregated signature provides proof that the stakes associated with the public keys have all signed on the message. BLS signature is much slower than ECDSA signature. So for performance reasons, Monad’s implementation of MonadBFT adopts a blended signature scheme where BLS signatures are only used on aggregatable message types (votes and timeouts). Message integrity and authenticity is still provided by ECDSA signatures. [Peer Discovery\ \ Previous](https://docs.monad.xyz/monad-arch/consensus/peer-discovery) [Transport Protocol Usage\ \ Next](https://docs.monad.xyz/monad-arch/consensus/transport-protocols) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Staking - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/monad-arch/consensus/staking#content-area) Monad uses staking to determine validator voting weights and each epoch’s leader schedule in [MonadBFT](https://docs.monad.xyz/monad-arch/consensus/monad-bft) . Validators must stake at least a minimum amount, and others can delegate to them. For a developer-oriented guide to interacting with the staking precompile, see the documentation [overview](https://docs.monad.xyz/reference/staking/overview) and [API](https://docs.monad.xyz/reference/staking/api) . [​](https://docs.monad.xyz/monad-arch/consensus/staking#validator-set) Validator set --------------------------------------------------------------------------------------- To be part of the active validator set, a validator must meet all of the following criteria: * **Self-delegation:** the validator’s `authAddress` must have self-delegated at least `MIN_AUTH_ADDRESS_STAKE` (100,000 MON) * **Total stake:** the validator must have total delegation of at least `ACTIVE_VALIDATOR_STAKE` (10,000,000 MON) * **Rank:** the validator must be in the top `ACTIVE_VALSET_SIZE` (200) validators by stake weight Validators that fall below these thresholds are removed from the active set at the next epoch boundary. [​](https://docs.monad.xyz/monad-arch/consensus/staking#rewards-and-commission) Rewards and commission --------------------------------------------------------------------------------------------------------- When a block is produced, the leader who produced it earns a block reward from two sources: 1. **Inflationary reward** — a fixed `REWARD` of 18 MON per block, minted by the protocol 2. **Priority fees** — the priority fees from all transactions in the block ### [​](https://docs.monad.xyz/monad-arch/consensus/staking#commission) Commission Each validator sets a commission rate (0%–100%) that determines what fraction of the inflationary block reward they keep before distributing the remainder to delegators. The remainder is distributed **pro rata** by stake weight. As a delegator, your share of a block’s reward is proportional to your stake relative to the validator’s total stake. **Example:** Suppose you have delegated to a validator and comprise 20% of that validator’s total stake. The inflationary block reward is 10 MON and the commission is 10%. You receive: > 10 MON × 90% × 20% = **1.8 MON** ### [​](https://docs.monad.xyz/monad-arch/consensus/staking#priority-fees) Priority fees Currently, priority fees go only to the validator. Validators may choose to share priority fees with delegators (including themselves) by calling the [`externalReward`](https://docs.monad.xyz/reference/staking/api#externalreward) method on the staking precompile. Commission is **not** deducted from external rewards. ### [​](https://docs.monad.xyz/monad-arch/consensus/staking#claiming-and-compounding) Claiming and compounding Each delegation accumulates rewards over time. Delegators can either: * **Claim** rewards — withdrawn to the delegator’s account immediately * **Compound** rewards — added to the delegation, increasing stake weight (follows the standard epoch timing rules described below) [​](https://docs.monad.xyz/monad-arch/consensus/staking#epochs-and-boundaries) Epochs and boundaries ------------------------------------------------------------------------------------------------------- An **epoch** uses one set of delegations and leader validators for its entire duration. Every 50,000 blocks (the `BOUNDARY_BLOCK_PERIOD`) is a **boundary block** that commits the upcoming staking changes and the validator set to be used in the next epoch. Boundary blocks happen approximately every 5.5 hours. The next epoch does not start immediately at the boundary block, but after a 5,000-round delay (`EPOCH_DELAY_ROUNDS`) to allow all nodes to update their epoch information. ![timeline showing the placement of boundary blocks within an epoch](https://mintcdn.com/monadfoundation-40611fb6/c3ZcPFY7YVeS_v57/static/img/developer-essentials/staking/staking-timeline.png?w=2500&fit=max&auto=format&n=c3ZcPFY7YVeS_v57&q=85&s=09c9c8c0b8c7423c776025bfe31493ee) ### [​](https://docs.monad.xyz/monad-arch/consensus/staking#timing-of-staking-actions) Timing of staking actions Most staking actions take effect after they are committed in a boundary block and the next epoch starts. The exceptions are `claimRewards()` and `externalReward()`, which take effect immediately. As an example, consider `delegate()` during epoch #4: * If the `delegate()` takes place before the boundary block for epoch #5, the stake will be included in epoch #5. * If the `delegate()` transaction is in the boundary block itself, it will not be included in epoch #5 (the snapshot is taken at the start of the block, before user transactions). The delegation will be picked up in the boundary block for epoch #6. * If the `delegate()` transaction is after the boundary block but before the end of epoch #4, the delegation will take effect in epoch #6. The `BOUNDARY_BLOCK_PERIOD` is denominated in **blocks**, while `EPOCH_DELAY_ROUNDS` is denominated in **rounds**. If perfect consensus is achieved, these increment at the same rate. However, upon a failed block proposal (e.g. timeout), the round increments while the block does not. [​](https://docs.monad.xyz/monad-arch/consensus/staking#execution-snapshot-and-consensus-views) Execution, snapshot, and consensus views ------------------------------------------------------------------------------------------------------------------------------------------- The staking system maintains three views that staking state passes through: 1. **Execution view** — the real-time state. When validators are added, delegations change, or any staking transaction happens, the execution view is updated immediately. 2. **Snapshot view** — at the start of each boundary block, the current execution view is copied into the snapshot view. Any transaction changes after this point will not affect the following epoch. The snapshot now matches what the next epoch will look like. 3. **Consensus view** — after `EPOCH_DELAY_ROUNDS` (5,000 rounds) from the boundary block, the new epoch starts and the snapshot view is copied into the consensus view. The consensus view holds the validators and voting stake weights being used by the consensus system for the remainder of the epoch. [​](https://docs.monad.xyz/monad-arch/consensus/staking#slashing) Slashing ----------------------------------------------------------------------------- Robust logging provides accountability for malicious, slashable offenses. However, automated in-protocol slashing is not currently implemented. [​](https://docs.monad.xyz/monad-arch/consensus/staking#constants) Constants ------------------------------------------------------------------------------- | Constant | Meaning | Value | | --- | --- | --- | | `BOUNDARY_BLOCK_PERIOD` | Blocks from boundary block to boundary block | 50,000 blocks | | `EPOCH_DELAY_ROUNDS` | Rounds between the boundary block and the start of each epoch | 5,000 rounds | | `WITHDRAWAL_DELAY` | Number of epochs before unstaked tokens can be withdrawn | 1 epoch | | `MIN_AUTH_ADDRESS_STAKE` | Min MON self-delegated by a validator to be eligible for the active set | 100,000 MON | | `ACTIVE_VALIDATOR_STAKE` | Min total MON staked with a validator for active set eligibility | 10,000,000 MON | | `ACTIVE_VALSET_SIZE` | Number of validators in the active set | 200 | | `REWARD` | MON reward per block | 18 MON | [Transport Protocol Usage\ \ Previous](https://docs.monad.xyz/monad-arch/consensus/transport-protocols) [Execution\ \ Next](https://docs.monad.xyz/monad-arch/execution) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Execution Events and WebSocket Setup - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/events-and-websockets#content-area) [​](https://docs.monad.xyz/node-ops/events-and-websockets#summary) Summary ----------------------------------------------------------------------------- The [Execution Events](https://docs.monad.xyz/execution-events) and [WebSocket](https://docs.monad.xyz/reference/websockets) features were designed to work together to make Monad even faster for high volume applications. Execution Events is a low-level system, and WebSocket support is one specific usage of that system. ### [​](https://docs.monad.xyz/node-ops/events-and-websockets#execution-events) Execution Events [Execution Events](https://docs.monad.xyz/execution-events) offers developers the highest performance option for listening to real-time data from the Monad blockchain. * Execution Events uses a shared memory communication system that requires additional setup, which is described here. This setup is not part of the default instructions; it’s only needed if you run real-time data consumers that use the Execution Events feature. * The “shared memory” nature of the communication means that consumers of execution events must run directly on the same host as the Monad node, so they can observe real-time data in the host’s RAM * Monad’s RPC server can optionally use execution events for better performance, and to support certain features, namely, the `eth_subscribe` JSON-RPC call [Here](https://docs.monad.xyz/monad-arch/realtime-data/data-sources) is an overview of all real-time data offerings in Monad. [Here](https://docs.monad.xyz/execution-events) is a tutorial on writing programs that consume execution events. ### [​](https://docs.monad.xyz/node-ops/events-and-websockets#websockets) WebSockets In Monad’s JSON-RPC server, WebSockets have two uses: * Creating a persistent connection to make JSON-RPC requests * The ability to call the `eth_subscribe` API, which will “push” new real-time data as it happens, so you do not need to poll for new events WebSocket support must be explicitly enabled in the RPC server with command-line flag `--ws-enabled`. When `--ws-enabled` is passed, then the host must be configured to support execution events, otherwise RPC will exit with an error. A user guide to WebSockets on Monad is [here](https://docs.monad.xyz/reference/websockets) . [​](https://docs.monad.xyz/node-ops/events-and-websockets#requirements) Requirements --------------------------------------------------------------------------------------- * A running Monad full node ([setup instructions](https://docs.monad.xyz/node-ops/full-node-installation) ) * A `hugetlbfs` filesystem mount * This can be set up using the `hugeadm` utility; see below for an example * Custom (aka “override”) `systemd` unit files for both `RPC` and `Execution` * Examples are both below [​](https://docs.monad.xyz/node-ops/events-and-websockets#setup-a-hugetlbfs-mount-using-hugeadm) Setup a `hugetlbfs` mount using `hugeadm` --------------------------------------------------------------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/node-ops/events-and-websockets#general-prerequisites) General prerequisites Install the required package: sudo apt install libhugetlbfs-bin ### [​](https://docs.monad.xyz/node-ops/events-and-websockets#execution-events-sdk-prerequisites) Execution events SDK prerequisites If you want to consume real-time data in your own software using the execution events SDK, you must install these additional packages: sudo apt install libhugetlbfs-dev libhugetlbfs0 libzstd-dev These are only required for the SDK; if you only need to enable WebSocket support in the RPC server, you _do not_ need these packages. ### [​](https://docs.monad.xyz/node-ops/events-and-websockets#cli-one-time-setup) CLI one-time setup This is for one-time testing and will NOT persist after a reboot # NOTE: here we use `monad` but if you are running as a custom user, that should be set here $ sudo hugeadm --create-user-mounts monad ### [​](https://docs.monad.xyz/node-ops/events-and-websockets#sample-systemd-unit-file) Sample `systemd` unit file This makes the mounts persistent after a reboot. Create the service file: sudo nano /etc/systemd/system/events-hugepages-mounts.service Paste the following contents: # NOTE: as mentioned above, you can change the `monad` user to your custom user (if needed) [Unit] Description=Create hugepage mounts for monad After=local-fs.target [Service] Type=oneshot ExecStart=/usr/bin/hugeadm --create-user-mounts monad RemainAfterExit=yes [Install] WantedBy=multi-user.target Save and exit (`Ctrl+O`, `Enter`, `Ctrl+X`). Enable and start the service: sudo systemctl daemon-reload sudo systemctl enable --now events-hugepages-mounts ### [​](https://docs.monad.xyz/node-ops/events-and-websockets#create-the-event-rings-directory) Create the event-rings directory The event-rings directory must exist for WebSocket events to work: sudo mkdir -p /var/lib/hugetlbfs/user/monad/pagesize-2MB/event-rings sudo chown monad:monad /var/lib/hugetlbfs/user/monad/pagesize-2MB/event-rings [​](https://docs.monad.xyz/node-ops/events-and-websockets#configure-the-systemd-overrides) Configure the `systemd` overrides ------------------------------------------------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/node-ops/events-and-websockets#important-items) Important items `systemd`: * As a reminder, if you installed Monad via `apt`, the `systemd` unit files live in: `/usr/lib/systemd/system` * This means we need to create a `systemd` override * `systemd` overrides for ExecStart (and other additive settings) require two blocks. The first “clears” the original value and the second sets the new value. * You will need to do a `systemctl daemon-reload` after the changes `events` + `WebSockets`: * `RPC` + `WebSockets` has a HARD dependency on `Execution` running with `events` `WebSockets` specific: * You will need to open a port in your firewall * The default is `8081` * If you want to use a custom port, the `--ws-port ` for `RPC` allows you to set the port of your choosing ### [​](https://docs.monad.xyz/node-ops/events-and-websockets#configure-the-execution-override-for-systemd) Configure the `Execution` override for `systemd` This override enables the `events` sub-component for `Execution` If `RPC` + `WebSockets` is started without `events` being enabled for `Execution`, `RPC` will start and then crash You can launch the override editor via: sudo systemctl edit monad-execution Which will make a new file at `/etc/systemd/system/monad-execution.service.d/override.conf` File contents (as viewed when using the override editor): ### Anything between here and the comment below will become the contents of the drop-in file # NOTE: BOTH ExecStarts are REQUIRED [Service] ExecStart= ExecStart=/usr/local/bin/monad \ --chain "$CHAIN" \ --db /dev/triedb \ --block_db /home/monad/monad-bft/ledger \ --statesync /home/monad/monad-bft/statesync.sock \ --exec-event-ring /var/lib/hugetlbfs/user/monad/pagesize-2MB/event-rings/monad-exec-events \ --sq_thread_cpu 1 \ --log_level INFO ### Edits below this comment will be discarded Do reload: sudo systemctl daemon-reload ### [​](https://docs.monad.xyz/node-ops/events-and-websockets#restart-execution) Restart `Execution` Adding this step here to ensure that `Execution` is restarted with the `events` enabled sudo systemctl restart monad-execution ### [​](https://docs.monad.xyz/node-ops/events-and-websockets#configure-the-rpc-override-for-systemd) Configure the `RPC` override for `systemd` This override enables the `WebSockets` sub-component for `RPC` You can launch the override editor via: sudo systemctl edit monad-rpc Which will make a new file at `/etc/systemd/system/monad-rpc.service.d/override.conf` File contents: # NOTE: BOTH ExecStarts are REQUIRED [Service] ExecStart= ExecStart=/usr/local/bin/monad-rpc \ --ipc-path /home/monad/monad-bft/mempool.sock \ --triedb-path /dev/triedb \ --otel-endpoint "http://0.0.0.0:4317" \ --allow-unprotected-txs \ --node-config /home/monad/monad-bft/config/node.toml \ --exec-event-path /var/lib/hugetlbfs/user/monad/pagesize-2MB/event-rings/monad-exec-events \ --ws-enabled ### [​](https://docs.monad.xyz/node-ops/events-and-websockets#restart-rpc) Restart `RPC` sudo systemctl restart monad-rpc ### [​](https://docs.monad.xyz/node-ops/events-and-websockets#checking-the-connectivity) Checking the connectivity A quick way to check if WebSocket connectivity is working is to use a general purpose command-line tool that can act as WebSocket client, such as [`websocat`](https://github.com/vi/websocat) . This is a powerful command-line “swiss army knife” tool, like `nc` or the original `socat`. It is not officially packaged for Debian/Ubuntu yet, but precompiled binaries can be downloaded or installed via `cargo install websocat` (it is a Rust program). Here is an example of running it in verbose mode (`-v`), with the WebSocket service hosted on default port 8081: $ websocat -v ws://localhost:8081 [INFO websocat::lints] Auto-inserting the line mode [INFO websocat::stdio_threaded_peer] get_stdio_peer (threaded) [INFO websocat::ws_client_peer] get_ws_client_peer [INFO websocat::net_peer] Connected to TCP 127.0.0.1:8081 [INFO websocat::ws_client_peer] Connected to ws [INFO websocat::ws_peer] Received WebSocket ping To subscribe, type the subscription JSON RPC call for `eth_subscribe` into your terminal’s stdin and press enter: { "id": 1, "jsonrpc": "2.0", "method": "eth_subscribe", "params": ["newHeads"] } Every half-second or so, you should see updates about new blocks. [How Full Nodes Receive Blocks\ \ Previous](https://docs.monad.xyz/node-ops/full-node-block-delivery) [Archive Data Setup\ \ Next](https://docs.monad.xyz/node-ops/archive-data) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Configuring RPC to use archive data - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/archive-data/configuring-rpc#content-area) Integration with the archive is designed for full nodes servicing RPC requests, **not for validator nodes**. Enabling `--trace_calls` is recommended for **RPC** nodes. This preserves the detailed error information necessary for call traces, e.g. `debug_traceTransaction`. To make this override, please run `sudo systemctl edit monad-execution` and add the `--trace_calls` CLI param to the `ExecStart` definition (may need a line continuation character `\`): sudo systemctl edit monad-execution [Service] Type=simple ExecStart= ExecStart=/usr/local/bin/monad \ [... existing cli commands, see comment at the bottom of the systemctl editor ...] --trace_calls [​](https://docs.monad.xyz/node-ops/archive-data/configuring-rpc#configuring-monad-rpc-with-archive-server-backup) Configuring `monad-rpc` with Archive Server backup ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1. Configure an [Archive Server](https://docs.monad.xyz/node-ops/archive-data/running-an-archive-server) that is geographically close to this full node. 2. Add the following vars to your `/home/monad/.env`: # Replace , and with your values from Step (1) MONGO_URL="mongodb://:@:27017" MONGO_DB_NAME="archive-db" DB_HOST= DB_PWD= DB_USERNAME= 3. Verify connectivity: source /home/monad/.env nc -vz $DB_HOST 27017 mongosh "$MONGO_URL" --quiet --eval ' try { db.adminCommand({ping: 1}); const archiveDb = db.getSiblingDB("archive-db"); const hasCollection = archiveDb.getCollectionNames().includes("block_level"); print(hasCollection ? "OK: Collection exists" : "FAIL: Collection missing"); quit(hasCollection ? 0 : 1); } catch(e) { print("FAIL: " + e.message); quit(1); } ' 4. Add the following systemd override to `monad-rpc`: sudo systemctl edit monad-rpc [Service] ExecStart= ExecStart=/usr/local/bin/monad-rpc \ [... existing cli commands, see comment at the bottom of the systemctl editor ...] --mongo-url ${MONGO_URL} \ --mongo-db-name ${MONGO_DB_NAME} \ --use-eth-get-logs-index 5. Reload and restart: sudo systemctl daemon-reload sudo systemctl restart monad-rpc 6. Check for an early block outside local retention: curl -X POST -H "Content-Type: application/json" --data '{ "jsonrpc": "2.0", "method": "eth_getBlockByNumber", "params": ["0x1", false], "id": 1 }' http://localhost:8080 [​](https://docs.monad.xyz/node-ops/archive-data/configuring-rpc#configuring-monad-rpc-with-aws-backup) Configuring `monad-rpc` with AWS backup -------------------------------------------------------------------------------------------------------------------------------------------------- 1. Ensure an AWS identity and credentials are on the box. * Run `aws configure` to setup your AWS credentials and config on the full node. This should generate `config` and `credentials` files under `/home/monad/.aws/`. See the [AWS CLI docs](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html) . * When running in systemd, AWS permissions need to be created under `monad` user. See the general validator or fullnode docs for the broader instructions to run rpc, but ensure the `monad` user has aws credentials with access to the bucket. 2. Create an AWS IAM policy using this [user guide](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create-console.html#access_policies_create-json-editor) and the following sample json: { "Version": "2012-10-17", "Statement": [\ {\ "Effect": "Allow",\ "Action": [\ "s3:GetObject",\ "s3:ListBucket",\ "s3:GetBucketRequestPayment",\ "execute-api:Invoke"\ ],\ "Resource": [\ "arn:aws:s3:::*/*",\ "arn:aws:s3:::*",\ "arn:aws:execute-api:*:*:*"\ ],\ "Condition": {\ "StringEquals": {\ "aws:ResourceOrgID": "o-sq9ayub2wk"\ }\ }\ }\ ] } 3. To obtain a free-tier api-key, send an AWS Signature v4 signed request to `https://9df09fanz1.execute-api.us-east-2.amazonaws.com/prod/free-tier-key` * ex. using `awscurl` utility: awscurl https://9df09fanz1.execute-api.us-east-2.amazonaws.com/prod/free-tier-key --region us-east-2 4. Add the following vars to your `/home/monad/.env`: ARCHIVE_API_KEY= # Replace with appropriate mainnet, localnet or testnet bucket # Below is the public testnet bucket maintained by Category Labs ARCHIVE_BUCKET="testnet-can-004-0-aavn9ll" # Below is the public mainnet bucket maintained by Category Labs ARCHIVE_BUCKET="mainnet-deu-010-0" # mainnet-deu-009-0 is a sibling bucket you can also use 5. Add the following systemd override to `monad-rpc`: sudo systemctl edit monad-rpc [Service] ExecStart= ExecStart=/usr/local/bin/monad-rpc \ [... existing cli commands, see comment at the bottom of the systemctl editor ...] --s3-bucket ${ARCHIVE_BUCKET} \ --region "us-east-2" \ --archive-url "https://9df09fanz1.execute-api.us-east-2.amazonaws.com/prod" \ --archive-api-key ${ARCHIVE_API_KEY} 6. Reload and restart: sudo systemctl daemon-reload sudo systemctl restart monad-rpc 7. Check for an early block outside local retention: If you already have MongoDB backend enabled, this will not test anything by default. To test, temporarily remove the MongoDB backend, run the following and restore the MongoDB config. curl -X POST -H "Content-Type: application/json" --data '{ "jsonrpc": "2.0", "method": "eth_getBlockByNumber", "params": ["0x1", false], "id": 1 }' http://localhost:8080 [Running an Archive Server\ \ Previous](https://docs.monad.xyz/node-ops/archive-data/running-an-archive-server) [Genesis Replay\ \ Next](https://docs.monad.xyz/node-ops/archive-data/genesis-replay) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Hard Reset Instructions - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/node-recovery/hard-reset#content-area) Hard reset wipes the local state and downloads the most recent chain snapshot. After the snapshot is applied, the node catches up using [statesync](https://docs.monad.xyz/monad-arch/consensus/statesync) and [blocksync](https://docs.monad.xyz/monad-arch/consensus/blocksync) . Hard reset is the most powerful means of resetting a node. Steps are: 1. Download a recent snapshot of the network state. 2. Initialize the DB from the snapshot (this can take up to an hour on testnet and a few minutes on mainnet) 3. Catch up to the tip of the chain via statesync / blocksync (typically < 5 minutes assuming snapshot is a few hours old) **Monad Foundation** and **Category Labs** are snapshot providers. If there is an issue, please refer to Discord validator channels for more snapshot providers. [​](https://docs.monad.xyz/node-ops/node-recovery/hard-reset#prerequisite) Prerequisite ------------------------------------------------------------------------------------------ * `aria2` must be installed on the node [​](https://docs.monad.xyz/node-ops/node-recovery/hard-reset#instructions) Instructions ------------------------------------------------------------------------------------------ 1. SSH into the node as `root` user. 2. Stop the monad services and reset the workspace to delete all runtime data. bash /opt/monad/scripts/reset-workspace.sh 3. Download and import TrieDB database snapshot. * Mainnet * Testnet On mainnet, database snapshot restoration **takes from 1 to 5 minutes**. As the blockchain grows over time, snapshot restoration takes longer. Using Monad Foundation provider: MF_BUCKET=https://bucket.monadinfra.com curl -sSL $MF_BUCKET/scripts/mainnet/restore-from-snapshot.sh | bash Using Category Labs provider: CL_BUCKET=https://pub-b0d0d7272c994851b4c8af22a766f571.r2.dev curl -sSL $CL_BUCKET/scripts/mainnet/restore_from_snapshot.sh | bash On testnet, database snapshot restoration **takes under 5 minutes**. As the blockchain grows over time, snapshot restoration takes longer. Using Monad Foundation provider: MF_BUCKET=https://bucket.monadinfra.com curl -sSL $MF_BUCKET/scripts/testnet/restore-from-snapshot.sh | bash Using Category Labs provider: CL_BUCKET=https://pub-b0d0d7272c994851b4c8af22a766f571.r2.dev curl -sSL $CL_BUCKET/scripts/testnet/restore_from_snapshot.sh | bash 4. Fetch latest [`forkpoint.toml`](https://docs.monad.xyz/monad-arch/consensus/forkpoint) and `validators.toml` runtime files. This step is optional if automatic remote config fetching is configured (v0.12.1+). Ensure `REMOTE_VALIDATORS_URL` and `REMOTE_FORKPOINT_URL` are defined in `/home/monad/.env` file. See [Full Node Installation](https://docs.monad.xyz/node-ops/full-node-installation#remote-configuration-fetching-v0121) for configuration details. If not configured, you may run the below commands. * Mainnet * Testnet MF_BUCKET=https://bucket.monadinfra.com VALIDATORS_FILE=/home/monad/monad-bft/config/validators/validators.toml curl -sSL $MF_BUCKET/scripts/mainnet/download-forkpoint.sh | bash curl $MF_BUCKET/validators/mainnet/validators.toml -o $VALIDATORS_FILE chown monad:monad $VALIDATORS_FILE MF_BUCKET=https://bucket.monadinfra.com VALIDATORS_FILE=/home/monad/monad-bft/config/validators/validators.toml curl -sSL $MF_BUCKET/scripts/testnet/download-forkpoint.sh | bash curl $MF_BUCKET/validators/testnet/validators.toml -o $VALIDATORS_FILE chown monad:monad $VALIDATORS_FILE 5. Start all services systemctl start monad-bft monad-execution monad-rpc [Soft Reset Instructions\ \ Previous](https://docs.monad.xyz/node-ops/node-recovery/soft-reset) [Full Replay\ \ Next](https://docs.monad.xyz/node-ops/node-recovery/full-replay) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Soft Reset Instructions - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/node-recovery/soft-reset#content-area) A soft reset is typically required when node is (re-)joining the network and the node tip is close to the network tip. Soft reset utilizes [statesync](https://docs.monad.xyz/monad-arch/consensus/statesync) to determine the difference between the current state and the chain tip and to skip ahead. In v0.12.1+, the node will automatically attempt to fetch remote configuration files on startup if env variables are defined: * [`forkpoint.toml`](https://docs.monad.xyz/monad-arch/consensus/forkpoint) : Changes every round * `validators.toml`: Changes every epoch This simplifies node operations by automating configuration updates. The remote fetching includes threshold logic to determine when remote configs should be used.**Note**: For automatic remote config fetching (v0.12.1+), ensure `REMOTE_VALIDATORS_URL` and `REMOTE_FORKPOINT_URL` are defined in `/home/monad/.env` file. See [Full Node Installation](https://docs.monad.xyz/node-ops/full-node-installation#remote-configuration-fetching-v0121) for configuration details. [​](https://docs.monad.xyz/node-ops/node-recovery/soft-reset#automated-soft-reset-v0-12-1+) Automated Soft Reset (v0.12.1+) ------------------------------------------------------------------------------------------------------------------------------ Starting with v0.12.1, soft resets are largely automated if the appropriate variables are defined in `.env`: 1. SSH into the node as `root` user 2. Restart monad-related services (`monad-bft` will auto-fetch configs on startup): systemctl restart monad-bft monad-execution monad-rpc 3. Verify the systemd services are running: systemctl list-units --type=service monad-bft.service monad-execution.service monad-rpc.service UNIT LOAD ACTIVE SUB DESCRIPTION monad-bft.service loaded active running "Service file for Monad BFT" monad-execution.service loaded active running "Service file for Monad Execution" monad-rpc.service loaded active running "Service file for Monad RPC" # Check logs for a specific process to verify config fetching journalctl -u monad-bft [​](https://docs.monad.xyz/node-ops/node-recovery/soft-reset#manual-soft-reset) Manual Soft Reset ---------------------------------------------------------------------------------------------------- To disable the automated fetching, remove any existing definitions (and remove from `/home/monad/.env` if desired) unset REMOTE_VALIDATORS_URL unset REMOTE_FORKPOINT_URL 1. SSH into the node as `root` user 2. Stop monad-related services systemctl stop monad-bft monad-execution monad-rpc 3. Fetch new `forkpoint.toml` and `validators.toml`. * Mainnet * Testnet MF_BUCKET=https://bucket.monadinfra.com VALIDATORS_FILE=/home/monad/monad-bft/config/validators/validators.toml curl -sSL $MF_BUCKET/scripts/mainnet/download-forkpoint.sh | bash curl $MF_BUCKET/validators/mainnet/validators.toml -o $VALIDATORS_FILE chown monad:monad $VALIDATORS_FILE MF_BUCKET=https://bucket.monadinfra.com VALIDATORS_FILE=/home/monad/monad-bft/config/validators/validators.toml curl -sSL $MF_BUCKET/scripts/testnet/download-forkpoint.sh | bash curl $MF_BUCKET/validators/testnet/validators.toml -o $VALIDATORS_FILE chown monad:monad $VALIDATORS_FILE You may see the following log message: failed to fetch remote configs, using local forkpoint and validators config 4. Start monad-related services systemctl start monad-bft monad-execution monad-rpc 5. Verify the systemd services are running: systemctl list-units --type=service monad-bft.service monad-execution.service monad-rpc.service UNIT LOAD ACTIVE SUB DESCRIPTION monad-bft.service loaded active running "Service file for Monad BFT" monad-execution.service loaded active running "Service file for Monad Execution" monad-rpc.service loaded active running "Service file for Monad RPC" # Check logs for a specific process, e.g. bft journalctl -u monad-bft [​](https://docs.monad.xyz/node-ops/node-recovery/soft-reset#configuration-details) Configuration Details ------------------------------------------------------------------------------------------------------------ ### [​](https://docs.monad.xyz/node-ops/node-recovery/soft-reset#forkpoint-serialization) Forkpoint Serialization Starting with v0.12.1, forkpoints are serialized in both TOML and RLP formats: * **RLP format**: Source of truth * **TOML format**: Maintained for backward compatibility * If TOML serialization fails, the node will no longer panic * Nodes can start from either format for operational backwards compatibility [Recovering a Node\ \ Previous](https://docs.monad.xyz/node-ops/node-recovery) [Hard Reset Instructions\ \ Next](https://docs.monad.xyz/node-ops/node-recovery/hard-reset) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Archive Data Setup - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/archive-data#content-area) The Data Waterfall ------------------ Where RPC looks for historical data Running an Archive Server ------------------------- Configuring RPC to use Archive Data ----------------------------------- How to configure RPC to use archive data Genesis Replay -------------- Re-execute historical blocks to reconstruct state [Execution Events and WebSocket Setup\ \ Previous](https://docs.monad.xyz/node-ops/events-and-websockets) [The Data Waterfall\ \ Next](https://docs.monad.xyz/node-ops/archive-data/data-waterfall) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # MonadBFT - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/monad-arch/consensus/monad-bft#content-area) [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#summary) Summary ----------------------------------------------------------------------------- MonadBFT represents a major leap in Byzantine Fault Tolerant (BFT) consensus. It is responsible for ensuring that the Monad network aligns on valid proposed blocks efficiently and securely, while supporting 10,000+ tx/s and sub-second time-to-finality, while also supporting a large consensus node set. MonadBFT combines all of these properties while also being resilient to **tail-forking**, a critical weakness of pipelined leader-based BFT protocols where a leader can fork away its predecessor’s block. For a full description and deep technical dive into MonadBFT, please refer to the [full research paper](https://arxiv.org/abs/2502.20692) , the [latest blog post from Category Labs](https://www.category.xyz/blogs/monadbft-update-fast-recovery-leader-fault-isolation) and the [original blog post](https://www.category.xyz/blogs/monadbft-fast-responsive-fork-resistant-streamlined-consensus) introducing MonadBFT. MonadBFT achieves: * **Speculative finality in a single consensus round**, and **full finality in two rounds**. * **Linear message and authenticator complexity** on the happy path (meaning under normal operations, when no failures occur). This allows the consensus validator set to scale to a large number of nodes. * **Optimistic responsiveness**: round progression without waiting for the worst-case network delay, both in the common case and while recovering from failed rounds. * **Leader fault isolation** A single failed leader only incurs one timeout delay. All other rounds are able to proceed as quickly as the network allows. This is in contrast to existing pipelined BFT protocols, which have a two timeouts for a failed leader. * **Tail-forking resistance**: built-in protection against [tail-forking](https://docs.monad.xyz/monad-arch/consensus/monad-bft#no-tail-forking) , a class of Maximal Extractable Value (MEV) attacks where a malicious leader could otherwise fork away its predecessor’s block. This resolves a critical issue in prior pipelined leader-based BFT consensus mechanisms. No other pipelined leader-based BFT protocol combines all these features. Category Labs has made several recent improvements to MonadBFT. This page and the research paper have now been updated with full details. Find out what’s new in the [Fast Recovery](https://docs.monad.xyz/monad-arch/consensus/monad-bft#fast-recovery) section or by reading [this blog post](https://www.category.xyz/blogs/monadbft-update-fast-recovery-leader-fault-isolation) . [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#configuration-in-monad) Configuration in Monad ----------------------------------------------------------------------------------------------------------- | | | | --- | --- | | Sybil resistance mechanism | Proof-of-Stake (PoS) | | Min block time | 300 ms | | Finality | 2 slots (600 ms) | | Speculative finality _(can only revert in [rare circumstances](https://docs.monad.xyz/monad-arch/consensus/monad-bft#speculative-finality)
requiring equivocation by the original leader_) | 1 slot (300 ms) | | Delegation allowed | Yes | [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#demo) Demo ----------------------------------------------------------------------- See [this](https://www.category.xyz/blogs/monad-viz-a-visual-representation-of-monadbft) blog post from Category Labs for a live demo of MonadBFT! The demo runs the exact implementation of [`monad-bft`](https://github.com/category-labs/monad-bft) that powers the live Monad blockchain, compiled to Wasm and run in your browser against a simulation framework ([`mock-swarm`](https://github.com/category-labs/monad-bft/tree/master/monad-mock-swarm) ). [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#common-concepts) Common Concepts --------------------------------------------------------------------------------------------- To explain MonadBFT, it helps to define a few concepts first. We will start with some concepts common to many BFT mechanisms: ### [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#byzantine-threshold) Byzantine threshold As is customary, let there be `n = 3f+1` nodes, where `f` is the max number of Byzantine (faulty) nodes. That is, `2f+1` (2/3) of the nodes are non-Byzantine. In the discussion below, we treat all nodes as having equal stake weight; in practice all thresholds can be expressed in terms of stake weight rather than in node count. ### [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#supermajority) Supermajority \>2/3 of the stake weight. ### [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#round) Round The protocol proceeds in rounds, also referred to as views. The round number increases by 1 with each step of the protocol regardless of whether a block proposal is successfully made. ### [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#leader) Leader Each round has one leader who has the authority to make a block proposal. The leader rotates each round according to a schedule determined previously using the stake weights. ### [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#block) Block A block consist of a round number, a payload (an ordered list of transactions), and a [QC](https://docs.monad.xyz/monad-arch/consensus/monad-bft#quorum-certificate-qc) . A block builds on a _parent_ block, and includes a QC certifying that parent block. Blocks are chained together via the parent relationship, which is why we called it a blockchain. ### [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#quorum-certificate-qc) Quorum Certificate (QC) Validators evaluate the validity of each block proposal and send their votes to the next leader. If the next leader receives a supermajority of YES votes, they aggregate those votes into a Quorum Certificate (QC) on that block proposal. A QC is proof that 2/3 of the network received and voted YES on a block proposal. Although this is more of an implementation detail, it is worth noting that in Monad’s implementation of MonadBFT, validators sign with [BLS signatures](https://en.wikipedia.org/wiki/BLS_digital_signature) because those signatures can be efficiently aggregated, making signature verification on the QC relatively inexpensive. ### [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#linear-communication) Linear communication Each round follows a fan-out fan-in pattern. The leader sends their block proposal to each validator (using [RaptorCast](https://docs.monad.xyz/monad-arch/consensus/raptorcast) for efficient broadcast). Validators evaluate the block proposal and send a signed vote directly to the next leader. This linear communication mechanism contrasts with other protocols which rely on all-to-all (quadratic) communication; it allows the consensus set to scale. [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#concepts-relatively-unique-to-monadbft) Concepts relatively unique to MonadBFT ------------------------------------------------------------------------------------------------------------------------------------------- The following are concepts that are relatively unique to MonadBFT. We are splitting them out to aid in comprehension. For simplicity, we focus on the standard recovery in MonadBFT. The fast recovery optimizations are explained in the [Fast Recovery](https://docs.monad.xyz/monad-arch/consensus/monad-bft#fast-recovery) section. ### [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#proposal) Proposal A block proposal (often just called _proposal_) consists of the current round number, a block, an optional [TC](https://docs.monad.xyz/monad-arch/consensus/monad-bft#timeout-certificate-tc) or [NEC](https://docs.monad.xyz/monad-arch/consensus/monad-bft#no-endorsement-message-and-no-endorsement-certificate) , and a signature (from the leader making the proposal) over the previous elements. In the simple case, optional fields are blank and the round number is the same as the block’s round number, such that the proposal is basically a signed block. Sometimes, a block that failed to get traction gets reproposed; in that case, the block will still have the round number from when it was first proposed, but the proposal will have the round number of when it is reproposed. #### [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#fresh-proposal) Fresh Proposal A fresh proposal is a [proposal](https://docs.monad.xyz/monad-arch/consensus/monad-bft#proposal) containing a new block, i.e. one that is not influenced by prior failed proposals. A fresh proposal will either: 1. have a round number that is equal to its [QC](https://docs.monad.xyz/monad-arch/consensus/monad-bft#quorum-certificate-qc) ’s round number plus 1. This is the common case, when leaders are honest and online, and the network does not have any abnormal delays. 2. have a [TC](https://docs.monad.xyz/monad-arch/consensus/monad-bft#timeout-certificate-tc) identifying a high QC. This happens when a leader recovers from a failed round ([fast recovery](https://docs.monad.xyz/monad-arch/consensus/monad-bft#fast-recovery) ). 3. have a [NEC](https://docs.monad.xyz/monad-arch/consensus/monad-bft#no-endorsement-message-and-no-endorsement-certificate) . This happens very rarely, when a leader recovers from a more complex failure (standard recovery). #### [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#reproposal) Reproposal A reproposal is a [proposal](https://docs.monad.xyz/monad-arch/consensus/monad-bft#proposal) containing a block from a previous fresh proposal that the current leader is trying to revive or finalize. A reproposal will have a round number greater than its [QC](https://docs.monad.xyz/monad-arch/consensus/monad-bft#quorum-certificate-qc) ’s round number plus 1. Whether a leader recovering from a failure has to repropose a previous block or not is determined by the [TC](https://docs.monad.xyz/monad-arch/consensus/monad-bft#timeout-certificate-tc) . If the TC contains a high tip (instead of a high QC), then the block corresponding to the high tip must be reproposed. Reproposals are part of the standard recovery. In practice, reproposals can often be skipped with fast recovery. ### [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#tip) Tip A tip is a proposal minus the block’s payload. You can think of it as the block header of the proposal plus a bit of extra metadata, including the round number that that proposal was received. In MonadBFT, every validator keeps track of its latest tip, which is updated whenever the validator votes for a proposal. If the validator votes for a reproposal, the tip is set to the original proposal, not its reproposal. ### [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#high-tip) High Tip Given a set of tips, high tip is just the tip with the highest round number. If there are multiple such tips, then the tip that builds on the highest QC embedded in it is chosen. ### [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#timeout-message) Timeout Message A timeout message is a signed attestation that a validator produces when it hasn’t received a valid block from the scheduled leader in the expected time. The timeout message attests to the lack of a valid block. Each validator sends the timeout message to all other validators, utilizing all-to-all communication. Timeout messages are utilized in other BFT protocols. In MonadBFT, timeout messages include the sender’s [tip](https://docs.monad.xyz/monad-arch/consensus/monad-bft#tip) - additional information about their view of the world which will be utilized in MonadBFT to recover gracefully from the timeout. For fast recovery, the timeout message contains the validator’s highest QC, if it is of equal or higher view than the view of the local tip. ### [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#timeout-certificate-tc) Timeout Certificate (TC) When a timeout occurs, validators start sending and receiving [timeout messages](https://docs.monad.xyz/monad-arch/consensus/monad-bft#timeout-message) . Each validator accumulates the timeout messages that it receives; if it gets to a supermajority of such messages, it builds a Timeout Certificate (TC). The TC includes information on all of the tips from all of the validators contributing timeout messages. The [high tip](https://docs.monad.xyz/monad-arch/consensus/monad-bft#high-tip) (for standard recovery) is also computed. In most cases, fast recovery is possible, and the TC contains a high QC instead of a high tip. ### [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#no-endorsement-message-and-no-endorsement-certificate) No-Endorsement Message and No-Endorsement Certificate Under certain conditions, a leader will ask the other validators for the full proposal (block) corresponding to a tip. If the validator doesn’t have it, they will respond with a signed No-Endorsement Message attesting to this. If the leader gets a supermajority of No-Endorsement Messages when trying to recover the proposal of a tip, they can produce a No-Endorsement Certificate - proof that a supermajority of the network didn’t have that proposal. [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#block-states-due-to-monadbft) Block states due to MonadBFT ----------------------------------------------------------------------------------------------------------------------- Blocks can be in one of three states due to MonadBFT: 1. `Proposed` 2. `Voted` 3. `Finalized` These are three of the four states that blocks can be in overall within Monad, as mentioned in [Block States](https://docs.monad.xyz/monad-arch/consensus/block-states) . (The fourth state, `Verified`, is achieved outside of MonadBFT as a part of [Asynchronous Execution](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution) .) Below, we describe how blocks progress through these states. [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#happy-path) Happy Path ----------------------------------------------------------------------------------- The happy path describes the ordinary case of how a block goes from being proposed to being finalized without any timeouts or failed rounds. ### [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#scenario) Scenario To describe the flow of the happy path, we’ll follow the scenario shown in the diagram below. It is currently [round](https://docs.monad.xyz/monad-arch/consensus/monad-bft#round) `K` and the scheduled [leader](https://docs.monad.xyz/monad-arch/consensus/monad-bft#leader) is Alice. Bob and Charlie are the next two leaders in the schedule. Alice has last seen [block](https://docs.monad.xyz/monad-arch/consensus/monad-bft#block) `N-1`, so she is going to propose block `N`. ![](https://mintcdn.com/monadfoundation-40611fb6/5Mt9_Scj9fq4fC68/static/img/monad-arch/consensus/monadbft/monadbft.png?w=2500&fit=max&auto=format&n=5Mt9_Scj9fq4fC68&q=85&s=3c0f6b187d005ca0d2904fb412fae4f8) MonadBFT proceeds as follows. ### [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#round-k-alice%E2%80%99s-proposal) Round `K`: Alice’s proposal 1. **Proposal:** Alice, the designated leader for round `K`, chooses a payload, i.e. a list of transactions chosen from her mempool. She builds block `N`, consisting of the payload and a QC from the previous proposal (don’t worry about this part). Alice sends the proposal consisting of that block directly to all other validators. 2. **Voting:** Each validator checks Alice’s proposal for validity. If the proposal is valid, the validator sends signed votes directly to Bob, the designated leader for round `K+1`, and marks block `N` as [`Proposed`](https://docs.monad.xyz/monad-arch/consensus/block-states#proposed) . 3. **QC Formation**: Upon getting a supermajority of votes about Alice’s proposal, Bob aggregates the votes into a [QC](https://docs.monad.xyz/monad-arch/consensus/monad-bft#quorum-certificate-qc) about Alice’s proposal. ### [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#round-k+1-bob%E2%80%99s-proposal) Round `K+1`: Bob’s proposal 4. **Proposal:** Bob chooses a payload. Bob combines the payload with the [QC](https://docs.monad.xyz/monad-arch/consensus/monad-bft#quorum-certificate-qc) from Alice’s proposal to produce a new block, which he sends to all other validators. 5. **Voting:** Each validator checks Bob’s proposal for validity. If the proposal is valid, the validator sends votes directly to Charlie, the designated leader for round `K+2`, and marks block `N` as [`Voted`](https://docs.monad.xyz/monad-arch/consensus/block-states#voted) (and block `N+1` as [`Proposed`](https://docs.monad.xyz/monad-arch/consensus/block-states#proposed) .) This also means that the block can be **speculatively finalized**. This speculative finality will only revert under very specific rare conditions, which also come with accountability. [More on this later.](https://docs.monad.xyz/monad-arch/consensus/monad-bft#speculative-finality) 6. **QC Formation**: Upon getting a supermajority of votes about Bob’s proposal, Charlie aggregates the votes into a [QC](https://docs.monad.xyz/monad-arch/consensus/monad-bft#quorum-certificate-qc) about Bob’s proposal. This QC can also be thought of a QC-squared on Alice’s proposal, since it is a QC attesting to the fact that a supermajority received the QC about Alice’s proposal. ### [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#round-k+2-charlie%E2%80%99s-proposal) Round `K+2`: Charlie’s proposal 7. **Charlie’s proposal:** As before, Charlie builds a block, consisting of a new payload and the [QC](https://docs.monad.xyz/monad-arch/consensus/monad-bft#quorum-certificate-qc) on Bob’s proposal. Charlie sends the proposal to everyone. 8. **Voting:** Each validator checks Charlie’s proposal for validity. If the proposal is valid, the validator sends votes directly to David, the designated leader for round `K+3`, and marks block `N` as [`Finalized`](https://docs.monad.xyz/monad-arch/consensus/block-states#finalized) (and block `N+1` as [`Voted`](https://docs.monad.xyz/monad-arch/consensus/block-states#voted) and block `N+2` as [`Proposed`](https://docs.monad.xyz/monad-arch/consensus/block-states#proposed) .) Although we will stop describing the sequence at this point, the consensus mechanism continues repetitively. As soon as each validator receives David’s proposal (which contains a QC about Charlie’s proposal aka a QC-squared about Bob’s proposal), they can mark Bob’s proposal as `Finalized` (and Charlie’s as `Voted`). And so on. This underscores the pipelining aspect of MonadBFT. Every round, a new payload and a new QC about the previous proposal gets shared, allowing the parent proposal to be speculatively finalized and the grandparent proposal to be fully finalized. You can see this here: ![](https://mintcdn.com/monadfoundation-40611fb6/5Mt9_Scj9fq4fC68/static/img/monad-arch/consensus/monadbft/monadbft-pipelining.png?w=2500&fit=max&auto=format&n=5Mt9_Scj9fq4fC68&q=85&s=addba4c594e5b1933551966f6d905c99) Illustrating the pipelined (staggered) nature of MonadBFT. Same diagram as the previous, but zoomed out to include one more round. [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#unhappy-path-fault-handling) Unhappy Path (Fault Handling) ----------------------------------------------------------------------------------------------------------------------- The unhappy path describes the abnormal case where either the leader fails to send out a valid proposal or the QC builder (next leader) fails to build a QC. Understanding the unhappy path is crucial to understanding how the happy path works as well! The thing that ultimately allows a validator to speculatively finalize a proposal after receiving the child proposal, or finalize a proposal after receiving the grandchild proposal, is knowing that the fallback mechanism will still preserve the original proposal. Here, we will focus on the standard recovery, which is actually the fallback of the fallback mechanism. In most cases in practice, we can use [fast recovery](https://docs.monad.xyz/monad-arch/consensus/monad-bft#fast-recovery) , which substantially speeds up the time for the protocol to go back to the happy path after a failure occurs. However, for the protocol as a whole to achieve the tail forking resistance, even in the worst case of Byzantine failures, we rely on the standard recovery, which we now present. ### [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#scenario-2) Scenario As before, to describe the flow of the unhappy path, we’ll follow a scenario shown in a diagram. Again, suppose that it is currently round `K` and Alice is the scheduled leader. Bob and Charlie are the next two leaders in the schedule. Alice has last seen block `N-1`, so she is going to propose block `N`. In our example, Alice sends block `N` at round `K`, but Bob fails to send a block at round `K+1`. This could be because he was offline, or it could be that Alice either sent an invalid block, or not enough people voted for it. ![](https://mintcdn.com/monadfoundation-40611fb6/-TCPhWHMfGzx9j3a/static/img/monad-arch/consensus/monadbft/unhappy-path.png?w=2500&fit=max&auto=format&n=-TCPhWHMfGzx9j3a&q=85&s=264068ed65493b7dfeb652a6c9ec0c43) ### [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#round-k-alice%E2%80%99s-proposal-2) Round `K`: Alice’s proposal 1. **Proposal:** Alice, the designated leader for round `K`, chooses a payload and builds block `N`, consisting of the payload and a [QC](https://docs.monad.xyz/monad-arch/consensus/monad-bft#quorum-certificate-qc) from the previous proposal (again, don’t worry about this part). Alice sends the proposal directly to all other validators. 2. **Voting:** Each validator checks the proposal for validity and, if valid, sends signed votes directly to Bob, the designated leader for round `K+1`. Each validator marks Alice’s proposal locally as [`Proposed`](https://docs.monad.xyz/monad-arch/consensus/block-states#proposed) . ### [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#when-round-k+1-was-expected-bob%E2%80%99s-missed-slot) When round `K+1` was expected: Bob’s missed slot 3. **Bob fails to propose block `N+1`**, so all votes are blackholed and no QC for Alice’s block is produced. 4. **Everyone sends timeout messages:** After a timeout window, each validator “realizes” that round `K` has failed since no QC is formed for Alice’s block. Therefore, everyone sends a [timeout message](https://docs.monad.xyz/monad-arch/consensus/monad-bft#timeout-message) about block `K` to every other validator. (Note that this communication is all-to-all.) 5. **TC assembly**: Upon getting a supermajority of timeout messages, every validator including Bob assembles a [TC](https://docs.monad.xyz/monad-arch/consensus/monad-bft#timeout-certificate-tc) , proving that round `K` (Alice proposer, Bob QC builder) failed. Upon building a TC for `K`, validators advance their round to `K+1`. ### [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#round-k+1-as-progressed-by-tc) Round `K+1`, as progressed by TC The TC contains a computed value called [`high_tip`](https://docs.monad.xyz/monad-arch/consensus/monad-bft#high-tip) , which (roughly speaking) is the block header of the latest valid block that any of the validators contributing to the timeout message have seen. You can think of `high_tip` as the max block observed over the 2/3 of the stake weight required to sign the TC. In this specific example, `high_tip` will be the block header of Alice’s block. Under the rules of MonadBFT, the next leader is obligated to either re-propose the block referenced in `high_tip` of the TC (i.e. Alice’s block), or to prove that that block is unsupported. (We’ll discuss this in more detail below.) Since we are now in Round `K+1`, the next leader is **Bob**. (You might find this ironic, but it is a necessary consequence of the fact that the protocol cannot distinguish between the possibility that Bob was offline, and the possibility that either Alice sent an invalid block or not enough people voted on Alice’s block. In either of the latter cases, it would be unfair to skip Bob.) 6. **(Optional) Requesting Alice’s block from other validators**: Bob needs to re-propose Alice’s block. However, the `high_tip` is only a block header - not the full block body - so if Bob doesn’t have Alice’s block, he can request the full version from the other validators (via [blocksync](https://docs.monad.xyz/monad-arch/consensus/blocksync) ). #### [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#reproposal-case-bob-re-proposes-alice%E2%80%99s-block) Reproposal case (Bob re-proposes Alice’s block) 7. **Reproposal**: If Bob has Alice’s block (either due to already receiving it when he originally proposed it, or via blocksync) then he proposes it along with the TC justifying the re-proposal. 8. **Voting:** Each validator votes on the validity of Bob’s reproposal. If the reproposal is valid, validators send their votes to the next leader, Charlie. 9. **QC Formation:** Charlie assembles a QC from the votes. 10. **Charlie’s proposal:** Charlie builds a block at round `K+2`, consisting of a new payload and the QC on reproposal from round `K+1`, and sends the block to everyone. At this point Alice’s block becomes [`Voted`](https://docs.monad.xyz/monad-arch/consensus/block-states#voted) to anyone who receives Charlie’s block. Everyone advances their rounds to `K+2` and the protocol returns to the happy path. #### [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#fresh-proposal-case-bob-proves-alice%E2%80%99s-block-is-unsupported) Fresh proposal case (Bob proves Alice’s block is unsupported) 7. **No-Endorsement of Bob’s block**: Recall that in step 6, Bob was allowed to poll the other validators for Alice’s block. When a validator is polled, if they also don’t have it, they can send Bob a signed [No-Endorsement Message](https://docs.monad.xyz/monad-arch/consensus/monad-bft#no-endorsement-message-and-no-endorsement-certificate) attesting to _not_ having seen Alice’s block. If a supermajority of the validators sign No-Endorsement Messages, then Bob may assemble a [No-Endorsement Certificate (NEC)](https://docs.monad.xyz/monad-arch/consensus/monad-bft#no-endorsement-message-and-no-endorsement-certificate) . 8. **Bob’s fresh proposal**: Under the rules of MonadBFT, Bob may skip re-proposing Alice’s block, and instead make a [fresh proposal](https://docs.monad.xyz/monad-arch/consensus/monad-bft#fresh-proposal) of a new block (at the same block height `N`) if he can also supply a NEC. It’s important to emphasize that Bob is only allowed to skip reproposing Alice’s block if a supermajority of validators sign the NEC. Otherwise, he is obligated to re-propose. This rule helps ensure that Alice’s block finalizes even though Bob failed to build a QC for Alice’s block. From this point, consensus proceeds normally, returning to the happy path. #### [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#no-proposal-case) No proposal case There is a third possibility, which is that Bob fails to propose anything at all in round `K+1`. (This is fairly likely, because he failed to send a block the first time that round `K+1` was expected.) In this case, a timeout occurs again, this time of round `K+1`, allowing consensus to move to round `K+2`, Charlie’s turn. Charlie then inherits the situation Bob was in in round `K+1`, i.e. he must either re-propose Alice’s block, or prove that Alice’s block is unsupported. More generally, if Charlie (and maybe a few subsequent leaders) also fail to propose anything, the situation will persist until someone either re-proposes Alice’s proposal or proves that it is unsupported. That’s the MonadBFT rule about the `high_tip`, and it ensures that Alice’s block will eventually finalize unless it never should have been supported. [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#discussion) Discussion ----------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#no-tail-forking) No-Tail-Forking In prior implementations of pipelined HotStuff-family consensus protocols, the case where Bob misses his slot results in Alice’s proposal also being rolled back (tail forked). The intuition behind this is: Bob is the only person responsible for receiving everyone’s votes on Alice’s proposal, so when he goes offline, all of those votes are blackholed, making it hard to distinguish between the case where most validators voted YES for Alice’s proposal and the case where most validators rejected her proposal. For instance, in [Fast-HotStuff](https://arxiv.org/abs/2010.11454) , TCs carry enough information to prove that Bob missed his slot, allowing Bob to justifiably propose a block that skips Alice’s block, making Alice’s block a casualty. Bob simply re-proposes the same block height as Alice did, replacing Alice’s block in the final blockchain. This is the reason why pipelined HotStuff consensus mechanisms prior to MonadBFT frequently see pairs of missed slots. **Tail forking is a serious weakness.** When Alice’s block is proposed, if Bob sees valuable MEV opportunities in it, Bob—as QC builder (next leader)—may refuse to build the QC for Alice’s block and to propose his own block carrying Alice’s QC. In this case, validators cannot detect whether Alice failed to propagate her proposal or Bob refused to build a QC; therefore Bob is given an opportunity in round K+1 to propose a block. Bob can then extract high-value MEV by selecting only preferred transactions, and by reordering or replacing them at will. In other blockchains, unintentionally allowing blocks to be re-mined has resulted in [massive impact](https://ethresear.ch/t/equivocation-attacks-in-mev-boost-and-epbs/15338) . The key to MonadBFT’s No-Tail-Forking property lies in the handling of the missed slot situation. Intuitively speaking, in MonadBFT, [TCs](https://docs.monad.xyz/monad-arch/consensus/monad-bft#timeout-certificate-tc) carry enough information to propagate the knowledge of the existence of Alice’s block forward even when Bob blackholes all of the votes about it. When it becomes Bob’s turn to propose, he is obliged to re-propose Alice’s block (based on the TC, which includes high\_tip, aka a valid block header for Alice’s block) unless he can get a supermajority (`2f+1`) to attest to _not_ seeing Alice’s block. The fact that a supermajority sign the [NEC](https://docs.monad.xyz/monad-arch/consensus/monad-bft#no-endorsement-message-and-no-endorsement-certificate) is key: even if `f` nodes are Byzantine, that still leaves `f+1` non-Byzantine nodes attesting to _not_ seeing Alice’s block, which guarantees that Alice’s block should _not_ have achieved quorum since quorum requires `2f+1` votes and there were at least `f+1` non-Byzantine NO votes. The [MonadBFT paper](https://arxiv.org/abs/2502.20692) provides a far more robust definition of the protocol, and a formal proof that tail-forking cannot occur. ### [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#speculative-finality) Speculative Finality The other extremely nice property of MonadBFT is one-slot speculative finality. To explain this, it is first helpful to issue a reminder that a block’s state is always from the perspective of a particular observer. For example, if you receive a QC for a block, then you can move that block to the [`Voted`](https://docs.monad.xyz/monad-arch/consensus/block-states#voted) state, but if your friend didn’t receive that QC yet, then she would still consider that block to be in the [`Proposed`](https://docs.monad.xyz/monad-arch/consensus/block-states#proposed) state. The challenge of building a distributed consensus mechanism lies in defining rules that allow nodes to individually update their state machines in response to messages even while assuming the worst, i.e. even while assuming that they might be the only one that received that message. #### [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#after-receiving-alice%E2%80%99s-proposal) After receiving Alice’s Proposal Say that you are Valerie, one of the validators in the network. You receive Alice’s proposal; you run the validity checks on it and they pass, so you mark Alice’s proposal as [`Proposed`](https://docs.monad.xyz/monad-arch/consensus/block-states#proposed) . Note that you don’t know if anyone else has received this proposal, Alice could be being tricky and have only sent the proposal to you (or to a very small number of nodes) in an attempt to get you to diverge from everyone else. #### [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#after-receiving-bob%E2%80%99s-proposal) After receiving Bob’s Proposal Now say you receive Bob’s proposal, which carries a QC for Alice’s proposal. You run validity checks on Bob’s proposal and they pass, so you mark Alice’s proposal as [`Voted`](https://docs.monad.xyz/monad-arch/consensus/block-states#voted) . Again, although you now possess proof that a supermajority voted for Alice’s proposal, you should be worried that Bob might be trying to trick you by only sending this to you. You should be worried that Bob’s proposal doesn’t reach quorum. The superpower of MonadBFT is that, due to the complicated set of rules for handling a timeout described earlier, when you are in Valerie’s position of having received Bob’s proposal, you can mostly overpower that fear, at least as it pertains to the status of Alice’s proposal. You may **speculatively finalize** Alice’s proposal upon moving it to the `Voted` stage. That is, you can be confident that Alice’s proposal will almost certainly end up being finalized, unless a very specific set of rare circumstances arises. Intuitively, this makes sense given what we said above. You, Valerie, possess a QC for Alice’s block, assembled by Bob. That actually means that, from your point of view, Bob was not offline. And **even if** Bob were _effectively offline_ to most people (e.g. he only sent the next proposal and QC-on-Alice’s-block to you), you know that the procedure will be to assemble a TC; that the `high_tip` in that TC will probably point to Alice’s block. Why? Because: 1. the QC in your hands proves that a supermajority (`2f+1`) has seen Alice’s block, 2. the TC will also require a supermajority (`2f+1`) 3. So at least `f+1` voters will be common to both the QC and TC, and at most `f` are Byzantine, so at least 1 will reference Alice’s block. And if Alice’s block makes it into `high_tip`, then Charlie will be forced to re-propose it (unless he could get a NEC on it, which he can’t because that would require No-Endorsement Messages from a supermajority, when a supermajority already signed a QC on Alice’s block). So at first glance it seems like we, Valerie, might be able to finalize Alice’s block as soon as we receive a QC on it. #### [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#the-only-loophole) The only loophole It turns out that there is one loophole which prevents us from being so confident. The loophole arises if _Alice_ **equivocated** — signed a second block `b'` at the same height as the first block `b` (which we have a QC for), and sent `b'` to a few nodes. Under those circumstances, in the event where Bob sent his proposal only to us before going offline, then it is possible that `high_tip` in the resultant TC will resolve to `b'` instead of `b`. If that were to happen, then Charlie could end up either re-proposing `b'`, or collecting an NEC on `b'` and using that to justify proposing a new block at Alice’s block height. In practice, this loophole is extremely rare for several reasons: 1. Equivocation is an easily provable fault - all you need as evidence is both blocks at the same height both signed by Alice. Equivocation is a huge deal in blockchains, and can be severely punished. 2. When Alice equivocates, she is only potentially disrupting herself (while also exposing herself to punishment for equivocation). The [MonadBFT paper](https://arxiv.org/abs/2502.20692) provides a much more rigorous version of this argument. But in summary, locally observing a QC (moving a proposal to `Voted`) is a very strong indicator that the proposal will finalize, since the only way it won’t is if Alice equivocated, Bob missed his slot, almost 1/3 of the network was Byzantine, and we still got quite unlucky with respect to which nodes ended up populating the TC. [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#fast-recovery) Fast Recovery ----------------------------------------------------------------------------------------- Since releasing the original [MonadBFT paper](https://arxiv.org/abs/2502.20692) in early 2025, Category Labs has analyzed the protocol’s behavior and designed, evaluated, and implemented several improvements. The protocol changes allow for fast recovery in the most common failure scenarios. This [blog post](https://www.category.xyz/blogs/monadbft-update-fast-recovery-leader-fault-isolation) gives a great introduction to how fast recovery works. In summary: * Validators now send their votes not only to the leader of the next view, but also to the leader of the current view. This gives each leader a chance to collect votes for its own proposal to form a QC, rather than relying solely on the next leader (who may be Byzantine). The leader broadcasts this QC. * Validators can include the highest QC that they have observed in their timeout message, instead of the tip. They do so if the QC is fresher (more recent) than the locally highest tip or produced in the same round as the tip. * If a validator sends a tip (instead of a high QC) in a timeout message, the validator also includes a tip vote, i.e., a vote for that tip with the current view number. `2f+1` votes for the same proposal in the same view, obtained via regular votes or timeout messages can be combined to form a new QC that can directly be extended by the next leader. * The timeout certificate includes the highest QC of the received timeout messages if it is at least as high as the highest tip. It also contains proof that the correct high tip or high QC was chosen. If the TC contains the high QC, then the leader can directly propose a fresh block extending that high QC. These mechanisms enable faster recovery in the most common failure scenarios. For example, consider a situation where the leader in view `v` is offline. In the original MonadBFT protocol, this would cause views `v-1` and `v` to time out (since the votes cast in `v-1` are lost, and no block is proposed in view `v`). Additionally, the block proposed in view `v-1` would have to be reproposed in view `v+1`, resulting in two consecutive views without a fresh block proposal. With the updated protocol, several mechanisms enable faster recovery. For instance, in the timeout message of view `v`, each validator includes a tip vote for the block proposed in view `v-1`. This allows the leader of view `v+1` to construct a QC in view `v`. Since no two conflicting QCs can be formed in the same view, the leader of `v+1` can directly propose a fresh block extending this QC. As a result, a single crashed leader only causes the leader’s view to time out; all other views succeed, and in each of them, a fresh block is proposed. The other mechanisms similarly provide fast recovery options. We still retain the reproposal and [NEC](https://docs.monad.xyz/monad-arch/consensus/monad-bft#no-endorsement-message-and-no-endorsement-certificate) mechanisms from the original MonadBFT paper to address more complex Byzantine failures. However, with these improvements, we believe most failures can now be handled smoothly via the new fast recovery paths. * * * [​](https://docs.monad.xyz/monad-arch/consensus/monad-bft#references) References ----------------------------------------------------------------------------------- * Mohammad Mussadiq Jalalzai, Kushal Babel. [MonadBFT: Fast, Responsive, Fork-Resistant Streamlined Consensus](https://arxiv.org/pdf/2502.20692) , 2025. * Maofan Yin, Dahlia Malkhi, Michael K. Reiter, Guy Golan Gueta, and Ittai Abraham. [HotStuff: BFT Consensus in the Lens of Blockchain](https://arxiv.org/abs/1803.05069) , 2018. * Mohammad M. Jalalzai, Jianyu Niu, Chen Feng, Fangyu Gai. [Fast-HotStuff: A Fast and Resilient HotStuff Protocol](https://arxiv.org/abs/2010.11454) , 2020. * Rati Gelashvili, Lefteris Kokoris-Kogias, Alberto Sonnino, Alexander Spiegelman, and Zhuolun Xiang. [Jolteon and ditto: Network-adaptive efficient consensus with asynchronous fallback](https://arxiv.org/pdf/2106.10362.pdf) . arXiv preprint arXiv:2106.10362, 2021. * The Diem Team. [DiemBFT v4: State Machine Replication in the Diem Blockchain](https://developers.diem.com/papers/diem-consensus-state-machine-replication-in-the-diem-blockchain/2021-08-17.pdf) , 2021. [Consensus\ \ Previous](https://docs.monad.xyz/monad-arch/consensus) [RaptorCast\ \ Next](https://docs.monad.xyz/monad-arch/consensus/raptorcast) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Recovering a Node - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/node-recovery#content-area) When a node is stopped (e.g. due to an upgrade or network outage), it may miss some blocks and fall out of sync with the network. The pages below describe a few options for recovering and rejoining the tip of the chain. Each option has tradeoffs: * **[soft reset](https://docs.monad.xyz/node-ops/node-recovery/soft-reset) ** is fast but only works if the node tip is close to the network tip. It skips execution of the intervening blocks, so no artifacts (logs, receipts, traces) will be produced locally for those blocks * **[hard reset](https://docs.monad.xyz/node-ops/node-recovery/hard-reset) ** is slow but works even if the node tip is far from the network tip. It skips everything before the snapshot, so no artifacts (logs, receipts, traces) will be produced locally for those blocks. * **[full replay](https://docs.monad.xyz/node-ops/node-recovery/full-replay) ** is more expensive, but it ensures the local archive has no gaps that would have to be served by [S3](https://docs.monad.xyz/node-ops/archive-data/data-waterfall) . Full replay may be desirable for RPC providers. * **[node migration](https://docs.monad.xyz/node-ops/node-recovery/node-migration) ** allows validators to achieve high availability by promoting a synced full node to validator status. This is useful for planned or unplanned maintenance with minimal downtime. Soft Reset ---------- Utilizes statesync to catch up to the tip of the chain, skipping execution of blocks in between. Hard Reset ---------- Restores state from a snapshot before resyncing. Full Replay ----------- Fetches and replays all missing blocks serially so that all transactional artifacts are available. Node Migration -------------- Promotes a synced full node to a validator by migrating configuration files and keys with minimal downtime. [v0.12.3\ \ Previous](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.3) [Soft Reset Instructions\ \ Next](https://docs.monad.xyz/node-ops/node-recovery/soft-reset) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Block States - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/monad-arch/consensus/block-states#content-area) In [MonadBFT](https://docs.monad.xyz/monad-arch/consensus/monad-bft) , a block progresses through [three states](https://docs.monad.xyz/monad-arch/consensus/monad-bft#block-states-due-to-monadbft) . Additionally, due to [asynchronous execution](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution) , block finalization is a separate (earlier) matter from state root verification. As a result of this architecture, each Monad block can be considered to be in one of four states. Note that a block’s state is from the perspective of a particular observer (any other validator or full node). As new messages arrive, they allow that observer to progress the block’s state locally. Although the states are defined locally, they correspond to assurance that the rest of the network will ultimately converge on an outcome consistent with that state. For example, if a node marks a block as `Finalized`, it is because that node has received a message carrying sufficient proof that the rest of the network will ultimately converge on enshrining that block at that block height. [​](https://docs.monad.xyz/monad-arch/consensus/block-states#states) States ------------------------------------------------------------------------------ A Monad block is in one of the four states: 1. `Proposed` 2. `Voted` 3. `Finalized` 4. `Verified` ![](https://mintcdn.com/monadfoundation-40611fb6/5Mt9_Scj9fq4fC68/static/img/monad-arch/consensus/asynchronous-execution/block_states.png?w=2500&fit=max&auto=format&n=5Mt9_Scj9fq4fC68&q=85&s=6a7f0f94a1dc870d57f87556fdecf6c1) Classification of historical blocks based on the latest **proposed** block N. ### [​](https://docs.monad.xyz/monad-arch/consensus/block-states#proposed) Proposed The block has been proposed by a leader but has not been voted upon. Note: if execution is not lagging behind consensus, a node may [speculatively execute](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution#speculative-execution) the proposed block. ### [​](https://docs.monad.xyz/monad-arch/consensus/block-states#voted) Voted We have a [Quorum Certificate (QC)](https://docs.monad.xyz/monad-arch/consensus/monad-bft#quorum-certificate-qc) in hand for the block, indicating that it has been voted affirmatively for by a supermajority of validators. (Typically, this is due to receiving a child block for this block.) In MonadBFT, `Voted` means the block can be [speculatively finalized](https://docs.monad.xyz/monad-arch/consensus/monad-bft#speculative-finality) . ### [​](https://docs.monad.xyz/monad-arch/consensus/block-states#finalized) Finalized We have a QC-squared in hand for the block (that is, we have a [QC](https://docs.monad.xyz/monad-arch/consensus/monad-bft#quorum-certificate-qc) for a block that contains a QC on the original block). This serves as proof that a supermajority of validators have ratified the existence and validity of a QC on the original block. Due to the consensus rules of MonadBFT, this means that the block is finalized. ### [​](https://docs.monad.xyz/monad-arch/consensus/block-states#verified) Verified A block containing the [delayed merkle root](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution#delayed-merkle-root) has been finalized, meaning that the execution outputs of the block has been agreed upon by a supermajority of validator nodes. Concretely, the latest verified block will be the `latest_finalized_block - execution_delay`. [​](https://docs.monad.xyz/monad-arch/consensus/block-states#mapping-to-json-rpc-commitment-levels) Mapping to JSON-RPC commitment levels -------------------------------------------------------------------------------------------------------------------------------------------- Monad uses a different consensus algorithm than Ethereum, but is API compatible with the [JSON-RPC](https://docs.monad.xyz/reference) programming interface defined by the [Geth client](https://geth.ethereum.org/docs/interacting-with-geth/rpc) . Geth communicates consensus information about blocks publicly over JSON-RPC using the tags `"latest"`, `"safe"`, and `"finalized"`. Here is how they map to Monad’s block states: | Geth RPC state | …corresponds to Monad block state | Why? | | --- | --- | --- | | `"latest"` | `Proposed` | Both states refer to the most recently observed block, before consensus finalizes the result | | `"safe"` | `Voted` | In Ethereum’s LMD-GHOST algorithm, “safe” means something like “extremely unlikely to be reverted, but still theoretically possible”; Monad’s voted has a similar meaning | | `"finalized"` | `Finalized` | This has the same meaning on both chains: not revertible without a hard fork | Geth recognizes two other block tags, `"earliest"` and `"pending"`. These are not consensus states. The former is a synonym for the genesis block, and the latter does not make sense given how Monad’s [transaction propagation mechanism](https://docs.monad.xyz/monad-arch/consensus/local-mempool) is different. [​](https://docs.monad.xyz/monad-arch/consensus/block-states#real-time-data-and-block-states) Real-time data and block states -------------------------------------------------------------------------------------------------------------------------------- Monad offers several [sources of real-time blockchain data](https://docs.monad.xyz/monad-arch/realtime-data/data-sources) . To provide the fastest service possible, some data feeds report blockchain data for the latest block your node knows about, as soon as it learns about it. As you can see above, the _latest_ block your node is aware of — the most recent block in the `Proposed` state — may be _speculatively executed_. Thus, you may see data about blocks that do not ultimately become part of the Monad blockchain, although this is very rare. [This page](https://docs.monad.xyz/monad-arch/realtime-data/spec-realtime) gives an in-depth overview of how the block state progression works, in case you want to consume real-time data and wish to understand how speculative execution and real-time data reporting fit together. To see an explicit example of how this relates to a real data feed, see the [WebSocket Guide](https://docs.monad.xyz/reference/websockets) section about [`monadNewHeads`](https://docs.monad.xyz/reference/websockets#monadnewheads-and-monadlogs) , an extension to the [Geth `newHeads` data feed](https://geth.ethereum.org/docs/interacting-with-geth/rpc/pubsub) that includes additional data for tracking each block’s progression through consensus. [Asynchronous Execution\ \ Previous](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution) [Local Mempool\ \ Next](https://docs.monad.xyz/monad-arch/consensus/local-mempool) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Best Practices for Building High Performance Apps - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/developer-essentials/best-practices#content-area) [​](https://docs.monad.xyz/developer-essentials/best-practices#configure-web-hosting-to-keep-costs-under-control) Configure web hosting to keep costs under control ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Vercel and Railway provide convenient serverless platforms for hosting your application, abstracting away the logistics of web hosting relative to using a cloud provider directly. You may end up paying a premium for the convenience, especially at higher volumes. * AWS and other cloud providers offer more flexibility and commodity pricing. * Before choosing any service, check pricing and be aware that many providers offer loss-leader pricing on lower volumes, but then charge higher rates once you hit a certain threshold. * For example, suppose there is a $20 plan that includes 1 TB per month of data transfer, with $0.20 per GB beyond that. Do the math to note that the second TB (and onward) will cost $200. If the next tier up says “contact us”, don’t assume the next tier up will be charging $20 per TB. * If you are building a high-traffic app and you aren’t careful about serving static files more cheaply, it will be easy to exceed the loss-leader tier and pay much more than you expect. * For production deployments on AWS, consider: * Amazon S3 + CloudFront for static file hosting and CDN * AWS Lambda for serverless functions * Amazon ECS or EKS for containerized applications * Amazon RDS for database needs * This setup typically provides granular cost control and scalability for high-traffic applications. [​](https://docs.monad.xyz/developer-essentials/best-practices#use-a-hardcoded-value-instead-of-eth_estimategas-call-if-gas-usage-is-static) Use a hardcoded value instead of `eth_estimateGas` call if gas usage is static ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Many on-chain actions have a fixed gas cost. The simplest example is that a transfer of native tokens always costs 21,000 gas, but there are many others. This makes it unnecessary to call `eth_estimateGas` for each transaction. Use a hardcoded value instead, as suggested [here](https://docs.monad.xyz/developer-essentials/gas-pricing#set-the-gas-limit-explicitly-if-it-is-constant) . Eliminating an `eth_estimateGas` call substantially speeds up the user workflow in the wallet, and avoids a potential bad behavior in some wallets when `eth_estimateGas` reverts (discussed in the linked page). [​](https://docs.monad.xyz/developer-essentials/best-practices#reduce-eth_call-latency-by-submitting-multiple-requests-concurrently) Reduce `eth_call` latency by submitting multiple requests concurrently -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Making multiple `eth_call` requests serially will introduce unnecessary latency due to multiple round trips to an RPC node. You can make many `eth_call`s concurrently, either by condensing them into a single `eth_call` or by submitting a batch of calls. Alternatively, you might find it better to switch to an indexer. ### [​](https://docs.monad.xyz/developer-essentials/best-practices#condensing-multiple-eth_calls-into-one) Condensing multiple `eth_call`s into one * **Multicall:** Multicall is a utility smart contract that allows you to aggregate multiple read requests (`eth_call`) into a single one. This is particularly effective for fetching data points like token balances, allowances, or contract parameters simultaneously. The standard `Multicall3` contract is deployed at [`0xcA11bde05977b3631167028862bE2a173976CA11`](https://monadvision.com/address/0xcA11bde05977b3631167028862bE2a173976CA11) on both Monad Mainnet and Monad Testnet. Many libraries offer helper functions to simplify multicall usage, e.g. [viem](https://viem.sh/docs/contract/multicall.html) . Read more about `Multicall3` [here](https://www.multicall3.com/) . * **Custom Batching Contracts:** For complex read patterns or scenarios not easily handled by the standard multicall contract, you can deploy a custom smart contract that aggregates the required data in a single function, which can then be invoked via a single `eth_call`. Multicall executes calls serially as you can see from the code [**here**](https://monadvision.com/address/0xcA11bde05977b3631167028862bE2a173976CA11?tab=Contract#file-Multicall3.sol) . So while using multicall avoids multiple round trips to an RPC server, it is still inadvisable to put too many expensive calls into one multicall. A batch of calls (explained next) can be executed on the RPC in parallel. ### [​](https://docs.monad.xyz/developer-essentials/best-practices#submitting-a-batch-of-calls) Submitting a batch of calls Most major libraries support batching multiple RPC requests into a single message. For example, `viem` handles `Promise.all()` on an array of promises by submitting them as a single batch: const resultPromises = Array(BATCH_SIZE) .fill(null) .map(async (_, i) => { return await PUBLIC_CLIENT.simulateContract({ address: ..., abi: ..., functionName: ..., args: [...], }) }) const results = await Promise.all(resultPromises) ### [​](https://docs.monad.xyz/developer-essentials/best-practices#use-indexers-for-read-heavy-loads) Use indexers for read-heavy loads If your application frequently queries historical events or derived state, consider using an indexer, as described next. [​](https://docs.monad.xyz/developer-essentials/best-practices#use-an-indexer-instead-of-repeatedly-calling-eth_getlogs-to-listen-for-your-events) Use an indexer instead of repeatedly calling `eth_getLogs` to listen for your events ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Below is a quickstart guide for the most popular data indexing solutions. Please view the [indexer docs](https://docs.monad.xyz/tooling-and-infra/indexers) for more details. ### [​](https://docs.monad.xyz/developer-essentials/best-practices#using-allium) Using Allium See also: [**Allium**](https://docs.monad.xyz/tooling-and-infra/indexers/common-data#allium) You’ll need an Allium account, which you can request [here](https://www.allium.so/contact) . * Allium Explorer * Blockchain analytics platform that provides SQL-based access to historical blockchain data (blocks, transactions, logs, traces, and contracts). * You can create Explorer APIs through the [GUI](https://app.allium.so/explorer/api) to query and analyze historical blockchain data. When creating a Query for an API [here](https://app.allium.so/explorer/queries) (using the `New` button), select `Monad Mainnet` or `Monad Testnet` from the chain list. * Relevant docs: * [Explorer Documentation](https://docs.allium.so/app/overview) * [Explorer API](https://docs.allium.so/api/explorer/overview) * Allium Datastreams * Provides real-time blockchain data streams (including blocks, transactions, logs, traces, contracts, and balance snapshots) through Kafka, Pub/Sub, and Amazon SNS. * [GUI](https://app.allium.so/developer/streams/new) to create new streams for onchain data. When creating a stream, select the relevant `Monad Mainnet` or `Monad Testnet` topics from the `Select topics` dropdown. * Relevant docs: * [Datastreams Documentation](https://docs.allium.so/data-products-real-time/allium-datastreams) * [Getting Started with Google Pub/Sub](https://docs.allium.so/data-products-real-time/allium-datastreams/kafka-pubsub/getting-started-with-google-pub-sub) * Allium Developers * Enables fetching wallet transaction activity and tracking balances (native, ERC20, ERC721, ERC1155). * For the request’s body, use `monad_mainnet` for Monad Mainnet or `monad_testnet` for Monad Testnet as the `chain` parameter. * Relevant docs: * [API Key Setup Guide](https://docs.allium.so/data-products-real-time/allium-developer/wallet-apis-1#getting-started) * [Wallet APIs Documentation](https://docs.allium.so/data-products-real-time/allium-developer/wallet-apis) ### [​](https://docs.monad.xyz/developer-essentials/best-practices#using-envio-hyperindex) Using Envio HyperIndex See also: [**Envio**](https://docs.monad.xyz/tooling-and-infra/indexers/indexing-frameworks#envio) and [**Guide: How to use Envio HyperIndex to build a token transfer notification bot**](https://docs.monad.xyz/guides/indexers/tg-bot-using-envio) * Follow the [quick start](https://docs.envio.dev/docs/HyperIndex/contract-import) to create an indexer. In the `config.yaml` file, use network ID `10143` to select Monad testnet (used in the example below) or network ID `143` for Monad mainnet. * Example configuration * Sample `config.yaml` file config.yaml name: your-indexers-name networks: - id: 10143 # Monad Testnet # Optional custom RPC configuration - only add if default indexing has issues # rpc_config: # url: YOUR_RPC_URL_HERE # Replace with your RPC URL (e.g., from Alchemy) # interval_ceiling: 50 # Maximum number of blocks to fetch in a single request # acceleration_additive: 10 # Speed up factor for block fetching # initial_block_interval: 10 # Initial block fetch interval size start_block: 0 # Replace with the block you want to start indexing from contracts: - name: YourContract # Replace with your contract name address: - 0x0000000000000000000000000000000000000000 # Replace with your contract address # Add more addresses if needed for multiple deployments of the same contract handler: src/EventHandlers.ts events: # Replace with your event signatures # Format: EventName(paramType paramName, paramType2 paramName2, ...) # Example: Transfer(address from, address to, uint256 amount) # Example: OrderCreated(uint40 orderId, address owner, uint96 size, uint32 price, bool isBuy) - event: EventOne(paramType1 paramName1, paramType2 paramName2) # Add more events as needed * Sample `EventHandlers.ts` EventHandlers.ts import { YourContract, YourContract_EventOne, } from "generated"; // Handler for EventOne // Replace parameter types and names based on your event definition YourContract.EventOne.handler(async ({ event, context }) => { // Create a unique ID for this event instance const entity: YourContract_EventOne = { id: `${event.chainId}_${event.block.number}_${event.logIndex}`, // Replace these with your actual event parameters paramName1: event.params.paramName1, paramName2: event.params.paramName2, // Add any additional fields you want to store }; // Store the event in the database context.YourContract_EventOne.set(entity); }) // Add more event handlers as needed * Important: The `rpc_config` section under a network (check `config.yaml` sample) is optional and should only be configured if you experience issues with the default Envio setup. This configuration allows you to: * Use your own RPC endpoint * Configure block fetching parameters for better performance * Relevant docs: * [Overview](https://docs.envio.dev/docs/HyperIndex/overview) ### [​](https://docs.monad.xyz/developer-essentials/best-practices#using-ghostgraph) Using GhostGraph See also: [**Ghost**](https://docs.monad.xyz/tooling-and-infra/indexers/indexing-frameworks#ghost) * Relevant docs: * [Getting Started](https://docs.tryghost.xyz/category/-getting-started) * [Setting up a GhostGraph Indexer on Monad Testnet](https://docs.monad.xyz/guides/indexers/ghost#setting-up-ghostgraph-indexing) ### [​](https://docs.monad.xyz/developer-essentials/best-practices#using-goldsky) Using Goldsky See also: [**Goldsky**](https://docs.monad.xyz/tooling-and-infra/indexers/common-data#goldsky) * Goldsky Subgraphs * To deploy a Goldsky subgraph follow [this guide](https://docs.goldsky.com/subgraphs/deploying-subgraphs#from-source-code) . * As the network identifier, use `monad-mainnet` for Monad Mainnet or `monad-testnet` for Monad Testnet. For subgraph configuration examples, refer to [The Graph Protocol section](https://docs.monad.xyz/developer-essentials/best-practices#using-the-graphs-subgraph) below. * For information about querying Goldsky subgraphs, see the [GraphQL API documentation](https://docs.goldsky.com/subgraphs/graphql-endpoints) . * Goldsky Mirror * Enables direct streaming of on-chain data to your database. * For the chain name in the `dataset_name` field when creating a `source` for a pipeline, use `monad_mainnet` for Monad Mainnet or `monad_testnet` for Monad Testnet (check below example) * Example `pipeline.yaml` config file pipeline.yaml name: monad-testnet-erc20-transfers apiVersion: 3 sources: monad_testnet_erc20_transfers: dataset_name: monad_testnet.erc20_transfers filter: address = '0x0' # Add erc20 contract address. Multiple addresses can be added with 'OR' operator: address = '0x0' OR address = '0x1' version: 1.2.0 type: dataset start_at: earliest # Data transformation logic (optional) transforms: select_relevant_fields: sql: | SELECT id, address, event_signature, event_params, raw_log.block_number as block_number, raw_log.block_hash as block_hash, raw_log.transaction_hash as transaction_hash FROM ethereum_decoded_logs primary_key: id # Sink configuration to specify where data goes eg. DB sinks: postgres: type: postgres table: erc20_transfers schema: goldsky secret_name: A_POSTGRESQL_SECRET from: select_relevant_fields * Relevant docs: * [Getting Started with Mirror](https://docs.goldsky.com/mirror/create-a-pipeline#goldsky-cli) * [Data Streaming Guides](https://docs.goldsky.com/mirror/guides/) ### [​](https://docs.monad.xyz/developer-essentials/best-practices#using-quicknode-streams) Using QuickNode Streams See also: [**QuickNode Streams**](https://docs.monad.xyz/tooling-and-infra/indexers/common-data#quicknode) * On your QuickNode Dashboard, select `Streams` > `Create Stream`. In the create stream UI, select Monad Mainnet or Monad Testnet under Network. Alternatively, you can use the [Streams REST API](https://www.quicknode.com/docs/streams/rest-api/getting-started) to create and manage streams—use `monad-mainnet` for Monad Mainnet or `monad-testnet` for Monad Testnet as the network identifier. * You can consume a Stream by choosing a destination during stream creation. Supported destinations include Webhooks, S3 buckets, and PostgreSQL databases. Learn more [here](https://www.quicknode.com/docs/streams/destinations) . * Relevant docs: * [Getting Started](https://www.quicknode.com/docs/streams/getting-started) ### [​](https://docs.monad.xyz/developer-essentials/best-practices#using-the-graph%E2%80%99s-subgraph) Using The Graph’s Subgraph See also: [**The Graph**](https://docs.monad.xyz/tooling-and-infra/indexers/indexing-frameworks#the-graph) * Network ID: Use `monad-mainnet` for Monad Mainnet or `monad-testnet` for Monad Testnet * Example configuration * Sample `subgraph.yaml` file subgraph.yaml specVersion: 1.2.0 indexerHints: prune: auto schema: file: ./schema.graphql dataSources: - kind: ethereum name: YourContractName # Replace with your contract name network: monad-testnet # Monad testnet configuration source: address: "0x0000000000000000000000000000000000000000" # Replace with your contract address abi: YourContractABI # Replace with your contract ABI name startBlock: 0 # Replace with the block where your contract was deployed/where you want to index from mapping: kind: ethereum/events apiVersion: 0.0.9 language: wasm/assemblyscript entities: # List your entities here - these should match those defined in schema.graphql # - Entity1 # - Entity2 abis: - name: YourContractABI # Should match the ABI name specified above file: ./abis/YourContract.json # Path to your contract ABI JSON file eventHandlers: # Add your event handlers here, for example: # - event: EventName(param1Type, param2Type, ...) # handler: handleEventName file: ./src/mapping.ts # Path to your event handler implementations * Sample `mappings.ts` file mappings.ts import { // Import your contract events here // Format: EventName as EventNameEvent EventOne as EventOneEvent, // Add more events as needed } from "../generated/YourContractName/YourContractABI" // Replace with your contract name, abi name you supplied in subgraph.yaml import { // Import your schema entities here // These should match the entities defined in schema.graphql EventOne, // Add more entities as needed } from "../generated/schema" /** * Handler for EventOne * Update the function parameters and body according to your event structure */ export function handleEventOne(event: EventOneEvent): void { // Create a unique ID for this entity let entity = new EventOne( event.transaction.hash.concatI32(event.logIndex.toI32()) ) // Map event parameters to entity fields // entity.paramName = event.params.paramName // Example: // entity.sender = event.params.sender // entity.amount = event.params.amount // Add metadata fields entity.blockNumber = event.block.number entity.blockTimestamp = event.block.timestamp entity.transactionHash = event.transaction.hash // Save the entity to the store entity.save() } /** * Add more event handlers as needed * Format: * * export function handleEventName(event: EventNameEvent): void { * let entity = new EventName( * event.transaction.hash.concatI32(event.logIndex.toI32()) * ) * * // Map parameters * entity.param1 = event.params.param1 * entity.param2 = event.params.param2 * * // Add metadata * entity.blockNumber = event.block.number * entity.blockTimestamp = event.block.timestamp * entity.transactionHash = event.transaction.hash * * entity.save() * } */ * Sample `schema.graphql` file schema.graphql # Define your entities here # These should match the entities listed in your subgraph.yaml # Example entity for a generic event type EventOne @entity(immutable: true) { id: Bytes! # Add fields that correspond to your event parameters # Examples with common parameter types: # paramId: BigInt! # uint256, uint64, etc. # paramAddress: Bytes! # address # paramFlag: Boolean! # bool # paramAmount: BigInt! # uint96, etc. # paramPrice: BigInt! # uint32, etc. # paramArray: [BigInt!]! # uint[] array # paramString: String! # string # Standard metadata fields blockNumber: BigInt! blockTimestamp: BigInt! transactionHash: Bytes! } # Add more entity types as needed for different events # Example based on Transfer event: # type Transfer @entity(immutable: true) { # id: Bytes! # from: Bytes! # address # to: Bytes! # address # tokenId: BigInt! # uint256 # blockNumber: BigInt! # blockTimestamp: BigInt! # transactionHash: Bytes! # } # Example based on Approval event: # type Approval @entity(immutable: true) { # id: Bytes! # owner: Bytes! # address # approved: Bytes! # address # tokenId: BigInt! # uint256 # blockNumber: BigInt! # blockTimestamp: BigInt! # transactionHash: Bytes! # } * Relevant docs: * [Quickstart](https://thegraph.com/docs/en/subgraphs/quick-start/) ### [​](https://docs.monad.xyz/developer-essentials/best-practices#using-thirdweb%E2%80%99s-insight-api) Using thirdweb’s Insight API See also: [**thirdweb**](https://docs.monad.xyz/tooling-and-infra/indexers/common-data#thirdweb) * REST API offering a wide range of on-chain data, including events, blocks, transactions, token data (such as transfer transactions, balances, and token prices), contract details, and more. * Use chain ID `143` for Monad Mainnet or `10143` for Monad Testnet when constructing request URLs. * Relevant docs: * [Get started](https://insight.thirdweb.com/reference) [​](https://docs.monad.xyz/developer-essentials/best-practices#manage-nonces-locally-if-sending-multiple-transactions-in-quick-succession) Manage nonces locally if sending multiple transactions in quick succession ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ This only applies if you are setting nonces manually. If you are delegating this to the wallet, no need to worry about this. * `eth_getTransactionCount` requires a network request. If you have multiple transactions from the same wallet in short succession, you should implement local nonce tracking. [​](https://docs.monad.xyz/developer-essentials/best-practices#submit-multiple-transactions-concurrently) Submit multiple transactions concurrently ------------------------------------------------------------------------------------------------------------------------------------------------------ If you are submitting a series of transactions, instead submitting sequentially, implement concurrent transaction submission for improved efficiency. Before: for (let i = 0; i < TIMES; i++) { const tx_hash = await WALLET_CLIENT.sendTransaction({ account: ACCOUNT, to: ACCOUNT_1, value: parseEther('0.1'), gasLimit: BigInt(21000), baseFeePerGas: BigInt(50000000000), chain: CHAIN, nonce: nonce + Number(i), }) } After: const transactionsPromises = Array(BATCH_SIZE) .fill(null) .map(async (_, i) => { return await WALLET_CLIENT.sendTransaction({ to: ACCOUNT_1, value: parseEther('0.1'), gasLimit: BigInt(21000), baseFeePerGas: BigInt(50000000000), chain: CHAIN, nonce: nonce + Number(i), }) }) const hashes = await Promise.all(transactionsPromises) [Historical Data\ \ Previous](https://docs.monad.xyz/developer-essentials/historical-data) [Changelog\ \ Next](https://docs.monad.xyz/developer-essentials/changelog) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # EIP-7702 on Monad - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/developer-essentials/eip-7702#content-area) [​](https://docs.monad.xyz/developer-essentials/eip-7702#summary) Summary ---------------------------------------------------------------------------- [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) is supported on Monad with the same workflow as in Ethereum: users sign a message authorizing the delegation to a specific account, which they or someone else can submit using transaction type `0x04`. After that occurs, the EOA becomes “delegated”, i.e. it can be called like a smart contract account with code equal to the account it has delegated to. EIP-7702-delegated accounts behave the same on Monad as on Ethereum in most cases. The two main nuances are: 1. If an EOA is EIP-7702-delegated, transactions that would reduce its balance to below 10 MON will unconditionally revert. * If the balance is below 10 MON but is unchanged or increased by this transaction, the transaction succeeds * If the delegation is removed, dipping below 10 MON is allowed under certain conditions * [Details](https://docs.monad.xyz/developer-essentials/eip-7702#delegated-eoas-cant-dip-below-10-mon) 2. When the EOA is treated like a smart contract, that code cannot call `CREATE` or `CREATE2`. [Details](https://docs.monad.xyz/developer-essentials/eip-7702#delegated-contract-code-cannot-call-createcreate2) [​](https://docs.monad.xyz/developer-essentials/eip-7702#eip-7702-primer) EIP-7702 Primer -------------------------------------------------------------------------------------------- [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) allows Externally Owned Accounts (EOAs) to add code to themselves, granting themselves the ability to add new capabilities previously reserved for smart contract accounts, such as transaction batching, gas sponsorship, and alternative authentication. To do this, the EOA signs an authorization designating a specific address as the source of its code. EIP-7702 introduces a new transaction type (type `0x04`) that submits this authorization. The authorization can be submitted by the EOA themselves, or by anyone else. EIP-7702 enables account abstraction directly on an EOA. It is an extension of EIP-4337, which introduced standards for smart contract wallets with flexible validation logic, but which had to assume a separate UserOp mempool and bundler infrastructure for submitting transactions. In Ethereum’s account-based model, there are two separate roles - “fee payer” (transaction submitter, i.e. who pays for gas to execute a transaction) and “asset owner” (spend authorizer, i.e. who holds keys with the power to spend from a balance). Originally, EOAs played both roles. Under EIP-4337, the roles were split - a smart contract wallet holds title to assets (and has its own logic for validating that spend was authorized), but fees must still be paid by an EOA, hence the roles are definitively split. With EIP-7702, EOAs are allowed to have code, thus allowing the same account to play both roles again. In essence, EIP-7702 makes it possible for today’s EOAs to gain smart wallet-like powers such as multisig, social recovery, session keys, and gas sponsorship **without abandoning their current accounts**, bridging the gap between the old EOA model and the future of full account abstraction. [​](https://docs.monad.xyz/developer-essentials/eip-7702#eip-7702-on-monad) EIP-7702 on Monad ------------------------------------------------------------------------------------------------ EIP-7702-delegated accounts behave the same on Monad as on Ethereum in most cases. The two main nuances are: 1. If an EOA is EIP-7702-delegated, transactions that would reduce its balance to below 10 MON will unconditionally revert. * If the balance is below 10 MON but is unchanged or increased by this transaction, the transaction succeeds * If the delegation is removed, dipping below 10 MON is allowed under certain conditions * [Details](https://docs.monad.xyz/developer-essentials/eip-7702#delegated-eoas-cant-dip-below-10-mon) 2. When the EOA is treated like a smart contract, that code cannot call `CREATE` or `CREATE2`. [Details](https://docs.monad.xyz/developer-essentials/eip-7702#delegated-contract-code-cannot-call-createcreate2) ### [​](https://docs.monad.xyz/developer-essentials/eip-7702#delegated-eoas-can%E2%80%99t-dip-below-10-mon) Delegated EOAs can’t dip below 10 MON In Monad, the [Reserve Balance](https://docs.monad.xyz/developer-essentials/reserve-balance) rules carve out a budget of 10 MON for consensus-time balance checks for inflight transactions from each EOA. (“Inflight” means transactions seen by consensus since the delayed view of state, 3 blocks ago.) Execution protects that budget by reverting if the balance of any EOA would _dip below_ 10 MON by an amount greater than the transaction’s max gas fee. (_“Dip below”_ means _“decrement **and** drop below”_; if an EOA’s MON balance is unchanged, that doesn’t count as dipping.) * An [exception](https://docs.monad.xyz/developer-essentials/reserve-balance#addressing-the-drawback) is made to this execution-time policy for **undelegated** EOAs where a transaction hasn’t been seen from this EOA in several blocks. That exception is what allows undelegated EOAs to submit transactions that would cause their balance to dip below 10 MON by amounts greater than the transaction’s max gas fee. * However, this exception can’t be made for EIP-7702-delegated accounts. Delegation breaks the invariant that an EOA’s balance can only be reduced by transactions signed by that EOA. There is not a reliable way to be sure (at the time of consensus) that another inflight transaction hasn’t spent funds from an EIP-7702-delegated account, therefore the exception made for undelegated accounts doesn’t apply to **delegated** accounts. An delegated account may be emptied by undelegating first. To be clear, EIP-7702-delegated accounts are **not** required to have a 10 MON balance. For example, a delegated EOA _A_ with a balance of 5 MON can still be called by a gas sponsor, and the transaction will succeed as long as _A_ ends with 5 MON or more still. This is discussed further [here](https://docs.monad.xyz/developer-essentials/reserve-balance#eip-7702-delegated-accounts) . ### [​](https://docs.monad.xyz/developer-essentials/eip-7702#delegated-contract-code-cannot-call-create/create2) Delegated contract code cannot call `CREATE/CREATE2` There is another difference: when contract code is executing in the context of an EIP‑7702‑delegated EOA (for example, because a contract `CALL`s that EOA’s address), the `CREATE` and `CREATE2` opcodes are not permitted. Any attempt to execute `CREATE` or `CREATE2` in such a frame causes that call frame to revert, and the caller (if any) observes the call as failed (the `CALL`/`DELEGATECALL`/`CALLCODE` returns 0). This prevents delegated code from changing the EOA’s nonce in ways that would make it difficult to statically validate transactions from that account. In contrast, normal contract‑creation transactions sent from a delegated EOA (transactions with no `to` field, where the transaction `data` is treated as init code) are allowed and behave as on Ethereum. Other than those differences, EIP-7702-delegated accounts behave normally with respect to both ordinary transactions sent by the EOA, and transactions that treat the EOA as a smart contract. [​](https://docs.monad.xyz/developer-essentials/eip-7702#faq) FAQ -------------------------------------------------------------------- What does an EIP-7702 (set code transaction) look like? An EIP-7702 transaction is an [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718) transaction with TransactionType `0x04`.This transaction type is only used to set code; once the code is set for an EOA, subsequent transactions will most likely use the default transaction type (TransactionType `0x02`; [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) ) transactions to interact with the EOA.Here is an example of an EIP-7702 transaction in a block explorer:![explorer_example](https://mintcdn.com/monadfoundation-40611fb6/c3ZcPFY7YVeS_v57/static/img/developer-essentials/eip-7702/1.png?w=2500&fit=max&auto=format&n=c3ZcPFY7YVeS_v57&q=85&s=942b61db784101e428b9800d5f776a91) Is it necessary for the EIP-7702 type transaction to be initiated by the EOA itself? No, the EOA can sign an “authorization tuple” which can then be used by the sponsoring entity to send the transaction. This will allow EOAs to behave like smart contracts without any funds for gas! How can I find out to which address EOA is currently delegating to? On successful delegation to a smart contract, the following code is deployed at the EOA’s address.`0xef0100` (3 bytes) + `smart_contract_address` (20 bytes)Example: If `0xabc...` (EOA) delegates to `0x493...` (smart contract), then code at `0xabc...` (EOA) is `0xef0100493...`Thus, you may determine the delegated address by inspecting the code. What if the EOA is pointing to another EOA which is also pointing to a smart contract? The chain of delegation is not followed; only the immediate code that the first EOA is pointing to is used. How do I clear the delegation on an EOA? Initiate a `0x04` type transaction from the EOA with `0x000...` (dead address) as the new delegated account. Does the delegation expire? No, the delegation remains valid in perpetuity unless another `0x04` transaction is sent changing the delegation to a different (or null) account. Is EIP-7702 compatible with ERC-4337? Yes; after delegating with EIP-7702, any EOA may behave like an EIP-4337 smart account. Simply initiate a transaction of type `0x04` while pointing to an address containing code for the 4337-compatible smart account. What happens if the EOA is pointing to a precompile address for code? If that’s an Ethereum precompile, the `CALL`, `STATICCALL`, `DELEGATECALL`, and `CALLCODE` opcodes, when called with enough gas, proceed with execution as if the EOA has no code.If that’s a Monad precompile, calls revert as if the EOA has code starting with an invalid instruction. Can you give me an example of submitting an EIP-7702 transaction using viem? import { createWalletClient, http, parseEther } from 'viem' import { monadTestnet } from 'viem/chains' import { privateKeyToAccount } from 'viem/accounts' const account = privateKeyToAccount('0x...') const walletClient = createWalletClient({ account, chain: monadTestnet, transport: http(), }) const authorization = await walletClient.signAuthorization({ account, contractAddress: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2' }) const hash = await walletClient.sendTransaction({ authorizationList: [authorization], data: '0xdeadbeef', to: walletClient.account.address, }) [Reserve Balance\ \ Previous](https://docs.monad.xyz/developer-essentials/reserve-balance) [Historical Data\ \ Next](https://docs.monad.xyz/developer-essentials/historical-data) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Gas Pricing - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/developer-essentials/gas-pricing#content-area) [​](https://docs.monad.xyz/developer-essentials/gas-pricing#summary) Summary ------------------------------------------------------------------------------- Monad, like Ethereum, charges for processing transactions based on the complexity of the transaction. Complexity is measured in units of **gas**. This page summarizes how gas is charged, i.e. the conversion between the gas of a transaction and the amount of MON that a user will have to pay. A separate page, [Opcode Pricing](https://docs.monad.xyz/developer-essentials/opcode-pricing) , describes how much each opcode costs in units of gas. | Feature | Detail | | --- | --- | | **Gas charged** | The gas charged for a transaction is the **gas limit**. [Discussion](https://docs.monad.xyz/developer-essentials/gas-pricing#gas-limit-not-gas-used) | | **Price per gas** | EIP-1559-compatible, i.e. price paid per unit of gas is the sum of a system-controlled base fee and a user-specified priority fee. [Discussion](https://docs.monad.xyz/developer-essentials/gas-pricing#eip-1559-compatibility) | | **Base fee** | Base fee (aka `base_price_per_gas`) follows a dynamic controller, similar to the EIP-1559 controller but with slower increases and faster decreases. [Details](https://docs.monad.xyz/developer-essentials/gas-pricing#base_price_per_gas-controller) | | **Minimum base fee** | 100 MON-gwei (`100 * 10^-9 MON`) | | **Block gas limit** | 200M gas | | **Transaction gas limit** | 30M gas | | **Opcode pricing** | See [Opcode Pricing](https://docs.monad.xyz/developer-essentials/opcode-pricing) | | **Transaction ordering** | Default Monad client behavior is to order transactions according to a Priority Gas Auction (descending total gas price). | These changes are covered formally in the [Monad Initial Spec Proposal](https://category-labs.github.io/category-research/monad-initial-spec-proposal.pdf) [​](https://docs.monad.xyz/developer-essentials/gas-pricing#gas-definitions) Gas definitions ----------------------------------------------------------------------------------------------- A common point of confusion among users is the distinction between **gas** of a transaction (units of work) and the **gas price** of a transaction (price in native tokens per unit of work). | Feature | Definition | | --- | --- | | **Gas** | A unit of work. Gas measures the amount of work the network has to do to process something.

Since the network has multiple kinds of resources (network bandwidth, CPU, SSD bandwidth, and state growth), gas is inherently a projection from many dimensions into a single one. | | **Gas price (price\_per\_gas)** | The **price** (in native tokens) paid **to process one unit** of gas. | | **Gas limit** | The maximum **number of units of gas** that a transaction is allowed to consume. | [​](https://docs.monad.xyz/developer-essentials/gas-pricing#gas-limit-not-gas-used) Gas limit, not gas used -------------------------------------------------------------------------------------------------------------- In Monad, the gas charged for a transaction is the gas limit set in the transaction, rather than the gas used in the course of execution. This is a design decision to support asynchronous execution. Under asynchronous execution, leaders build blocks (and validators vote on block validity) prior to executing. If the protocol charged `gas_used`, a user could submit a transaction with a large `gas_limit` that actually consumes very little gas. This transaction would take up a lot of space toward the block gas limit but wouldn’t pay very much for taking up that space, opening up a DOS vector. gas_paid = gas_limit * price_per_gas [​](https://docs.monad.xyz/developer-essentials/gas-pricing#eip-1559-compatibility) EIP-1559 Compatibility ------------------------------------------------------------------------------------------------------------- Monad supports EIP-1559. EIP-1559 (type 2) transactions have the parameters `priority_price_per_gas` and `max_price_per_gas`, which, together with `base_price_per_gas` (a system parameter that changes each block), determine the gas bid for the transaction: price_per_gas = min(base_price_per_gas + priority_price_per_gas, max_price_per_gas) Notes: * `base_price_per_gas` is a system parameter that changes each block. Every transaction in the same block will have the same `base_price_per_gas` * Users specify `priority_price_per_gas` and `max_price_per_gas` when signing a transaction * Since everyone in the same block will pay the same `base_price_per_gas`, the `priority_price_per_gas` is a way for users to pay more to prioritize their transactions. * Since users don’t determine `base_price_per_gas`, the `max_price_per_gas` is a safeguard that limits the amount they may end up paying. Of course, if that value is set too low, the transaction will not end up being chosen for inclusion. [This](https://www.blocknative.com/blog/eip-1559-fees) article provides another good explanation of EIP-1559 gas pricing. [​](https://docs.monad.xyz/developer-essentials/gas-pricing#base_price_per_gas-controller) `base_price_per_gas` controller ----------------------------------------------------------------------------------------------------------------------------- Monad uses a different controller for `base_price_per_gas` than Ethereum: block\_gask\=∑tx∈blockkgas\_limittxbase\_price\_per\_gask+1\=max⁡{min\_base\_price\_per\_gas,base\_price\_per\_gask⋅exp⁡(ηk⋅block\_gask−targetblock\_gas\_limit−target)}ηk\=max\_step\_size⋅ϵϵ+momentk−trendk2trendk+1\=β⋅trendk+(1−β)⋅(target−block\_gask)momentk+1\=β⋅momentk+(1−β)⋅(target−block\_gask)2\\begin{align\*} \\mathrm{block\\\_gas}\_{k} &= \\sum\\limits\_{\\mathrm{tx} \\in \\mathrm{block}\_k}\\mathrm{gas\\\_limit}\_\\mathrm{tx}\\\\ \\mathrm{base\\\_price\\\_per\\\_gas}\_{k+1} &= \\max\\left\\{\\text{min\\\_base\\\_price\\\_per\\\_gas}, \\mathrm{base\\\_price\\\_per\\\_gas}\_k \\cdot \\exp \\left( \\eta\_k \\cdot \\frac{\\mathrm{block\\\_gas}\_{k} - \\text{target}}{\\text{block\\\_gas\\\_limit} - \\text{target}} \\right) \\right\\} \\\\ \\eta\_k &= \\frac{\\text{max\\\_step\\\_size}\\cdot\\epsilon}{\\epsilon+\\sqrt{\\mathrm{moment}\_k - \\mathrm{trend}\_k^2}} \\\\ \\mathrm{trend}\_{k+1} &= \\beta\\cdot \\mathrm{trend}\_k + (1-\\beta)\\cdot \\left(\\text{target}-\\mathrm{block\\\_gas}\_{k} \\right) \\\\ \\mathrm{moment}\_{k+1} &= \\beta\\cdot \\mathrm{moment}\_k + (1-\\beta)\\cdot \\left(\\text{target}-\\mathrm{block\\\_gas}\_{k} \\right)^2 \\end{align\*}block\_gask​base\_price\_per\_gask+1​ηk​trendk+1​momentk+1​​\=tx∈blockk​∑​gas\_limittx​\=max{min\_base\_price\_per\_gas,base\_price\_per\_gask​⋅exp(ηk​⋅block\_gas\_limit−targetblock\_gask​−target​)}\=ϵ+momentk​−trendk2​​max\_step\_size⋅ϵ​\=β⋅trendk​+(1−β)⋅(target−block\_gask​)\=β⋅momentk​+(1−β)⋅(target−block\_gask​)2​ This inductive formula starts with base\_price\_per\_gas0\=0moment0\=0trend0\=0\\begin{align\*} \\mathrm{base\\\_price\\\_per\\\_gas}\_{0} &= 0 \\\\ \\mathrm{moment}\_{0} &= 0 \\\\ \\mathrm{trend}\_{0} &= 0 \\end{align\*}base\_price\_per\_gas0​moment0​trend0​​\=0\=0\=0​ and with the following parameters: max\_step\_size\=1/28target\=160M (80% full) β\=0.96ϵ\=target\=160M\\begin{align\*} \\mathrm{max\\\_step\\\_size} &= 1/28 \\\\ \\mathrm{target} &= 160\\text{M}\\ \\text{(80\\% full)}\\ \\\\ \\beta &= 0.96 \\\\ \\epsilon &= \\mathrm{target} = 160\\text{M} \\end{align\*}max\_step\_sizetargetβϵ​\=1/28\=160M (80% full) \=0.96\=target\=160M​ And min\_base\_price\_per\_gas\=100 MON-gwei (100×10−9 MON)\\text{min\\\_base\\\_price\\\_per\\\_gas} = 100\\ \\text{MON-gwei}\\ (100 \\times 10^{-9}\\ \\text{MON})min\_base\_price\_per\_gas\=100 MON-gwei (100×10−9 MON) Compared to the `base_price_per_gas` controller in Ethereum, this controller increases more slowly and decreases more quickly. This is to avoid underutilization of blockspace due to an overpriced `base_price_per_gas`. For a more comprehensive discussion of Monad controller design considerations and behavior, check out [this](https://www.category.xyz/blogs/redesigning-a-base-fee-for-monad) blog post from Category Labs. [​](https://docs.monad.xyz/developer-essentials/gas-pricing#recommendations-for-developers) Recommendations for developers ----------------------------------------------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/developer-essentials/gas-pricing#set-the-gas-limit-explicitly-if-it-is-constant) Set the gas limit explicitly if it is constant Many on-chain actions have a fixed gas cost. The simplest example is that a transfer of native tokens always costs 21,000 gas, but there are many others. For actions where the gas cost of the transaction is known ahead of time, it is recommended to set it directly prior to handing the transaction off to the wallet. This offers several benefits: * It reduces latency and gives users a better experience, since the wallet doesn’t have to call `eth_estimateGas` and wait for the RPC to respond. * It retains greater control over the user experience, avoiding cases where the wallet sets a high gas limit in a corner case as described in the warning below. Some wallets, including MetaMask, are known to have the following behavior: when `eth_estimateGas` is called and the contract call reverts, they set the gas limit for this transaction to a very high value.This is the wallet’s way of giving up on setting the gas limit and accepting whatever gas usage is at execution time. However, it doesn’t make sense on Monad where the full gas limit is charged.Contract call reversion happens whenever the user is trying to do something impossible. For example, a user might be trying to mint an NFT that has minted out.If the gas limit is known ahead of time, setting it explicitly is best practice, since it ensures the wallet won’t handle this case unexpectedly. [Wallet Developer Integration Guide\ \ Previous](https://docs.monad.xyz/developer-essentials/wallet-developers) [Opcode Pricing\ \ Next](https://docs.monad.xyz/developer-essentials/opcode-pricing) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Full Node Installation - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/full-node-installation#content-area) [​](https://docs.monad.xyz/node-ops/full-node-installation#components) Components ------------------------------------------------------------------------------------ Monad nodes are running services using `systemd`: * `monad-bft` - Consensus client * `monad-execution` - Execution client * `monad-rpc` - RPC server * `monad-mpt` - One-time execution for initializing the TrieDB disk * `monad-cruft` - Cleanup service running hourly * `otelcol` - OTEL collector service for metric collection The systemd services are running using `monad` service user. The configuration and data structure is: * `/home/monad/.env` - contains the environment variables to configure monad services * `/home/monad/monad-bft/config/node.toml` - contains configurable consensus parameters, most notably the name of the node, typically `"-1"` and a list of upstream validators (denoted by secp pubkey and DNS) who have been configured to republish blocks to your full node. * `/home/monad/monad-bft/config/forkpoint/` - contains the [forkpoint](https://docs.monad.xyz/monad-arch/consensus/forkpoint) , a saved snapshot of consensus state used to bootstrap the node on startup * `/home/monad/monad-bft/config/validators/` - contains validator sets generated at the [boundary block](https://docs.monad.xyz/monad-arch/consensus/staking#epochs-and-boundaries) . The newly generated file contains the consensus validator sets for the current epoch and for the upcoming epoch. The most recent validator set is found at `validators.toml`. * `/home/monad/monad-bft/ledger/` - contains consensus (BFT) block headers and bodies, including the transactions * `/dev/triedb` - TrieDB database device, contains the state of the blockchain [​](https://docs.monad.xyz/node-ops/full-node-installation#prerequisites) Prerequisites ------------------------------------------------------------------------------------------ Please refer to the [Hardware Requirements](https://docs.monad.xyz/node-ops/hardware-requirements) before continuing. * Bare-metal server * Ubuntu 24.04+ Operating system * Linux Kernel >= 6.8.0.60 and not 6.8.0.136 (see warnings below) * Disabled HyperThreading (HT) or Simultaneous MultiThreading (SMT) via BIOS settings. These features degrade the Monad node performance. [​](https://docs.monad.xyz/node-ops/full-node-installation#prepare-the-node) Prepare the Node ------------------------------------------------------------------------------------------------ The following instructions assume the commands are executed as `root` user. ### [​](https://docs.monad.xyz/node-ops/full-node-installation#check-linux-kernel) Check Linux kernel Get the current active Linux kernel version: uname -r There is a [known bug](https://bugs.launchpad.net/ubuntu/%2Bsource/linux/%2Bbug/2105471) affecting Linux kernel versions `v6.8.0.56-generic` to `v6.8.0.59-generic` (inclusive) that causes Monad clients to hang in an uninterruptible sleep state, severely impacting node stability. We recommend `v6.8.0.60-generic` or higher. There is a known bug affecting Linux kernel versions `v6.8.0.136-generic` that causes Monad clients to fail to start, with this error on `monad-bft` service:`failed to create buffer ring: Os { code: 22, kind: InvalidInput, message: "Invalid argument" }`We recommend `v6.8.0.134-generic`. Ignore unsupported Linux kernel versions, to prevent auto-upgrade: cat <<'EOF' > /etc/apt/preferences.d/block-kernel-6.8.0-136 Package: linux-image-6.8.0-136-generic linux-headers-6.8.0-136-generic linux-modules-6.8.0-136-generic linux-modules-extra-6.8.0-136-generic Pin: release * Pin-Priority: -1 EOF ### [​](https://docs.monad.xyz/node-ops/full-node-installation#update-the-system) Update the system Update the system. apt update apt upgrade -y Reboot the machine if required, for example if the upgrade prints `Pending kernel upgrade!`. Install additional dependencies. apt install -y curl nvme-cli aria2 jq ### [​](https://docs.monad.xyz/node-ops/full-node-installation#install-monad-package) Install `monad` package Configure the APT repository. cat < /etc/apt/sources.list.d/category-labs.sources Types: deb URIs: https://pkg.category.xyz/ Suites: noble Components: main Signed-By: /etc/apt/keyrings/category-labs.gpg EOF curl -fsSL https://pkg.category.xyz/keys/public-key.asc \ | gpg --dearmor --yes -o /etc/apt/keyrings/category-labs.gpg * Mainnet * Testnet Install `monad` package. Install `monad` package. ### [​](https://docs.monad.xyz/node-ops/full-node-installation#create-monad-user) Create `monad` user Create a non-privileged user named `monad` with a home directory and Bash shell. useradd -m -s /bin/bash monad Create config directories structure in `/home/monad`. mkdir -p /home/monad/monad-bft/config \ /home/monad/monad-bft/ledger \ /home/monad/monad-bft/config/forkpoint \ /home/monad/monad-bft/config/validators ### [​](https://docs.monad.xyz/node-ops/full-node-installation#configure-triedb-device) Configure TrieDB Device #### [​](https://docs.monad.xyz/node-ops/full-node-installation#create-the-device) Create the device Set the NVMe drive (e.g. `/dev/nvme1n1`) to be used for TrieDB device, create a new partition table and a partition that spans the entire drive. The drive should be on a disk that has no filesystem mounted and no RAID configured. **Formatting the wrong drive will destroy your operating system!** Before proceeding, verify which drive to use: nvme list lsblk -o NAME,SIZE,TYPE,MOUNTPOINT,MODEL Look for a drive with **no mountpoints**. Your OS drive will show `/`, `/boot`, or swap partitions. TRIEDB_DRIVE=/dev/nvme1n1 # CHANGE THIS TO YOUR NVME DRIVE parted $TRIEDB_DRIVE mklabel gpt parted $TRIEDB_DRIVE mkpart triedb 0% 100% Create a udev rule to set permissions and create a symlink for the partition. PARTUUID=$(lsblk -o PARTUUID $TRIEDB_DRIVE | tail -n 1) echo "Disk PartUUID: ${PARTUUID}" echo "ENV{ID_PART_ENTRY_UUID}==\"$PARTUUID\", MODE=\"0666\", SYMLINK+=\"triedb\"" \ | tee /etc/udev/rules.d/99-triedb.rules Trigger and reload udev rules, and verify TrieDB is pointing to the NVMe device. udevadm trigger udevadm control --reload udevadm settle ls -l /dev/triedb #### [​](https://docs.monad.xyz/node-ops/full-node-installation#verify-the-lba-configuration) Verify the LBA configuration Verify LBA Configuration, and enable 512 byte LBA if not enabled. Check if 512 byte LBA is enabled on `TRIEDB_DRIVE`: nvme id-ns -H $TRIEDB_DRIVE | grep 'LBA Format' | grep 'in use' This command should return the following expected output: LBA Format 0 : Metadata Size: 0 bytes - Data Size: 512 bytes - Relative Performance: 0 Best (in use) `Data Size` should be set to `512 bytes` and marked as `(in use)`. If that is **not** the case, then you will need to set the `TRIEDB_DRIVE` to use 512 byte LBA with the following command. nvme format --lbaf=0 $TRIEDB_DRIVE Verify that the configuration has been corrected. nvme id-ns -H $TRIEDB_DRIVE | grep 'LBA Format' | grep 'in use' #### [​](https://docs.monad.xyz/node-ops/full-node-installation#format-the-partition) Format the partition Format the TrieDB partition by executing the `monad-mpt` one-time service. systemctl start monad-mpt journalctl -u monad-mpt -n 14 -o cat This should return similar output. MPT database on storages: Capacity Used % Path 1.75 Tb 256.03 Mb 0.01% "/dev/nvme1n1p1" MPT database internal lists: Fast: 1 chunks with capacity 256.00 Mb used 0.00 bytes Slow: 1 chunks with capacity 256.00 Mb used 0.00 bytes Free: 7148 chunks with capacity 1.75 Tb used 0.00 bytes MPT database has 1 history, earliest is 18446744073709551615 latest is 18446744073709551615. It has been configured to retain no more than 33554432. Latest proposed is (18446744073709551615, 0000000000000000000000000000000000000000000000000000000000000000). Latest voted is (18446744073709551615, 0000000000000000000000000000000000000000000000000000000000000000). Latest finalized is 18446744073709551615, latest verified is 18446744073709551615, auto expire version is 0 monad-mpt.service: Deactivated successfully. Finished monad-mpt.service - "Service file for Monad MPT". ### [​](https://docs.monad.xyz/node-ops/full-node-installation#configure-firewall-rules) Configure Firewall rules Configure these firewall rules: * block all incoming traffic and enable all outgoing (default) * allow SSH inbound connections (remote access) * allow inbound and outbound to port 8000 for TCP/UDP (Consensus client P2P traffic) Setup the UFW firewall: ufw allow ssh ufw allow 8000 ufw allow 8001 ufw enable ufw status Configure the following iptables rule for improved robustness against spam: sudo iptables -I INPUT -p udp --dport 8000 -m length --length 0:1400 -j DROP Please note that this rule will be reset upon reboot, so node operators should use their preferred mechanism, e.g. `iptables-persistent` for persisting iptables rules. If using hardware firewalls, you may need to perform additional steps to open up port 8000 to UDP and TCP traffic. To verify outbound connectivity on TCP port 8000, test a connection to remote host: $ nc -vz 64.31.29.190 8000 Connection to 64.31.29.190 8000 port [tcp/*] succeeded! See the `node.toml` file to test with a remote bootstrap peer. ### [​](https://docs.monad.xyz/node-ops/full-node-installation#configure-otel-collector) Configure OTEL Collector The monad package supports OTEL collector. Through this, you will be able to see all the relevant Monad-specific metrics, available at `http://0.0.0.0:8889/metrics`. OTEL_VERSION="0.139.0" OTEL_CHECKSUM="1a1576dde7d51fa7094f4963ceaff37c91ac7b9c9593ba735a3a328ec6f8acd9" OTEL_PACKAGE="https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v${OTEL_VERSION}/otelcol_${OTEL_VERSION}_linux_amd64.deb" OTEL_DEB="/tmp/otelcol_linux_amd64.deb" curl -fsSL "$OTEL_PACKAGE" -o "$OTEL_DEB" if echo "${OTEL_CHECKSUM} ${OTEL_DEB}" | sha256sum --check --quiet; then dpkg -i "$OTEL_DEB" cp /opt/monad/scripts/otel-config.yaml /etc/otelcol/config.yaml systemctl restart otelcol else echo "Checksum verification failed — aborting install." >&2 fi [​](https://docs.monad.xyz/node-ops/full-node-installation#configure-the-node) Configure the Node ---------------------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/node-ops/full-node-installation#get-configuration-files) Get configuration files * Mainnet * Testnet Configuration files for **full nodes**: MF_BUCKET=https://bucket.monadinfra.com curl -o /home/monad/.env $MF_BUCKET/config/mainnet/latest/.env.example curl -o /home/monad/monad-bft/config/node.toml $MF_BUCKET/config/mainnet/latest/full-node-node.toml Configuration files for **validators**: MF_BUCKET=https://bucket.monadinfra.com curl -o /home/monad/.env $MF_BUCKET/config/mainnet/latest/.env.example curl -o /home/monad/monad-bft/config/node.toml $MF_BUCKET/config/mainnet/latest/node.toml Configuration files for **full nodes**: MF_BUCKET=https://bucket.monadinfra.com curl -o /home/monad/.env $MF_BUCKET/config/testnet/latest/.env.example curl -o /home/monad/monad-bft/config/node.toml $MF_BUCKET/config/testnet/latest/full-node-node.toml Configuration files for **validators**: MF_BUCKET=https://bucket.monadinfra.com curl -o /home/monad/.env $MF_BUCKET/config/testnet/latest/.env.example curl -o /home/monad/monad-bft/config/node.toml $MF_BUCKET/config/testnet/latest/node.toml ### [​](https://docs.monad.xyz/node-ops/full-node-installation#define-keystore-password) Define Keystore password Set your own unique and strong password for `KEYSTORE_PASSWORD`. This password is used to encrypt and decrypt your keystores. It must be wrapped in single quotes (e.g. `'password'`). Assuming `KEYSTORE_PASSWORD` in `/home/monad/.env` file is not already set, generate a secure random password. sed -i "s|^KEYSTORE_PASSWORD=$|KEYSTORE_PASSWORD='$(openssl rand -base64 32)'|" /home/monad/.env source /home/monad/.env mkdir -p /opt/monad/backup/ echo "Keystore password: ${KEYSTORE_PASSWORD}" > /opt/monad/backup/keystore-password-backup ### [​](https://docs.monad.xyz/node-ops/full-node-installation#generate-keystores) Generate Keystores Generate encrypted BLS and SECP keys using `monad-keystore` binary. bash <<'EOF' set -e source /home/monad/.env if [[ -z "$KEYSTORE_PASSWORD" || \\ -f /home/monad/monad-bft/config/id-secp || \\ -f /home/monad/monad-bft/config/id-bls ]]; then echo "Skipping: missing KEYSTORE_PASSWORD or keys already exist." exit 1 fi monad-keystore create \ --key-type secp \ --keystore-path /home/monad/monad-bft/config/id-secp \ --password "${KEYSTORE_PASSWORD}" > /opt/monad/backup/secp-backup monad-keystore create \ --key-type bls \ --keystore-path /home/monad/monad-bft/config/id-bls \ --password "${KEYSTORE_PASSWORD}" > /opt/monad/backup/bls-backup grep "public key" /opt/monad/backup/secp-backup /opt/monad/backup/bls-backup \ | tee /home/monad/pubkey-secp-bls echo "Success: New keystores generated" EOF Public keys are exported to `/home/monad/pubkey-secp-bls` for convenience. These files contain your node’s private keys — they define your node identity. Anyone with access to them can take over your node’s identity.**Please ensure that these backup files are stored in an external location outside of the node (e.g. a password manager or secrets vault). They are required to restore your full node or validator identity in the event of hardware failure or system loss:** * `/opt/monad/backup/secp-backup` * `/opt/monad/backup/bls-backup` For validators, this is especially important: losing your keys means you cannot migrate your validator, and re-registering with a new identity requires moving all delegations manually. ### [​](https://docs.monad.xyz/node-ops/full-node-installation#update-node-toml) Update `node.toml` Full nodes can receive block proposals either directly from a validator that whitelists it, or via a raptorcast group. These different configurations are described [here](https://docs.monad.xyz/node-ops/full-node-block-delivery) .The bellow instructions are intended for the **public full node** configuration, where a full node joins the network by connecting to available upstream validators participating in secondary raptorcast. Joining in this configuration is **permissionless**. Update the configuration that was downloaded previously (for reference, you can check the [testnet config](https://bucket.monadinfra.com/config/testnet/latest/full-node-node.toml) and the [mainnet config](https://bucket.monadinfra.com/config/mainnet/latest/full-node-node.toml) ): 1. Edit `/home/monad/monad-bft/config/node.toml` using a text editor (e.g., `nano /home/monad/monad-bft/config/node.toml`). 2. The `beneficiary` field to include the address that should receive block rewards. For **full nodes**, this field can be set to the burn address. beneficiary = "0x0000000000000000000000000000000000000000" For **validator**, use the beneficiary wallet address. This address should be prefixed by `0x`. beneficiary = "0x" 3. Update the `node_name` field to include your provider name. Note that if you are operating multiple nodes, **the node name should be unique**. node_name = "full_-" 4. Ensure `enable_client = true` under `[fullnode_raptorcast]`. 5. Ensure `expand_to_group = true` under `[statesync]`. 6. `[blocksync_override]` peers should remain empty for public full nodes. ### [​](https://docs.monad.xyz/node-ops/full-node-installation#node-signature-record) Node signature record The node Name record is a cryptographically signed record that contains a node’s network address information and is used for peer discovery and network topology management in the monad-bft system. Using the keypairs are created, a fullnode will need to sign its name record using the SECP key in order to participate in peer discovery. The sequence number (seq) in the record allows nodes to determine which version of a peer’s address information is most recent, supporting scenarios where nodes change their network location. * Mainnet * Testnet Generate the node record signature: source /home/monad/.env monad-sign-name-record \ --address $(curl -s4 ifconfig.me):8000 \ --authenticated-udp-port 8001 \ --keystore-path /home/monad/monad-bft/config/id-secp \ --password "${KEYSTORE_PASSWORD}" \ --self-record-seq-num 1 Running the command above prints the fields needed for the next step, for example: self_address = "12.34.56.78:8000" self_record_seq_num = 1 self_name_record_sig = "5995f8dc5af4ca70e3b49ce793e7fe353d72b261c14037272958a9f0cc105fdd4890e56cb99765750ca48bab113cccbb378fc61dff8b23da4a03c07bba60034300" Update the `peer_discovery` section in `node.toml` with the IP addresses, sequence number and name record signature generated from the previous command, for example: [peer_discovery] self_address = "12.34.56.78:8000" self_record_seq_num = 1 self_name_record_sig = "5995f8dc5af4ca70e3b49ce793e7fe353d72b261c14037272958a9f0cc105fdd4890e56cb99765750ca48bab113cccbb378fc61dff8b23da4a03c07bba60034300" Generate the node record signature: source /home/monad/.env monad-sign-name-record \ --ip $(curl -s4 ifconfig.me) \ --tcp-port 8000 \ --udp-port 8000 \ --authenticated-udp-port 8001 \ --keystore-path /home/monad/monad-bft/config/id-secp \ --password "${KEYSTORE_PASSWORD}" \ --self-record-seq-num 1 Running the command above prints the fields needed for the next step, for example: self_ip = "91.203.44.216" self_tcp_port = 8000 self_udp_port = 8000 self_record_seq_num = 1 self_name_record_sig = "5995f8dc5af4ca70e3b49ce793e7fe353d72b261c14037272958a9f0cc105fdd4890e56cb99765750ca48bab113cccbb378fc61dff8b23da4a03c07bba60034300" Update the `peer_discovery` section in `node.toml` with the IP addresses, sequence number and name record signature generated from the previous command, for example. `node.toml` still expects a single `self_address` field: * To build `self_address`, concatenate `self_ip` and `self_tcp_port` as `":"` * `self_udp_port` can be ignored [peer_discovery] self_address = "91.203.44.216:8000" self_record_seq_num = 1 self_name_record_sig = "5995f8dc5af4ca70e3b49ce793e7fe353d72b261c14037272958a9f0cc105fdd4890e56cb99765750ca48bab113cccbb378fc61dff8b23da4a03c07bba60034300" ### [​](https://docs.monad.xyz/node-ops/full-node-installation#remote-configuration-fetching-v0-12-1+) Remote Configuration Fetching (v0.12.1+) Nodes can automatically fetch `forkpoint.toml` and `validators.toml` from remote locations on startup. This feature is configured using the following environment variables in `/home/monad/.env`: * Mainnet * Testnet REMOTE_VALIDATORS_URL='https://bucket.monadinfra.com/validators/mainnet/validators.toml' REMOTE_FORKPOINT_URL='https://bucket.monadinfra.com/forkpoint/mainnet/forkpoint.toml' REMOTE_VALIDATORS_URL='https://bucket.monadinfra.com/validators/testnet/validators.toml' REMOTE_FORKPOINT_URL='https://bucket.monadinfra.com/forkpoint/testnet/forkpoint.toml' These URLs point to the latest configuration files. When defined, the node will automatically attempt to download fresh configuration files on startup, simplifying node operations and reducing manual intervention during network updates. Monad Foundation is not the exclusive provider of these configuration files. Feel free to replace the above remote links with those from other providers. ### [​](https://docs.monad.xyz/node-ops/full-node-installation#call-traces-optional) Call traces (optional) For full nodes intended for archiving or RPC workflows, enabling `--trace_calls` is recommended. This preserves the detailed error information necessary for call traces, e.g. `debug_traceTransaction`. To make this override, please run `systemctl edit monad-execution` and add the `--trace_calls` CLI param to the `ExecStart` definition (may need a line continuation character `\`): systemctl edit monad-execution [Service] Type=simple ExecStart= ExecStart=/usr/local/bin/monad \ ... --trace_calls ... ### [​](https://docs.monad.xyz/node-ops/full-node-installation#monad-cruft-service) Monad Cruft service Installation of the `monad` Debian package enables the `monad-cruft` timer, which runs hourly to clear old artifacts (`/opt/monad/scripts/clear-old-artifacts.sh`). This is necessary to prevent inode exhaustion as artifacts like `forkpoint.toml` and ledger files accumulate. Starting with v0.12.2, you can configure artifact retention times by setting environment variables in `/home/monad/.env`. The following variables control how long artifacts are retained before deletion (all values in minutes): * `RETENTION_LEDGER` - Ledger files (headers and bodies, default: 600 = 10 hours) * `RETENTION_WAL` - WAL files (default: 300 = 5 hours) * `RETENTION_FORKPOINT` - Forkpoint files (default: 300 = 5 hours) * `RETENTION_VALIDATORS` - Validators files (default: 43200 = 30 days) # Example: Add retention configuration to /home/monad/.env RETENTION_LEDGER=600 RETENTION_WAL=300 RETENTION_FORKPOINT=300 RETENTION_VALIDATORS=43200 To customize retention, add or modify these variables in `/home/monad/.env`. For example, to retain ledger files for 20 hours: echo "RETENTION_LEDGER=1200" >> /home/monad/.env These settings will be automatically picked up by the `monad-cruft` timer on its next hourly run. [​](https://docs.monad.xyz/node-ops/full-node-installation#start-the-node) Start the Node -------------------------------------------------------------------------------------------- Set filesystem permissions: chown -R monad:monad /home/monad/ Enable the monad services to allow them to automatically start whenever the server is rebooted: systemctl enable monad-bft monad-execution monad-rpc **Next, run the [Hard Reset Instructions](https://docs.monad.xyz/node-ops/node-recovery/hard-reset) ** to import a recent database snapshot into the node. Start the monad services: systemctl start monad-bft monad-execution monad-rpc **This completes the process of starting up a full node!** Refer to the [General Operations](https://docs.monad.xyz/node-ops/general-operations) to monitor the state of the node. [​](https://docs.monad.xyz/node-ops/full-node-installation#keeping-updated) Keeping Updated ---------------------------------------------------------------------------------------------- To stay updated on new releases: * join the [Monad Node Announcements](https://t.me/MonadNodeAnnouncements) telegram group, or * join the [Monad Developer Discord](https://discord.gg/monaddev) and follow the `#mainnet-fullnode-announcements` channel [Hardware Requirements\ \ Previous](https://docs.monad.xyz/node-ops/hardware-requirements) [Validator Installation\ \ Next](https://docs.monad.xyz/node-ops/validator-installation) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Differences between Monad and Ethereum - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/developer-essentials/differences#content-area) To take into account these differences, there is a custom [Monad Foundry](https://docs.monad.xyz/tooling-and-infra/toolkits/monad-foundry) to ensure that your local development environment matches Monad’s onchain behavior. This list assembles notable behavioral differences between Monad and Ethereum from the perspective of a smart contract developer. [​](https://docs.monad.xyz/developer-essentials/differences#virtual-machine) Virtual Machine ----------------------------------------------------------------------------------------------- 1. The maximum contract code size limit is 128 KB (up from 24 KB in Ethereum). Consequently, the max init code size limit is 256 KB (up from 48 KB in Ethereum). 2. A few opcodes and precompiles are repriced, to reweight relative scarcities of resources due to Monad optimizations. See [Opcode Pricing](https://docs.monad.xyz/developer-essentials/opcode-pricing) . 3. Memory expansion is priced linearly rather than quadratically, and a transaction can use at most 8 MB of memory. See [Memory expansion](https://docs.monad.xyz/developer-essentials/opcode-pricing#memory-expansion) . 4. The `secp256r1` (P256) verification precompile at `0x0100` per [EIP-7951](https://eips.ethereum.org/EIPS/eip-7951) is supported, enabling on-chain verification of WebAuthn/passkey signatures. See [Precompiles](https://docs.monad.xyz/developer-essentials/precompiles#p256-signature-verification) . [​](https://docs.monad.xyz/developer-essentials/differences#transactions) Transactions ----------------------------------------------------------------------------------------- 1. Transactions are charged based on gas limit rather than gas usage, i.e. total gas deducted from the sender’s balance is `value + gas_bid * gas_limit`. As discussed in [Gas in Monad](https://docs.monad.xyz/developer-essentials/gas-pricing) , this is a DoS-prevention measure for asynchronous execution. 2. Consensus and execution utilize the [Reserve Balance](https://docs.monad.xyz/developer-essentials/reserve-balance) mechanism to ensure that all transactions included in consensus can be paid for. This mechanism places light restrictions on transaction inclusion at consensus time, and defines select conditions under which a transaction will revert at execution time. 3. Due to the Reserve Balance mechanism, you may see transactions in the blockchain which ultimately fail due to trying to spend too much MON relative to account balance. These transactions still pay for gas and are valid transactions whose result is execution reversion. This isn’t a protocol difference, as many reverting Ethereum transactions are included in the chain, but it may be different from expectation. [Longer discussion](https://docs.monad.xyz/developer-essentials/reserve-balance#transactions-that-are-included-but-revert) . 4. Transaction type 3 (EIP-4844 aka blob transactions) is not supported. 5. There is no global mempool. For efficiency, transactions are forwarded to the next few leadersas described in [Local Mempool](https://docs.monad.xyz/monad-arch/consensus/local-mempool) . [​](https://docs.monad.xyz/developer-essentials/differences#eip-7702-delegation) EIP-7702 Delegation ------------------------------------------------------------------------------------------------------- 1. If an EOA is EIP-7702-delegated, its balance cannot be lowered below 10 MON due to the [Reserve Balance](https://docs.monad.xyz/developer-essentials/reserve-balance) rules. If the delegation is removed, dipping below 10 MON is allowed. [Discussion](https://docs.monad.xyz/developer-essentials/eip-7702#delegated-eoas-cant-dip-below-10-mon) . 2. If an EOA is EIP-7702-delegated, when it is called as a smart contract, the `CREATE` and `CREATE2` opcodes are banned. [Discussion](https://docs.monad.xyz/developer-essentials/eip-7702#delegated-contract-code-cannot-call-createcreate2) . [​](https://docs.monad.xyz/developer-essentials/differences#historical-data) Historical Data ----------------------------------------------------------------------------------------------- Due to Monad’s high throughput, full nodes do not provide access to arbitrary historic state, as this would require too much storage. See [Historical Data](https://docs.monad.xyz/developer-essentials/historical-data) for a fuller discussion. [​](https://docs.monad.xyz/developer-essentials/differences#rpc) RPC ----------------------------------------------------------------------- See: [RPC Differences](https://docs.monad.xyz/reference/rpc-differences) [Deployment Summary for Developers\ \ Previous](https://docs.monad.xyz/developer-essentials/summary) [Transactions\ \ Next](https://docs.monad.xyz/developer-essentials/transactions) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Changelog - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/developer-essentials/changelog#content-area) See the [Releases](https://docs.monad.xyz/developer-essentials/changelog/releases) page for a list of all notable releases. Some releases only apply to one network. [​](https://docs.monad.xyz/developer-essentials/changelog#how-changes-happen-in-monad) How changes happen in Monad --------------------------------------------------------------------------------------------------------------------- [Revisions](https://docs.monad.xyz/developer-essentials/changelog#revisions) are behavioral changes to the protocol (as contrasted with efficiency improvements to the client, which don’t impact correctness). Revisions are referred to in other blockchains as hard forks. Monad tracks revisions with a counter. The client code typically activates revisions at a future timestamp so that validators can come to agreement about whether to accept the revision and upgrade ahead of time. When the future timestamp is hit, a supermajority of the validators have already upgraded, and they update their behavior in sync, allowing the chain to continue without any pauses. There are multiple networks (owing to the existence of several test networks). Each network has a different schedule for when each Revision is adopted. These schedules are tracked in [ChainConfigs](https://docs.monad.xyz/developer-essentials/changelog#chainconfigs) . The node software is under active development, resulting in occasional [releases](https://docs.monad.xyz/developer-essentials/changelog/releases) . Releases are rolled out to different networks at different schedules, and not all releases apply to all networks. ### [​](https://docs.monad.xyz/developer-essentials/changelog#revisions) Revisions Monad revisions are major behavioral changes to the protocol, as defined in [`revision.h`](https://github.com/category-labs/monad/blob/main/category/vm/evm/monad/revision.h) . | Revision | Notes | | --- | --- | | `MONAD_NINE` | * \[[MIP-3](https://github.com/monad-crypto/MIPs/blob/main/MIPS/MIP-3.md)
\] Linear memory implementation
* \[[MIP-4](https://github.com/monad-crypto/MIPs/blob/main/MIPS/MIP-4.md)
\] Reserve balance precompile
* \[[MIP-5](https://github.com/monad-crypto/MIPs/blob/main/MIPS/MIP-5.md)
\] Activate Osaka fork (CLZ opcode) | | `MONAD_EIGHT` | * [Reserve balance](https://docs.monad.xyz/developer-essentials/reserve-balance)
checks now use final state code hash
* \[Staking\] Reduce pagination on staking precompile inverse mappings (`precompile_get_delegations()` and `precompile_get_delegators()`) from 100 to 50 | | `MONAD_SEVEN` | * [Opcode pricing](https://docs.monad.xyz/developer-essentials/opcode-pricing)
implemented | | `MONAD_SIX` | * EIP-2935 bugfix | | `MONAD_FIVE` | * \[Staking\] Lower `ACTIVE_VALIDATOR_STAKE` from `25,000,000 MON` to `10,000,000 MON` | | `MONAD_FOUR` | * [Staking](https://docs.monad.xyz/monad-arch/consensus/staking)
goes live with the following parameters:
* `ACTIVE_VALIDATOR_STAKE = 25,000,000 MON`
* `MIN_AUTH_ADDRESS_STAKE = 100,000 MON`
* [Reserve balance](https://docs.monad.xyz/developer-essentials/reserve-balance)

* [EIP-7702](https://docs.monad.xyz/developer-essentials/eip-7702)

* [Dynamic base fee](https://docs.monad.xyz/developer-essentials/gas-pricing)

* Min base fee [raised](https://docs.monad.xyz/developer-essentials/gas-pricing)
(50 MON-gwei -> 100 MON-gwei)
* [Per-transaction gas limit](https://docs.monad.xyz/developer-essentials/gas-pricing)
of 30M gas
* Block gas limit (150M -> 200M), i.e. gas per second 375Mgps -> 500Mgps
* Enable [EIP-2935](https://eips.ethereum.org/EIPS/eip-2935)
(extended historical block hashes)
* Enable [EIP-7951](https://eips.ethereum.org/EIPS/eip-7951)
(P256VERIFY precompile)
* Enable [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537)
(BLS12-381 precompiles)
* Raise max contract size for `CREATE`/`CREATE2` to 128 kb | | `MONAD_THREE` | * [MonadBFT](https://docs.monad.xyz/monad-arch/consensus/monad-bft)
implemented
* Block time (500ms -> 400ms), i.e. gas per second 300Mgps -> 375Mgps | | `MONAD_TWO` | * Raise max contract size for plain contract creation transactions (24.5kb -> 128 kb) | | `MONAD_ONE` | * Block time (1s -> 500ms)
* Block gas limit (300M -> 150M); gas per second unchanged at 300Mgps
* Transactions [charged by gas limit](https://docs.monad.xyz/developer-essentials/gas-pricing) | ### [​](https://docs.monad.xyz/developer-essentials/changelog#chainconfigs) ChainConfigs Each ChainConfig describes one network, including its history of upgrading to different Revisions. The ChainConfigs are defined in [`monad-chain-config/src/lib.rs`](https://github.com/category-labs/monad-bft/blob/master/monad-chain-config/src/lib.rs) . | ChainConfig | Notes | | --- | --- | | `mainnet` | Chain id 143 | | `testnet` | Chain id 10143; see [releases](https://docs.monad.xyz/developer-essentials/changelog/releases) | | `devnet` | Chain id 20143 | [Best Practices for Building High Performance Apps\ \ Previous](https://docs.monad.xyz/developer-essentials/best-practices) [Releases\ \ Next](https://docs.monad.xyz/developer-essentials/changelog/releases) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # v0.12.7 - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.7#content-area) Please do not proceed until Monad Foundation provides notice. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.7#instructions-for-node-operators) Instructions for node operators ------------------------------------------------------------------------------------------------------------------------------------ This release does not require any `node.toml` or systemctl override changes. It is a drop-in upgrade from v0.12.6. ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.7#1-ssh-into-the-node-as-root-user) 1\. SSH into the node as `root` user ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.7#2-upgrade-monad-package) 2\. Upgrade monad package sudo apt update && sudo apt install --reinstall monad=0.12.7 -y --allow-downgrades --allow-change-held-packages ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.7#3-restart-the-services-and-verify) 3\. Restart the services and verify sudo systemctl restart monad-bft monad-execution monad-rpc sudo systemctl status monad-bft monad-execution monad-rpc --no-pager -l Expected output: All services should show `Active: active (running)` ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.7#4-verify-the-correct-version-is-running) 4\. Verify the correct version is running monad-rpc --version Expected output: monad-rpc {"commit":"e1e9489b8fc42c0a5af208bab20f6704f83c91c0","tag":"v0.12.7","branch":"","modified":true} [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.7#patch-notes) Patch notes -------------------------------------------------------------------------------------------- Please refer to the public changelog for [`v0.12.7`](https://docs.monad.xyz/developer-essentials/changelog/releases#v0-12-7) . [v0.13.0 (MONAD\_NINE)\ \ Previous](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.13.0) [Authenticated UDP Migration\ \ Next](https://docs.monad.xyz/node-ops/upgrade-instructions/auth-udp) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # v0.14.2 Upgrade Instructions - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.2#content-area) This page contains upgrade instructions for **testnet** and **mainnet**. Always verify which network the instructions apply to. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.2#1-ssh-into-the-node-as-monad-user) 1\. SSH into the node as `monad` user -------------------------------------------------------------------------------------------------------------------------------------------- [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.2#2-upgrade-monad-package) 2\. Upgrade monad package ---------------------------------------------------------------------------------------------------------------------- sudo apt update && sudo apt install --reinstall monad=0.14.2 -y --allow-downgrades --allow-change-held-packages [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.2#3-restart-the-services-and-verify) 3\. Restart the services and verify ------------------------------------------------------------------------------------------------------------------------------------------ sudo systemctl restart monad-bft monad-execution monad-rpc sudo systemctl status monad-bft monad-execution monad-rpc --no-pager -l Expected output: All services should show `Active: active (running)` [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.2#4-verify-the-correct-version-is-running) 4\. Verify the correct version is running ------------------------------------------------------------------------------------------------------------------------------------------------------ monad-rpc --version Expected output: monad-rpc {"commit":"6307011c2acaf1349f2b6dbf488d2bb9e2844d2e","tag":"v0.14.2","branch":"","modified":true} [v0.14.3 Upgrade Instructions\ \ Previous](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.3) [v0.14.1 Upgrade Instructions\ \ Next](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.1) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # v0.14.3 Upgrade Instructions - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.3#content-area) This page contains upgrade instructions for **testnet** and **mainnet**. Always verify which network the instructions apply to. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.3#upgrade-notes) Upgrade notes ------------------------------------------------------------------------------------------------ No breaking changes. Authenticated UDP is now enforced at the code level — nodes that were already running with it (required since v0.14.0) are unaffected. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.3#1-ssh-into-the-node-as-root-user) 1\. SSH into the node as `root` user ------------------------------------------------------------------------------------------------------------------------------------------ [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.3#2-upgrade-monad-package) 2\. Upgrade monad package ---------------------------------------------------------------------------------------------------------------------- sudo apt update && sudo apt install --reinstall monad=0.14.3 -y --allow-downgrades --allow-change-held-packages sudo apt-mark hold monad [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.3#3-restart-the-services-and-verify) 3\. Restart the services and verify ------------------------------------------------------------------------------------------------------------------------------------------ sudo systemctl restart monad-bft monad-execution monad-rpc sudo systemctl status monad-bft monad-execution monad-rpc --no-pager -l Expected output: All services should show `Active: active (running)` [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.3#4-verify-the-correct-version-is-running) 4\. Verify the correct version is running ------------------------------------------------------------------------------------------------------------------------------------------------------ monad-rpc --version Expected output: monad-rpc {"commit":"f2a2092b9ba52c4e1fcd333b93fa382e52e44878","tag":"v0.14.3","branch":"","modified":true} [v0.14.4 Upgrade Instructions\ \ Previous](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.4) [v0.14.2 Upgrade Instructions\ \ Next](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.2) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Authenticated UDP Checking - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/upgrade-instructions/authenticated-udp-checking#content-area) In preparation for the upcoming Clear UDP traffic decommission, this guide helps verify that a Monad node is properly configured for Authenticated UDP. It checks that the node’s configuration and peer settings fully support Auth UDP operation. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/authenticated-udp-checking#steps) Steps --------------------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/authenticated-udp-checking#1-install-yq-tomlq-tool) 1\. Install yq (`tomlq` tool) sudo apt-get update && sudo apt-get install -y yq ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/authenticated-udp-checking#2-verify-the-configuration-validation-script) 2\. Verify the configuration validation script MF_BUCKET=https://bucket.monadinfra.com curl -fsSL $MF_BUCKET/scripts/validate-auth-udp-config.sh ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/authenticated-udp-checking#3-run-the-configuration-validation-script) 3\. Run the configuration validation script MF_BUCKET=https://bucket.monadinfra.com curl -fsSL $MF_BUCKET/scripts/validate-auth-udp-config.sh | bash -s - **Example output:** ====================================== Checking monad client configuration... Node name : my-node Node config file : /home/monad/monad-bft/config/node.toml Peers file : /home/monad/monad-bft/config/peers.toml peer_discovery.self_auth_port = 8001 ✔ bootstrap.peers[1] address=64.31.29.190:8000 auth_port=8001 ✔ bootstrap.peers[2] address=64.31.53.173:8000 auth_port=8001 ✔ bootstrap.peers[3] address=208.115.197.25:8000 auth_port=8001 ✔ bootstrap.peers[4] address=64.130.52.235:8000 auth_port=8001 ✔ bootstrap.peers[5] address=64.130.56.50:8000 auth_port=8001 ✔ bootstrap.peers[6] address=64.130.49.148:8000 auth_port=8001 ✔ bootstrap.peers[7] address=69.162.93.53:8000 auth_port=8001 ✔ bootstrap.peers[8] address=185.189.46.19:8001 auth_port=8001 ✔ Current peers (depends on the network): Auth UDP : 166 Clear UDP : 25 Total : 191 ✔ Configuration is Auth UDP compliant, and ready for Clear UDP decommission. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/authenticated-udp-checking#if-the-configuration-is-not-auth-udp-compliant) If the configuration is not Auth UDP compliant ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Please consider the following steps: 1. Follow the Auth UDP guide: [Authenticated UDP Migration](https://docs.monad.xyz/node-ops/upgrade-instructions/auth-udp) 2. Verify the **bootnode peers configuration** are updated, previous communication: Bootstrap Peers Update (11 Feb 2026) With the recent activation Authenticated UDP traffic, the bootstrap peers needed to be updated on all nodes, in order to join the network. 1. Get the new bootstrap peers signatures (all \[\[bootstrap.peers\]\] items): Mainnet: * Validators: [https://bucket.monadinfra.com/config/mainnet/latest/node.toml](https://bucket.monadinfra.com/config/mainnet/latest/node.toml) * Full node: [https://bucket.monadinfra.com/config/mainnet/latest/full-node-node.toml](https://bucket.monadinfra.com/config/mainnet/latest/full-node-node.toml) Testnet: * Validators: [https://bucket.monadinfra.com/config/testnet/latest/node.toml](https://bucket.monadinfra.com/config/testnet/latest/node.toml) * Full node: [https://bucket.monadinfra.com/config/testnet/latest/full-node-node.toml](https://bucket.monadinfra.com/config/testnet/latest/full-node-node.toml) 2. Make sure to replace existing peering records with the new ones. The configuration should not have duplicated entries for a given secp256k1\_pubkey. 3. Restart the node: systemctl restart monad-bft monad-execution monad-rpc. (No hard reset required) 4. Verify the node can rejoin the network. Note: Be aware that a hard reset wipes the node’s peering cache, since the reset-workspace.sh script deletes the peers.toml file. Any outdated peering setup may cause connection issues. After a hard reset, nodes must rebuild their peer list from scratch using the new bootstrap peering signatures. 3. Ensure the **upstream/downstream connections** (validator <> dedicated/prioritized full node) are using Auth UDP * If the **remote peer already supports Auth UDP**, the script should locate the corresponding record in peers.toml and print the expected configuration. * If the **remote peer is still using Clear UDP**, the script will not find a matching record. In this case, contact the remote peer operator to request Auth UDP activation and the new name record signature. [Authenticated UDP Migration\ \ Previous](https://docs.monad.xyz/node-ops/upgrade-instructions/auth-udp) [v0.12.6\ \ Next](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.6) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # v0.13.1 Upgrade Instructions - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.13.1#content-area) This is a **patch release** specifically for State Archive nodes experiencing RPC block query issues. Regular validator and full nodes on v0.13.0 are not affected and do not need to upgrade. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.13.1#1-ssh-into-the-node-as-monad-user) 1\. SSH into the node as `monad` user -------------------------------------------------------------------------------------------------------------------------------------------- [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.13.1#2-upgrade-monad-package) 2\. Upgrade monad package ---------------------------------------------------------------------------------------------------------------------- sudo apt update && sudo apt install --reinstall monad=0.13.1 -y --allow-downgrades --allow-change-held-packages [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.13.1#3-restart-the-services-and-verify) 3\. Restart the services and verify ------------------------------------------------------------------------------------------------------------------------------------------ sudo systemctl restart monad-rpc sudo systemctl status monad-rpc --no-pager -l Expected output: Service should show `Active: active (running)` [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.13.1#4-verify-the-correct-version-is-running) 4\. Verify the correct version is running ------------------------------------------------------------------------------------------------------------------------------------------------------ monad-rpc --version Expected output: monad-rpc {"commit":"7db6cea2e51e57bc78a8cba0d389ebb8ae73298b","tag":"v0.13.1","branch":"","modified":false} [v0.14.0 Upgrade Instructions\ \ Previous](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.0) [v0.13.0 (MONAD\_NINE)\ \ Next](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.13.0) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # v0.14.0 Upgrade Instructions - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.0#content-area) This page contains upgrade instructions for **testnet** and **mainnet**. Always verify which network the instructions apply to. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.0#upgrade-notes) Upgrade notes ------------------------------------------------------------------------------------------------ **Authenticated UDP configuration is enforced**As of this release, Authenticated UDP is required. Ensure your configuration is compliant using the [Authenticated UDP Checker](https://docs.monad.xyz/node-ops/upgrade-instructions/authenticated-udp-checking) , and follow the documentation if needed. **Raptor redundancy factor limit lowered**The protocol-wide `MAX_REDUNDANCY` cap has been lowered from 7 to 3. If you have customized `raptor10_fullnode_redundancy_factor` in your `node.toml` to be higher than 3, you must lower it before upgrading or the node will fail to start with `BuildError::RedundancyTooHigh`.Most operators use the default value (2) and are unaffected. **`monad-ledger-tail` flags updated**The `--node-config-path` flag has been removed and `--peers-path` has been introduced. Suggested configuration is: - --node-config-path=/home/monad/monad-bft/config/node.toml + --peers-path=/home/monad/monad-bft/config/peers.toml If you run `monad-ledger-tail` manually or in a custom systemd unit, update the configuration before upgrading. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.0#1-ssh-into-the-node-as-monad-user) 1\. SSH into the node as `monad` user -------------------------------------------------------------------------------------------------------------------------------------------- [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.0#2-upgrade-monad-package) 2\. Upgrade monad package ---------------------------------------------------------------------------------------------------------------------- sudo apt update && sudo apt install --reinstall monad=0.14.0 -y --allow-downgrades --allow-change-held-packages [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.0#3-restart-the-services-and-verify) 3\. Restart the services and verify ------------------------------------------------------------------------------------------------------------------------------------------ sudo systemctl restart monad-bft monad-execution monad-rpc sudo systemctl status monad-bft monad-execution monad-rpc --no-pager -l Expected output: All services should show `Active: active (running)` [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.0#4-verify-the-correct-version-is-running) 4\. Verify the correct version is running ------------------------------------------------------------------------------------------------------------------------------------------------------ monad-rpc --version Expected output: monad-rpc {"commit":"2d487de007d7beb70c14cbbdf20ed5c63c36de28","tag":"v0.14.0","branch":"","modified":true} [v0.14.1 Upgrade Instructions\ \ Previous](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.1) [v0.13.1 Upgrade Instructions\ \ Next](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.13.1) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # v0.14.5 Upgrade Instructions - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.5#content-area) This page contains upgrade instructions for **testnet** and **mainnet**. Always verify which network the instructions apply to. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.5#upgrade-notes) Upgrade notes ------------------------------------------------------------------------------------------------ **`eth_sendRawTransactionSync`** now subscribes to block updates from execution events, improving response time by up to 100ms. This method is now only supported with execution events enabled. Operators running RPC with websockets enabled will experience no changes; nodes without execution events will respond with “method not supported” for this endpoint. See the [execution events setup guide](https://docs.monad.xyz/node-ops/events-and-websockets) for configuration details. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.5#1-ssh-into-the-node-as-root-user) 1\. SSH into the node as `root` user ------------------------------------------------------------------------------------------------------------------------------------------ [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.5#2-upgrade-monad-package) 2\. Upgrade monad package ---------------------------------------------------------------------------------------------------------------------- If you encounter issues with the GPG signature (e.g. signatures were invalid), please renew the keys with the command below. curl -fsSL https://pkg.category.xyz/keys/public-key.asc \ | gpg --dearmor --yes -o /etc/apt/keyrings/category-labs.gpg sudo apt update && sudo apt install --reinstall monad=0.14.5 -y --allow-downgrades --allow-change-held-packages sudo apt-mark hold monad The `apt-mark hold monad` command prevents the monad package from being upgraded automatically by `apt-get upgrade`. Without it, unattended system upgrades can install a newer version of monad that has not been approved for your network, causing version mismatch issues. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.5#3-restart-the-services-and-verify) 3\. Restart the services and verify ------------------------------------------------------------------------------------------------------------------------------------------ sudo systemctl restart monad-bft monad-execution monad-rpc sudo systemctl status monad-bft monad-execution monad-rpc --no-pager -l Expected output: All services should show `Active: active (running)` [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.5#4-verify-the-correct-version-is-running) 4\. Verify the correct version is running ------------------------------------------------------------------------------------------------------------------------------------------------------ monad-rpc -V Expected output: monad-rpc {"commit":"25672d619cc35467f621d9fe9e6443d206b6bcd9","tag":"v0.14.5","branch":"","modified":true} [v0.15.0 Upgrade Instructions\ \ Previous](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.0) [v0.14.4 Upgrade Instructions\ \ Next](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.4) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # v0.14.4 Upgrade Instructions - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.4#content-area) This page contains upgrade instructions for **testnet** and **mainnet**. Always verify which network the instructions apply to. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.4#upgrade-notes) Upgrade notes ------------------------------------------------------------------------------------------------ No breaking changes or config requirements for v0.14.4. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.4#1-ssh-into-the-node-as-root-user) 1\. SSH into the node as `root` user ------------------------------------------------------------------------------------------------------------------------------------------ [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.4#2-upgrade-monad-package) 2\. Upgrade monad package ---------------------------------------------------------------------------------------------------------------------- If you encounter issues with the GPG signature (e.g. signatures were invalid), please renew the keys with the command below. curl -fsSL https://pkg.category.xyz/keys/public-key.asc \ | gpg --dearmor --yes -o /etc/apt/keyrings/category-labs.gpg sudo apt update && sudo apt install --reinstall monad=0.14.4 -y --allow-downgrades --allow-change-held-packages sudo apt-mark hold monad The `apt-mark hold monad` command prevents the monad package from being upgraded automatically by `apt-get upgrade`. Without it, unattended system upgrades can install a newer version of monad that has not been approved for your network, causing version mismatch issues. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.4#3-restart-the-services-and-verify) 3\. Restart the services and verify ------------------------------------------------------------------------------------------------------------------------------------------ sudo systemctl restart monad-bft monad-execution monad-rpc sudo systemctl status monad-bft monad-execution monad-rpc --no-pager -l Expected output: All services should show `Active: active (running)` [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.4#4-verify-the-correct-version-is-running) 4\. Verify the correct version is running ------------------------------------------------------------------------------------------------------------------------------------------------------ monad-rpc --version Expected output: monad-rpc {"commit":"06ed5828c45804bc6a0bece00519472152ede07b","tag":"v0.14.4","branch":"","modified":true} [v0.14.5 Upgrade Instructions\ \ Previous](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.5) [v0.14.3 Upgrade Instructions\ \ Next](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.3) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # v0.13.0 (MONAD_NINE) - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.13.0#content-area) [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.13.0#v0-13-0-monad_nine) v0.13.0 (MONAD\_NINE) ============================================================================================================= Please do not proceed until Monad Foundation provides notice. This release activates **MONAD\_NINE** at timestamps (all nodes must upgrade before activation): * `1773153000` - `2026-03-10 14:30GMT` (testnet) * `1773930600` - `2026-03-19 14:30GMT` (mainnet) [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.13.0#instructions-for-node-operators) Instructions for node operators ------------------------------------------------------------------------------------------------------------------------------------ This release does not require any `node.toml` or systemctl override changes. It is a drop-in upgrade from v0.12.7. ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.13.0#1-ssh-into-the-node-as-root-user) 1\. SSH into the node as `root` user ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.13.0#2-upgrade-monad-package) 2\. Upgrade monad package sudo apt update && sudo apt install --reinstall monad=0.13.0 -y --allow-downgrades --allow-change-held-packages ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.13.0#3-restart-the-services-and-verify) 3\. Restart the services and verify sudo systemctl restart monad-bft monad-execution monad-rpc sudo systemctl status monad-bft monad-execution monad-rpc --no-pager -l Expected output: All services should show `Active: active (running)` ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.13.0#4-verify-the-correct-version-is-running) 4\. Verify the correct version is running monad-rpc --version Expected output: monad-rpc {"commit":"0a9cbb8227207a7b33ddf5caf7bd796e855df99f","tag":"v0.13.0","branch":"","modified":true} [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.13.0#patch-notes) Patch notes -------------------------------------------------------------------------------------------- Please refer to the public changelog for [`v0.13.0`](https://docs.monad.xyz/developer-essentials/changelog/releases#v0-13-0-monad_nine) . ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.13.0#key-changes-in-monad_nine) Key changes in MONAD\_NINE * **[MIP-3](https://github.com/monad-crypto/MIPs/blob/main/MIPS/MIP-3.md) **: Linear memory implementation * **[MIP-4](https://github.com/monad-crypto/MIPs/blob/main/MIPS/MIP-4.md) **: Reserve balance precompile * **[MIP-5](https://github.com/monad-crypto/MIPs/blob/main/MIPS/MIP-5.md) **: Osaka fork (CLZ opcode - EIP-7939) [v0.13.1 Upgrade Instructions\ \ Previous](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.13.1) [v0.12.7\ \ Next](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.7) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # v0.14.1 Upgrade Instructions - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.1#content-area) This page contains upgrade instructions for **testnet** and **mainnet**. Always verify which network the instructions apply to. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.1#upgrade-notes) Upgrade notes ------------------------------------------------------------------------------------------------ **Authenticated UDP configuration is enforced**As of this release, Authenticated UDP is required. Ensure your configuration is compliant using the [Authenticated UDP Checker](https://docs.monad.xyz/node-ops/upgrade-instructions/authenticated-udp-checking) , and follow the documentation if needed. **Raptor redundancy factor limit lowered**The protocol-wide `MAX_REDUNDANCY` cap has been lowered from 7 to 3. If you have customized `raptor10_fullnode_redundancy_factor` in your `node.toml` to be higher than 3, you must lower it before upgrading or the node will fail to start with `BuildError::RedundancyTooHigh`.Most operators use the default value (2) and are unaffected. **`monad-ledger-tail` flags updated**The `--node-config-path` flag has been removed and `--peers-path` has been introduced. Suggested configuration is: - --node-config-path=/home/monad/monad-bft/config/node.toml + --peers-path=/home/monad/monad-bft/config/peers.toml If you run `monad-ledger-tail` manually or in a custom systemd unit, update the configuration before upgrading. > Patch release on top of v0.14.0. No breaking changes to `node.toml`. **API behavior change:** `eth_fillTransaction` with insufficient balance now returns `reserve balance violation` instead of `insufficient balance`. Callers that match on the exact error string should update accordingly. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.1#1-ssh-into-the-node-as-monad-user) 1\. SSH into the node as `monad` user -------------------------------------------------------------------------------------------------------------------------------------------- [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.1#2-upgrade-monad-package) 2\. Upgrade monad package ---------------------------------------------------------------------------------------------------------------------- sudo apt update && sudo apt install --reinstall monad=0.14.1 -y --allow-downgrades --allow-change-held-packages [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.1#3-restart-the-services-and-verify) 3\. Restart the services and verify ------------------------------------------------------------------------------------------------------------------------------------------ sudo systemctl restart monad-bft monad-execution monad-rpc sudo systemctl status monad-bft monad-execution monad-rpc --no-pager -l Expected output: All services should show `Active: active (running)` [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.1#4-verify-the-correct-version-is-running) 4\. Verify the correct version is running ------------------------------------------------------------------------------------------------------------------------------------------------------ monad-rpc --version Expected output: monad-rpc {"commit":"4ed79392...","tag":"v0.14.1","branch":"","modified":false} [v0.14.2 Upgrade Instructions\ \ Previous](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.2) [v0.14.0 Upgrade Instructions\ \ Next](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.0) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Opcode Pricing - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/developer-essentials/opcode-pricing#content-area) [​](https://docs.monad.xyz/developer-essentials/opcode-pricing#summary) Summary ---------------------------------------------------------------------------------- Monad is a highly optimized system that introduces efficiencies across all dimensions - compute, state access, and bandwidth utilization. However, the multiplier relative to legacy EVM systems is not equal across all dimensions. As a result, some opcode gas price changes are needed so that applications can unlock the full potential of the chain. To minimize the number of gas price changes, rather than adjusting the gas pricing of almost all opcodes down, Monad instead adjusts a few opcode prices up. This has the same relative effect as discounting almost all opcodes. The following costs are changed: * [Cold access to state](https://docs.monad.xyz/developer-essentials/opcode-pricing#cold-access-cost) * [A few precompiles](https://docs.monad.xyz/developer-essentials/opcode-pricing#precompiles) * [Memory expansion](https://docs.monad.xyz/developer-essentials/opcode-pricing#memory-expansion) All other costs are as on Ethereum; [evm.codes](https://www.evm.codes/) is a helpful reference. These changes are covered formally in the [Monad Initial Spec Proposal](https://category-labs.github.io/category-research/monad-initial-spec-proposal.pdf) [​](https://docs.monad.xyz/developer-essentials/opcode-pricing#why-are-changes-needed) Why are changes needed? ----------------------------------------------------------------------------------------------------------------- The EVM’s current pricing model needs adaptation to support a high-performance, low-fee regime. The pricing model assigns a weight (gas amount) to each opcode based on perceived costliness to the system, then charges the user only based on the calculated sum of weights. As resource scarcity changes - and especially in the event of a completely new system - those weightings must be revised. The changes described in this page make the minimal set of adjustments to allow Monad to deliver high performance and low fees, while minimizing disruption to users and protecting the system against DOS attacks. [​](https://docs.monad.xyz/developer-essentials/opcode-pricing#cold-access-cost) Cold access cost ---------------------------------------------------------------------------------------------------- To account for the relatively higher cost of state reads from disk when compared to computation in the Monad execution client, the cost for “cold” account and storage access costs changes: | Access Type | Ethereum | Monad | | --- | --- | --- | | Account | 2600 | 10100 | | Storage | 2100 | 8100 | The following opcodes are impacted because of the differed gas costs: * Account access: `BALANCE`, `EXTCODESIZE`, `EXTCODECOPY`, `EXTCODEHASH`, `CALL`, `CALLCODE`, `DELEGATECALL`, `STATICCALL`, `SELFDESTRUCT` * Storage access: `SLOAD`, `SSTORE` Gas costs for warm account access (100 gas) and storage access (100 gas) are the same on Monad as on Ethereum. [​](https://docs.monad.xyz/developer-essentials/opcode-pricing#precompiles) Precompiles ------------------------------------------------------------------------------------------ A few [precompiles](https://docs.monad.xyz/developer-essentials/precompiles) have been repriced to accurately reflect their relative costs in execution. | Precompile | Address | Ethereum | Monad | Multiplier | | --- | --- | --- | --- | --- | | `ecRecover` | `0x01` | 3000 | 6000 | 2 | | `ecAdd` | `0x06` | 150\* | 300\* | 2 | | `ecMul` | `0x07` | 6000\* | 30,000\* | 5 | | `ecPairing` | `0x08` | 45,000\* | 225,000\* | 5 | | `blake2f` | `0x09` | rounds∗1\\text{rounds} \* 1rounds∗1 | rounds∗2\\text{rounds} \* 2rounds∗2 | 2 | | `point eval` | `0x0a` | 50,000 | 200,000 | 4 | ∗: Per input/operation, as defined in the respective precompile specification [​](https://docs.monad.xyz/developer-essentials/opcode-pricing#memory-expansion) Memory expansion ---------------------------------------------------------------------------------------------------- Memory expansion is priced linearly, and the memory a transaction can use is capped at 8 MB (8,388,608 bytes). | Item | Ethereum | Monad | | --- | --- | --- | | Expansion cost | 3w+w2/5123w + w^2 / 5123w+w2/512 | w/2w / 2w/2 | | Memory limit | Bounded by the gas limit | 8 MB per transaction | where www is the memory size in 32-byte words. Expanding all the way to the 8 MB cap costs 131,072 gas. Memory is counted cumulatively across call frames: the memory available to a child call is 8 MB minus the memory already used by the current call and its parents. Memory returns to the pool once a call returns. Exceeding the limit halts the call frame exceptionally, consuming all the gas that frame was given and reverting its state changes. From the caller’s perspective this is indistinguishable from an ordinary out-of-gas. These changes are activated in the [`MONAD_NINE`](https://docs.monad.xyz/developer-essentials/changelog/releases#v0-13-0-monad_nine) revision. [Gas Pricing\ \ Previous](https://docs.monad.xyz/developer-essentials/gas-pricing) [Precompiles\ \ Next](https://docs.monad.xyz/developer-essentials/precompiles) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # v0.12.6 - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.6#content-area) Please do not proceed until Monad Foundation provides notice. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.6#instructions-for-node-operators) Instructions for node operators ------------------------------------------------------------------------------------------------------------------------------------ ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.6#1-ssh-into-the-node-as-root-user) 1\. SSH into the node as `root` user ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.6#2-update-configuration-file) 2\. Update configuration file Add the `ping_rate_limit_per_second` parameter to the `[peer_discovery]` section in your configuration file: nano /home/monad/monad-bft/config/node.toml Add the following line to the `[peer_discovery]` section: [peer_discovery] self_address = "YOUR_IP:8000" self_record_seq_num = 0 # This remains the same as your current self_record_seq_num self_name_record_sig = "YOUR_SIGNATURE" refresh_period = 20 request_timeout = 5 unresponsive_prune_threshold = 3 last_participation_prune_threshold = 1000 min_num_peers = 1 max_num_peers = 450 ping_rate_limit_per_second = 100 # This is new to 0.12.6 ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.6#3-check-systemctl-overrides-if-applicable) 3\. Check systemctl overrides (if applicable) This release adds `--persisted-peers-path /home/monad/monad-bft/config/peers.toml` to the `monad-bft` service startup. If you have existing systemctl overrides for `monad-bft`, you must ensure this flag is included in your override configuration. To check if you have overrides: systemctl cat monad-bft | grep -A 10 "override" If you have an existing override, edit it to include the persisted peers path: sudo systemctl edit monad-bft Ensure your override includes: --persisted-peers-path /home/monad/monad-bft/config/peers.toml ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.6#4-upgrade-monad-package) 4\. Upgrade monad package sudo apt update && sudo apt install --reinstall monad=0.12.6 -y --allow-downgrades --allow-change-held-packages ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.6#5-restart-the-services-and-verify) 5\. Restart the services and verify sudo systemctl restart monad-bft monad-execution monad-rpc sudo systemctl status monad-bft monad-execution monad-rpc --no-pager -l Expected output: All services should show `Active: active (running)` ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.6#6-verify-the-correct-version-is-running) 6\. Verify the correct version is running monad-rpc --version Expected output: monad-rpc {"commit":"cced63c687c6ab67846c94bc9fd6d6ae60272cd4","tag":"v0.12.6","branch":"","modified":true} Sidecars need their own CPU cores and **cannot share cores** with monad processes. Monad uses all 16 cores on a standard setup (cores 0-15), so running a sidecar on the same cores will cause performance issues. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.6#patch-notes) Patch notes -------------------------------------------------------------------------------------------- Please refer to the public changelog for [`v0.12.6`](https://docs.monad.xyz/developer-essentials/changelog/releases#v0-12-6) . ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.6#important-updates-for-node-operators) Important updates for node operators * **\[Node ops / Peer Discovery\]** Add ping rate limiting configuration * New **required** parameter: `ping_rate_limit_per_second = 100` in `[peer_discovery]` section * Prevents excessive ping traffic and improves network stability [Authenticated UDP Checking\ \ Previous](https://docs.monad.xyz/node-ops/upgrade-instructions/authenticated-udp-checking) [v0.12.5 - \`testnet\` re-genesis\ \ Next](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.5-testnet-regenesis) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # v0.15.1 Upgrade Instructions - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.1#content-area) These instructions are only applicable to **mainnet**. Testnet operators should remain on v0.15.0 until further notice. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.1#upgrade-notes) Upgrade notes ------------------------------------------------------------------------------------------------ v0.15.1 is a **consensus-only patch** on top of v0.15.0. It sets the mainnet activation round for the vote pace change and block reward update (MIP-12) at **Round 89,758,000** (~Thu Jul 23, 10:30 AM EDT). **All mainnet nodes must be upgraded to v0.15.1 before Round 89,758,000.** Nodes not on v0.15.1 at that round will not recognize the new block reward and will fall out of consensus. **DB migration required (existing nodes only):** If upgrading from v0.14.5 or earlier, a one-time database metadata migration is required before starting services. See [Step 4](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.1#4-run-db-migration-existing-nodes-only) for the exact command. Nodes already running v0.15.0 can skip Step 4. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.1#1-ssh-into-the-node-as-root-user) 1\. SSH into the node as `root` user ------------------------------------------------------------------------------------------------------------------------------------------ [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.1#2-stop-services) 2\. Stop services ------------------------------------------------------------------------------------------------------ sudo systemctl stop monad-bft monad-execution monad-rpc [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.1#3-upgrade-monad-package) 3\. Upgrade monad package ---------------------------------------------------------------------------------------------------------------------- If you encounter issues with the GPG signature (e.g. signatures were invalid), please renew the keys with the command below. curl -fsSL https://pkg.category.xyz/keys/public-key.asc \ | gpg --dearmor --yes -o /etc/apt/keyrings/category-labs.gpg sudo apt update && sudo apt install --reinstall monad=0.15.1 -y --allow-downgrades --allow-change-held-packages sudo apt-mark hold monad The `apt-mark hold monad` command prevents the monad package from being upgraded automatically by `apt-get upgrade`. Without it, unattended system upgrades can install a newer version of monad that has not been approved for your network, causing version mismatch issues. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.1#4-run-db-migration-existing-nodes-only) 4\. Run DB migration (existing nodes only) ------------------------------------------------------------------------------------------------------------------------------------------------------ This step is required for nodes upgrading from v0.14.5 or earlier. Nodes already running v0.15.0 can skip this step.If this step is skipped on an existing database, services will abort on startup with a log message indicating the upgrade is needed — no data corruption occurs. Run the migration and start again. monad-mpt --storage /dev/triedb --upgrade Expected output: the migration completes in under 1 second with no errors. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.1#5-start-services-and-verify) 5\. Start services and verify ------------------------------------------------------------------------------------------------------------------------------ sudo systemctl start monad-bft monad-execution monad-rpc sudo systemctl status monad-bft monad-execution monad-rpc --no-pager -l Expected output: All services should show `Active: active (running)` [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.1#6-verify-the-correct-version-is-running) 6\. Verify the correct version is running ------------------------------------------------------------------------------------------------------------------------------------------------------ monad-rpc -V Expected output: monad-rpc {"commit":"fb3328c2e...","tag":"v0.15.1","branch":"","modified":true} [v0.15.2 Upgrade Instructions\ \ Previous](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.2) [v0.15.0 Upgrade Instructions\ \ Next](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.0) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # v0.12.3 - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.3#content-area) Please do not proceed until Monad Foundation provides notice. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.3#instructions-for-node-operators) Instructions for node operators ------------------------------------------------------------------------------------------------------------------------------------ ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.3#1-ssh-into-the-node-as-monad-user) 1\. SSH into the node as `monad` user ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.3#2-upgrade-monad-package) 2\. Upgrade monad package * Mainnet * Testnet sudo apt update && sudo apt install --reinstall monad=0.12.3 -y --allow-downgrades --allow-change-held-packages sudo apt update && sudo apt install --reinstall monad=0.12.3~rc.2 -y --allow-downgrades --allow-change-held-packages ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.3#3-restart-the-services-and-verify) 3\. Restart the services and verify sudo systemctl restart monad-bft monad-execution monad-rpc sudo systemctl status monad-bft monad-execution monad-rpc --no-pager -l Expected output: All services should show `Active: active (running)` ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.3#4-verify-the-correct-version-is-running) 4\. Verify the correct version is running monad-rpc --version Expected output: * Mainnet * Testnet monad-rpc {"commit":"6323f3fcaf067c18884e3ffe72a22fb1a8d0216a","tag":"v0.12.3","branch":"","modified":true} monad-rpc {"commit":"6323f3fcaf067c18884e3ffe72a22fb1a8d0216a","tag":"","branch":"","modified":true} [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.3#patch-notes) Patch notes -------------------------------------------------------------------------------------------- Please refer to the public changelog for [`v0.12.3`](https://docs.monad.xyz/developer-essentials/changelog/releases#v0-12-3) . ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.3#important-updates-for-node-operators) Important updates for node operators * **\[Node ops\]** Add `--root-offsets-chunk-count` flag to `monad-mpt` to configure the number of chunks allocated for root offsets * Each chunk holds approximately 16.5M blocks. Previously, all nodes were hardcoded to use 2 chunks (max TrieDB capacity of ~33M blocks) * New default: 16 **must be a power of 2** * Note that the default value of 16 translates to approximately 268M blocks ~ 1240 days. In most cases the limiting factor is disk capacity which will auto-compact when filled to 80% * Ref: [monad PR #1937](https://github.com/category-labs/monad/pull/1937) * **\[RPC / Node ops\]** Allow RPC to run without `monad-bft` * Enables standalone RPC operation for improved deployment flexibility * Ref: [monad-bft PR #2613](https://github.com/category-labs/monad-bft/pull/2613) * **\[RPC\]** [EIP-7966](https://eips.ethereum.org/EIPS/eip-7966) (`eth_sendRawTransactionSync`) support * Ref: [monad-bft PR #2542](https://github.com/category-labs/monad-bft/pull/2542) * **\[Node ops / Archive\]** Archive infrastructure improvements * Refactor `monad-block-writer` for improved reliability with `--max-blocks-per-iter` configuration * Async backfill with traces-only archive support * Add `require-traces` archiver flag and indexer fallback source * Support for historical execution event archiving with generic directory archiving * **Potentially breaking: Remove `--start-block` from `monad-archiver` systemd service; operators must use imperative CLI to set start block** * Example: `monad-archiver set-start-block --block 1000000 --archive-sink s3://bucket-name/path` * Use `--async-backfill` flag to set the async-backfill marker instead of primary marker * Ref: [monad-bft PR #2610](https://github.com/category-labs/monad-bft/pull/2610) , [monad-bft PR #2606](https://github.com/category-labs/monad-bft/pull/2606) , [monad-bft PR #2598](https://github.com/category-labs/monad-bft/pull/2598) , [monad-bft PR #2514](https://github.com/category-labs/monad-bft/pull/2514) , [monad-bft PR #2612](https://github.com/category-labs/monad-bft/pull/2612) , [monad-bft PR #2569](https://github.com/category-labs/monad-bft/pull/2569) , [monad-bft PR #2623](https://github.com/category-labs/monad-bft/pull/2623) * **\[Node ops\]** Networking configuration updates * Use default MTU 1500 * Add HDR histogram for broadcast latency tracking in `monad-executor` and `monad-raptorcast` * Ref: [monad-bft PR #2576](https://github.com/category-labs/monad-bft/pull/2576) , [monad-bft PR #2602](https://github.com/category-labs/monad-bft/pull/2602) * **\[Consensus\]** _Opt-in_ Wire authentication protocol for UDP * Node operator instructions to be provided in the future * Includes replay window adjustments for improved reliability * Ref: [monad-bft PR #2417](https://github.com/category-labs/monad-bft/pull/2417) , [monad-bft PR #2544](https://github.com/category-labs/monad-bft/pull/2544) , [monad-bft PR #2626](https://github.com/category-labs/monad-bft/pull/2626) , [monad-bft PR #2091](https://github.com/category-labs/monad-bft/pull/2091) [v0.12.5 - \`testnet\` re-genesis\ \ Previous](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.5-testnet-regenesis) [Recovering a Node\ \ Next](https://docs.monad.xyz/node-ops/node-recovery) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # v0.15.2 Upgrade Instructions - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.2#content-area) This page contains upgrade instructions for **testnet** and **mainnet**. Always verify which network the instructions apply to. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.2#upgrade-notes) Upgrade notes ------------------------------------------------------------------------------------------------ No breaking changes to `node.toml` config for `v0.15.2`. **Page-encoded timeline support**v0.15.2 introduces dual-timeline storage. Every node will eventually activate and populate a secondary page-encoded timeline. This is a one-time procedure requiring approximately 8 minutes offline per node. See [MIP-8 Activation and Page Storage Migration](https://docs.monad.xyz/node-ops/upgrade-instructions/page-storage-mip-8-migration) for details.**PLEASE WAIT FOR OFFICIAL ANNOUNCEMENT BEFORE RUNNING THE PHASE-A MIGRATION** **`eth_call` revert error code changed.** `eth_call` execution revert error code changed from `-32603` to `3`. If your integration checks for `-32603` on reverts, update to expect `3`. **Optional:** If you previously used `--prometheus-addr` or related CLI flags on `monad-bft`, these are now configured in the `[prometheus]` section of `node.toml`. Remove the CLI flag and add: [prometheus] addr = "0.0.0.0:9090" **Note:** If you have a custom `full_node_raptorcast.round_span` value in `node.toml`, verify it is `≤ 960`. Values above this cap are now rejected at startup. **`monad-sign-name-record` flag change.** The `--address ip:port` flag has been replaced with separate `--ip`, `--tcp-port`, and `--udp-port` flags. Update any scripts that call `monad-sign-name-record`. - monad-sign-name-record --address 1.2.3.4:30000 ... + monad-sign-name-record --ip 1.2.3.4 --tcp-port 30000 --udp-port 30000 ... [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.2#1-ssh-into-the-node-as-root-user) 1\. SSH into the node as `root` user ------------------------------------------------------------------------------------------------------------------------------------------ [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.2#2-stop-services) 2\. Stop services ------------------------------------------------------------------------------------------------------ sudo systemctl stop monad-bft monad-execution monad-rpc [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.2#3-upgrade-monad-package) 3\. Upgrade monad package ---------------------------------------------------------------------------------------------------------------------- If you encounter issues with the GPG signature (e.g. signatures were invalid), please renew the keys with the command below. curl -fsSL https://pkg.category.xyz/keys/public-key.asc \ | gpg --dearmor --yes -o /etc/apt/keyrings/category-labs.gpg sudo apt update && sudo apt install --reinstall monad=0.15.2 -y --allow-downgrades --allow-change-held-packages sudo apt-mark hold monad The `apt-mark hold monad` command prevents the monad package from being upgraded automatically by `apt-get upgrade`. Without it, unattended system upgrades can install a newer version of monad that has not been approved for your network, causing version mismatch issues. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.2#4-start-services-and-verify) 4\. Start services and verify ------------------------------------------------------------------------------------------------------------------------------ sudo systemctl start monad-bft monad-execution monad-rpc sudo systemctl status monad-bft monad-execution monad-rpc --no-pager -l All services should show `Active: active (running)`. Confirm the node rejoins and advances blocks. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.2#5-verify-the-correct-version-is-running) 5\. Verify the correct version is running ------------------------------------------------------------------------------------------------------------------------------------------------------ monad-rpc -V Expected output: monad-rpc {"commit":"6373056bfa14318d2a6d7a371cc43c636bf0aab6","tag":"v0.15.2","branch":"","modified":true} [MIP-8 Activation and Page Storage Migration\ \ Previous](https://docs.monad.xyz/node-ops/upgrade-instructions/page-storage-mip-8-migration) [v0.15.1 Upgrade Instructions\ \ Next](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.1) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Developer Essentials - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/developer-essentials#content-area) [​](https://docs.monad.xyz/developer-essentials#quick-reference) Quick Reference ----------------------------------------------------------------------------------- Network Information - Mainnet ----------------------------- Chain config, RPC, block explorers and canonical deployments Tokens and Bridges ------------------ Token addresses and bridge links Deployment Summary ------------------ Everything you need to know when deploying on Monad Tooling & Infra --------------- Third-party infra supporting Monad Testnet RPC Reference ------------- JSON-RPC API Differences between Monad & Ethereum ------------------------------------ [​](https://docs.monad.xyz/developer-essentials#finer-details) Finer Details ------------------------------------------------------------------------------- Transactions ------------ Supported transaction types and format (TLDR: same as Ethereum, except no EIP-4844 transaction type) Wallet Developers ----------------- Guidance and recipes for improving Monad support in EVM wallets Gas Pricing ----------- Why the gas limit is charged + details of the base fee controller Opcode Pricing -------------- Opcode pricing adjustments Precompiles ----------- Supported precompiles, including P256 signature verification and staking Staking ------- Staking behavior + staking precompile reference Reserve Balance --------------- How the reserve balance ensures safety under asynchronous execution EIP-7702 -------- EIP-7702 reference Historical Data --------------- Data retention policy for state and ledger data [​](https://docs.monad.xyz/developer-essentials#best-practices) Best Practices --------------------------------------------------------------------------------- Best Practices -------------- Recommendations for building high-performance apps [​](https://docs.monad.xyz/developer-essentials#monad%E2%80%99s-architecture-in-depth) Monad’s Architecture in Depth ----------------------------------------------------------------------------------------------------------------------- Monad for Devs -------------- One-page summary of Monad architecture Monad Architecture ------------------ [​](https://docs.monad.xyz/developer-essentials#changelog) Changelog ----------------------------------------------------------------------- Changelog --------- Revision list and changelog [​](https://docs.monad.xyz/developer-essentials#testnet) Testnet ------------------------------------------------------------------- Network Information - Testnet ----------------------------- Links and canonical deployments for testnet [​](https://docs.monad.xyz/developer-essentials#get-support) Get Support --------------------------------------------------------------------------- Discord ------- Join other Monad developers on Discord Telegram -------- Join other Monad developers on Telegram [Monad for Developers\ \ Previous](https://docs.monad.xyz/introduction/monad-for-developers) [Network Information - Mainnet\ \ Next](https://docs.monad.xyz/developer-essentials/network-information) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Transactions - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/developer-essentials/transactions#content-area) [​](https://docs.monad.xyz/developer-essentials/transactions#summary) Summary -------------------------------------------------------------------------------- * Same address space and transaction format/fields as Ethereum, so the same wallet software is supported. * Transaction types 0 (“legacy”), 1 (“EIP-2930”), 2 (“EIP-1559”), and 4 (“EIP-7702”) are currently supported. * Pre-[EIP-155](https://eips.ethereum.org/EIPS/eip-155) transactions are allowed on the protocol level, as in Ethereum and many other EVM-compatible blockchains. As a result, users are discouraged from using an Ethereum address that had previously sent pre-EIP-155 transactions. [​](https://docs.monad.xyz/developer-essentials/transactions#address-space) Address space -------------------------------------------------------------------------------------------- Same address space as Ethereum (last 20 bytes of ECDSA public key) [​](https://docs.monad.xyz/developer-essentials/transactions#transaction-format) Transaction format ------------------------------------------------------------------------------------------------------ [Same as Ethereum](https://ethereum.org/en/developers/docs/transactions/) . Monad transactions use the same typed transaction envelope introduced in [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718) , encoded with [RLP](https://ethereum.org/en/developers/docs/data-structures-and-encoding/rlp/) . [​](https://docs.monad.xyz/developer-essentials/transactions#transaction-types) Transaction types ---------------------------------------------------------------------------------------------------- These [transaction types](https://ethereum.org/en/developers/docs/transactions/#typed-transaction-envelope) are supported: * Type 0 (“legacy”) * Type 1 ([“EIP-2930”](https://eips.ethereum.org/EIPS/eip-2930) ) * Type 2 ([“EIP-1559”](https://eips.ethereum.org/EIPS/eip-1559) ; the default in Ethereum) * Type 4 ([“EIP-7702”](https://eips.ethereum.org/EIPS/eip-7702) ) (see [EIP-7702 on Monad](https://docs.monad.xyz/developer-essentials/eip-7702) ) These types are not supported: * Type 3 (“EIP-4844”) [​](https://docs.monad.xyz/developer-essentials/transactions#access-lists) Access lists ------------------------------------------------------------------------------------------ Access lists ([EIP-2930](https://eips.ethereum.org/EIPS/eip-2930) ) are supported but not required. [​](https://docs.monad.xyz/developer-essentials/transactions#transactions-without-a-chain_id) Transactions without a chain\_id --------------------------------------------------------------------------------------------------------------------------------- [EIP-155](https://eips.ethereum.org/EIPS/eip-155) introduced a transaction standard that includes a chain id, to prevent transactions from one blockchain from being replayed on another one. Transactions on Monad should always set the chain id, except for one very specific corner case: **The corner case:** Some standard smart contracts such as ERC-1820 use a keyless deployment method (also known as Nick’s method) that exploits replayability, as discussed [here](https://eips.ethereum.org/EIPS/eip-1820#deployment-method) . In this method, a transaction is submitted on Ethereum but is intended to be replayed on other chains in order to have the contract deployed at the same address on other blockchains. In order to support this use case, pre-EIP-155 transactions are still allowed on the protocol level (i.e. according to consensus rules) on Monad. This makes Monad consistent with most blockchains including Ethereum. (Blockchains that have tried disallowing pre-EIP-155 transactions at the protocol level have typically ended up reversing course, e.g. [Celo](https://github.com/celo-org/celo-blockchain/issues/1734) .) However, because of this, please heed the following warning: Because replay of pre-EIP-155 transactions is allowed, it is discouraged to send funds to an Ethereum address that had previously sent pre-EIP-155 transactions. [Differences between Monad and Ethereum\ \ Previous](https://docs.monad.xyz/developer-essentials/differences) [Wallet Developer Integration Guide\ \ Next](https://docs.monad.xyz/developer-essentials/wallet-developers) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # v0.12.5 - `testnet` re-genesis - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.5-testnet-regenesis#content-area) These instructions are only applicable to **`testnet`**. This can be ignored for `mainnet`. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.5-testnet-regenesis#part-1-to-halt) Part 1: To Halt --------------------------------------------------------------------------------------------------------------------- Node operators must stop all `monad` services before re-genesis. ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.5-testnet-regenesis#1-ssh-into-the-node-as-root-user) 1\. SSH into the node as `root` user ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.5-testnet-regenesis#2-stop-all-monad-services) 2\. Stop all monad services systemctl stop monad-bft monad-execution monad-rpc ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.5-testnet-regenesis#3-verify-services-are-stopped) 3\. Verify services are stopped systemctl status monad-bft monad-execution monad-rpc --no-pager -l Expected output: All services should show `Active: inactive (dead)` * * * [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.5-testnet-regenesis#part-2-re-genesis) Part 2: Re-genesis --------------------------------------------------------------------------------------------------------------------------- **Do not proceed until Monad Foundation provides notice that re-genesis is ready.** ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.5-testnet-regenesis#1-hard-reset) 1\. Hard reset Perform a hard reset to wipe local state and prepare for the new genesis. bash /opt/monad/scripts/reset-workspace.sh ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.5-testnet-regenesis#2-upgrade-monad-package) 2\. Upgrade monad package sudo apt update && sudo apt install --reinstall monad=0.12.5 -y --allow-downgrades --allow-change-held-packages ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.5-testnet-regenesis#3-fetch-configuration-files) 3\. Fetch configuration files If you have automated remote config fetching configured (v0.12.1+), the new `forkpoint.toml` and `validators.toml` files will be automatically fetched on startup.Ensure `REMOTE_VALIDATORS_URL` and `REMOTE_FORKPOINT_URL` are defined in `/home/monad/.env`. See [Soft Reset Instructions](https://docs.monad.xyz/node-ops/node-recovery/soft-reset) for more details on automated configuration fetching.If not using automated fetching, run the commands below. MF_BUCKET=https://bucket.monadinfra.com VALIDATORS_FILE=/home/monad/monad-bft/config/validators/validators.toml curl -sSL $MF_BUCKET/scripts/testnet/download-forkpoint.sh | bash curl $MF_BUCKET/validators/testnet/validators.toml -o $VALIDATORS_FILE chown -R monad:monad /home/monad/monad-bft/config/ ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.5-testnet-regenesis#4-optional-archivers-reset-archive-sources) 4\. (Optional) Archivers: Reset archive sources If you are running an archive node, you must either: 1. **Wipe your existing archiver sources** - Clear all existing archived data to start fresh with the new genesis, or 2. **Point to a new bucket/source** - Configure your archiver to use a new destination for the re-genesis chain Failure to do so may result in conflicting data from the previous chain. ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.5-testnet-regenesis#5-start-services-and-verify) 5\. Start services and verify systemctl start monad-bft monad-execution monad-rpc systemctl status monad-bft monad-execution monad-rpc --no-pager -l Expected output: All services should show `Active: active (running)` ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.5-testnet-regenesis#6-verify-the-correct-version-is-running) 6\. Verify the correct version is running monad-rpc --version Expected output: monad-rpc {"commit":"a1fe1fbef7ff5d51e1eeb42809457cd68f7525dd","tag":"v0.12.5","branch":"","modified":true} All nodes are expected to initially join the network as **public full nodes** before transitioning to validators. Monad Foundation will coordinate validator registration and delegation. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.5-testnet-regenesis#patch-notes) Patch notes -------------------------------------------------------------------------------------------------------------- Please refer to the public changelog for [`v0.12.5`](https://docs.monad.xyz/developer-essentials/changelog/releases#v0-12-5) . [v0.12.6\ \ Previous](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.6) [v0.12.3\ \ Next](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.3) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # v0.15.0 Upgrade Instructions - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.0#content-area) These instructions are only applicable to **testnet**. These can be ignored for **mainnet**. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.0#upgrade-notes) Upgrade notes ------------------------------------------------------------------------------------------------ **Upgrading from v0.14.5 or earlier:** v0.14.6 and v0.14.7 were not deployed to external node operators. For reference, the changes in those releases are listed in the [v0.14.6 release notes](https://github.com/category-labs/monad-bft/releases/tag/v0.14.6) and [v0.14.7 release notes](https://github.com/category-labs/monad/releases/tag/v0.14.7) . The v0.15.0 upgrade instructions below cover the full upgrade from v0.14.5. No breaking changes to `node.toml` config for v0.15.0. **DB migration required (existing nodes only):** v0.15.0 requires a one-time database metadata migration before starting services. See [Step 4](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.0#4-run-db-migration-existing-nodes-only) for the exact command. Newly provisioned nodes (fresh DB) can skip Step 4. Always run the migration using the v0.15.0 `monad-mpt` binary — install it first in Step 3. **Compressed RPC requests no longer accepted:** If your integration sends compressed request bodies (e.g. `Content-Encoding: gzip`), switch to uncompressed requests before upgrading. v0.15.0 removes decompression support — compressed requests will be rejected after upgrading. **Note:** The v0.15.0 `monad-mpt` binary includes fixes for two migration edge cases present in earlier builds: * Nodes with databases created before `num_cnv_chunks` was tracked would crash during migration with `Assertion 'r != MAP_FAILED'` — fixed. ([monad PR #2353](https://github.com/category-labs/monad/pull/2353) ) * Nodes with ≥15.8 TB disk could have data silently corrupted during migration — fixed. ([monad PR #2387](https://github.com/category-labs/monad/pull/2387) ) [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.0#1-ssh-into-the-node-as-root-user) 1\. SSH into the node as `root` user ------------------------------------------------------------------------------------------------------------------------------------------ [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.0#2-stop-services) 2\. Stop services ------------------------------------------------------------------------------------------------------ sudo systemctl stop monad-bft monad-execution monad-rpc [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.0#3-upgrade-monad-package) 3\. Upgrade monad package ---------------------------------------------------------------------------------------------------------------------- If you encounter issues with the GPG signature (e.g. signatures were invalid), please renew the keys with the command below. curl -fsSL https://pkg.category.xyz/keys/public-key.asc \ | gpg --dearmor --yes -o /etc/apt/keyrings/category-labs.gpg sudo apt update && sudo apt install --reinstall monad=0.15.0 -y --allow-downgrades --allow-change-held-packages sudo apt-mark hold monad The `apt-mark hold monad` command prevents the monad package from being upgraded automatically by `apt-get upgrade`. Without it, unattended system upgrades can install a newer version of monad that has not been approved for your network, causing version mismatch issues. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.0#4-run-db-migration-existing-nodes-only) 4\. Run DB migration (existing nodes only) ------------------------------------------------------------------------------------------------------------------------------------------------------ This step is required for any node with an existing database. Newly provisioned nodes (fresh DB) can skip this step.If this step is skipped on an existing database, services will abort on startup with a log message indicating the upgrade is needed — no data corruption occurs. Run the migration and start again. monad-mpt --storage /dev/triedb --upgrade Expected output: the migration completes in under 1 second with no errors. **Note:** If you use `monad-status` to check node health, ensure you have the latest version — the `monad-mpt` status output format changed in v0.15.0 and `monad-status` has been updated to support it. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.0#5-start-services-and-verify) 5\. Start services and verify ------------------------------------------------------------------------------------------------------------------------------ sudo systemctl start monad-bft monad-execution monad-rpc sudo systemctl status monad-bft monad-execution monad-rpc --no-pager -l Expected output: All services should show `Active: active (running)` [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.0#6-verify-the-correct-version-is-running) 6\. Verify the correct version is running ------------------------------------------------------------------------------------------------------------------------------------------------------ monad-rpc -V Expected output: monad-rpc {"commit":"8facc4faef28d390b8100e297e1d26022ea561e2","tag":"v0.15.0","branch":"","modified":true} * * * [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.0#notice-for-operators-using-monad-status-optional) Notice for operators using `monad-status` (Optional) -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- For operators using `monad-status`, please download [the new version as per these instructions](https://docs.monad.xyz/node-ops/general-operations#node-status-with-monad-status) . The new version of the script is compatible with monad `0.15.0`, and backward compatible with previous versions of the monad client. * * * [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.0#notice-for-rpc-providers-optional--enable-eth_simulatev1) Notice for RPC providers (Optional): Enable `eth_simulateV1` ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ `eth_simulateV1` is **disabled by default** in v0.15.0. Operators who want to expose this method can enable it by adding `--enable-eth-simulate-v1` to the `monad-rpc` service. ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.0#how-to-enable) How to enable **Step 1:** Find your current `monad-rpc` systemd override file: systemctl cat monad-rpc The output will show one or more files. Look for the drop-in file under `/etc/systemd/system/monad-rpc.service.d/` — this is the file you need to edit. **Step 2:** Open the drop-in file and append `--enable-eth-simulate-v1` to the end of the `ExecStart` line: sudo nano /etc/systemd/system/monad-rpc.service.d/.conf The `ExecStart` line should look like this after editing: ExecStart=/usr/local/bin/monad-rpc --enable-eth-simulate-v1 **Step 3:** Reload and restart `monad-rpc`: sudo systemctl daemon-reload sudo systemctl restart monad-rpc sudo systemctl status monad-rpc --no-pager -l ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.0#verify) Verify curl -s -X POST http://localhost:8080 \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","method":"eth_simulateV1","params":[{"blockStateCalls":[]},"latest"],"id":1}' If enabled, you will receive an execution response (not `"Method not supported"`). [v0.15.1 Upgrade Instructions\ \ Previous](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.1) [v0.14.5 Upgrade Instructions\ \ Next](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.14.5) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Official Links - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/official-links#content-area) ### [​](https://docs.monad.xyz/official-links#mainnet-network) Mainnet Network | What | Where | | --- | --- | | Block Explorer (MonadVision) | | | Block Explorer (Monadscan) | | | Network Visualization | | | App Hub | | ### [​](https://docs.monad.xyz/official-links#announcements-and-socials) Announcements and Socials | What | Where | | --- | --- | | Website | | | Blog | | | X | | | Monad Ecosytem on X | | | The Pipeline on X | | | Announcement Telegram | | | Youtube | | | Newsletter | | | Community Discord | | | r/Monad Subreddit | | ### [​](https://docs.monad.xyz/official-links#developer-community) Developer Community | What | Where | | --- | --- | | `monad-developers` Github | | | DevNads on X | | | Developer Discord | | | Research Forum | | | Developer Portal | | | Dev Announcements Telegram | | | DeltaV Founder Community | | ### [​](https://docs.monad.xyz/official-links#validator-community) Validator Community | What | Where | | --- | --- | | Monad Node Announcements | | ### [​](https://docs.monad.xyz/official-links#tech) Tech | What | Where | | --- | --- | | Consensus Client Github | | | Execution Client Github | | | Monad Improvement Proposals (MIPs) | | ### [​](https://docs.monad.xyz/official-links#opportunities) Opportunities | What | Where | | --- | --- | | Monad Foundation Jobs | | | Monad Ecosystem Jobs | | ### [​](https://docs.monad.xyz/official-links#testnet) Testnet | What | Where | | --- | --- | | Block Explorer (MonadVision) | | | Testnet Faucet | | [Frequently Asked Questions\ \ Previous](https://docs.monad.xyz/faq) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Why Blockchain? - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/introduction/why-blockchain#content-area) A blockchain is decentralized agreement among a diverse set of participants about two things: 1. An official **ordering** (ledger) of transactions 2. An official **state of the world**, including balances of accounts and the state of various programs. In modern blockchains such as Ethereum, transactions consist of balance transfers, creation of new programs, and function calls against existing programs. The aggregate result of all transactions up to now produces the current state, which is why _agreement about (1) above implies agreement about (2)._ A blockchain system has a set of protocol rules, also known as a consensus mechanism, which describe how a distributed set of nodes which are currently in sync will communicate with each other to agree upon additional transactions to add to the ledger. ([MonadBFT](https://docs.monad.xyz/monad-arch/consensus/monad-bft) is an example of a consensus mechanism.) Induction keeps the nodes in sync: they start with the same state and apply the same transactions, so at the end of applying a new list of transactions, they still have consistent state. Shared global state enables the development of decentralized apps - apps that live “on the blockchain”, i.e. on each of the nodes in the blockchain system. A decentralized app is a chunk of code (as well as persistent, app-specific state) that can get invoked by any user, who does so by submitting a transaction pointing to a function on that app. Each of the nodes in the blockchain is responsible for correctly executing the bytecode being called; duplication keeps each node honest. [​](https://docs.monad.xyz/introduction/why-blockchain#an-example-app) An example app ---------------------------------------------------------------------------------------- Decentralized apps can implement functionality that we might otherwise expect to be implemented in a centralized fashion. For example, a very simple example of a decentralized app is a _Virtual Bank_ (typically referred to in crypto as a Lending Protocol). In the physical world, a bank is a business that takes deposits and loans them out at a higher rate. The bank makes the spread between the high rate and the low rate; the borrower gets a loan to do something economically productive; and you earn interest on your deposits. Everyone wins! A Virtual Bank is simply an app with four major methods: `deposit`, `withdraw`, `borrow`, and `repay`. The logic for each of those methods is mostly bookkeeping to ensure that deposits and loans are being tracked correctly: class VirtualBank: def deposit(sender, amount): # transfer amount from sender to myself (the bank) # do internal bookkeeping to credit the sender def withdraw(sender, amount): # ensure the sender had enough on deposit # do internal bookkeeping to debit the sender # transfer amount from myself (the bank) to sender def borrow(sender, amount): # ... def repay(sender, amount); # ... In Ethereum, or in Monad, someone can write code for this Virtual Bank and upload it; then anyone can utilize it for borrowing and lending, potentially far more easily than when trying to get access to banking services in their home country. This simple example shows the power of decentralized apps. Here are a few other benefits to call out: * **Open APIs / composability**: decentralized apps can be called atomically by other decentralized apps, allowing developers to build more complex functionality by stacking existing components. * **Transparency**: app logic is expressed purely through code, so anyone can review the logic for side effects. State is transparent and auditable; proof of reserves in DeFi is the default. * **Censorship-resistance and credible neutrality:** anyone can submit transactions or upload applications to a permissionless network. * **Global reach**: anyone with access to the internet can access crucial financial services, including unbanked/underbanked users. [Introduction\ \ Previous](https://docs.monad.xyz/) [Why Monad: Decentralization + Performance\ \ Next](https://docs.monad.xyz/introduction/why-monad) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Upgrade Instructions - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/upgrade-instructions#content-area) To stay updated on new releases: * join the [Monad Node Announcements](https://t.me/MonadNodeAnnouncements) telegram group, or * join the [Monad Developer Discord](https://discord.gg/monaddev) and follow the `#mainnet-fullnode-announcements` channel MIP-8 Activation and Page Storage Migration ------------------------------------------- Migration instructions for MIP-8 activation and the slot → page storage change v0.15.2 ------- Upgrade instructions for v0.15.2 v0.15.1 ------- Upgrade instructions for v0.15.1 v0.15.0 ------- Upgrade instructions for v0.15.0 v0.14.5 ------- Upgrade instructions for v0.14.5 v0.14.4 ------- Upgrade instructions for v0.14.4 v0.14.3 ------- Upgrade instructions for v0.14.3 v0.14.2 ------- Upgrade instructions for v0.14.2 v0.14.1 ------- Upgrade instructions for v0.14.1 - eth\_fillTransaction patch v0.14.0 ------- Upgrade instructions for v0.14.0 v0.13.1 ------- Upgrade instructions for v0.13.1 - State Archive patch v0.13.0 (MONAD\_NINE) --------------------- Upgrade instructions for v0.13.0 - Hard Fork v0.12.7 ------- Upgrade instructions for v0.12.7 Authenticated UDP Migration --------------------------- Migration instructions for Authenticated UDP Authenticated UDP Checking -------------------------- Validate that your node is properly configured for Authenticated UDP v0.12.6 ------- Upgrade instructions for v0.12.6 v0.12.5 Testnet Re-genesis -------------------------- Re-genesis instructions for testnet v0.12.5 v0.12.3 ------- Upgrade instructions for v0.12.3 [Announcements\ \ Previous](https://docs.monad.xyz/node-ops/announcements) [MIP-8 Activation and Page Storage Migration\ \ Next](https://docs.monad.xyz/node-ops/upgrade-instructions/page-storage-mip-8-migration) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Privacy - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/tooling-and-infra/privacy#content-area) Privacy protocols let users transact on Monad without publicly exposing balances, token holdings, amounts, or counterparties, typically using zero-knowledge proofs. [​](https://docs.monad.xyz/tooling-and-infra/privacy#provider-summary) Provider Summary ------------------------------------------------------------------------------------------ * Mainnet * Testnet | Provider | Status | Docs | Support notes | | --- | --- | --- | --- | | [Unlink](https://www.unlink.xyz/) | Supported | [Docs](https://docs.unlink.xyz/) | Private accounts via zero-knowledge proofs; deposit, transfer, withdraw, and execute operations | | Provider | Status | Docs | Support notes | | --- | --- | --- | --- | | [Unlink](https://www.unlink.xyz/) | Supported | [Docs](https://docs.unlink.xyz/) | Private accounts via zero-knowledge proofs; deposit, transfer, withdraw, and execute operations | [​](https://docs.monad.xyz/tooling-and-infra/privacy#provider-details) Provider Details ------------------------------------------------------------------------------------------ ### [​](https://docs.monad.xyz/tooling-and-infra/privacy#unlink) Unlink [Unlink](https://www.unlink.xyz/) adds private accounts to applications on existing chains. Users own, send, receive, and interact with contracts without exposing balances, token types, amounts, or transaction history, using zero-knowledge proofs. Unlink closes the counterparty dimension of privacy — it hides who transacts with whom, not just the amounts. Encrypted UTXO notes hold balances inside the contract, and Groth16 zero-knowledge proofs verify each operation without revealing the sender, recipient, or amount. You integrate Unlink as an onchain smart contract paired with a TypeScript SDK ([`@unlink-xyz/sdk`](https://www.npmjs.com/package/@unlink-xyz/sdk) ). #### [​](https://docs.monad.xyz/tooling-and-infra/privacy#features) Features * Counterparty, amount, and balance privacy on internal transfers between private accounts * Four core operations: `deposit`, `transfer`, `withdraw`, and `execute` for private smart contract interactions * Gasless private actions through relayers and ERC-4337 sponsorship * Flexible custody: non-custodial browser integration or custodial server #### [​](https://docs.monad.xyz/tooling-and-infra/privacy#use-cases) Use cases * Private payouts, payroll, and stablecoin operations * Treasury rebalancing and settlement without exposing strategy * Scoped funds for AI-agent wallets To get started, visit the [Unlink documentation](https://docs.unlink.xyz/) . [Payment Orchestrators\ \ Previous](https://docs.monad.xyz/tooling-and-infra/payment-orchestrators) [RPC Providers\ \ Next](https://docs.monad.xyz/tooling-and-infra/rpc-providers) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Payment Orchestrators - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/tooling-and-infra/payment-orchestrators#content-area) Payment orchestrators connect multiple providers, rails, and chains behind a single API — routing stablecoin and fiat flows (onramps, offramps, transfers, payouts, and swaps) across networks so builders can move money without managing fragmented integrations. **See also:** [Onramps](https://docs.monad.xyz/tooling-and-infra/onramps) . [​](https://docs.monad.xyz/tooling-and-infra/payment-orchestrators#provider-summary) Provider Summary -------------------------------------------------------------------------------------------------------- | Provider | Status | Docs | Support notes | Currencies & Countries Supported | | --- | --- | --- | --- | --- | | [Brale](https://brale.xyz/) | ✅ | [Docs](https://docs.brale.xyz/) | [Orchestration](https://docs.brale.xyz/documentation/platform/stablecoin-orchestration)
:

* [Unified transfers](https://docs.brale.xyz/key-concepts/transfers)
(one `address_id` across on- and off-chain rails)
* [Multi-rail transfer types](https://docs.brale.xyz/coverage/transfer-types)
: ACH, wire, plus onchain rails
* [Virtual-account automations](https://docs.brale.xyz/key-concepts/automations)

* [ACH payout branding](https://docs.brale.xyz/key-concepts/transfers)

* Program controls: [idempotency](https://docs.brale.xyz/key-concepts/idempotency)
, scoped credentials, and [webhooks](https://docs.brale.xyz/webhooks/overview) | [Supported Currencies](https://docs.brale.xyz/coverage/value-types) | | [Bridge](https://www.bridge.xyz/) | ✅ | [Docs](https://apidocs.bridge.xyz/) | [Orchestration](https://apidocs.bridge.xyz/platform/orchestration/overview)
:

* [Transfers](https://apidocs.bridge.xyz/platform/orchestration/transfers/transfer)
(one-time fiat or stablecoin)
* [Static Template Transfers](https://apidocs.bridge.xyz/platform/orchestration/transfers/static-templates)
(reusable instructions)
* [Virtual Accounts](https://apidocs.bridge.xyz/get-started/guides/move-money/virtualaccounts)
(fiat deposit addresses)
* [Liquidation Address](https://apidocs.bridge.xyz/platform/orchestration/liquidation_address/liquidation_address)
(map an on-chain address to a fiat/crypto destination) | USD (ACH & wire), EUR (SEPA), GBP, MXN (SPEI) & more via [virtual accounts](https://apidocs.bridge.xyz/get-started/guides/move-money/virtualaccounts) | | [Checker](https://www.checker.finance/) | ✅ | [Docs](https://docs.checker.finance/) | [Orchestration](https://docs.checker.finance/docs/getting-started)
:

* [Order management & trade execution](https://docs.checker.finance/docs/creating-a-trade-order)

* [RFQ](https://docs.checker.finance/docs/request-for-quote-rfq)
+ [liquidity-provider quotes](https://docs.checker.finance/docs/get-prices-from-venues)

* [Asset coverage](https://docs.checker.finance/docs/supported-currencies)
plus [deposits](https://docs.checker.finance/reference/create_2)
and [withdrawals](https://docs.checker.finance/reference/create_4)

* [Cross-border payments (FX)](https://docs.checker.finance/docs/currency-conversion)
and [FX quote requests](https://docs.checker.finance/reference/create_3)

* [Market data coverage](https://docs.checker.finance/docs/data-coverage)
and [waterfall pricing](https://docs.checker.finance/reference/getprice)

* [Custodian ops & PSP pay-in/pay-out](https://docs.checker.finance/docs/payments-sequence-diagram)
(launching) | 75+ currencies via 50+ integrated providers (banks, exchanges, OTC desks, payment providers) | | [Mesh](https://www.meshpay.com/) | ✅ | [Docs](https://docs.meshconnect.com/) | [Orchestration](https://docs.meshconnect.com/build/prepare-to-build)
:

* [Exchange & wallet integrations](https://docs.meshconnect.com/resources/concepts)
behind one API and SDK
* [Deposit addresses & crypto transfers](https://docs.meshconnect.com/resources/manual-deposits)

* [Onramp](https://docs.meshconnect.com/extend/onramp)
(buy flows) and [withdrawals / offramp](https://docs.meshconnect.com/extend/withdrawal)

* [15-minute quickstart](https://docs.meshconnect.com/build/15min-quickstart)
with sandbox & testnets
* [Supported networks and tokens](https://docs.meshconnect.com/resources/supported-tokens) | [USD, EUR, GBP](https://docs.meshconnect.com/resources/fiat-currency#supported-currencies) | | [zerohash](https://zerohash.com/) | ✅ | [Docs](https://docs.zerohash.com/) | [Orchestration](https://docs.zerohash.com/docs/getting-started)
:

* Transact: [payins](https://docs.zerohash.com/docs/payins)
, [payouts](https://docs.zerohash.com/docs/payouts)
, [on/off ramps](https://docs.zerohash.com/docs/on-off-ramps)
, and [fiat rails](https://docs.zerohash.com/docs/fiat)

* Trade: [buy/sell](https://docs.zerohash.com/docs/buysell)
, [order management](https://docs.zerohash.com/docs/supported-orders)
, and [RFQ](https://docs.zerohash.com/docs/request-for-quote)

* Tokenize: [payment rails](https://docs.zerohash.com/docs/tokenization-payment-rails)
and [tokenization engine](https://docs.zerohash.com/docs/tokenization-engine)

* Stablecoins: [issuer fees](https://docs.zerohash.com/docs/issuer-fees)

* [Onboarding](https://docs.zerohash.com/docs/onboarding-experience-sample)
, [SDK](https://docs.zerohash.com/docs/sdk)
, [Client Portal](https://docs.zerohash.com/docs/onboarding)
, and [Tax](https://docs.zerohash.com/docs/crypto-tax-overview) | [Supported Countries](https://docs.zerohash.com/docs/supported-regions) | [​](https://docs.monad.xyz/tooling-and-infra/payment-orchestrators#provider-details) Provider details -------------------------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/tooling-and-infra/payment-orchestrators#brale) Brale [Brale](https://brale.xyz/) is a stablecoin infrastructure platform that enables developers to onramp fiat to stablecoins, offramp stablecoins back to fiat, swap between [stablecoins](https://docs.brale.xyz/coverage/value-types) and [networks](https://docs.brale.xyz/coverage/transfer-types) , and issue branded stablecoins, all through a single unified API. Brale handles regulatory compliance, reserves, and multi-chain orchestration so builders can focus on their product. Brale also provides fiat onramps and offramps — see [Onramps](https://docs.monad.xyz/tooling-and-infra/onramps) . To get started, visit the [Brale documentation](https://docs.brale.xyz/) . ### [​](https://docs.monad.xyz/tooling-and-infra/payment-orchestrators#bridge) Bridge [Bridge](https://www.bridge.xyz/) (a Stripe company) is a stablecoin payments platform whose orchestration APIs let developers build onramps, offramps, and crypto-to-crypto transfers, alongside virtual accounts, stablecoin issuance, wallets, and card products. Bridge also provides fiat onramps and offramps — see [Onramps](https://docs.monad.xyz/tooling-and-infra/onramps) . To get started, visit the [documentation](https://apidocs.bridge.xyz/) . ### [​](https://docs.monad.xyz/tooling-and-infra/payment-orchestrators#checker) Checker [Checker](https://www.checker.finance/) is a digital asset orchestration platform that unifies stablecoin and digital asset operations for financial institutions through a single API. It connects 50+ providers---exchanges, OTC desks, banks, and payment providers---into one programmable network, giving institutions access to trading, payments, treasury, and credit without managing fragmented integrations. To get started, visit the [documentation](https://docs.checker.finance/) . ### [​](https://docs.monad.xyz/tooling-and-infra/payment-orchestrators#mesh) Mesh [Mesh](https://www.meshpay.com/) is an embedded crypto payments and transfers platform that connects exchanges, wallets, and brokerages behind a single API and SDK, letting builders move digital assets for deposits, payments, onramps, and withdrawals without managing each integration individually. To get started, visit the [Mesh quickstart](https://docs.meshconnect.com/build/15min-quickstart) . ### [​](https://docs.monad.xyz/tooling-and-infra/payment-orchestrators#zerohash) zerohash [zerohash](https://zerohash.com/) is a B2B2C embedded infrastructure platform that provides APIs and SDKs, enabling businesses to integrate digital asset trading, custody, and fiat-to-crypto on-ramps directly into their applications. zerohash also provides fiat onramps and offramps — see [Onramps](https://docs.monad.xyz/tooling-and-infra/onramps) . To get started, visit the [documentation](https://docs.zerohash.com/) . [Oracles\ \ Previous](https://docs.monad.xyz/tooling-and-infra/oracles) [Privacy\ \ Next](https://docs.monad.xyz/tooling-and-infra/privacy) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Precompiles - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/developer-essentials/precompiles#content-area) Precompiles are contracts at predefined addresses that provide cryptographic and utility functions implemented natively rather than in EVM bytecode. They are callable like any other contract via `CALL` or `STATICCALL`. Monad supports all Ethereum precompiles as of the Fusaka fork (`0x01` to `0x11`), plus three additional precompiles: * **`0x0100`** - [P256 signature verification](https://docs.monad.xyz/developer-essentials/precompiles#p256-signature-verification) ([EIP-7951](https://eips.ethereum.org/EIPS/eip-7951) ) * **`0x1000`** - [Staking precompile](https://docs.monad.xyz/developer-essentials/precompiles#staking-precompile) * **`0x1001`** - [Reserve balance precompile](https://docs.monad.xyz/developer-essentials/precompiles#reserve-balance-precompile) [​](https://docs.monad.xyz/developer-essentials/precompiles#ethereum-precompiles) Ethereum precompiles --------------------------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/developer-essentials/precompiles#cryptographic-and-hashing) Cryptographic and hashing | Address | Name | Gas | Description | | --- | --- | --- | --- | | `0x01` | `ecRecover` | `6000` | ECDSA public key recovery | | `0x02` | `sha256` | `60 + 12 * word_size` | SHA-256 hash function | | `0x03` | `ripemd160` | `600 + 120 * word_size` | RIPEMD-160 hash function | | `0x09` | `blake2f` | `rounds * 2` | BLAKE2 compression function F | ### [​](https://docs.monad.xyz/developer-essentials/precompiles#arithmetic-and-utility) Arithmetic and utility | Address | Name | Gas | Description | | --- | --- | --- | --- | | `0x04` | `identity` | `15 + 3 * word_size` | Returns the input unchanged | | `0x05` | `modexp` | [see evm.codes](https://www.evm.codes/precompiled) | Arbitrary-precision modular exponentiation | ### [​](https://docs.monad.xyz/developer-essentials/precompiles#elliptic-curve-alt_bn128) Elliptic curve alt\_bn128 | Address | Name | Gas | Description | | --- | --- | --- | --- | | `0x06` | `ecAdd` | `300` | Point addition on alt\_bn128 | | `0x07` | `ecMul` | `30,000` | Scalar multiplication on alt\_bn128 | | `0x08` | `ecPairing` | `225,000` | Bilinear pairing check on alt\_bn128 | ### [​](https://docs.monad.xyz/developer-essentials/precompiles#kzg-commitment) KZG commitment | Address | Name | Gas | Description | | --- | --- | --- | --- | | `0x0a` | `point_eval` | `200,000` | KZG commitment verification ([EIP-4844](https://eips.ethereum.org/EIPS/eip-4844#point-evaluation-precompile)
) | ### [​](https://docs.monad.xyz/developer-essentials/precompiles#bls12-381) BLS12-381 These precompiles provide operations on the BLS12-381 curve per [EIP-2537](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2537.md) . | Address | Name | Gas | Description | | --- | --- | --- | --- | | `0x0b` | `bls12_g1_add` | `375` | Point addition in G1 | | `0x0c` | `bls12_g1_msm` | [see EIP-2537](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2537.md) | Multi-scalar multiplication in G1 | | `0x0d` | `bls12_g2_add` | `600` | Point addition in G2 | | `0x0e` | `bls12_g2_msm` | [see EIP-2537](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2537.md) | Multi-scalar multiplication in G2 | | `0x0f` | `bls12_pairing_check` | [see EIP-2537](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2537.md) | Pairing check over (G1, G2) point pairs | | `0x10` | `bls12_map_fp_to_g1` | `5500` | Map base field element to G1 point | | `0x11` | `bls12_map_fp2_to_g2` | `23800` | Map extension field element to G2 point | [​](https://docs.monad.xyz/developer-essentials/precompiles#p256-signature-verification) P256 signature verification ----------------------------------------------------------------------------------------------------------------------- Address `0x0100` verifies signatures on the `secp256r1` (P256) elliptic curve per [EIP-7951](https://eips.ethereum.org/EIPS/eip-7951) . EIP-7951 supersedes [RIP-7212](https://github.com/ethereum/RIPs/blob/master/RIPS/rip-7212.md) . If you are migrating from a chain that uses RIP-7212 at `0x100`, note that the address and interface are identical — only the EIP designation has changed. The P256 curve is used by WebAuthn, Apple Secure Enclave, Android Keystore, and hardware security modules. With this precompile, you can verify passkey signatures on-chain, enabling biometric authentication flows for smart accounts without relying on off-chain signature verification. ### [​](https://docs.monad.xyz/developer-essentials/precompiles#input-and-output) Input and output The precompile accepts exactly **160 bytes**: | Offset | Size | Parameter | Description | | --- | --- | --- | --- | | 0 | 32 bytes | `hash` | Message hash | | 32 | 32 bytes | `r` | Signature component r | | 64 | 32 bytes | `s` | Signature component s | | 96 | 32 bytes | `qx` | Public key x-coordinate | | 128 | 32 bytes | `qy` | Public key y-coordinate | All values are big-endian encoded as 256-bit unsigned integers. **Returns:** * `0x0000...0001` (32 bytes) on a valid signature * Empty bytes on an invalid signature or malformed input **Gas cost:** 6900 ### [​](https://docs.monad.xyz/developer-essentials/precompiles#solidity-example) Solidity example address constant P256_VERIFY = address(0x0100); function verifyP256Signature( bytes32 hash, uint256 r, uint256 s, uint256 qx, uint256 qy ) internal view returns (bool) { (bool success, bytes memory result) = P256_VERIFY.staticcall( abi.encodePacked(hash, r, s, qx, qy) ); return success && result.length == 32 && abi.decode(result, (uint256)) == 1; } For passkey infrastructure and embedded wallet providers on Monad, see [Embedded Wallets](https://docs.monad.xyz/tooling-and-infra/wallet-infra/embedded-wallets) . [​](https://docs.monad.xyz/developer-essentials/precompiles#staking-precompile) Staking precompile ----------------------------------------------------------------------------------------------------- Address `0x1000` provides the interface for validator delegation, undelegation, reward claims, and staking queries. Gas costs vary by function. * [Staking overview](https://docs.monad.xyz/reference/staking/overview) — key concepts, common actions, and constraints * [Staking API reference](https://docs.monad.xyz/reference/staking/api) — full method signatures, parameters, gas costs, events, and ABI [​](https://docs.monad.xyz/developer-essentials/precompiles#reserve-balance-precompile) Reserve balance precompile --------------------------------------------------------------------------------------------------------------------- Address `0x1001` exposes a single method, `dippedIntoReserve()` (selector `0x3a61584e`, gas cost `100`), which returns a `bool` indicating whether the current execution state is in [reserve balance](https://docs.monad.xyz/developer-essentials/reserve-balance) violation. It is specified in [MIP-4](https://mips.monad.xyz/MIPs/MIP-4) . `dippedIntoReserve()` must be invoked via `CALL`. Invoking it via `STATICCALL` - or via `DELEGATECALL` or `CALLCODE` - reverts. Although it reads state and returns a value, it is intentionally not a `view` function, so that a Solidity call site compiles to `CALL` rather than `STATICCALL`. [​](https://docs.monad.xyz/developer-essentials/precompiles#gas-pricing-differences) Gas pricing differences --------------------------------------------------------------------------------------------------------------- A few precompiles (`0x01`, `0x06`, `0x07`, `0x08`, `0x09`, `0x0a`) are repriced relative to Ethereum to reflect their relative costs in Monad’s execution environment. The gas values in the tables above reflect Monad’s pricing. See [Opcode pricing](https://docs.monad.xyz/developer-essentials/opcode-pricing#precompiles) for a comparison. [​](https://docs.monad.xyz/developer-essentials/precompiles#source-code) Source code --------------------------------------------------------------------------------------- See the [precompile implementation](https://github.com/category-labs/monad/blob/main/category/execution/ethereum/precompiles.cpp) . [Opcode Pricing\ \ Previous](https://docs.monad.xyz/developer-essentials/opcode-pricing) [Reserve Balance\ \ Next](https://docs.monad.xyz/developer-essentials/reserve-balance) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Tokens and Bridges - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/developer-essentials/network-information/tokens-and-bridges#content-area) This page is generated from the [**token-list**](https://github.com/monad-crypto/token-list) repo. See the repo (or the [raw json](https://raw.githubusercontent.com/monad-crypto/token-list/refs/heads/main/tokenlist-mainnet.json) ) for a fuller list of tokens. Assets issued natively on another chain are bridged to Monad via a few different bridges, including LayerZero OFT, Chainlink CCIP, Hyperlane, and the 2/2 NTT Bridge, typically designated by the asset issuer.To bridge an asset to Monad, users typically have two options: 1. Use a frontend integrating the native bridge, e.g. * [Stargate](https://stargate.finance/?dstChain=monad&dstToken=0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) for LayerZero OFT * [Transporter](https://app.transporter.io/?tab=token&to=monad) for Chainlink CCIP * [Nexus](http://nexus.hyperlane.xyz/) for Hyperlane * [MonadBridge](https://monadbridge.com/?toChain=Monad&toToken=WETH&fromChain=Ethereum&fromToken=ETH) for 2/2 NTT 2. Use a bridge aggregator that incorporates multiple solvers and cross-chain swaps, and has selective coverage of native bridges: * [Jumper](https://jumper.exchange/?fromChain=1&toChain=143&toToken=0x0000000000000000000000000000000000000000) - incorporates multiple solvers and select OFTs and CCIP-bridged assets via [Glacis](https://li.fi/knowledge-hub/li-fi-partners-with-glacis-to-accelerate-the-adoption-of-interop-token/) . Option 1 ensures the native (wrapping/unwrapping) mechanism is considered, but Option 2 may be convenient if bridging from a remote chain or executing a cross-chain swap.The tables below link to the appropriate bridge (option 1) for each asset. Notable markets are linked based on TVL/volume. [​](https://docs.monad.xyz/developer-essentials/network-information/tokens-and-bridges#bridged-assets) Bridged Assets ------------------------------------------------------------------------------------------------------------------------ ### [​](https://docs.monad.xyz/developer-essentials/network-information/tokens-and-bridges#dollar-related) Dollar-related | Symbol | Name | Address | Bridge + Link | Bridgeable from | Select Markets | | --- | --- | --- | --- | --- | --- | | `AUSD` | Agora USD | | LayerZero OFT ([Stargate](https://stargate.finance/?srcChain=ethereum&srcToken=0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a&dstChain=monad&dstToken=0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a)
) | Eth, Avax, Base | [Curve 3pool](https://www.curve.finance/dex/monad/pools/factory-stable-ng-2)

[Uni AUSD/USDC](https://app.uniswap.org/explore/pools/monad/0xd112fde908d7342135fc7297cc53d25bf7a11d6c6e21fe7ac3e73c40f70827e8) | | `USDC` | USD Coin | | Circle CCTP ([link](https://monadbridge.com/?fromChain=Ethereum&fromToken=USDC&toChain=Monad&toToken=USDC)
) | 17 chains | [Curve 3pool](https://www.curve.finance/dex/monad/pools/factory-stable-ng-2) | | `USDT0` | Tether USD | | LayerZero OFT ([Stargate](https://stargate.finance/?srcChain=ethereum&srcToken=0xdAC17F958D2ee523a2206206994597C13D831ec7&dstChain=monad&dstToken=0xe7cd86e13AC4309349F30B3435a9d337750fC82D)
) | 18 chains | [Curve 3pool](https://www.curve.finance/dex/monad/pools/factory-stable-ng-2)

[Uni AUSD/USDT0](https://app.uniswap.org/explore/pools/monad/0xe56868928b91fcd5ebeada3d0ec8767f2bbfeb1e7da181203d13f6af76b03bf9) | | `mUSD` | MetaMask USD | | Hyperlane ([Nexus](https://nexus.hyperlane.xyz/?origin=ethereum&originToken=mUSD&destination=monad&destinationToken=mUSD)
) | Eth, BNB, Linea | | | `USD1` | USD1 | | Chainlink CCIP ([Transporter](https://app.transporter.io/?from=mainnet&tab=token&to=monad&token=USD1)
) | Eth | [PCS USD1/USDC](https://pancakeswap.finance/liquidity/pool/monad/0x8CcB070b6F871AbA552972c76D3b7DF8d88Ffa1a) | | `GHO` | Gho Token | | Chainlink CCIP ([Transporter](https://app.transporter.io/?from=mainnet&tab=token&to=monad&token=GHO)
) | Eth, Arb, Base, Avax, +5 | | | `USDe` | USDe | | LayerZero OFT ([Stargate](https://stargate.finance/?srcChain=ethereum&srcToken=0x4c9EDD5852cd905f086C759E8383e09bff1E68B3&dstChain=monad&dstToken=0x5d3a1Ff2b6BAb83b63cd9AD0787074081a52ef34)
) | Eth, Arb, Base, Sol, +10 | | | `sUSDe` | Staked USDe | | LayerZero OFT ([Stargate](https://stargate.finance/?srcChain=ethereum&srcToken=0x9D39A5DE30e57443BfF2A8307A4256c8797A3497&dstChain=monad&dstToken=0x211Cc4DD073734dA055fbF44a2b4667d5E5fE5d2)
) | Eth, Arb, Base, +10 | | | `syrupUSDC` | Syrup USDC | | Chainlink CCIP ([Transporter](https://app.transporter.io/?from=mainnet&tab=token&to=monad&token=syrupUSDC)
) | Eth | | | `wsrUSD` | Wrapped srUSD | | LayerZero OFT ([Stargate](https://stargate.finance/?srcChain=ethereum&srcToken=0xd3fD63209FA2D55B07A0f6db36C2f43900be3094&dstChain=monad&dstToken=0x4809010926aec940b550D34a46A52739f996D75D)
) | Eth | | | `syzUSD` | Staked Yuzu USD | | LayerZero OFT ([Stargate](https://stargate.finance/?srcChain=ethereum&srcToken=0x6DFF69eb720986E98Bb3E8b26cb9E02Ec1a35D12&dstChain=monad&dstToken=0x484be0540aD49f351eaa04eeB35dF0f937D4E73f)
) | Eth, Plasma | | ### [​](https://docs.monad.xyz/developer-essentials/network-information/tokens-and-bridges#eth-related) Eth-related | Symbol | Name | Address | Bridge + Link | Bridgeable from | Select Markets | | --- | --- | --- | --- | --- | --- | | `WETH` | Wrapped Ether | | NTT 2/2 ([MonadBridge](https://monadbridge.com/?fromChain=Ethereum&fromToken=ETH&toChain=Monad&toToken=WETH)
) | many | [Uni WETH/MON](https://app.uniswap.org/explore/pools/monad/0x3783b51e33900eb366a9e8473c76cda441e7170d2e5d96927f30c16a7add93aa)

[Uni USDC/WETH](https://app.uniswap.org/explore/pools/monad/0xad408916c1c310da9c258d4c128a7bf50fd9edc42a218cc970da39cfc8a05d93) | | `wstETH` | Lido Wrapped Staked ETH | | Chainlink CCIP ([Transporter](https://app.transporter.io/?tab=token&to=monad&token=wstETH)
) | Eth, Ink, Plasma | [Uni wstETH/WETH](https://app.uniswap.org/explore/pools/monad/0x55d7ed991392eb9597a76a5f41dfb964e291452c15107c0e64fd3d25925394ce) | | `weETH` | Wrapped EtherFi ETH | | LayerZero OFT ([Stargate](https://stargate.finance/?srcChain=ethereum&srcToken=0xCd5fE23C85820F7B72D0926FC9b05b43E359b7ee&dstChain=monad&dstToken=0xA3D68b74bF0528fdD07263c60d6488749044914b)
) | Eth, Base | [Uni weETH/WETH](https://app.uniswap.org/explore/pools/monad/0x2884b37c4a144e7047a1377ba7201d4b8ea318f0240369e01dc400f04e6cac40) | | `ezETH` | Renzo Restaked ETH | | Hyperlane ([Nexus](https://nexus.hyperlane.xyz/?token=ezETH&origin=ethereum&destination=monad)
) | many | [Curve ezETH/WETH](https://www.curve.finance/dex/monad/pools/factory-stable-ng-15) | | `rETH` | Rocket Pool ETH | | Chainlink CCIP ([Transporter](https://app.transporter.io/?from=mainnet&tab=token&to=monad&token=RETH)
) | Eth | | ### [​](https://docs.monad.xyz/developer-essentials/network-information/tokens-and-bridges#btc-related) BTC-related | Symbol | Name | Address | Bridge + Link | Bridgeable from | Select Markets | | --- | --- | --- | --- | --- | --- | | `cbBTC` | Coinbase Wrapped BTC | | Chainlink CCIP ([Transporter](https://app.transporter.io/?from=base&tab=token&to=monad&token=cbBTC)
) | Base | [Curve cbBTC/WBTC/LBTC](https://www.curve.finance/dex/monad/pools/0xd2634e05ebed90bd0a6c0e93d48d7bd8036653b1)

[Uni USDC/cbBTC](https://app.uniswap.org/explore/pools/monad/0x7fc6232a9ec6cc4e9434640dcde5ee08ccae3b07de3247bf788fc9e2051b449e) | | `WBTC` | Wrapped Bitcoin | | LayerZero OFT ([Stargate](https://stargate.finance/?srcChain=ethereum&srcToken=0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599&dstChain=monad&dstToken=0x0555E30da8f98308EdB960aa94C0Db47230d2B9c)
) | Eth, Base, +15 | [Curve cbBTC/WBTC/LBTC](https://www.curve.finance/dex/monad/pools/0xd2634e05ebed90bd0a6c0e93d48d7bd8036653b1)

[Uni MON/WBTC](https://app.uniswap.org/explore/pools/monad/0x1c93dd2f2f47439330150bf728c3beeaad71de45420a49183214898b044b65d1)

[Uni WBTC/USDC](https://app.uniswap.org/explore/pools/monad/0xd77c0f253764f5d5fbc78e13888afcc35c839262e6b21cd02baa9d8551a9898a) | | `LBTC` | Lombard Staked Bitcoin | | Chainlink CCIP ([Transporter](https://app.transporter.io/?from=mainnet&tab=token&to=monad&token=LBTC)
) | Eth, Avax, Base, BNB, Sonic | [Curve cbBTC/WBTC/LBTC](https://www.curve.finance/dex/monad/pools/0xd2634e05ebed90bd0a6c0e93d48d7bd8036653b1)

[Curve Bitcoin Converter](https://www.curve.finance/dex/monad/pools/factory-stable-ng-8) | | `BTC.b` | BTC.b | | Chainlink CCIP ([Transporter](https://app.transporter.io/?from=mainnet&tab=token&to=monad&token=BTC.b)
) | Eth, Avax | [Curve Bitcoin Converter](https://www.curve.finance/dex/monad/pools/factory-stable-ng-8) | | `SolvBTC` | Solv BTC | | Chainlink CCIP ([Transporter](https://app.transporter.io/?from=mainnet&tab=token&to=monad&token=SolvBTC)
) | Eth | | | `xSolvBTC` | xSolvBTC | | Chainlink CCIP ([Transporter](https://app.transporter.io/?from=mainnet&tab=token&to=monad&token=xSolvBTC)
) | Eth | | ### [​](https://docs.monad.xyz/developer-essentials/network-information/tokens-and-bridges#others) Others | Symbol | Name | Address | Bridge + Link | Bridgeable from | Select Markets | | --- | --- | --- | --- | --- | --- | | `SOL` | Wrapped SOL | | Wormhole ([Portal](https://monadbridge.com/?fromChain=Solana&fromToken=SOL&toChain=Monad&toToken=SOL)
) | many | | | `XAUt0` | Tether Gold | | LayerZero OFT ([Stargate](https://stargate.finance/?srcChain=ethereum&srcToken=0x68749665FF8D2d112Fa859AA293F07A622782F38&dstChain=monad&dstToken=0x01bFF41798a0BcF287b996046Ca68b395DbC1071)
) | Eth, Arb, Sol, +10 | [Uni XAUt0/AUSD](https://app.uniswap.org/explore/pools/monad/0xe1a8600687e4d06ca4787e5d0ccdacb1d360bfc9ca6ca2a49a688e14d0ef37b4) | [​](https://docs.monad.xyz/developer-essentials/network-information/tokens-and-bridges#natively-issued-assets) Natively-Issued Assets ---------------------------------------------------------------------------------------------------------------------------------------- | Symbol | Name | Address | | --- | --- | --- | | `WMON` | Wrapped MON | | [​](https://docs.monad.xyz/developer-essentials/network-information/tokens-and-bridges#market-data) Market Data ------------------------------------------------------------------------------------------------------------------ * [Defined](https://www.defined.fi/tokens/discover?network=mon) * [GeckoTerminal](https://www.geckoterminal.com/monad/pools) * [MonadVision Tokens](https://monadvision.com/tokens) * [DeFiLlama Monad](https://defillama.com/chain/monad) [​](https://docs.monad.xyz/developer-essentials/network-information/tokens-and-bridges#bridge-integrations) Bridge Integrations ---------------------------------------------------------------------------------------------------------------------------------- See [Cross-Chain](https://docs.monad.xyz/tooling-and-infra/cross-chain) for a list of supported bridges and bridge aggregators. [​](https://docs.monad.xyz/developer-essentials/network-information/tokens-and-bridges#mon-on-other-blockchains) MON on other blockchains -------------------------------------------------------------------------------------------------------------------------------------------- Partial list of wrapped MON addresses on other blockchains | Name | Blockchain | Address | Notes | | --- | --- | --- | --- | | `WMON` | Solana | | | | `WMON` | Ethereum | | 2/2 NTT | [Network Information - Mainnet\ \ Previous](https://docs.monad.xyz/developer-essentials/network-information) [Network Information - Testnet\ \ Next](https://docs.monad.xyz/developer-essentials/testnet) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Earn/Yield Infrastructure - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/tooling-and-infra/earn-yield#content-area) Earn/yield infrastructure providers offer vaults, strategies, and APIs that let builders embed yield-generating products — staking, lending, and DeFi strategies — directly into their apps, without integrating each underlying protocol individually. [​](https://docs.monad.xyz/tooling-and-infra/earn-yield#provider-summary) Provider Summary --------------------------------------------------------------------------------------------- | Provider | Docs | Description | | --- | --- | --- | | [Blend](https://blend.money/) | [Docs](https://docs.blend.money/) | Compliance-first account layer that lets platforms offer non-custodial yield, routing stablecoin and DeFi yields across sources like Morpho and Aave. | | [Pods Finance](https://www.pods.finance/) | [Docs](https://docs.pods.finance/) | Yield aggregation platform that routes deposits into strategies across DeFi protocols such as Aave, Morpho, and Lido, with cross-chain and same-chain swaps. | | [Vaults.fyi](https://vaults.fyi/) | [Docs](https://docs.vaults.fyi/) | Yield-data API that normalizes yields across 1,000+ vaults and 80+ protocols, exposing market data, transaction payloads, and portfolio tracking. | | [Veda](https://veda.tech/) | [Docs](https://docs.veda.tech/) | Institutional-grade vault infrastructure that lets partners embed customizable onchain yield with built-in risk and compliance controls. | | [Yield.xyz](https://yield.xyz/) | [Docs](https://docs.yield.xyz/docs/getting-started) | Non-custodial yield API powering wallets, custodians, and AI agents across 80+ networks, with a unified interface for staking, DeFi lending, and restaking. | [​](https://docs.monad.xyz/tooling-and-infra/earn-yield#provider-details) Provider details --------------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/tooling-and-infra/earn-yield#blend) Blend [Blend](https://blend.money/) is a compliance-first account layer that lets platforms offer non-custodial yield products to their users. It routes stablecoin and DeFi yields across sources like Morpho and Aave through individual user accounts, with built-in screening and reporting. To get started, visit the [documentation](https://docs.blend.money/) . ### [​](https://docs.monad.xyz/tooling-and-infra/earn-yield#pods-finance) Pods Finance [Pods Finance](https://www.pods.finance/) is a DeFi yield aggregation platform that routes deposits into yield strategies across protocols such as Aave, Morpho, and Lido. It also supports cross-chain and same-chain token swaps, helping users discover optimal yield opportunities and manage positions from a single interface. To get started, visit the [documentation](https://docs.pods.finance/) . ### [​](https://docs.monad.xyz/tooling-and-infra/earn-yield#vaults-fyi) Vaults.fyi [Vaults.fyi](https://vaults.fyi/) is a REST API that normalizes yield data across 1,000+ vaults and 80+ protocols, letting builders integrate DeFi earning features without protocol-by-protocol development. It provides market data, transaction payloads, portfolio tracking, and an MCP server for AI agents to query and compare yields across networks. To get started, visit the [documentation](https://docs.vaults.fyi/) . ### [​](https://docs.monad.xyz/tooling-and-infra/earn-yield#veda) Veda [Veda](https://veda.tech/) is a DeFi infrastructure platform that provides institutional-grade vaults, enabling organizations to offer onchain yield products with built-in risk and compliance controls. Partners can embed customizable earn features directly into their own platforms. To get started, visit the [documentation](https://docs.veda.tech/) . ### [​](https://docs.monad.xyz/tooling-and-infra/earn-yield#yield-xyz) Yield.xyz [Yield.xyz](https://yield.xyz/) is a non-custodial yield API that powers wallets, custodians, and AI agents across 80+ networks. It provides a unified interface for staking, DeFi lending, restaking, and other onchain yield opportunities, with self-custodial transaction construction. To get started, visit the [documentation](https://docs.yield.xyz/docs/getting-started) . [Custody\ \ Previous](https://docs.monad.xyz/tooling-and-infra/custody) [Indexers\ \ Next](https://docs.monad.xyz/tooling-and-infra/indexers) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Block Explorers - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/tooling-and-infra/block-explorers#content-area) [​](https://docs.monad.xyz/tooling-and-infra/block-explorers#block-explorer-summary) Block Explorer Summary -------------------------------------------------------------------------------------------------------------- * Mainnet * Testnet | Block explorer | Powered by | Status | URL | Verifier Type & URL | | --- | --- | --- | --- | --- | | **MonadVision** | BlockVision | ✅ | | Sourcify: | | **Monadscan** | Etherscan | ✅ | | Etherscan: | _✅ = supported, ⌛️ = in progress, ❓ = unknown, ❌ = won’t support_ | Block explorer | Powered by | Status | URL | Verifier Type & URL | | --- | --- | --- | --- | --- | | **MonadVision** | BlockVision | ✅ | | Sourcify: | | **Monadscan** | Etherscan | ✅ | | Etherscan: | _✅ = supported, ⌛️ = in progress, ❓ = unknown, ❌ = won’t support_ [​](https://docs.monad.xyz/tooling-and-infra/block-explorers#userop-explorers) UserOp Explorers -------------------------------------------------------------------------------------------------- | UserOp Explorer | Status | URL | Notes | | --- | --- | --- | --- | | JiffyScan | ✅ | | UserOp explorer for EIP-4337 | [​](https://docs.monad.xyz/tooling-and-infra/block-explorers#detailed-transaction-explorers) Detailed Transaction Explorers ------------------------------------------------------------------------------------------------------------------------------ | Transaction Explorer | Status | URL | Notes | | --- | --- | --- | --- | | Tenderly Explorer | ✅ | | Detailed transaction analyzer featuring call stack, balance changes, gas usage, and more | | Blocksec Phalcon Explorer | ✅ | | Detailed transaction analyzer featuring call stack, balance changes, fund flows, and more | [​](https://docs.monad.xyz/tooling-and-infra/block-explorers#provider-details) Provider Details -------------------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/tooling-and-infra/block-explorers#blockvision) BlockVision [MonadVision](https://monadvision.com/) is built by [BlockVision](https://blockvision.org/) , a leading provider of next-gen data infrastructure and enterprise solutions for the blockchain. BlockVision is supports the EVM and Sui and specializes in explorer service, RPC nodes, indexing APIs and validator service. To get started, visit the [documentation](https://docs.blockvision.org/reference/monad-indexing-api) . ### [​](https://docs.monad.xyz/tooling-and-infra/block-explorers#monadscan) Monadscan [Monadscan](https://monadscan.com/) is built by [Etherscan](https://etherscan.io/) to deliver trusted and high-performance access to on-chain data. Leveraging Etherscan’s industry-leading expertise, MonadScan provides robust explorer tools, developer-friendly APIs, and reliable infrastructure tailored for the Monad ecosystem. To get started, visit the [documentation](https://docs.monadscan.com/) . [Analytics\ \ Previous](https://docs.monad.xyz/tooling-and-infra/analytics) [Cross-Chain\ \ Next](https://docs.monad.xyz/tooling-and-infra/cross-chain) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Wallet Developer Integration Guide - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/developer-essentials/wallet-developers#content-area) For wallet teams adding or improving Monad support in an EVM wallet. Monad works with most EVM wallets out of the box — same addresses, transaction format, signatures, and dapp connection flow as Ethereum. But a handful of network-level differences — gas billed on the limit, asynchronous execution, no global mempool view — change how a wallet should quote gas, poll status, and surface pending state. For end-user instructions, see [Add Monad to Wallet](https://docs.monad.xyz/guides/add-monad-to-wallet) . For chain IDs, RPC URLs, tokens, and protocol contract addresses, see [Network Information](https://docs.monad.xyz/developer-essentials/network-information) , the [`token-list`](https://github.com/monad-crypto/token-list) , and [`protocols`](https://github.com/monad-crypto/protocols) . [​](https://docs.monad.xyz/developer-essentials/wallet-developers#tune-gas-handling) Tune gas handling --------------------------------------------------------------------------------------------------------- On Monad, users pay for the transaction’s **gas limit**, not the gas it actually uses. This is the single biggest wallet-side difference from Ethereum: large safety buffers significantly overcharge users and reserve block space the transaction never uses. Use a small, Monad-specific gas-limit margin, and warn users when they manually set a gas limit far above the estimate. [Category Labs’ gas-limit analysis](https://www.category.xyz/blogs/setting-your-gas-limit-on-monad) recommends `eth_estimateGas` with only a modest buffer. A fixed buffer is a good starting point; a dynamic buffer keyed on receiver address and function selector reduces unused gas further once you have enough history to calibrate. Quote fees from current Monad data, not Ethereum defaults: * `eth_maxPriorityFeePerGas` returns a hardcoded 2 gwei — not a live network recommendation. * `eth_feeHistory` duplicates the latest `baseFeePerGas` when `newest_block` is `latest`. Don’t count it twice in charts or averages. See [Gas Pricing](https://docs.monad.xyz/developer-essentials/gas-pricing) and the JSON-RPC [fee estimation notes](https://docs.monad.xyz/reference/json-rpc/overview#fee-estimation) . [​](https://docs.monad.xyz/developer-essentials/wallet-developers#handle-transaction-lifecycle) Handle transaction lifecycle ------------------------------------------------------------------------------------------------------------------------------- A successful `eth_sendRawTransaction` means “accepted by this RPC node” — not a guarantee the transaction will land or succeed. The RPC node may accept it before checking nonce and balance against the latest state. Distinguish three stages: | Stage | What to show | Signal | | --- | --- | --- | | Submitted | Pending | `eth_sendRawTransaction` returns a hash | | Included and executed locally | Completed or failed | `eth_getTransactionReceipt` returns a receipt | | Finalized | Finalized | The receipt’s block number is at or below the block returned for the `finalized` tag | If an account just received MON and is about to spend it, wait until the receiving transaction’s receipt block is at least `k` blocks behind the current block. Currently `k = 3` (~1.2 seconds), but this can change. If a spend drops an undelegated account below 10 MON, wait `k` blocks before another MON spend. After undelegating, wait `k` blocks before emptying the account. Monad has no global mempool. Don’t use `txpool_content` or `newPendingTransactions` for pending state. Instead: * Track local pending nonces for transactions you submitted. * Reconcile against receipts and `eth_getTransactionCount`. * Use `txpool_statusByAddress` or `txpool_statusByHash` for node-level pending status. * Scope pending lists to the user’s account, not the whole network. [​](https://docs.monad.xyz/developer-essentials/wallet-developers#simulation-and-rpc-differences) Simulation and RPC differences ----------------------------------------------------------------------------------------------------------------------------------- `debug_trace*` methods don’t return opcode-level struct logs. Use call-frame or prestate tracers for simulation and risk previews. WebSocket subscriptions: `newHeads`, `logs`, plus Monad-specific `monadNewHeads` and `monadLogs` for pre-finalization data. The `syncing` and `newPendingTransactions` WebSocket subscription types are not supported. See [WebSocket subscriptions](https://docs.monad.xyz/reference/json-rpc/overview#websocket-subscriptions) . Full nodes may serve recent state, but not arbitrary old state. Check RPC capability before showing past-state UI or old-block simulation, and link to an archive endpoint when needed. See [Historical Data](https://docs.monad.xyz/developer-essentials/historical-data) . [​](https://docs.monad.xyz/developer-essentials/wallet-developers#eips-and-evm-differences) EIPs and EVM differences ----------------------------------------------------------------------------------------------------------------------- Monad supports transaction types 0, 1, 2, and 4. Type 3 blob transactions are not supported. | Feature | Status | Wallet implication | | --- | --- | --- | | EIP-4844 | Not supported | Reject type 3 transaction construction with a clear error. | | EIP-7702 | Supported with Monad-specific restrictions | A delegated EOA can hold less than 10 MON, but any transaction that lowers its balance below 10 MON reverts. Delegated account code also cannot run `CREATE` or `CREATE2`. | Monad has larger contract-size limits than Ethereum and some opcode repricing. Use Monad-specific thresholds for deploy-size warnings, and re-estimate per chain rather than hardcoding opcode costs. See [Differences from Ethereum](https://docs.monad.xyz/developer-essentials/differences) . [​](https://docs.monad.xyz/developer-essentials/wallet-developers#recipes) Recipes ------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/developer-essentials/wallet-developers#apply-a-chain-specific-gas-limit-margin) Apply a chain-specific gas-limit margin Use Category Labs’ 7.5% fixed-buffer result as a Monad starting point, then tune from production data — success rates, retries, and out-of-gas events. Basis points avoid floating-point rounding errors. const DEFAULT_GAS_LIMIT_MARGIN_BPS = 15_000n // 1.5x const GAS_LIMIT_MARGIN_BPS_BY_CHAIN: Record = { // 7.5% buffer. Measure against your wallet's transaction mix. 143: 10_750n, 10143: 10_750n, } export const applyGasLimitMargin = ({ chainId, estimatedGas, }: { chainId: number estimatedGas: bigint }) => { const margin = GAS_LIMIT_MARGIN_BPS_BY_CHAIN[chainId] ?? DEFAULT_GAS_LIMIT_MARGIN_BPS return (estimatedGas * margin + 9_999n) / 10_000n } ### [​](https://docs.monad.xyz/developer-essentials/wallet-developers#warn-on-manual-gas-limit-overspend) Warn on manual gas-limit overspend const CHAINS_CHARGING_GAS_LIMIT = new Set([143, 10143]) // Warn only on egregious overrides — not normal 1.5–2x safety buffers. const OVERSPEND_WARNING_MULTIPLIER = 10n export const shouldWarnGasLimitOverspend = ({ chainId, gasLimit, recommendedGasLimit, }: { chainId: number gasLimit: bigint recommendedGasLimit: bigint }) => { if (!CHAINS_CHARGING_GAS_LIMIT.has(chainId)) return false if (recommendedGasLimit <= 0n || gasLimit < 21_000n) return false return gasLimit > recommendedGasLimit * OVERSPEND_WARNING_MULTIPLIER } Show this inline and require explicit acknowledgement before signing. Reset the acknowledgement when the user changes the gas limit. ### [​](https://docs.monad.xyz/developer-essentials/wallet-developers#wait-for-receipt-and-finality) Wait for receipt and finality The manual loop below works with standard RPC. If your RPC supports it, `eth_sendRawTransactionSync` is the shorter path. const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)) const hexToBigInt = (hex: string) => BigInt(hex) export const waitForReceipt = async (provider: EIP1193Provider, txHash: string) => { while (true) { // A receipt means the transaction has executed locally on this RPC node. const receipt = await provider.request({ method: "eth_getTransactionReceipt", params: [txHash], }) if (receipt) return receipt await sleep(400) } } export const waitUntilFinalized = async (provider: EIP1193Provider, receiptBlockNumber: string) => { while (true) { // Compare the receipt's block with the node's finalized commitment level. const finalizedBlock = await provider.request({ method: "eth_getBlockByNumber", params: ["finalized", false], }) if (hexToBigInt(finalizedBlock.number) >= hexToBigInt(receiptBlockNumber)) return await sleep(400) } } Use receipts for ordinary status. Wait for finality before crediting bridges, deposits, or irreversible off-chain settlement. [​](https://docs.monad.xyz/developer-essentials/wallet-developers#learning-resources) Learning resources ----------------------------------------------------------------------------------------------------------- Gas Pricing ----------- How Monad charges gas and how EIP-1559 works on Monad JSON-RPC Overview ----------------- RPC differences, block tags, WebSockets, limits, and errors Reserve Balance --------------- When accounts can spend below the 10 MON reserve EIP-7702 on Monad ----------------- Delegated EOA behavior and Monad-specific restrictions Historical Data --------------- Current-state and historical-state availability [Transactions\ \ Previous](https://docs.monad.xyz/developer-essentials/transactions) [Gas Pricing\ \ Next](https://docs.monad.xyz/developer-essentials/gas-pricing) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Tooling and Infrastructure - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/tooling-and-infra#content-area) The most popular Ethereum tools and infrastructure providers support Monad. The enclosing pages survey each category of tools and attempt a feature comparison. See also the [`protocols`](https://github.com/monad-crypto/protocols) repo for a listing of contract addresses for each protocol. Analytics --------- Tools for understanding app activity on Monad Block Explorers --------------- View accounts and transactions; read and write contracts Cross-Chain ----------- Bridges and protocols for cross-chain communication Custody ------- Institutional-grade custody solutions for secure asset management Earn/Yield Infrastructure ------------------------- Vaults, strategies, and APIs for embedding onchain yield Indexers -------- Common transformations for blockchain data + custom calculators Onramps ------- Ways to convert between fiat and crypto Oracles ------- Data feeds bringing off-chain information on-chain Payment Orchestrators --------------------- Unified APIs that route stablecoin and fiat flows across providers and chains Privacy ------- Private accounts and transactions using zero-knowledge proofs RPC Providers ------------- Endpoints for interacting with Monad Toolkits -------- Development frameworks and tools for building on Monad Wallets ------- Tools for storing private keys, signing transactions, and managing assets Wallet Infrastructure --------------------- Embedded wallets and smart accounts [Releases\ \ Previous](https://docs.monad.xyz/developer-essentials/changelog/releases) [Agentic Payments\ \ Next](https://docs.monad.xyz/tooling-and-infra/agentic-payments) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Authenticated UDP Migration - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/upgrade-instructions/auth-udp#content-area) Please do not proceed until Monad Foundation provides notice. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/auth-udp#overview) Overview --------------------------------------------------------------------------------------- UDP Authentication provides secure, authenticated peer-to-peer communication for Monad nodes. This feature is currently **opt-in** and will become required in a future release. **Benefits:** * **Enhanced Security**: Cryptographically authenticated peer connections using your existing validator keys * **DoS Protection**: Prevents resource exhaustion from spoofed packets * **Traffic Prioritization**: Enables efficient QoS policies for transaction forwarding * **Performance**: ~100x faster packet verification compared to per-packet ECDSA signatures * * * [​](https://docs.monad.xyz/node-ops/upgrade-instructions/auth-udp#prerequisites) Prerequisites ------------------------------------------------------------------------------------------------- * **Monad Version**: `0.12.6` or later * **Access**: Root/sudo privileges on your node * **Keystore**: Existing `/home/monad/monad-bft/config/id-secp` file * **Network**: Ability to open UDP port 8001 on your firewall * * * [​](https://docs.monad.xyz/node-ops/upgrade-instructions/auth-udp#instructions-for-node-operators) Instructions for node operators ------------------------------------------------------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/auth-udp#1-verify-the-monad-version) 1\. Verify the Monad version Verify the installation: monad-node --version # Expected output 0.12.6+ If not, please refer to the official documentation to upgrade to the latest recommended version: [https://docs.monad.xyz/node-ops/upgrade-instructions/](https://docs.monad.xyz/node-ops/upgrade-instructions/) . * * * ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/auth-udp#2-configure-firewall) 2\. Configure Firewall Open UDP port 8001 for authenticated traffic: sudo ufw allow 8001/udp comment 'monad authenticated udp' Verify the rule was added: sudo ufw status | grep 8001 **Expected output:** 8001/udp ALLOW Anywhere # monad authenticated udp Note: if the node is behind a Network Firewall, make sure to also open the port 8001. * * * ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/auth-udp#3-generate-authentication-signature) 3\. Generate Authentication Signature Generate your node’s authenticated name record signature: source /home/monad/.env monad-sign-name-record \ --address $(curl -4 -s ifconfig.me):8000 \ --authenticated-udp-port 8001 \ --self-record-seq-num 1 \ --keystore-path /home/monad/monad-bft/config/id-secp \ --password "$KEYSTORE_PASSWORD" > **Important**: The `--self-record-seq-num` value must be **greater** than your current `self_record_seq_num` in `node.toml`. > > * If your config shows `self_record_seq_num = 0`, use `1` > * If your config shows `self_record_seq_num = 1`, use `2` **Example Output:** self_address = "15.235.224.21:8000" self_record_seq_num = 1 authenticated_udp_port = 8001 self_name_record_sig = "f754ed009f82a5c0e402b8f573a1b7e44e9f5fc957cf6360316b5a3baf617f0d1ffe23558845747dd21a51408ac2555a4f4bb70a0032cdf59921d5905663e41200" Warning: do not copy the `authenticated_udp_port` parameter, as the parameter name in `node.toml` is `self_auth_port`. **Save this output** - you’ll need it in the next step. * * * ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/auth-udp#4-update-configuration) 4\. Update Configuration Edit your Monad configuration: sudo vim /home/monad/monad-bft/config/node.toml #### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/auth-udp#4-1-update-peer-discovery-section) 4.1 Update Peer Discovery Section In the node configuration: * replace the values in the `[peer_discovery]` section with your output from Step 3 * add the `self_auth_port` parameter [peer_discovery] self_address = "YOUR_IP:8000" self_auth_port = 8001 self_record_seq_num = 1 self_name_record_sig = "YOUR_GENERATED_SIGNATURE_FROM_STEP_3" #### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/auth-udp#4-2-update-network-section) 4.2 Update Network Section Add the `authenticated_bind_address_port` parameter to `[network]`: [network] bind_address_host = "0.0.0.0" bind_address_port = 8000 authenticated_bind_address_port = 8001 # Add this line max_rtt_ms = 300 max_mbps = 1000 #### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/auth-udp#4-3-update-peer-records-validators-only) 4.3 Update Peer Records (Validators Only) If you operate a **validator** with downstream full nodes, update peer configurations as they enable UDP authentication. **For peers that have enabled UDP authentication**: * update `record_seq_num` and `name_record_sig` using the new values of the downstream node * set the `auth_port = 8001` Note: Authenticated UDP activated nodes would appear in the `peers.toml` file with `auth_port = 8001`. [[bootstrap.peers]] address = "188.214.131.5:8000" record_seq_num = 1 secp256k1_pubkey = "0x0342f3e447bd6951b2cf7cd717958a84e58dbe8cfbe2780f0247c69591216d2d7c" name_record_sig = "0x215e845dade986e48f6fcb1f065f3ff993ddf0d38b0ef41a05f6621d71bf4c6c2d25747629ac8a3d583418857bc0b4c75140202e14919faf643f431ade4b944d00" auth_port = 8001 # Add this for upgraded peers **For peers not yet enabled**, nothing needs to be updated, `auth_port` line should be omited: [[bootstrap.peers]] address = "188.214.131.6:8000" record_seq_num = 0 secp256k1_pubkey = "0x..." name_record_sig = "0x..." # No auth_port - this peer hasn't upgraded yet Note: the downstream nodes peering configuration do not need to be updated. Save and exit the file. * * * ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/auth-udp#5-restart-and-verify) 5\. Restart and Verify Restart the Monad service: sudo systemctl restart monad-bft Monitor the logs for successful startup: journalctl -u monad-bft -f -n 50 --no-pager * * * [​](https://docs.monad.xyz/node-ops/upgrade-instructions/auth-udp#verification) Verification ----------------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/auth-udp#check-service-status) Check Service Status systemctl status monad-bft --no-pager Expected: `active (running)` ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/auth-udp#verify-port-binding) Verify Port Binding sudo ss -ulpn | grep 8001 **Expected output:** udp UNCONN 0 0 0.0.0.0:8001 0.0.0.0:* users:(("monad-node",pid=12345,fd=20)) [​](https://docs.monad.xyz/node-ops/upgrade-instructions/auth-udp#troubleshooting) Troubleshooting ----------------------------------------------------------------------------------------------------- * * * ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/auth-udp#issue-%E2%80%9Cinvalid-name-record-signature-in-config-file%E2%80%9D) Issue: “invalid name record signature in config file” **Cause:** The signature in `node.toml` doesn’t match the parameters. **Solution:** 1. Verify you incremented `self_record_seq_num` correctly 2. Re-run `monad-sign-name-record` with the correct seq\_num 3. Copy the new signature to `node.toml` 4. Restart the service * * * ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/auth-udp#issue-port-8001-not-listening) Issue: Port 8001 Not Listening **Solution:** # Verify config grep -A5 "\[network\]" /home/monad/monad-bft/config/node.toml | grep authenticated # Check for startup errors journalctl -u monad-bft -n 100 --no-pager | grep -i error # Restart service sudo systemctl restart monad-bft * * * ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/auth-udp#issue-firewall-blocking-connections) Issue: Firewall Blocking Connections **Solution:** # Check current UFW rules sudo ufw status numbered # Add rule if missing sudo ufw allow 8001/udp comment 'monad authenticated udp' # Reload firewall sudo ufw reload * * * [​](https://docs.monad.xyz/node-ops/upgrade-instructions/auth-udp#rollback-instructions) Rollback Instructions ----------------------------------------------------------------------------------------------------------------- To disable UDP authentication if needed: ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/auth-udp#1-generate-new-signature-without-auth-port) 1\. Generate New Signature Without Auth Port source /home/monad/.env monad-sign-name-record \ --address $(curl -4 -s ifconfig.me):8000 \ --self-record-seq-num 2 \ --keystore-path /home/monad/monad-bft/config/id-secp \ --password "$KEYSTORE_PASSWORD" Note: Increment the seq\_num from your current value. ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/auth-udp#2-update-configuration) 2\. Update Configuration Edit `/home/monad/monad-bft/config/node.toml`: * Update `self_record_seq_num` and `self_name_record_sig` in `[peer_discovery]` * Remove or comment out `authenticated_bind_address_port` in `[network]` * Remove all `auth_port` entries from peer configurations ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/auth-udp#3-restart-service) 3\. Restart Service sudo systemctl restart monad-bft * * * [​](https://docs.monad.xyz/node-ops/upgrade-instructions/auth-udp#quick-health-check-script) Quick Health Check Script ------------------------------------------------------------------------------------------------------------------------- Save this as `check_udp_auth.sh` for quick verification: #!/bin/bash echo "=== Monad UDP Authentication Health Check ===" echo "" echo "Checking Monad version..." monad-node --version 2>/dev/null || echo "monad-node not found" echo "" echo "Checking firewall rule..." sudo ufw status | grep 8001 || echo "No UFW rule for 8001/udp" echo "" echo "Checking port binding..." sudo ss -tulpn | grep 8001 || echo "Port 8001 not bound" echo "" echo "Checking service status..." systemctl is-active monad-bft || echo "Service not active" echo "" echo "Checking configuration..." grep -q "authenticated_bind_address_port = 8001" /home/monad/monad-bft/config/node.toml && \ echo "authenticated_bind_address_port configured" || \ echo "authenticated_bind_address_port not found" echo "" echo "Complete!" Make it executable: chmod +x check_udp_auth.sh ./check_udp_auth.sh **Expected output:** === Monad UDP Authentication Health Check === Checking Monad version... monad-node {"commit":"e1e9489b8fc42c0a5af208bab20f6704f83c91c0","tag":"v0.12.7","branch":"","modified":true} Checking firewall rule... 8001/udp ALLOW Anywhere # authenticated udp port Checking port binding... udp UNCONN 0 0 0.0.0.0:8001 0.0.0.0:* users:(("monad-node",pid=3433495,fd=13)) Checking service status... active Checking configuration... authenticated_bind_address_port configured Complete! * * * [​](https://docs.monad.xyz/node-ops/upgrade-instructions/auth-udp#additional-notes) Additional Notes ------------------------------------------------------------------------------------------------------- * **Backward Compatibility**: Nodes can communicate with both authenticated and non-authenticated peers * **Gradual Rollout**: You can enable authentication at your own pace during the opt-in period * **Future Requirement**: UDP authentication will become mandatory in a future release (date TBD) * **Sequence Numbers**: Always increment `self_record_seq_num` when regenerating signatures * **Key Reuse**: Authentication uses your existing validator keys (secp256k1) * * * [​](https://docs.monad.xyz/node-ops/upgrade-instructions/auth-udp#support) Support ------------------------------------------------------------------------------------- If you encounter issues not covered in this guide: 1. Check logs: `journalctl -u monad-bft -n 500 --no-pager` 2. Verify all configuration parameters match the examples 3. Ensure your firewall and network policies allow UDP/8001 4. Contact Monad support with your logs and configuration (sanitized of sensitive data) [v0.12.7\ \ Previous](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.7) [Authenticated UDP Checking\ \ Next](https://docs.monad.xyz/node-ops/upgrade-instructions/authenticated-udp-checking) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Custody - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/tooling-and-infra/custody#content-area) See also [Institutional Wallets](https://docs.monad.xyz/tooling-and-infra/wallets/institutional-wallets) . [​](https://docs.monad.xyz/tooling-and-infra/custody#provider-summary) Provider Summary ------------------------------------------------------------------------------------------ The Monad blockchain and MON token are supported by a number of leading custody providers. | Service | Supported (Mainnet) | Docs | | --- | --- | --- | | [Anchorage Digital](https://www.anchorage.com/) | ✅ | | | [BitGo](https://www.bitgo.com/) | ✅ | [Docs](https://developers.bitgo.com/) | | [Coinbase Custody](https://www.coinbase.com/custody) | ✅ | [Docs](https://docs.cdp.coinbase.com/prime/introduction/welcome) | | [Fireblocks](https://www.fireblocks.com/) | ✅ | [Docs](https://developers.fireblocks.com/) | | [HexTrust](https://www.hextrust.com/) | ✅ | | [​](https://docs.monad.xyz/tooling-and-infra/custody#provider-details) Provider Details ------------------------------------------------------------------------------------------ ### [​](https://docs.monad.xyz/tooling-and-infra/custody#anchorage-digital) Anchorage Digital As the trusted custodian for leading institutions, Anchorage Digital offers a solution built to deliver the highest standards of security, mitigating the risk of human error and attack vectors while offering participation in digital assets through regulated entities. Clients can access Anchorage Digital’s custody services through Anchorage Digital Bank, the only federally chartered crypto bank in the U.S. and an unequivocal qualified custodian, or Anchorage Digital Singapore, a licensed Major Payment Institution by the Monetary Authority of Singapore (MAS). Learn more at [anchorage.com](https://www.anchorage.com/) . ### [​](https://docs.monad.xyz/tooling-and-infra/custody#bitgo) BitGo BitGo is the digital asset infrastructure company, delivering custody, wallets, staking, trading, financing, and settlement services from regulated cold storage. Since its founding in 2013, BitGo has been focused on accelerating the transition of the financial system to a digital asset economy. With a global presence and multiple regulated entities, BitGo serves thousands of institutions, including many of the industry’s top brands, exchanges, platforms, and millions of investors. For more information, visit [bitgo.com](https://www.bitgo.com/) . ### [​](https://docs.monad.xyz/tooling-and-infra/custody#coinbase-custody) Coinbase Custody Coinbase Custody provides a secure, institutional-grade cold storage solution for digital assets, enabling institutions to safely store and manage crypto assets with advanced security measures and operational controls. Learn more at [coinbase.com/custody](https://www.coinbase.com/custody) . ### [​](https://docs.monad.xyz/tooling-and-infra/custody#fireblocks) Fireblocks Fireblocks is the world’s most trusted digital asset infrastructure company, empowering organizations of all sizes to build, manage and grow their business on the blockchain. Secure and manage your digital assets with cutting-edge security technology, execute day-to-day treasury operations with automated workflows and connect seamlessly to exchanges, on/off-ramps, and DeFi protocols to access liquidity and earn yield. Learn more at [fireblocks.com](https://www.fireblocks.com/) . ### [​](https://docs.monad.xyz/tooling-and-infra/custody#hextrust) HexTrust Hex Trust is a licensed and regulated financial institution for digital assets, providing institutional-grade Markets, Custody, and Staking solutions. Trusted by builders, investors, and service providers, Hex Trust integrates directly with protocols and platforms to deliver secure, compliant, and scalable digital asset infrastructure. Learn more at [hextrust.com](https://www.hextrust.com/) . [Cross-Chain\ \ Previous](https://docs.monad.xyz/tooling-and-infra/cross-chain) [Earn/Yield Infrastructure\ \ Next](https://docs.monad.xyz/tooling-and-infra/earn-yield) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Oracles - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/tooling-and-infra/oracles#content-area) Oracles make off-chain data accessible on chain. [​](https://docs.monad.xyz/tooling-and-infra/oracles#definitions) Definitions -------------------------------------------------------------------------------- | Term | Description | | --- | --- | | Push oracle | Provider regularly pushes price data to the oracle contract on chain | | Pull (on-demand) oracle | User triggers price data update while calling a smart contract | | Custom oracle | A custom calculator | | VRF (Verifiable Random Function) | Provides random numbers on chain | [​](https://docs.monad.xyz/tooling-and-infra/oracles#provider-summary) Provider Summary ------------------------------------------------------------------------------------------ * Mainnet * Testnet | Provider | Status | Docs | Contract addresses | Live data | Support notes | | --- | --- | --- | --- | --- | --- | | [Chainlink](https://chain.link/) | ✅ | [Docs](https://docs.chain.link/) | See [contract addresses](https://github.com/monad-crypto/protocols/blob/main/mainnet/chainlink.jsonc) | [Live data](https://data.chain.link/streams) | * Push oracle ([Price Feeds](https://docs.chain.link/data-feeds/price-feeds)
)
* Pull oracle ([Data Streams](https://docs.chain.link/data-streams)
) | | [Chronicle](https://chroniclelabs.org/) | ✅ | [Docs](https://docs.chroniclelabs.org/) | See [contract addresses](https://github.com/monad-crypto/protocols/blob/main/mainnet/chronicle.jsonc) | | Push oracle; custom oracles | | [Pyth](https://www.pyth.network/) | ✅ | [Docs](https://docs.pyth.network/) | See [contract addresses](https://github.com/monad-crypto/protocols/blob/main/mainnet/pyth.jsonc) | [Live data](https://www.pyth.network/price-feeds) | [Pull oracle](https://docs.pyth.network/price-feeds/pull-updates)
;
[VRF](https://docs.pyth.network/entropy) | | [Redstone](https://www.redstone.finance/) | ✅ | [Docs](https://docs.redstone.finance/) | See [contract addresses](https://github.com/monad-crypto/protocols/blob/main/mainnet/redstone.jsonc) | [Live data](https://app.redstone.finance/app/tokens/) | [Push oracle](https://app.redstone.finance/app/feeds/?networks=10143)
;
[pull oracle](https://app.redstone.finance/app/pull-model/redstone-primary-prod) | | [Stork](https://stork.network/) | ✅ | [Docs](https://docs.stork.network/) | * See [contract addresses](https://github.com/monad-crypto/protocols/blob/main/mainnet/stork.jsonc)


* [Addresses](https://docs.stork.network/resources/contract-addresses/evm)
; [APIs](https://docs.stork.network/api-reference/contract-apis/evm)
; [Asset ID Registry](https://docs.stork.network/resources/asset-id-registry) | [Live Data](https://data.stork.network/) | [Push oracle](https://docs.stork.network/resources/stork-pushed-assets)
;
[Pull oracle](https://docs.stork.network/introduction/core-concepts) | | [Supra](https://supra.com/) | ✅ | [Docs](https://docs.supra.com/) | See [contract addresses](https://github.com/monad-crypto/protocols/blob/main/mainnet/supra_oracles.jsonc) | [Live data](https://supra.com/data) | [Push oracle](https://docs.supra.com/oracles/data-feeds/push-oracle)
;
[Pull oracle](https://docs.supra.com/oracles/data-feeds/pull-oracle)
;
[dVRF](https://docs.supra.com/oracles/dvrf) | | [Switchboard](https://switchboard.xyz/) | ✅ | [Docs](https://docs.switchboard.xyz/) | * See [contract addresses](https://github.com/monad-crypto/protocols/blob/main/mainnet/switchboard.jsonc)

* More info: [Deployments](https://docs.switchboard.xyz/docs-by-chain/evm) | | [Pull oracle](https://docs.switchboard.xyz/docs-by-chain/evm)
;
[Oracle aggregator](https://docs.switchboard.xyz/custom-feeds/advanced-feed-configuration/oracle-aggregator)
;
[VRF](https://docs.switchboard.xyz/docs-by-chain/evm/randomness) | _✅ = supported, ⌛️ = in progress, ❓ = unknown, ❌ = won’t support_ | Provider | Status | Docs | Contract addresses | Live data | Support notes | | --- | --- | --- | --- | --- | --- | | [Chainlink](https://chain.link/) | ✅ | [Docs](https://docs.chain.link/) | Price Feeds \[push oracle\]:

* BTC / USD: [`0x2Cd9D7E85494F68F5aF08EF96d6FD5e8F71B4d31`](https://testnet.monadvision.com/address/0x2Cd9D7E85494F68F5aF08EF96d6FD5e8F71B4d31)

* ETH / USD: [`0x0c76859E85727683Eeba0C70Bc2e0F5781337818`](https://testnet.monadvision.com/address/0x0c76859E85727683Eeba0C70Bc2e0F5781337818)

* LINK / USD: [`0x4682035965Cd2B88759193ee2660d8A0766e1391`](https://testnet.monadvision.com/address/0x4682035965Cd2B88759193ee2660d8A0766e1391)

* USDC / USD: [`0x70BB0758a38ae43418ffcEd9A25273dd4e804D15`](https://testnet.monadvision.com/address/0x70BB0758a38ae43418ffcEd9A25273dd4e804D15)

* USDT / USD: [`0x14eE6bE30A91989851Dc23203E41C804D4D71441`](https://testnet.monadvision.com/address/0x14eE6bE30A91989851Dc23203E41C804D4D71441)

* [general reference](https://docs.chain.link/data-feeds/price-feeds/addresses?page=1&testnetPage=1&network=monad)




Data Streams \[pull oracle\]:

* Data stream verifier proxy address: [`0xC539169910DE08D237Df0d73BcDa9074c787A4a1`](https://testnet.monadvision.com/address/0xC539169910DE08D237Df0d73BcDa9074c787A4a1) | [Live data](https://data.chain.link/streams) | * Push oracle ([Price Feeds](https://docs.chain.link/data-feeds/price-feeds)
)
* Pull oracle ([Data Streams](https://docs.chain.link/data-streams)
) | | [Chronicle](https://chroniclelabs.org/) | ✅ | [Docs](https://docs.chroniclelabs.org/) | [Address reference](https://docs.chroniclelabs.org/Developers/testnet) | [Dashboard](https://chroniclelabs.org/dashboard/oracles?blockchain=MON-TESTNET)
(toggle dev mode) | Push oracle; custom oracles | | [eOracle](https://eo.app/) | ✅ | [Docs](https://docs.eo.app/docs) | * Update conditions: 0.5% deviation & 24h heartbeat | [Dashboard](https://data.eo.app/) | Push oracle | | [Gelato VRF](https://docs.gelato.network/web3-services/vrf/quick-start) | ✅ | [Docs](https://docs.gelato.network/web3-services/vrf/quick-start) | | | VRF | | [Pyth](https://www.pyth.network/) | ✅ | [Docs](https://docs.pyth.network/) | * Price feeds: [`0x2880aB155794e7179c9eE2e38200202908C17B43`](https://testnet.monadvision.com/address/0x2880aB155794e7179c9eE2e38200202908C17B43)



* Beta price feeds (incl MON/USDC): [`0xad2B52D2af1a9bD5c561894Cdd84f7505e1CD0B5`](https://testnet.monadvision.com/address/0xad2B52D2af1a9bD5c561894Cdd84f7505e1CD0B5)



* Entropy: [`0x36825bf3Fbdf5a29E2d5148bfe7Dcf7B5639e320`](https://testnet.monadvision.com/address/0x36825bf3Fbdf5a29E2d5148bfe7Dcf7B5639e320) | [Live data](https://www.pyth.network/price-feeds)


[Beta live data](https://www.pyth.network/developers/price-feed-ids#beta)
(includes MON / USDC) | [Pull oracle](https://docs.pyth.network/price-feeds/pull-updates)
;
[VRF](https://docs.pyth.network/entropy) | | [Redstone](https://www.redstone.finance/) | ✅ | [Docs](https://docs.redstone.finance/) | * Push oracle [addresses](https://app.redstone.finance/app/feeds/?networks=10143)


* Update conditions for all: 0.5% deviation & 6h heartbeat | [Live data](https://app.redstone.finance/app/tokens/) | [Push oracle](https://app.redstone.finance/app/feeds/?networks=10143)
;
[pull oracle](https://app.redstone.finance/app/pull-model/redstone-primary-prod) | | [Stork](https://stork.network/) | ✅ | [Docs](https://docs.stork.network/) | * Pull oracle (includes MON/USD): [`0xacC0a0cF13571d30B4b8637996F5D6D774d4fd62`](https://testnet.monadvision.com/address/0xacC0a0cF13571d30B4b8637996F5D6D774d4fd62)


* [Addresses](https://docs.stork.network/resources/contract-addresses/evm)
; [APIs](https://docs.stork.network/api-reference/contract-apis/evm)
; [Asset ID Registry](https://docs.stork.network/resources/asset-id-registry) | [Live Data](https://data.stork.network/) | [Pull oracle](https://docs.stork.network/introduction/core-concepts) | | [Supra](https://supra.com/) | ✅ | [Docs](https://docs.supra.com/) | * Storage: [`0xf0e852BC3F940447862D6b67e5B9807E64B433F6`](https://testnet.monadvision.com/address/0xf0e852BC3F940447862D6b67e5B9807E64B433F6)

* Pull: [`0xF8522B7fcE37439b98A2be282d413A44269028bE`](https://testnet.monadvision.com/address/0xF8522B7fcE37439b98A2be282d413A44269028bE)

* Router: [`0x5CbC3Dfa33223884E7752a833Fa6aD28Ee015FC4`](https://testnet.monadvision.com/address/0x5CbC3Dfa33223884E7752a833Fa6aD28Ee015FC4)

* Deposit: [`0x95bfe6e94D5ff9e9d087647bc589acC9E3D31619`](https://testnet.monadvision.com/address/0x95bfe6e94D5ff9e9d087647bc589acC9E3D31619) | [Live data](https://supra.com/data) | [Push oracle](https://docs.supra.com/oracles/data-feeds/push-oracle)
;
[Pull oracle](https://docs.supra.com/oracles/data-feeds/pull-oracle)
;
[dVRF](https://docs.supra.com/oracles/dvrf) | | [Switchboard](https://switchboard.xyz/) | ✅ | [Docs](https://docs.switchboard.xyz/) | * Pull oracle: [`0xD3860E2C66cBd5c969Fa7343e6912Eff0416bA33`](https://testnet.monadvision.com/address/0xD3860E2C66cBd5c969Fa7343e6912Eff0416bA33)



* More info: [Deployments](https://docs.switchboard.xyz/docs-by-chain/evm) | [Live data](https://explorer.switchboardlabs.xyz/) | [Pull oracle](https://docs.switchboard.xyz/docs-by-chain/evm)
;
[Oracle aggregator](https://docs.switchboard.xyz/custom-feeds/advanced-feed-configuration/oracle-aggregator)
;
[VRF](https://docs.switchboard.xyz/docs-by-chain/evm/randomness) | _✅ = supported, ⌛️ = in progress, ❓ = unknown, ❌ = won’t support_ [​](https://docs.monad.xyz/tooling-and-infra/oracles#provider-details) Provider Details ------------------------------------------------------------------------------------------ ### [​](https://docs.monad.xyz/tooling-and-infra/oracles#chainlink) Chainlink #### [​](https://docs.monad.xyz/tooling-and-infra/oracles#chainlink-data-streams) Chainlink Data Streams [Chainlink Data Streams](https://docs.chain.link/data-streams) deliver low-latency market data offchain, which can be verified onchain. This approach provides decentralized applications (dApps) with on-demand access to high-frequency market data backed by decentralized, fault-tolerant, and transparent infrastructure. Traditional push-based oracles update onchain data at set intervals or when certain price thresholds are met. In contrast, Chainlink Data Streams uses a pull-based design that preserves trust-minimization with onchain verification. To get started, check out the [documentation](https://docs.chain.link/data-streams) . #### [​](https://docs.monad.xyz/tooling-and-infra/oracles#chainlink-price-feeds) Chainlink Price Feeds [Chainlink Price Feeds](https://docs.chain.link/data-feeds) are the quickest way to connect your smart contracts to real-world data such as asset prices. Data Feeds aggregate many data sources and publish them onchain using a combination of the [Decentralized Data Model](https://docs.chain.link/architecture-overview/architecture-decentralized-model?parent=dataFeeds) and [Offchain Reporting](https://docs.chain.link/architecture-overview/off-chain-reporting?parent=dataFeeds) . To get started, check out the [documentation](https://docs.chain.link/data-feeds) . ### [​](https://docs.monad.xyz/tooling-and-infra/oracles#chronicle) Chronicle Chronicle’s decentralized oracle network was originally built within MakerDAO for the development of DAI and is now available to builders on Monad. * **Data Feeds**: Builders can choose from 90+ data feeds, including crypto assets, yield rates, and RWAs. Chronicle’s data is sourced via custom-built data models, only utilizing Tier 1 sources. * **Transparency & Integrity**: Chronicle’s oracle network is fully transparent and verifiable via the [Chronicle dashboard](https://chroniclelabs.org/dashboard/oracles?blockchain=MON-TESTNET) . Users can cryptographically challenge the integrity of every oracle update using the ‘verify’ feature. Data is independently sourced by a [community of Validators](https://chroniclelabs.org/validators) including Gitcoin, Etherscan, Infura, DeFi Saver, and MakerDAO. * **Gas Efficiency**: Pioneering the Schnorr-based oracle architecture, Chronicle’s oracles use 60-80% less gas per update than other oracle providers. This lowest cost per update allows Push oracle updates to be made more frequently, enabling granular data reporting. * Every oracle implementation is customized to fit your needs. Implement one of our existing data models or contact Chronicle to develop custom oracle data feeds via [Discord](https://discord.gg/CjgvJ9EspJ) . Developers can dive deeper into Chronicle Protocol’s architecture and unique design choices via the [docs](https://docs.chroniclelabs.org/) . ### [​](https://docs.monad.xyz/tooling-and-infra/oracles#pyth) Pyth The [Pyth Network](https://www.pyth.network/) is one of the largest first-party oracle networks, delivering real-time data across a number of chains. Pyth introduces a low-latency [pull oracle](https://docs.pyth.network/price-feeds/pull-updates) design. Data providers push price updates to [Pythnet](https://docs.pyth.network/price-feeds/how-pyth-works/pythnet) every 400 ms. Users pull aggregated prices from Pythnet onto Monad when needed, enabling everyone in the onchain environment to access that data point most efficiently. Pyth Price Feeds features: * 400ms latency * [First-party](https://www.pyth.network/publishers) data sourced directly from financial institutions * [Price feeds](https://www.pyth.network/developers/price-feed-ids) ranging from crypto, stocks, FX, and metals * See also: [beta price feeds](https://www.pyth.network/developers/price-feed-ids#beta) (testnet MON/USD is a beta price feed) * Available on [many](https://docs.pyth.network/price-feeds/contract-addresses) major chains Contract Addresses for Monad Testnet: * Price feeds: [`0x2880aB155794e7179c9eE2e38200202908C17B43`](https://testnet.monadvision.com/address/0x2880aB155794e7179c9eE2e38200202908C17B43) * Beta price feeds: [`0xad2B52D2af1a9bD5c561894Cdd84f7505e1CD0B5`](https://testnet.monadvision.com/address/0xad2B52D2af1a9bD5c561894Cdd84f7505e1CD0B5) (testnet MON/USD is a beta price feed) * Entropy: [`0x36825bf3Fbdf5a29E2d5148bfe7Dcf7B5639e320`](https://testnet.monadvision.com/address/0x36825bf3Fbdf5a29E2d5148bfe7Dcf7B5639e320) The testnet `MON/USD` price feed is currently a beta feed on Pyth Network. To use the MON/USD feed, integrate the [beta price feed](https://testnet.monadvision.com/address/0xad2B52D2af1a9bD5c561894Cdd84f7505e1CD0B5) contract instead of the primary price feed contract.To get the MON/USD price feed offchain, use the beta hermes endpoint: [https://hermes-beta.pyth.network](https://hermes-beta.pyth.network/) ### [​](https://docs.monad.xyz/tooling-and-infra/oracles#redstone) Redstone [RedStone](https://www.redstone.finance/) is the fastest-growing modular oracle, specializing in yield-bearing collateral for lending markets, such as LSTs, LRTs and BTCFi. To get started, visit the [Redstone documentation](https://docs.redstone.finance/docs/introduction) . ### [​](https://docs.monad.xyz/tooling-and-infra/oracles#stork) Stork [Stork](https://stork.network/) is an oracle protocol that enables ultra low latency connections between data providers and both on and off-chain applications. The most common use-case for Stork is pulling and consuming market data in the form of real time price feeds for DeFi. Stork is implemented as a [pull oracle](https://docs.stork.network/introduction/core-concepts#docs-internal-guid-4b312e7b-7fff-1147-c04b-bbaadec1a82a) . Stork continuously aggregates, verifies, and audits data from trusted publishers, and makes that aggregated data available at sub-second latency and frequency. This data can then be pulled into any on or off-chain application as often as needed. To learn more about how Stork works, visit [Core Concepts](https://docs.stork.network/introduction/core-concepts) and [How It Works](https://docs.stork.network/introduction/how-it-works) . ### [​](https://docs.monad.xyz/tooling-and-infra/oracles#supra) Supra [Supra](https://supra.com/) provides VRF and decentralized oracle price feeds (push and pull based) that can be used for onchain and offchain use-cases such as spot and perpetual DEXes, lending protocols, and payments protocols. To get started, visit the [Supra documentation](https://docs.supra.com/) ### [​](https://docs.monad.xyz/tooling-and-infra/oracles#switchboard) Switchboard [Switchboard](https://switchboard.xyz/) is a permissionless oracle protocol that enables developers to bring any off-chain or cross-chain data onto Monad through verifiable, ultra-low-latency feeds. Switchboard features: * Fully permissionless feed creation via the [Feed Builder](https://explorer.switchboardlabs.xyz/feed-builder) : deploy custom oracles in minutes * [Switchboard Surge](https://docs.switchboard.xyz/docs-by-chain/evm/surge) : Low-latency data feeds with sub-10 ms updates for high-performance applications * Enterprise-grade reliability * [Aggregator](https://docs.switchboard.xyz/custom-feeds/advanced-feed-configuration/oracle-aggregator) : access multiple oracle sources (like the ones on this page) in a single transaction * [Data Feed Variables](https://docs.switchboard.xyz/product-documentation/data-feeds/designing-feeds/data-feed-variable-overrides) : bring API-gated or confidential data on-chain without exposing API keys * Customizable feeds: adjust feed parameters (confidence intervals, deviation thresholds, and more) to your dapp’s needs * Decentralized oracle network secured by globally distributed validator set * Verifiable Randomness: generate secure, verifiable random numbers for games, lotteries, and more * Supports any data type: prices, prediction markets, sports, weather, RWAs, etc Contract Address for Monad Mainnet: [`0xB7F03eee7B9F56347e32cC71DaD65B303D5a0E67`](https://monadvision.com/address/0xB7F03eee7B9F56347e32cC71DaD65B303D5a0E67) For more details, check out [Switchboard’s detailed EVM documentation](https://docs.switchboard.xyz/docs-by-chain/evm) . [Onramps\ \ Previous](https://docs.monad.xyz/tooling-and-infra/onramps) [Payment Orchestrators\ \ Next](https://docs.monad.xyz/tooling-and-infra/payment-orchestrators) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # MPP API Reference - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/reference/mpp/api#content-area) This page is a technical reference for `@monad-crypto/mpp`. For a developer-oriented guide with examples, visit the [overview](https://docs.monad.xyz/reference/mpp/overview) . [​](https://docs.monad.xyz/reference/mpp/api#server) Server -------------------------------------------------------------- ### [​](https://docs.monad.xyz/reference/mpp/api#example) Example server.ts import { monad } from "@monad-crypto/mpp/server"; import { Mppx } from "mppx"; import { privateKeyToAccount } from "viem/accounts"; const account = privateKeyToAccount(process.env.SERVER_PRIVATE_KEY as `0x${string}`); const mppx = Mppx.create({ methods: [\ monad({\ account,\ recipient: account.address,\ // ... parameters below\ }),\ ], }); ### [​](https://docs.monad.xyz/reference/mpp/api#parameters) Parameters The `monad` server payment method accepts the following parameters. | Parameter | Type | Default | Description | | --- | --- | --- | --- | | `amount` | `string` | — | Default payment amount, human-readable (e.g. `"1.50"`) | | `currency` | `string` | USDC | ERC-20 token contract address | | `decimals` | `number` | `6` | Token decimals | | `description` | `string` | — | Human-readable description | | `externalId` | `string` | — | External identifier to echo back in receipt | | `recipient` | `string` | — | Recipient address for payments | | `testnet` | `boolean` | `false` | Testnet mode | | `waitForConfirmation` | `boolean` | `true` | Whether to wait for the charge transaction to confirm on-chain | | `getClient` | `(params: { chainId?: number }) => Client` | — | Function that returns a viem Client for the given chain ID | | `account` | `Account \| Address` | — | Server account used to broadcast `receiveWithAuthorization` transactions. Required when accepting `authorization` payloads. The server pays gas from this account. | | `store` | `Store` | — | Store for transaction hash replay protection. Use a shared store in multi-instance deployments so consumed hashes are visible across all server instances. | [​](https://docs.monad.xyz/reference/mpp/api#client) Client -------------------------------------------------------------- ### [​](https://docs.monad.xyz/reference/mpp/api#example-2) Example client.ts import { monad } from "@monad-crypto/mpp/client"; import { Mppx } from "mppx/client"; import { privateKeyToAccount } from "viem/accounts"; const account = privateKeyToAccount(process.env.CLIENT_PRIVATE_KEY as `0x${string}`); const mppx = Mppx.create({ methods: [monad({ \ account,\ // ... parameters below\ })], }); // Make a paid request const response = await fetch("http://localhost:3000/premium"); const data = await response.json(); console.log(data); ### [​](https://docs.monad.xyz/reference/mpp/api#parameters-2) Parameters The `monad` client payment method accepts the following parameters. | Parameter | Type | Default | Description | | --- | --- | --- | --- | | `account` | `Account \| Address` | — | Wallet account. If omitted, resolved from the viem Client. | | `mode` | `"push" \| "pull"` | Auto | Payment mode. Defaults to `"push"` for JSON-RPC accounts, `"pull"` for local accounts. | | `getClient` | `(params: { chainId?: number }) => Client` | — | Custom viem Client resolver. Uses built-in RPC URLs if not provided. | [MPP Overview\ \ Previous](https://docs.monad.xyz/reference/mpp/overview) [Guides\ \ Next](https://docs.monad.xyz/guides) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # JSON-RPC Playground - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/reference/json-rpc/playground#content-area) [JSON-RPC Overview\ \ Previous](https://docs.monad.xyz/reference/json-rpc/overview) [JSON-RPC API Reference\ \ Next](https://docs.monad.xyz/reference/json-rpc/api) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Analytics - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/tooling-and-infra/analytics#content-area) **See also:** [Indexers → Common Data](https://docs.monad.xyz/tooling-and-infra/indexers/common-data) for providers of standard indexed chain data. [​](https://docs.monad.xyz/tooling-and-infra/analytics#provider-summary) Provider Summary -------------------------------------------------------------------------------------------- * Mainnet * Testnet | Service | Status | Docs | Description | | --- | --- | --- | --- | | [Blockaid](https://www.blockaid.io//) | ✅ | | Real-time detection platform for on-chain monitoring and fraud prevention | | [Birdeye](https://birdeye.so/) | ✅ | [Docs](https://docs.birdeye.so/) | Birdeye platform provides comprehensive multi-market data for cryptocurrency tokens, pulling information from both decentralized exchanges (DEX) and centralized exchanges (CEX). | | [Bubblemaps](https://bubblemaps.io/) | ✅ | [Docs](https://docs.bubblemaps.io/) | Visual analytics platform to investigate wallets, trace funds, and map token activity in real time | | [Chainalysis (including Hexagate)](https://www.chainalysis.com/) | ✅ | [Docs](https://auth-developers.chainalysis.com/) | Blockchain data platform for compliance, investigations, and risk management, including Hexagate real-time threat detection and prevention | | [CoinGecko](https://www.coingecko.com/) | ✅ | [Docs](https://docs.coingecko.com/) | Comprehensive crypto price & market data provider with on-chain DEX data, token discovery, and trading analytics | | [Collab.Land](https://collab.land/) | ✅ | [Docs](https://docs.collab.land/) | Community management tool that supports a wide range of projects, including DAOs, NFT communities, brands, and creators of all sizes | | [DeBank](https://debank.com/) | ✅ | [Docs](https://docs.cloud.debank.com/) | DeFi portfolio tracker and analytics platform | | [DeFiLlama](https://defillama.com/) | ✅ | [Docs](https://defillama.com/docs/api) | Open-source DeFi TVL and analytics platform aggregating data from thousands of protocols across multiple chains. See [How to list a DeFi project](https://docs.llama.fi/list-your-project/submit-a-project) | | [Dune](https://www.dune.com/) | ✅ | [Docs](https://docs.dune.com/home) | Datasets and dashboards about on-chain activity | | [Elliptic](https://www.elliptic.co/) | ✅ | [Docs](https://developers.elliptic.co/) | Analytics for compliance, risk management, and intelligence | | [Flipside](https://www.flipsidecrypto.xyz/) | ✅ | [Docs](https://docs.flipsidecrypto.xyz/) | AI-powered analytics for on-chain activity | | [InsightX](https://app.insightx.network/) | ✅ | [Docs](https://docs.insightx.network/docs) | Web3 transparency and security platform combining smart contract scanning with real-time holder maps for on-chain trading | | [Matrica](https://matrica.io/) | ✅ | [Docs](https://docs.matrica.io/) | Cross-chain Web3 social platform and community management solution. | | [Nansen](https://www.nansen.ai/) | ✅ | [Docs](https://docs.nansen.ai/) | Blockchain analytics platform providing wallet profiling, smart money tracking, and on-chain insights | | [Phalcon Explorer by Blocksec](https://blocksec.com/explorer) | ✅ | [Docs](https://docs.blocksec.com/phalcon/phalcon) | Explorer for understanding transaction details with fund flow, balance changes, invocation flow, gas usage, and more | | [Philidor](https://philidor.io/) | ✅ | [Docs](https://docs.philidor.io/docs) | Independent DeFi risk ratings and monitoring, scoring on-chain assets, vaults, and protocols across asset, platform, and governance dimensions | | [Tenderly](https://tenderly.co/) | ✅ | [Docs](https://docs.tenderly.co/) | Comprehensive toolkit including virtual testnets, explorer, debugger, transaction simulator, and monitoring | | [TRM Labs](https://www.trmlabs.com/) | ✅ | [Docs](https://docs.trmlabs.com/) | Blockchain intelligence platform for compliance, risk management, and financial crime investigation | | [zeroShadow](https://www.zeroshadow.io/) | ✅ | | Incident response and blockchain intelligence firm for investigations, threat detection, and stolen-asset recovery | _✅ = supported, ⌛️ = in progress, ❓ = unknown, ❌ = won’t support_ | Service | Status | Docs | Description | | --- | --- | --- | --- | | [Dune](https://www.alchemy.com/) | ✅ | [Docs](https://docs.dune.com/home) | Datasets and dashboards about on-chain activity | | [Flipside](https://www.flipsidecrypto.xyz/) | ✅ | [Docs](https://docs.flipsidecrypto.xyz/) | AI-powered analytics for on-chain activity | | [Phalcon](https://blocksec.com/explorer) | ✅ | [Docs](https://docs.blocksec.com/phalcon/phalcon) | Explorer for understanding transaction details with fund flow, balance changes, invocation flow, gas usage, and more | _✅ = supported, ⌛️ = in progress, ❓ = unknown, ❌ = won’t support_ [​](https://docs.monad.xyz/tooling-and-infra/analytics#provider-details) Provider Details -------------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/tooling-and-infra/analytics#birdeye) Birdeye [Birdeye](https://birdeye.so/) platform provides comprehensive multi-market data for cryptocurrency tokens, pulling information from both decentralized exchanges (DEX) and centralized exchanges (CEX). This allows users to monitor and analyze token performance across different exchange types in real-time, providing a holistic view of the market landscape. To learn more about the platform, check out the [documentation](https://docs.birdeye.so/) . ### [​](https://docs.monad.xyz/tooling-and-infra/analytics#blockaid) Blockaid [Blockaid](https://blockaid.io/) is the real-time detection platform purpose-built for web3 builders and operators to measure performance, mitigate risk, and prevent theft. ### [​](https://docs.monad.xyz/tooling-and-infra/analytics#bubblemaps) Bubblemaps [Bubblemaps](https://bubblemaps.io/) is a visual analytics platform to investigate wallets, trace funds, and map token activity in real time across all chains. To get started, check out the [docs](https://docs.bubblemaps.io/) or launch the [app](https://v2.bubblemaps.io/) . ### [​](https://docs.monad.xyz/tooling-and-infra/analytics#chainalysis-including-hexagate) Chainalysis (including Hexagate) [Chainalysis](https://www.chainalysis.com/) is a blockchain data platform providing compliance, investigation, and risk management solutions used by governments, financial institutions, and crypto businesses, with capabilities spanning transaction monitoring, address and sanctions screening, and on-chain investigations. It also includes [Hexagate](https://www.chainalysis.com/product/hexagate/) , a real-time web3 security platform that detects and helps mitigate on-chain threats such as exploits, hacks, and governance and financial risks. To get started, check out the [Chainalysis documentation](https://auth-developers.chainalysis.com/) . ### [​](https://docs.monad.xyz/tooling-and-infra/analytics#coingecko) CoinGecko [CoinGecko API](https://www.coingecko.com/en/api) is one of the most comprehensive and reliable crypto price & market data providers, serving on-chain DEX data across 250+ blockchain networks. CoinGecko provides real-time token prices, market statistics, trading data, OHLCV charts, and token discovery tools including trending pools, new pools, and advanced filtering capabilities. To get started, visit the [documentation](https://docs.coingecko.com/) for full details, or [sign up](https://www.coingecko.com/en/api/pricing) for a free API key. ### [​](https://docs.monad.xyz/tooling-and-infra/analytics#collab-land) Collab.Land [Collab.Land](https://docs.collab.land/) is a community management tool that supports a wide range of projects, including DAOs, NFT communities, brands, and creators of all sizes. Our mission is to provide tools that encourage pro-social activity within communities, particularly those that use tokens as a means of membership verification. To learn more about Collab.Land, check out the [documentation](https://docs.collab.land/) . ### [​](https://docs.monad.xyz/tooling-and-infra/analytics#debank) DeBank [DeBank](https://debank.com/) is a DeFi portfolio tracker and analytics platform that helps users manage their crypto assets across multiple chains. It provides comprehensive portfolio tracking, transaction history, and protocol analytics. To get started, check out the [DeBank documentation](https://docs.cloud.debank.com/) ### [​](https://docs.monad.xyz/tooling-and-infra/analytics#defillama) DeFiLlama [DeFiLlama](https://defillama.com/) is the largest open-source Total Value Locked (TVL) and DeFi analytics platform. It aggregates data from thousands of DeFi protocols across multiple chains, providing comprehensive insights into protocol TVL, token prices, yields, and DeFi trends. DeFiLlama offers both a user-friendly dashboard and a robust API for developers. To get started, visit the [DeFiLlama platform](https://defillama.com/) or check out the [API documentation](https://defillama.com/docs/api) . ### [​](https://docs.monad.xyz/tooling-and-infra/analytics#dune) Dune Dune is a blockchain analytics platform that empowers users to query, visualize, and share on-chain data across dozens of blockchains. It uses SQL as its primary query language, enabling analysts, developers, and researchers to build custom dashboards and explore everything from DeFi protocols to NFT markets. With a large library of community-created dashboards and visualizations, Dune fosters collaboration and open access to blockchain intelligence, while also offering premium features such as faster queries and private dashboards for professional teams. To get started, check out the [Dune documentation](https://docs.dune.com/home) ### [​](https://docs.monad.xyz/tooling-and-infra/analytics#elliptic) Elliptic [Elliptic](https://www.elliptic.co/) provides blockchain analytics for compliance, risk management, and intelligence, helping organizations screen wallets and transactions, monitor for illicit activity, and investigate on-chain funds flows across a broad range of assets and chains. To get started, check out the [Elliptic documentation](https://developers.elliptic.co/) . ### [​](https://docs.monad.xyz/tooling-and-infra/analytics#flipside) Flipside [Flipside](https://flipsidecrypto.xyz/home/) generates the most reliable and comprehensive blockchain data. All for free. To get started, check out the [Flipside documentation](https://docs.flipsidecrypto.xyz/) . ### [​](https://docs.monad.xyz/tooling-and-infra/analytics#insightx) InsightX [InsightX](https://app.insightx.network/) delivers actionable transparency and security insights across multiple chains, enabling traders to rapidly assess the risk and potential of on-chain assets in real time. To get started, check out the [docs](https://docs.insightx.network/docs) or launch the [app](https://app.insightx.network/) . ### [​](https://docs.monad.xyz/tooling-and-infra/analytics#matrica) Matrica [Matrica](https://matrica.io/) is a popular cross-chain web3 social platform and community management solution. It provides essential infrastructure for digital identity and community engagement, primarily focusing on Non-Fungible Tokens (NFTs). To get started, check out the [documentation](https://docs.matrica.io/) ### [​](https://docs.monad.xyz/tooling-and-infra/analytics#nansen) Nansen [Nansen](https://www.nansen.ai/) is a blockchain analytics platform that combines on-chain data with millions of wallet labels to provide actionable insights. It offers features like smart money tracking, wallet profiling, token analytics, and real-time alerts to help users discover opportunities and understand blockchain activity. To get started, visit the [Nansen platform](https://www.nansen.ai/) or check out the [Nansen documentation](https://docs.nansen.ai/) . ### [​](https://docs.monad.xyz/tooling-and-infra/analytics#phalcon) Phalcon Blocksec [Phalcon Explorer](https://blocksec.com/explorer) is a powerful transaction explorer designed for the DeFi community. It provides comprehensive data on invocation flow, source code, balance changes, transaction fund flows, gas profiler, and state changes. It also supports transaction debugging and transaction simulation. This tool aims to help developers, security researchers, and traders intuitively understand transactions. To get started, check out the [explorer](https://blocksec.com/explorer) or the [Phalcon documentation](https://docs.blocksec.com/phalcon/explorer) . ### [​](https://docs.monad.xyz/tooling-and-infra/analytics#philidor) Philidor [Philidor](https://philidor.io/) is an independent DeFi risk infrastructure platform that scores and monitors on-chain assets, vaults, and protocols using open, independent risk models. It produces deterministic composite risk scores across three vectors — asset, platform, and governance — delivered through dashboards and public APIs for allocators, protocol teams, and agents. To get started, check out the [documentation](https://docs.philidor.io/docs) . ### [​](https://docs.monad.xyz/tooling-and-infra/analytics#tenderly) Tenderly [Tenderly](https://tenderly.co/) is a comprehensive toolkit for smart contract developers. The platform offers features like real-time transaction monitoring, advanced debugging with detailed stack traces, gas profiling, smart contract verification, and simulation environments that allow developers to fork mainnets and test contract interactions without deploying to live networks. To get started, check out the [explorer](https://dashboard.tenderly.co/explorer) or the [documentation](https://docs.tenderly.co/) . ### [​](https://docs.monad.xyz/tooling-and-infra/analytics#trm-labs) TRM Labs [TRM Labs](https://www.trmlabs.com/) is a blockchain intelligence platform for compliance, risk management, and financial crime investigation. Its BLOCKINT API connects addresses to entities, surfaces risk exposure, and enables real-time wallet screening and transaction monitoring across dozens of chains. To get started, check out the [TRM Labs documentation](https://docs.trmlabs.com/) . ### [​](https://docs.monad.xyz/tooling-and-infra/analytics#zeroshadow) zeroShadow [zeroShadow](https://www.zeroshadow.io/) is an incident response and blockchain intelligence firm specializing in investigations, threat detection, and stolen-asset recovery. Its investigators trace the on-chain movement of stolen funds, coordinate with exchanges and law enforcement in real time, and support clients through the full incident lifecycle. To learn more, visit the [zeroShadow website](https://www.zeroshadow.io/) . [Agentic Payments\ \ Previous](https://docs.monad.xyz/tooling-and-infra/agentic-payments) [Block Explorers\ \ Next](https://docs.monad.xyz/tooling-and-infra/block-explorers) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Add Monad Testnet to Wallet - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/guides/add-monad-to-wallet/testnet#content-area) Follow this quick guide to add Monad Testnet to your wallet. * Add Monad Testnet automatically * Add Monad Testnet manually Click the button below to automatically add Monad Testnet to your wallet: To manually add Monad Testnet to your wallet, navigate to your wallet’s network settings and add a custom network with the following details: **Network Details:** [Add Monad Mainnet to Wallet\ \ Previous](https://docs.monad.xyz/guides/add-monad-to-wallet/mainnet) [Deploy a Contract\ \ Next](https://docs.monad.xyz/guides/deploy-smart-contract) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # EVM Resources - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/guides/evm-resources#content-area) Resources for learning about EVM development, from Solidity basics to low-level assembly languages. Solidity Resources ------------------ A comprehensive guide to learning Solidity, from beginner to advanced EVM Behavior ------------ EVM behavioral specification, opcode reference, and storage layout Other Languages --------------- Resources for Vyper, Huff, and Yul [How to Consume Execution Events in Rust\ \ Previous](https://docs.monad.xyz/guides/execution-events/consume-rust) [EVM Behavior\ \ Next](https://docs.monad.xyz/guides/evm-resources/evm-behavior) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Add Monad Mainnet to Wallet - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/guides/add-monad-to-wallet/mainnet#content-area) Follow this quick guide to add Monad Mainnet to your wallet. * Add Monad Mainnet automatically * Add Monad Mainnet manually Click the button below to automatically add Monad Mainnet to your wallet: To manually add Monad Mainnet to your wallet, navigate to your wallet’s network settings and add a custom network with the following details: **Network Details:** [Add Monad to Wallet\ \ Previous](https://docs.monad.xyz/guides/add-monad-to-wallet) [Add Monad Testnet to Wallet\ \ Next](https://docs.monad.xyz/guides/add-monad-to-wallet/testnet) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Reserve Balance - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/developer-essentials/reserve-balance#content-area) [​](https://docs.monad.xyz/developer-essentials/reserve-balance#introduction) Introduction --------------------------------------------------------------------------------------------- The **Reserve Balance** mechanism is a set of light constraints - at consensus time on which transactions can be **included**, and at execution time on which transactions **don’t revert** - which allow Monad to simultaneously support [asynchronous execution](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution) and [EIP-7702](https://docs.monad.xyz/developer-essentials/eip-7702) . The Reserve Balance mechanism is designed to preserve safety under asynchronous execution without interfering with normal usage patterns. **Most users and developers need not worry about the Reserve Balance constraints**, however we provide the details here for those encountering corner cases. [​](https://docs.monad.xyz/developer-essentials/reserve-balance#summary) Summary ----------------------------------------------------------------------------------- Asynchronous execution means that nodes achieve consensus on a block proposal prior to executing the transactions in that block. Execution is required to be completed in the next `k` (delay factor) blocks. (Currently `k=3`. _NOTE_: In the context of discussing [block states](https://docs.monad.xyz/monad-arch/consensus/block-states) and [asynchronous execution](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution) , letter `D` is usually used to denote the same parameter.) Because consensus operates on a `k`\-block delayed view of the global state, it is necessary to adjust the consensus and execution rules slightly to allow consensus to safely build and validate blocks that include only transactions whose gas costs can be paid for. Monad introduces the **Reserve Balance** mechanism to allow consensus and execution to collaborate across a multi-block lag to ensure that all EOAs must have enough MON in their account to pay for gas for any transaction included in the blockchain. Throughout this document, an **inflight transaction** refers to a transaction that has been included in a block less than `k` blocks ago. Here is a very brief summary of the rules: * From the perspective of a particular EOA, MON spent from that EOA in the course of a transaction is partitioned into two parts: **gas spend** and **value spend**. * In the case where the EOA was the sender: * **gas spend** is `gas_price * gas_limit`; * **value spend** is the `value` parameter on that transaction. * In the case where the EOA wasn’t the sender (where they previously delegated via EIP-7702 and some other EOA submitted a transaction which called this EOA): * **gas spend** is 0; * **value spend** is whatever MON is sent out during the course of executing this EOA’s code. * Let `user_reserve_balance = 10 MON` * _Execution time_: during execution, transactions revert due to **value spend** when that account’s ending balance (before refunds) dips below `user_reserve_balance`, except in certain circumstances described below. * _Consensus time_: For each account, consensus has a budget for the **gas spend** for all inflight transactions; this budget is `user_reserve_balance` (or the account’s balance from the lagged execution state, whichever is lower). The budget is further reduced if the first inflight transaction earned the exception mentioned above, by that transaction’s **value spend**. When performing block validity checks for block `n`, consensus checks that the budget is not exceeded. See also the formal definition in the [Monad Initial Spec](https://category-labs.github.io/category-research/monad-initial-spec-proposal.pdf) proposal from Category Labs. [​](https://docs.monad.xyz/developer-essentials/reserve-balance#parameters) Parameters ----------------------------------------------------------------------------------------- | Parameter | Value | | --- | --- | | `user_reserve_balance` | 10 MON | [​](https://docs.monad.xyz/developer-essentials/reserve-balance#why-is-reserve-balance-needed) Why is reserve balance needed? -------------------------------------------------------------------------------------------------------------------------------- Monad has asynchronous execution: consensus is allowed to progress with building and validating blocks without waiting for execution to catch up. Specifically, proposing and validating consensus block `n` only requires knowledge of the state obtained after applying block `n-k`. While asynchronous execution has performance benefits, it introduces a novel challenge: how is consensus supposed to know the validity of a block if it does not have the latest state? Let’s illustrate this challenge with an example (for our examples, we will use `k = 3`): Consensus is validating block 4, which contains a transaction `t` from Alice with the relevant fields as: sender=Alice, to=Bob, value=100, gas=1 Consensus only has the state that was obtained by executing block 1: block=1, balances={Alice: 110} If consensus simply accepts block 4 as valid because Alice appears to have enough balance, it risks a safety failure. For instance, Alice may have already spent her balance in transaction `t’` in block 2. This creates a denial-of-service (DoS) vector, as Alice could cause consensus to include many transactions for free. [​](https://docs.monad.xyz/developer-essentials/reserve-balance#first-attempt-at-a-solution) First attempt at a solution --------------------------------------------------------------------------------------------------------------------------- One idea is for the consensus client to statically inspect transactions in blocks 2 and later, checking if Alice has spent any value in her transactions. This would let consensus reject block 4 as invalid if any transaction before `t` (such as `t'`) in blocks 2, 3, or 4 originates from Alice and spends some value or gas. While this is a fine solution on the face of it, it suffers from two shortcomings: 1. Suppose, as part of smart contract execution in blocks 2 or 3, Alice received a lot of currency. She would have had enough balance to pay for transaction `t` despite `t'` existing, if only we had the latest state. So, rejecting transactions based solely on static checks is overly restrictive. 2. It is not only restrictive, it is also not safe with EIP-7702. With EIP-7702, Alice could have her account delegated to a smart contract, which can transfer out currency from Alice’s account in a way that is not statically inspectable by consensus. Concretely in our example, Alice does not need to send a transaction like `t'` from her account in order to spend currency from her account, if her account is delegated. A spend could potentially be triggered by a transaction submitted by anyone else. So our static check would not succeed and it may be unsafe to accept block 4 as valid even if we don’t see any other transaction from Alice in blocks 2, 3 and 4. [​](https://docs.monad.xyz/developer-essentials/reserve-balance#reserve-balance-as-the-solution) Reserve balance as the solution ----------------------------------------------------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/developer-essentials/reserve-balance#simple-version) Simple version Intuitively, the core idea of reserve balance is as follows: if consensus and execution agree ahead of time that, for each EOA, execution will prevent the ending balance from dropping below a certain pre-determined threshold known to consensus (`user_reserve_balance`), up to the sender’s **gas spend** allowance, then consensus can safely include a series of transactions whose running **gas spend** stays below `user_reserve_balance`, without knowing the latest state and without being vulnerable to the DoS vector described above. This concept can be generalized as follows: * _Execution time_: after execution (before gas refunds), a reserve-balance check is applied to the ending balance. For a non-sender account, the ending balance must not be lower than `min(balance at transaction start, user_reserve_balance)`. For the sender, the ending balance may be lower by at most the transaction’s **gas spend** (unless the emptying exception below applies). Excessive intermediate debits during execution are allowed as long as the ending balance is sufficient. * _Consensus time_: For each account, consensus has a budget for the **gas spend** for all inflight transactions; this budget is `user_reserve_balance` (or the account’s balance from the lagged execution state, whichever is lower). When performing block validity checks for block `n`, consensus checks that the budget is not exceeded. In Monad, `user_reserve_balance` is currently set to `10 MON` for each EOA. The above rule is sufficient to ensure all transactions included in consensus can be paid for, thus solving our problem. However, it has a drawback, which is that EOAs can’t spend all of their MON, and EOAs with balances below `user_reserve_balance` won’t be able to send any successful transactions. For instance, the following behaviors might be desired, but are currently blocked by the above rule (with `user_reserve_balance` set to `10 MON`): * Alice has a balance of 5 MON and wants to send 4.99 MON to Bob (plus pay 0.01 MON in gas) * Alice has a balance of 20 MON and wants to swap 18 MON into a memecoin (plus pay 0.01 MON in gas) To address this, we add some additional conditions under which transactions are allowed. ### [​](https://docs.monad.xyz/developer-essentials/reserve-balance#addressing-the-drawback) Addressing the drawback First let’s define an “emptying transaction”: A transaction is an **“emptying transaction”** iff * the sender is undelegated. * the sender has not sent any other transaction within the past `k` blocks. * nobody has sent a delegation or undelegation request for the sender within the past `k` blocks, including in this transaction. Such transactions are eligible for the emptying exception (see rules below). Notice that if a user account is **not** EIP-7702-delegated, then consensus can simply inspect transactions statically in order to estimate the lowest a user’s balance can possibly go. (This is because an undelegated user’s account can only be debited due to value transfers and gas fees specified in the transaction data). Therefore, we add the following exception to the reversion rule: 3. _Execution policy_: for each **undelegated** account sender: * _if_ a transaction is an emptying transaction * _then_ allow that transaction to proceed anyway (an “emptying transaction”). 4. _Consensus policy_: for each **undelegated** account sender: * _if_ a transaction is an emptying transaction * _then_ statically inspect that transaction’s total MON needs (i.e. `gas_bid * gas_limit + value`), and take into account the fact that execution will still allow this transaction through. This means that for any subsequent transactions in the next `k` blocks, the reserve balance that consensus is working with will be lower by `value`. This rule lets execution allow consistently-undelegated accounts to dip below the reserve balance once every `k` blocks. Since `k` blocks is 1.2 seconds, this policy should allow most small accounts to still interact with the blockchain normally. Note that an account is not eligible for the exception criteria if there was recent (within `k` blocks) undelegation request for the account even if it was already undelegated at that time. See [Full specification](https://docs.monad.xyz/developer-essentials/reserve-balance#full-specification) for details. The additional policy allows both of the examples mentioned at the end of the previous section, as long as they are the first transaction sent by the sender in `k` blocks. [​](https://docs.monad.xyz/developer-essentials/reserve-balance#discussion) Discussion ----------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/developer-essentials/reserve-balance#eip-7702-delegated-accounts) EIP-7702-delegated accounts If an EOA is not EIP-7702-delegated, then the reserve balance is rarely invasive, even if the EOA’s balance is very low, because most transactions are the first transaction in `k=3` blocks sent by that EOA. But what if the EOA _is_ EIP-7702-delegated? What is the impact? * The only transactions that will revert are ones in which the balance of an EIP-7702-delegated EOA **dips below** 10 MON. * _‘Dips below’_ means _‘decrements **and** drops below’_. * Transactions where the EOA’s balance ends above or at 10 MON are fine. * Transactions where the EOA’s balance is unchanged or increases are fine. * **Only** transactions that decrement the balance **and** result in a final balance below 10 MON are reverted. * Delegated EOAs cannot use the emptying exception described above. For example, many sponsored gas workflows have users set up EIP-7702-delegated EOAs that don’t interact with MON at all (i.e. they start out empty, and only receive MON involuntarily). Under a typical such workflow, a sponsor submits a transaction that calls into the EOA as smart contract. This workflow works fine in Monad; it’s fine for the EOA in question to have a zero or very small balance. The only case where a sponsored gas workflow will be blocked is if the EOA’s balance is (say) 6 MON, and the sponsored transaction calls code that tries to transfer (say) 1 MON out of the EOA. ### [​](https://docs.monad.xyz/developer-essentials/reserve-balance#transactions-that-are-included-but-revert) Transactions that are included but revert Because of the Reserve Balance rules, you may see transactions _included_ in the chain whose execution _reverts_, such as transactions trying to transfer out more MON than are in the account balance. These transactions are still _valid_ transactions that pay for gas, but the _result_ of these transactions is nothing except for gas being decremented from the sender. They are included because at the time of consensus, the proposer cannot be sure that the account isn’t going to receive more MON from someone else, and the sender has the budget to pay for gas. Ethereum includes many transactions whose execution reverts, so this is not a protocol difference. However, in practice, Ethereum block builders may screen out transactions with insufficient balance to process a transfer out, so this behavior may be different from what you’re accustomed to seeing. ### [​](https://docs.monad.xyz/developer-essentials/reserve-balance#detecting-a-reserve-balance-dip) Detecting a reserve balance dip A contract can check at execution time whether its current execution has dipped into the reserve balance by calling the [reserve balance precompile](https://docs.monad.xyz/developer-essentials/precompiles#reserve-balance-precompile) at `0x1001`. It exposes a single method, `dippedIntoReserve()` (selector `0x3a61584e`, gas cost `100`), which returns a `bool`. It is specified in [MIP-4](https://mips.monad.xyz/MIPs/MIP-4) . `dippedIntoReserve()` must be invoked via `CALL`. Invoking it via `STATICCALL` - or via `DELEGATECALL` or `CALLCODE` - reverts. Although it reads state and returns a value, it is intentionally not a `view` function, so that a Solidity call site compiles to `CALL` rather than `STATICCALL`. [​](https://docs.monad.xyz/developer-essentials/reserve-balance#full-specification) Full specification --------------------------------------------------------------------------------------------------------- See the [reserve balance spec](https://category-labs.github.io/category-research/monad-initial-spec-proposal.pdf) for the formal set of Reserve Balance rules. Algorithms 1 and 2 implement this check for consensus and execution, respectively. Algorithm 3 implements the mechanism to detect the dipping into the reserve balance (Algorithm 2 uses Algorithm 3 to revert transactions that dip). Algorithm 4 specifies the criteria for emptying transactions: * The sender account must be undelegated in the prior `k` blocks. This is checked statically by verifying the account was undelegated in a known state in the past `k` blocks, and there have been no delegation or undelegation requests in the last `k` blocks (this can be inspected statically). * There must not be another transaction from the same sender in the prior k blocks. Here is a quick summary of the reserve balance rules at consensus time: #### [​](https://docs.monad.xyz/developer-essentials/reserve-balance#if-the-account-is-not-delegated-and-there-are-no-inflight-transactions) If the account is not delegated and there are no inflight transactions If the account is not delegated, and there are no previous inflight transactions, then consensus checks that the gas fee for this transaction is less than the balance from the lagged state. gas\_fees(tx)≤balance\\text{gas\\\_fees}(\\text{tx}) \\leq \\text{balance}gas\_fees(tx)≤balance #### [​](https://docs.monad.xyz/developer-essentials/reserve-balance#if-the-account-is-not-delegated-and-has-one-emptying-inflight-transaction) If the account is not delegated and has one emptying inflight transaction If the account is not delegated, and there is one previous inflight transaction, then consensus has to take into account the inflight transaction’s total MON expenditures (including `value`): let adjusted\_balance\=balance−(first\_tx.value+gas\_fees(first\_tx))\\text{let adjusted\\\_balance} = \\text{balance} - (\\text{first\\\_tx.value} + \\text{gas\\\_fees}(\\text{first\\\_tx}))let adjusted\_balance\=balance−(first\_tx.value+gas\_fees(first\_tx)) let reserve\=min⁡(user\_reserve\_balance(t.sender),adjusted\_balance)\\text{let } \\text{reserve} = \\min(\\text{user\\\_reserve\\\_balance}(t.\\text{sender}), \\text{adjusted\\\_balance}) \\quadlet reserve\=min(user\_reserve\_balance(t.sender),adjusted\_balance) A new transaction can only be included if the sum of all inflight transactions’ gas fees (excluding the first one) is less than the reserve: ∑tx∈I\[1:\]gas\_fees(tx)≤reserve\\sum\_{tx \\in I\[1:\]} \\text{gas\\\_fees}(tx) \\leq \\text{reserve}tx∈I\[1:\]∑​gas\_fees(tx)≤reserve #### [​](https://docs.monad.xyz/developer-essentials/reserve-balance#all-other-cases) All other cases The reserve is equal to minimum of systemwide reserve balance (`10 MON`) or the account’s balance at block `n - k`: reserve\=min⁡(user\_reserve\_balance(t.sender),balance)\\text{reserve} = \\min(\\text{user\\\_reserve\\\_balance}(t.\\text{sender}), \\text{balance})reserve\=min(user\_reserve\_balance(t.sender),balance) A new transaction can only be included if the sum of all inflight transactions’ gas fees is less than the reserve: ∑tx∈Igas\_fees(tx)≤reserve\\sum\_{tx \\in I} \\text{gas\\\_fees}(tx) \\leq \\text{reserve}tx∈I∑​gas\_fees(tx)≤reserve [​](https://docs.monad.xyz/developer-essentials/reserve-balance#adjusting-the-reserve-balance) Adjusting the reserve balance ------------------------------------------------------------------------------------------------------------------------------- The reserve balance is currently the same for every account (`10 MON`). In a future version, the protocol could allow users, through a stateful precompile, to customize their reserve balance. [​](https://docs.monad.xyz/developer-essentials/reserve-balance#coq-proofs) Coq proofs ----------------------------------------------------------------------------------------- The safety of the reserve balance specification has been formally proved in Coq. The full proofs documentation is available [here](https://category-labs.github.io/category-research/reserve-balance-coq-proofs) . The consensus check is formalized in Coq as `consensusAcceptableTxs`. The predicate, `consensusAcceptableTxs s ltx`, defines the criteria for the consensus module to accept the list of transactions `ltx` on top of state `s`. The proof shows that `consensusAcceptableTxs s ltx` implies that when the execution module executes all the transactions in ltx one by one on top of s, none of them will fail due to having insufficient balance to cover gas fees. The proof is by induction on the list `ltx`: one can think of this as doing natural induction on the length of `ltx`. The proof in the inductive step involves unfolding the definitions of the consensus and execution checks and considering all the cases. In each case, the estimates of effective reserve balance in consensus checks is shown to be conservative with respect to what happens in execution. [​](https://docs.monad.xyz/developer-essentials/reserve-balance#additional-examples) Additional examples ----------------------------------------------------------------------------------------------------------- To test your understanding, here are some examples along with the expected outcome. Each example is independent. In the following examples, we use `start_block = 2`, meaning the initial balances and reserves are after block 1. We also specify the reserve balance parameter for each example, although it is a constant system wide parameter. For each transaction, the expected result is indicated by a code: * **2**: Successfully executed * **1**: Included but reverted during execution (due to reserve balance dip) * **0**: Excluded by consensus ### [​](https://docs.monad.xyz/developer-essentials/reserve-balance#example-1-basic-transaction-inclusion) Example 1: Basic transaction inclusion Initial state: Alice: balance = 100, reserve = 10 Bob: balance = 5, reserve = 10 Transactions: Block 2: [\ Alice: send 1 MON, fee 0.05 — Expected: 2\ Bob: send 2 MON, fee 0.05 — Expected: 2\ ] Final balances: Alice: 98.95 Bob: 2.95 ### [​](https://docs.monad.xyz/developer-essentials/reserve-balance#example-2-low-reserve-balance-but-high-balance) Example 2: Low reserve balance but high balance Initial state: Alice: balance = 100, reserve = 1 Transactions: Block 2: [\ Alice: send 3 MON, fee 2 — Expected: 2 (emptying transaction)\ Alice: send 3 MON, fee 2 — Expected: 0 (excluded)\ ] Final balance: Alice: 95.0 ### [​](https://docs.monad.xyz/developer-essentials/reserve-balance#example-3-multi-block-low-reserve-but-high-balance) Example 3: Multi-block, low reserve but high balance Initial state: Alice: balance = 100, reserve = 1 Transactions: Block 2: [\ Alice: send 3 MON, fee 2 — Expected: 2\ ] Block 5: [\ Alice: send 3 MON, fee 2 — Expected: 2\ ] Final balance: Alice: 90.0 ### [​](https://docs.monad.xyz/developer-essentials/reserve-balance#example-4-comprehensive) Example 4: Comprehensive Initial state: Alice: balance = 100, reserve = 1 Transactions: Block 2: [\ Alice: send 99 MON, fee 0.1 — Expected: 2 (large emptying transaction)\ ] Block 3: [\ Alice: send 0.5 MON, fee 0.99 — Expected: 0 (excluded)\ ] Block 4: [\ Alice: send 0.8 MON, fee 0.1 — Expected: 1 (included but reverted)\ ] Block 5: [\ Alice: send 0 MON, fee 0.9 — Expected: 0 (excluded)\ Alice: send 5 MON, fee 0.1 — Expected: 1 (included but reverted)\ Alice: send 5 MON, fee 0.8 — Expected: 0 (excluded)\ ] Final balance: Alice: 0.70 ### [​](https://docs.monad.xyz/developer-essentials/reserve-balance#example-5-edge-case-%E2%80%94-zero-value-transactions) Example 5: Edge case — zero value transactions Initial state: Alice: balance = 2, reserve = 1 Transactions: Block 2: [\ Alice: send 0 MON, fee 0.5 — Expected: 2\ Alice: send 0 MON, fee 0.6 — Expected: 2\ Alice: send 0 MON, fee 0.5 — Expected: 0 (exceeds reserve)\ ] Final balance: Alice: 0.9 ### [​](https://docs.monad.xyz/developer-essentials/reserve-balance#example-6-reserve-balance-boundary) Example 6: Reserve balance boundary Initial state: Alice: balance = 10, reserve = 2 Transactions: Block 2: [\ Alice: send 1 MON, fee 2 — Expected: 2 (matches reserve)\ Alice: send 0 MON, fee 0.01 — Expected: 2\ ] Final balance: Alice: 6.99 ### [​](https://docs.monad.xyz/developer-essentials/reserve-balance#example-7-account-delegated-in-the-interim) Example 7: Account delegated in the interim Initial state: Alice: balance = 15, reserve = 10 Transactions: Block 1: [] Block 2: [\ Alice is delegated\ Bob on behalf of Alice: send 5 MON, fee 0 — Expected: 2 (executed)\ Alice is undelegated\ ] Block 3: [\ Alice: send 3 MON, fee 0.1 — Expected: 1 (included but reverted)\ ] Block 4: [] Block 5: [\ Alice: send 0 MON, fee 8 - Expected: 2 (executed)\ ] Final balance: Alice: 1.9 **NOTE**: If execution would not have reverted transaction in `Block 3` (by checking delegation status in prior `k` blocks), consensus would include transaction in `Block 5` which would later run out of MON for the fee. Also, consider `Block 2` is empty instead. Transaction in `Block 3` is then an emptying transaction, which proceeds with execution, but transaction in `Block 5` is excluded as not having enough reserve for fee. ### [​](https://docs.monad.xyz/developer-essentials/reserve-balance#example-8-account-receives-mon-before-second-inflight-tx) Example 8: Account receives MON before second inflight tx Initial state: Alice: balance = 15, reserve = 10 Transactions: Block 1: [] Block 2: [\ Alice: send 6 MON, fee 0.1 - Expected: 2 (executed, emptying tx)\ ] Block 3: [\ Alice receives 6 MON from a smart contract \ Alice: send 7 MON, fee 0.1 — Expected: 1 (included but reverted, cannot be 2nd emptying so soon)\ ] Block 4: [] Block 5: [\ Alice: send 0 MON, fee 8 - Expected: 2 (executed)\ ] Final balance: Alice: 6.8 **NOTE**: If execution would not have reverted the 2nd transaction in `Block 3` (from Alice; by checking existence of emptying transactions in prior `k` blocks), consensus would include transaction in `Block 5` which would later run out of MON for the fee. Also, consider `Block 2` is empty instead. Transaction in `Block 3` (from Alice) is then an emptying transaction, which proceeds with execution, but transaction in `Block 5` is excluded as one potentially not having enough reserve for fee - consensus doesn’t see Alice being credited in `Block 3`. [Precompiles\ \ Previous](https://docs.monad.xyz/developer-essentials/precompiles) [EIP-7702 on Monad\ \ Next](https://docs.monad.xyz/developer-essentials/eip-7702) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # RPC Providers - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/tooling-and-infra/rpc-providers#content-area) See also: [API reference](https://docs.monad.xyz/reference/json-rpc) [​](https://docs.monad.xyz/tooling-and-infra/rpc-providers#provider-summary) Provider Summary ------------------------------------------------------------------------------------------------ * Mainnet * Testnet | Provider | Status | Notes | | --- | --- | --- | | [Alchemy](https://www.alchemy.com/) | ✅ | Alchemy Monad [docs](https://www.alchemy.com/docs/reference/monad-api-quickstart) | | [Ankr](https://www.ankr.com/) | ✅ | Ankr Monad [docs](https://www.ankr.com/web3-api/chains-list/monad/) | | [Blockdaemon](https://www.blockdaemon.com/) | ✅ | Blockdaemon Monad [docs](https://www.blockdaemon.com/protocols/monad) | | [BlockPI](https://blockpi.io/) | ✅ | BlockPI Monad [docs](https://blockpi.io/chain/monad) | | [Chainstack](https://chainstack.com/build-better-with-monad/) | ✅ | Chainstack Monad [docs](https://docs.chainstack.com/reference/monad-getting-started) | | [dRPC NodeCloud](https://drpc.org/) | ✅ | dRPC NodeCloud Monad [docs](https://drpc.org/chainlist/monad-mainnet-rpc) | | [Dwellir](https://dwellir.com/) | ✅ | Dwellir Monad [docs](https://dwellir.com/networks/monad) | | [Envio](https://envio.dev/) | ✅ | HyperRPC is a performant read-only RPC. See [docs](https://docs.envio.dev/docs/HyperRPC/overview-hyperrpc) | | [GetBlock](https://getblock.io/) | ✅ | GetBlock Monad [docs](https://getblock.io/nodes/monad/) | | [OnFinality](https://onfinality.io/) | ✅ | OnFinality Monad [docs](https://onfinality.io/en/networks/monad-mainnet) | | [Quicknode](https://www.quicknode.com/) | ✅ | Quicknode Monad [docs](https://www.quicknode.com/chains/monad) | | [Spectrum](https://spectrumnodes.com/) | ✅ | | | [Tatum](https://tatum.io/) | ✅ | Tatum Monad [docs](https://tatum.io/exclusive/monad) | | [thirdweb](https://thirdweb.com/) | ✅ | thirdweb RPC Edge [docs](https://portal.thirdweb.com/infrastructure/rpc-edge/overview) | | [Triton One](https://triton.one/) | ✅ | Triton One Monad [docs](https://docs.triton.one/chains/monad) | | [Validation Cloud](https://validationcloud.io/) | ✅ | Validation Cloud Monad [docs](https://docs.validationcloud.io/monad) | _✅ = supported, ⌛️ = in progress, ❓ = unknown, ❌ = won’t support_ | Provider | Status | Notes | | --- | --- | --- | | [Alchemy](https://www.alchemy.com/) | ✅ | Alchemy Monad [docs](https://www.alchemy.com/docs/reference/monad-api-quickstart) | | [Ankr](https://www.ankr.com/) | ✅ | Ankr Monad [docs](https://www.ankr.com/web3-api/chains-list/monad/) | | [Blockdaemon](https://www.blockdaemon.com/) | ✅ | Blockdaemon Monad [docs](https://www.blockdaemon.com/protocols/monad) | | [BlockPI](https://blockpi.io/) | ✅ | BlockPI Monad [docs](https://blockpi.io/chain/monad) | | [Chainstack](https://chainstack.com/build-better-with-monad/) | ✅ | Chainstack Monad [docs](https://docs.chainstack.com/reference/monad-getting-started) | | [dRPC NodeCloud](https://drpc.org/) | ✅ | dRPC NodeCloud Monad [docs](https://drpc.org/chainlist/monad-testnet-rpc) | | [Dwellir](https://dwellir.com/) | ✅ | Dwellir Monad [docs](https://dwellir.com/networks/monad) | | [Envio](https://envio.dev/) | ✅ | HyperRPC is a performant read-only RPC. See [docs](https://docs.envio.dev/docs/HyperRPC/overview-hyperrpc) | | [GetBlock](https://getblock.io/) | ✅ | GetBlock Monad [docs](https://getblock.io/nodes/monad/) | | [OnFinality](https://onfinality.io/) | ✅ | OnFinality Monad [docs](https://onfinality.io/en/networks/monad-mainnet) | | [Quicknode](https://www.quicknode.com/) | ✅ | Quicknode Monad [docs](https://www.quicknode.com/chains/monad) | | [Spectrum](https://spectrumnodes.com/) | ✅ | | | [Tatum](https://tatum.io/) | ✅ | Tatum Monad [docs](https://tatum.io/chain/monad) | | [thirdweb](https://thirdweb.com/) | ✅ | thirdweb RPC Edge [docs](https://portal.thirdweb.com/infrastructure/rpc-edge/overview) | | [Validation Cloud](https://validationcloud.io/) | ✅ | Validation Cloud Monad [docs](https://docs.validationcloud.io/monad) | _✅ = supported, ⌛️ = in progress, ❓ = unknown, ❌ = won’t support_ [​](https://docs.monad.xyz/tooling-and-infra/rpc-providers#provider-details) Provider Details ------------------------------------------------------------------------------------------------ ### [​](https://docs.monad.xyz/tooling-and-infra/rpc-providers#alchemy) Alchemy [Alchemy](https://www.alchemy.com/) is a popular API provider and developer platform. Its robust, free tier offers access to JSON-RPC APIs, and hosted testnet nodes for Monad Testnet. ### [​](https://docs.monad.xyz/tooling-and-infra/rpc-providers#ankr) Ankr [Ankr](https://www.ankr.com/web3-api/) provides private and public RPC endpoints for Monad, powered by a globally distributed and decentralized network of nodes. ### [​](https://docs.monad.xyz/tooling-and-infra/rpc-providers#blockdaemon) Blockdaemon [Blockdaemon](https://www.blockdaemon.com/) provides enterprise-grade web3 infrastructure, including dedicated nodes, APIs, staking, liquid staking, MPC wallets, and more. To get started, visit the [Blockdaemon documentation](https://docs.blockdaemon.com/) . ### [​](https://docs.monad.xyz/tooling-and-infra/rpc-providers#blockpi) BlockPI [BlockPI](https://blockpi.io/) provides enterprise-grade, high-performance RPC services for both Monad Mainnet and Testnet. Whatever you’re building on Monad, we offer this premium service at a fraction of the market average price, making high-quality RPC access affordable for everyone. To get started, visit [BlockPI’s Monad page](https://blockpi.io/chain/monad) . ### [​](https://docs.monad.xyz/tooling-and-infra/rpc-providers#chainstack) Chainstack [Chainstack](https://chainstack.com/build-better-with-monad/) provides low-latency, highly reliable, and scalable RPC infrastructure for Monad. You can deploy robust Monad Mainnet and Testnet nodes and access [geo-balanced RPC endpoints](https://chainstack.com/global-nodes/) on a secure, SOC 2–certified platform. To get started, create a free account with a [Monad RPC node](https://chainstack.com/) . ### [​](https://docs.monad.xyz/tooling-and-infra/rpc-providers#drpc-nodecloud) dRPC NodeCloud [dRPC NodeCloud](https://drpc.org/) delivers robust, low-latency RPC for Monad. Free accounts & paid plans from $10. Full speed. No limits, build confidently. To get started, visit the [dRPC’s Monad page](https://drpc.org/chainlist/monad-testnet-rpc) . ### [​](https://docs.monad.xyz/tooling-and-infra/rpc-providers#dwellir) Dwellir [Dwellir](https://dwellir.com/) supports Monad Mainnet and Testnet endpoints as well as over 100+ other blockchain networks. And best of all: every response costs the same—no compute units. To get started, visit the [Dwellir Monad page](https://dwellir.com/networks/monad) . ### [​](https://docs.monad.xyz/tooling-and-infra/rpc-providers#envio) Envio [Envio](https://envio.dev/) has a free read only RPC that supports a subset of data intensive [methods](https://docs.envio.dev/docs/HyperRPC/overview-hyperrpc#supported-methods) , Envio’s purpose built rust node supports historical data allowing you to query past 10,000 blocks into the past. To get started, visit the [Envio documentation](https://docs.envio.dev/docs/HyperRPC/overview-hyperrpc) ### [​](https://docs.monad.xyz/tooling-and-infra/rpc-providers#getblock) GetBlock [GetBlock](https://getblock.io/) provides reliable RPC endpoints for Monad, offering shared and dedicated nodes with high availability and performance. To get started, visit the [GetBlock Monad page](https://getblock.io/nodes/monad/) . ### [​](https://docs.monad.xyz/tooling-and-infra/rpc-providers#onfinality) OnFinality [OnFinality](https://onfinality.io/) provides high performance RPC for Monad Mainnet and Testnet, along with support for many other leading networks so teams can build cross chain from Monad with ease. OnFinality infrastructure delivers 99.99% uptime, fast response times, and pricing that is friendly for teams of every size. Start building on Monad today with reliable and scalable RPC from [OnFinality](https://onfinality.io/en/networks/monad-mainnet) . ### [​](https://docs.monad.xyz/tooling-and-infra/rpc-providers#quicknode) Quicknode [Quicknode](https://www.quicknode.com/) offers access to their [Core RPC API](https://www.quicknode.com/core-api) for both Monad Testnet and Mainnet. Quicknode provides managed, high-performance RPC endpoints with instant access. To get started, visit [Quicknode’s Monad page](https://www.quicknode.com/chains/monad) . ### [​](https://docs.monad.xyz/tooling-and-infra/rpc-providers#spectrum) Spectrum [Spectrum](https://spectrumnodes.com/) is an enterprise-grade RPC Infrastructure provider that makes it easy to deploy and manage dedicated RPC endpoints to over 150 networks. Sign up today to get started on Monad. To get started, visit the [Spectrum dashboard](https://dashboard.spectrumnodes.com/auth/signup) . ### [​](https://docs.monad.xyz/tooling-and-infra/rpc-providers#tatum) Tatum [Tatum](https://tatum.io/) provides RPC nodes, blockchain data, and real-time notifications. To get started, visit the [Tatum documentation](https://docs.tatum.io/) . ### [​](https://docs.monad.xyz/tooling-and-infra/rpc-providers#thirdweb) thirdweb [thirdweb](https://thirdweb.com/) ’s [RPC Edge](https://portal.thirdweb.com/infrastructure/rpc-edge/overview) provides an RPC endpoint for developers building on Monad. To get started, visit the [Thirdweb RPC Edge documentation](https://portal.thirdweb.com/infrastructure/rpc-edge/overview) . ### [​](https://docs.monad.xyz/tooling-and-infra/rpc-providers#triton-one) Triton One [Triton One](https://triton.one/triton-rpc/) is a reliable, globally distributed Monad RPC provider built for teams that need consistent performance under load, high throughput, and uninterrupted uptime. To get started, visit the Triton One Monad [docs](https://docs.triton.one/chains/monad) . ### [​](https://docs.monad.xyz/tooling-and-infra/rpc-providers#validation-cloud) Validation Cloud [Validation Cloud](https://validationcloud.io/) is the world’s fastest node provider according to Compare Nodes. With 50 million compute units available for use without a credit card and a scale tier that never has rate limits, Validation Cloud is built to support your most rigorous and low-latency workloads. To get started, visit the [Validation Cloud Monad documentation](https://docs.validationcloud.io/monad) . [Privacy\ \ Previous](https://docs.monad.xyz/tooling-and-infra/privacy) [Toolkits\ \ Next](https://docs.monad.xyz/tooling-and-infra/toolkits) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Cross-Chain - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/tooling-and-infra/cross-chain#content-area) [​](https://docs.monad.xyz/tooling-and-infra/cross-chain#definitions) Definitions ------------------------------------------------------------------------------------ At a high level, bridges offer the following features: | Feature | Description | | --- | --- | | **Arbitrary Messaging Bridge (AMB)** | Allows arbitrary messages to be securely relayed from a smart contract on chain 1 to a smart contract on chain 2.

AMB provides guarantees that messages delivered to chain 2 represent events finalized on chain 1. | | **Token Bridge** | Allows user to lock native tokens or ERC20 tokens on chain 1 and mint claim tokens on chain 2.

Bridge maintains the invariant that, for each token minted on chain 2, there exists a corresponding token locked on chain 1. | | **Intents Bridge / Liquidity Layer** | Allows user to turn in tokens on one chain and quickly redeem tokens on another chain, typically relying on drawing on a pool of assets maintained on each side. Provides greater immediacy relative to waiting for full finality of an AMB. | | **Bridge Aggregator** | Aggregates multiple liquidity layers or token bridges, potentially integrating swapping as well so that users may receive a different token than the one they input. | | **Chain Abstraction** | Enables a user experience exempt from the manual processes required to interact with multiple chains. | [​](https://docs.monad.xyz/tooling-and-infra/cross-chain#provider-summary) Provider Summary ---------------------------------------------------------------------------------------------- * Mainnet * Testnet | Provider | Status | Docs | Bridge Type | Contract Addresses | Explorer | | --- | --- | --- | --- | --- | --- | | [Across](https://app.across.to/bridge-and-swap) | ✅ | [Docs](https://docs.across.to/) | Intents Bridge | See [contract addresses](https://github.com/monad-crypto/protocols/blob/main/mainnet/across.jsonc) | | | [Axelar](https://www.axelar.network/) | ✅ | [Docs](https://docs.axelar.dev/) | AMB; Token Bridge | See [contract addresses](https://github.com/monad-crypto/protocols/blob/main/mainnet/axelar.jsonc) | [Axelarscan](https://axelarscan.io/) | | [Bungee](https://www.bungee.exchange/?fromChainId=1&fromTokenAddress=0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee&toChainId=143&toTokenAddress=0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee) | ✅ | [Docs](https://docs.bungee.exchange/) | Bridge Aggregator | See [contract addresses](https://github.com/monad-crypto/protocols/blob/main/mainnet/bungee.jsonc) | | | [ChangeHero](https://changehero.io/) | ✅ | [Docs](https://api-docs.changehero.io/) | Bridge Aggregator | | | | [Chainlink CCIP](https://chain.link/cross-chain) | ✅ | [Docs](https://docs.chain.link/ccip) | AMB; Token Bridge | See [contract addresses](https://github.com/monad-crypto/protocols/blob/main/mainnet/chainlink.jsonc) | [CCIP Explorer](https://ccip.chain.link/) | | [Circle CCTP](https://www.circle.com/cross-chain-transfer-protocol) | ✅ | [Docs](https://developers.circle.com/cctp) | Token Bridge | See [contract addresses](https://github.com/monad-crypto/protocols/blob/main/mainnet/circle_cctp.jsonc) | | | [deBridge](https://app.debridge.com/?inputChain=1&outputChain=143) | ✅ | [Docs](https://docs.debridge.com/) | AMB; Token Bridge | See [contract addresses](https://github.com/monad-crypto/protocols/blob/main/mainnet/debridge.jsonc) | [deExplorer](https://app.debridge.finance/orders) | | [DZap](https://www.dzap.io/) | ✅ | [Docs](https://docs.dzap.io/) | Bridge Aggregator | | | | [Exolix](https://exolix.com/) | ✅ | [Docs](https://exolix.com/developers) | Bridge Aggregator | | | | [Flashnet](https://flashnet.xyz/) | ✅ | [Docs](https://docs.flashnet.xyz/products/orchestration/overview) | Liquidity Layer | | | | [Garden](https://garden.finance/) | ✅ | [Docs](https://docs.garden.finance/) | Token Bridge for BTC | See [contract addresses](https://github.com/monad-crypto/protocols/blob/main/mainnet/garden.jsonc) | | | [Gas.zip](https://www.gas.zip/) | ✅ | [Docs](https://dev.gas.zip/) | Token Bridge | See [contract addresses](https://github.com/monad-crypto/protocols/blob/main/mainnet/gas_zip.jsonc) | [Explorer](https://www.gas.zip/scan) | | [Houdini](https://houdiniswap.com/) | ✅ | [Docs](https://docs.houdiniswap.com/overview/getting-started/what-is-houdini) | Bridge Aggregator | | | | [Hyperlane](https://nexus.hyperlane.xyz/) | ✅ | [Docs](https://docs.hyperlane.xyz/) | AMB; Token Bridge | See [contract addresses](https://github.com/monad-crypto/protocols/blob/main/mainnet/hyperlane_nexus.jsonc) | [Hyperlane Explorer](https://explorer.hyperlane.xyz/) | | [Jumper](https://jumper.exchange/) | ✅ | | Bridge aggregator | | | | [LayerZero](https://layerzero.network/) | ✅ | [Docs](https://docs.layerzero.network/) | AMB; Token Bridge | See [contract addresses](https://github.com/monad-crypto/protocols/blob/main/mainnet/layerzero.jsonc) | [LayerZeroScan](https://testnet.layerzeroscan.com/) | | [LetsExchange](https://letsexchange.io/) | ✅ | [Docs](https://api-doc.letsexchange.io/) | Bridge Aggregator | | | | [Li.fi](https://li.fi/) | ✅ | [Docs](https://docs.li.fi/) | Bridge aggregator SDK | See [contract addresses](https://github.com/monad-crypto/protocols/blob/main/mainnet/li_fi.jsonc) | [Li.Fi Scan](https://scan.li.fi/) | | [Mayan](https://swap.mayan.finance/) | ✅ | [Docs](https://docs.mayan.finance/) | Bridge Aggregator | | [Mayan Explorer](https://explorer.mayan.finance/) | | [Particle Network](https://particle.network/) | ✅ | [Docs](https://developers.particle.network/intro/introduction) | Chain Abstraction | | Explorer: `https://universalx.app/activity/details?id=${transactionId}`
(Replace `transactionId`) | | [Polymer](https://polymerlabs.org/) | ✅ | [Docs](https://docs.polymerlabs.org/docs/build/start/) | AMB | | [PolyScan](https://dashboard.polymerlabs.org/) | | [Relay](https://relay.link/bridge) | ✅ | [Docs](https://docs.relay.link/) | Liquidity Layer | | [Transactions](https://relay.link/transactions) | | [SimpleSwap](https://simpleswap.io/) | ✅ | [Docs](https://api.simpleswap.io/docs/getting-started/) | Bridge Aggregator | | | | [Socket](https://www.socket.tech/) | ✅ | [Docs](https://www.socket.tech/) | AMB | | [Socketscan](https://www.socketscan.io/) | | [Squid](https://www.squidrouter.com/) | ✅ | [Docs](https://docs.squidrouter.com/) | Liquidity Layer | | [Explorer (Axelarscan)](https://axelarscan.io/) | | [Stargate](https://stargate.finance/?srcChain=ethereum&srcToken=0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48&dstChain=monad&dstToken=0x754704Bc059F8C67012fEd69BC8A327a5aafb603) | ✅ | [Docs](https://docs.stargate.finance/) | Liquidity Layer | | | | [Trails](https://trails.build/) | ✅ | [Docs](https://docs.trails.build/) | Intents Bridge / Liquidity Layer | | | | [Trustware](https://trustware.io/) | ✅ | [Docs](https://docs.trustware.io/) | Chain Abstraction | | | | [Wormhole](https://wormhole.com/)
/ [Portal](https://portalbridge.com/) | ✅ | [Docs](https://wormhole.com/docs) | AMB; Token Bridge | See [contract addresses](https://github.com/monad-crypto/protocols/blob/main/mainnet/wormhole_portal.jsonc) | [WormholeScan](https://wormholescan.io/#/?network=Testnet) | _✅ = supported, ⌛️ = in progress, ❓ = unknown, ❌ = won’t support_ | Provider | Status | Docs | Bridge Type | Contract Addresses | Explorer | | --- | --- | --- | --- | --- | --- | | Axelar | ✅ | [Docs](https://docs.axelar.dev/) | AMB; Token Bridge | See [contract addresses](https://github.com/monad-crypto/protocols/blob/main/testnet/axelar.jsonc) | [Axelarscan](https://axelarscan.io/) | | Chainlink CCIP | ✅ | [Docs](https://docs.chain.link/ccip) | AMB; Token Bridge | See [contract addresses](https://github.com/monad-crypto/protocols/blob/main/testnet/chainlink_ccip.jsonc) | [CCIP Explorer](https://ccip.chain.link/) | | [Garden](https://testnet.garden.finance/) | ✅ | [Docs](https://docs.garden.finance/) | Token Bridge | See [contract addresses](https://github.com/monad-crypto/protocols/blob/main/testnet/garden.jsonc) | | | LayerZero | ✅ | [Docs](https://docs.layerzero.network/) | AMB; Token Bridge | See [contract addresses](https://github.com/monad-crypto/protocols/blob/main/testnet/layerzero.jsonc) | [LayerZeroScan](https://testnet.layerzeroscan.com/) | | Polymer | ✅ | [Docs](https://docs.polymerlabs.org/docs/build/start) | AMB | See [contract addresses](https://github.com/monad-crypto/protocols/blob/main/testnet/polymer.jsonc) | [PolyScan](https://dashboard.sepolia.polymer.zone/) | | Wormhole | ✅ | [Docs](https://wormhole.com/docs) | AMB; Token Bridge | See [contract addresses](https://github.com/monad-crypto/protocols/blob/main/testnet/wormhole_portal.jsonc) | [WormholeScan](https://wormholescan.io/#/?network=Testnet) | _✅ = supported, ⌛️ = in progress, ❓ = unknown, ❌ = won’t support_ [​](https://docs.monad.xyz/tooling-and-infra/cross-chain#provider-details) Provider Details ---------------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/tooling-and-infra/cross-chain#axelar) Axelar [Axelar](https://www.axelar.network/) is an interchain platform that connects blockchains to enable universal web3 transactions. By integrating with Axelar, applications built on Monad can now easily send messages and assets between the 49+ blockchains connected via Axelar. To learn more about Axelar visit our [docs](https://docs.axelar.dev/) and [GitHub](https://github.com/axelarnetwork/axelar-examples) . To view current transactions and live stats about the Axelar network, please visit the [Axelarscan block explorer](https://axelarscan.io/) . ### [​](https://docs.monad.xyz/tooling-and-infra/cross-chain#bungee-exchange) Bungee Exchange [Bungee](https://www.bungee.exchange/) provides seamless swaps between any blockchain. With over $24B in volume and trusted by major wallets and dApps, Bungee makes moving assets between networks efficient, secure, and accessible to everyone, powered by the SOCKET. To learn more, check out the [docs](https://docs.bungee.exchange/) . ### [​](https://docs.monad.xyz/tooling-and-infra/cross-chain#changehero) ChangeHero [ChangeHero](https://changehero.io/) is a cross-chain swap platform enabling frictionless asset exchanges across a wide range of networks. Leveraging aggregated liquidity and optimized routing logic, it delivers fast settlement and consistent pricing for any supported pair. Its clean integration pathways and dependable execution make ChangeHero a straightforward tool for powering multi-chain swaps within decentralized applications. To learn more, check out the [docs](https://api-docs.changehero.io/) . ### [​](https://docs.monad.xyz/tooling-and-infra/cross-chain#chainlink-ccip) Chainlink CCIP [Chainlink](https://chain.link/) Cross-Chain Interoperability Protocol (CCIP) is the standard for cross-chain interoperability. CCIP enables developers to build secure cross-chain apps that can transfer tokens, send messages, and initiate actions across blockchains. Through the [Cross-Chain Token (CCT)](https://blog.chain.link/ccip-v-1-5-upgrade/) standard, CCIP enables token developers to integrate new and existing tokens with CCIP in a self-serve manner in minutes, without requiring vendor lock-in, hard-coded functions, or external dependencies that may limit future optionality. CCTs support self-serve deployments, full control and ownership for developers, zero-slippage transfers, and enhanced programmability via configurable rate limits and reliability features such as Smart Execution. CCIP is powered by Chainlink decentralized oracle networks (DONs)—a proven standard with a track record of securing tens of billions of dollars and enabling over $19 trillion in onchain transaction value. Key CCIP developer tools: * [CCIP official documentation](https://docs.chain.link/ccip) : start integrating CCIP into your cross-chain application. * [CCIP Token Manager](https://tokenmanager.chain.link/) : an intuitive front-end web interface for the deployment of new and management of existing CCTs by their developers, including no-code guided deployments and configuration tools. * [CCIP SDK](https://docs.chain.link/ccip/ccip-javascript-sdk) : a software development kit that streamlines the process of integrating CCIP, allowing developers to use JavaScript to create a token transfer frontend dApp. Contract Addresses: * Router (testnet): [`0x5f16e51e3Dcb255480F090157DD01bA962a53E54`](https://testnet.monadvision.com/address/0x5f16e51e3Dcb255480F090157DD01bA962a53E54) * Router (mainnet): `0x33566fE5976AAa420F3d5C64996641Fc3858CaDB` ### [​](https://docs.monad.xyz/tooling-and-infra/cross-chain#circle-cctp) Circle CCTP [Cross-Chain Transfer Protocol (CCTP)](https://www.circle.com/cross-chain-transfer-protocol) by Circle is a permissionless onchain utility that facilitates USDC transfers securely between supported blockchains via native burning and minting. Circle created CCTP to improve capital efficiency and minimize trust assumptions when using USDC across blockchains. CCTP enables developers to build multichain applications that allow users to perform 1:1 transfers of USDC securely across blockchains. To get started, visit the [Circle CCTP documentation](https://developers.circle.com/cctp) ### [​](https://docs.monad.xyz/tooling-and-infra/cross-chain#debridge) deBridge Build once, interoperate everywhere. deBridge enables secure, fast, and capital-efficient connectivity across 20+ chains, so you can swap and transfer assets natively, trigger Cross-Chain logic in seconds, all with chain abstraction and one unified protocol. To get started, visit the deBridge [documentation](https://docs.debridge.com/) or check out the [app](https://app.debridge.finance/) . ### [​](https://docs.monad.xyz/tooling-and-infra/cross-chain#dzap) DZap [DZap](https://www.dzap.io/) is a DeFi aggregation and composability layer that lets wallets, apps, and protocols access any liquidity and automate multi-step DeFi actions—swaps, bridges, lending, staking, and LP positions—across 200+ protocols and 70+ chains, including Monad. Its swap-and-bridge aggregator finds the best route across DEXs and bridges, and supports single-signature intent execution where a solver settles the outcome, with gasless and cross-chain flows exposed through a REST API and SDK. To get started, visit the [DZap documentation](https://docs.dzap.io/) . ### [​](https://docs.monad.xyz/tooling-and-infra/cross-chain#exolix) Exolix [Exolix](https://exolix.com/) is a non-custodial cross-chain exchange aggregator that sources liquidity from both centralized and decentralized exchanges to deliver instant swaps across 200+ blockchains, including Monad. It supports fixed and floating rates, requires no account signup, and never custodies user funds or private keys. Developers can integrate Exolix’s instant-exchange API to embed cross-chain swaps directly into wallets, dApps, and DeFi products, with a revenue-share model for partners. To get started, visit the [Exolix developer documentation](https://exolix.com/developers) . ### [​](https://docs.monad.xyz/tooling-and-infra/cross-chain#flashnet) Flashnet [Flashnet](https://flashnet.xyz/) builds Bitcoin exchange infrastructure. Its Orchestra API enables cross-chain swaps between stablecoins and native BTC with sub-10 second settlement and ultra-low-fees. Orchestra handles all routing, execution, and settlement, allowing applications on Monad to offer the best native Bitcoin swaps through a single integration. To get started, visit the [documentation](https://docs.flashnet.xyz/products/orchestration/overview) . ### [​](https://docs.monad.xyz/tooling-and-infra/cross-chain#garden) Garden [Garden](https://garden.finance/) is transforming Bitcoin interoperability with its next-gen bridge. It is built by the renBTC team using an intents based architecture with trustless settlement, enabling cross-chain Bitcoin swaps in as little as 30 seconds with zero custody risk. In its first year, Garden processed over $1 billion in volume—proving the market’s demand for seamless, cost-effective Bitcoin bridging solutions. Now, Garden is unlocking a new era of interoperability—supporting non-likewise assets, external liquidity, and a wallet-friendly API—to onboard the next wave of partners and users. To get started, visit the [documentation](https://docs.garden.finance/) . ### [​](https://docs.monad.xyz/tooling-and-infra/cross-chain#gas-zip) Gas.zip [Gas.zip](https://www.gas.zip/) is a token bridge that enables seamless cross-chain asset transfers. Contract Address: * Deployment: `0x9E22ebeC84c7e4C4bD6D4aE7FF6f4D436D6D8390` ### [​](https://docs.monad.xyz/tooling-and-infra/cross-chain#houdini) Houdini [Houdini](https://houdiniswap.com/) is a non-custodial, privacy-focused cross-chain swap aggregator that routes transactions through a combination of decentralized exchanges, centralized exchange liquidity, and cross-chain solvers. It supports swaps across 100+ chains, including Monad, without requiring users to bridge manually, connect a wallet, or complete KYC. Houdini offers three swap modes: Private Swap (breaks the on-chain link between sender and receiver via compliant privacy routing), No Wallet Connect Swap (execute a swap with only a receiving address), and Onchain DEX Swap (cross-chain swaps via leading DEXs). It includes MEV protection, slippage control, gasless options, and AML/OFAC screening. To get started, visit the [Houdini documentation](https://docs.houdiniswap.com/overview/getting-started/what-is-houdini) or explore the [developer hub](https://docs.houdiniswap.com/developer-hub/overview/what-you-can-build) for API integration. ### [​](https://docs.monad.xyz/tooling-and-infra/cross-chain#hyperlane) Hyperlane [Hyperlane](https://hyperlane.xyz/) is a permissionless interoperability protocol for cross-chain communication. It enables message passing and asset transfers across different chains without relying on centralized intermediaries or requiring any permissions. To get started, visit the [Hyperlane documentation](https://docs.hyperlane.xyz/) . #### [​](https://docs.monad.xyz/tooling-and-infra/cross-chain#hyperlane-explorer) Hyperlane Explorer To view status of your cross chain transactions, please visit the [Hyperlane Explorer](https://explorer.hyperlane.xyz/) . ### [​](https://docs.monad.xyz/tooling-and-infra/cross-chain#layerzero) LayerZero [LayerZero](https://layerzero.network/) is an omnichain interoperability protocol that enables cross-chain messaging. Applications built on Monad can use the LayerZero protocol to connect to 35+ supported blockchains seamlessly. To get started with integrating LayerZero, visit the LayerZero [documentation](https://docs.layerzero.network/v1/developers/evm/evm-guides/send-messages) and provided examples on [GitHub](https://github.com/LayerZero-Labs/endpoint-v1-solidity-examples) . ### [​](https://docs.monad.xyz/tooling-and-infra/cross-chain#letsexchange) LetsExchange [LetsExchange](https://letsexchange.io/) is a non-custodial instant exchange and cross-chain swap aggregator that sources liquidity from 20+ centralized and decentralized providers to deliver swaps across 6,000+ cryptocurrencies, including Monad. It supports both fixed and floating rates and lets users swap cross-chain without exposing their private keys or personal data. Developers can integrate the LetsExchange API to embed instant swaps into wallets, aggregators, and payment products, with a revenue-share affiliate model for partners. To get started, visit the [LetsExchange API documentation](https://api-doc.letsexchange.io/) . ### [​](https://docs.monad.xyz/tooling-and-infra/cross-chain#li-fi) Li.fi [LI.FI](https://li.fi/) delivers a seamless solution for multi-chain payments and swaps through a single unified API and SDK. By combining access to all liquidity sources—including DEX aggregators, bridges, and solvers—it ensures comprehensive coverage across ecosystems. Its smart routing technology identifies the cheapest and fastest path for any payment or trade, optimizing efficiency and cost. Additionally, LI.FI offers a plug-and-play [widget](https://docs.li.fi/widget/overview) that enables instant, user-friendly payment flows, making integration simple for developers and intuitive for end users. To get started, visit [Li.fi documentation](https://docs.li.fi/) ### [​](https://docs.monad.xyz/tooling-and-infra/cross-chain#particle-network) Particle Network Particle Network enables chain abstraction through its [Universal Accounts](https://developers.particle.network/universal-accounts/cha/overview) (UA) infrastructure. A UA provides each user with a single account and a combined balance across [multiple chains](https://developers.particle.network/universal-accounts/cha/chains) (EVM and non-EVM). This allows users to interact with a dApp on Monad even if their assets are held on another network—without manual bridging or chain-switching. Universal Accounts support: * Cross-chain deposits and swaps without manual bridging   * Unified balance aggregation across chains   * Gas abstraction, allowing transaction fees to be paid in any [supported token](https://developers.particle.network/universal-accounts/cha/chains#primary-assets) ### [​](https://docs.monad.xyz/tooling-and-infra/cross-chain#mayan) Mayan [Mayan](https://mayan.finance/) is a cross-chain swap protocol that enables fast and efficient token transfers across multiple blockchains. Mayan provides seamless token bridging with optimized routing to ensure the best execution for cross-chain transfers. To get started, visit the [Mayan documentation](https://docs.mayan.finance/) or explore transactions on the [Mayan Explorer](https://explorer.mayan.finance/) . ### [​](https://docs.monad.xyz/tooling-and-infra/cross-chain#polymer) Polymer [Polymer](https://www.polymerlabs.org/) is an interoperability protocol tailor made for multi-rollup applications. It places control in the hands of the builder, by combining cross-chain merkle proofs and a simple API to allow application builders to flexibly adopt Polymer’s infrastructure for their own needs. Prove any action. Cross-chain. To get started visit the [Polymer documentation](https://docs.polymerlabs.org/docs/build/start) . ### [​](https://docs.monad.xyz/tooling-and-infra/cross-chain#relay) Relay [Relay](https://relay.link/bridge) is the fastest and cheapest way to bridge and transact across chains, offering a multichain payments network that makes swapping and transacting across hundreds of blockchains delightfully simple. Since its launch in 2024, Relay has served over 5 million users, processed 50 million transactions, and facilitated more than $5 billion in volume across 85+ networks. At its core, Relay combines two powerful components: instant, low-cost cross-chain intents powered by the Relay Protocol, and comprehensive DEX meta-aggregation spanning 85 chains (including Monad), ensuring users always get the best execution. To get started, visit the [Relay documentation](https://docs.relay.link/what-is-relay) ### [​](https://docs.monad.xyz/tooling-and-infra/cross-chain#simpleswap) SimpleSwap [SimpleSwap](https://simpleswap.io/) is a privacy-focused, self-custody crypto exchange aggregator with 3000+ currencies and cross-chain support across 130+ blockchains. It offers competitive rates and timing, significantly simplifying buying and exchanging crypto with sign-up-free solutions. To learn more, check out the [docs](https://api.simpleswap.io/docs/getting-started/) . ### [​](https://docs.monad.xyz/tooling-and-infra/cross-chain#socket) Socket [SOCKET Protocol](https://socket.tech/) is the first chain-abstraction protocol, empowering developers to build applications that seamlessly leverage multiple blockchains. It enables the creation of chain-abstracted apps that interact across chains as if operating on a single one. To get started, visit the SOCKET [documentation](https://docs.socket.tech/) . ### [​](https://docs.monad.xyz/tooling-and-infra/cross-chain#squid) Squid [Squid](https://www.squidrouter.com/) creates unlimited access for anything in crypto. Squid can be used to seamlessly swap tokens from 100+ chains across including Monad. Squid’s API, SDK, and Widgets offer ease of integration for projects building on any chain to enable cross-chain functionality in just 1 click. ### [​](https://docs.monad.xyz/tooling-and-infra/cross-chain#stargate) Stargate [Stargate Finance](https://stargate.finance/) is a cross-chain bridge protocol that enables users to transfer native assets between different blockchains with instant guaranteed finality using unified liquidity pools. To get started, visit the Stargate [documentation](https://docs.stargate.finance/) . ### [​](https://docs.monad.xyz/tooling-and-infra/cross-chain#trails) Trails [Trails](https://trails.build/) is the universal intents SDK for 1-click crypto transactions. Trails lets users transact with any wallet, any token, across any chain by orchestrating swaps, bridges, and payments behind the scenes. Developers can integrate pay, swap, fund, and checkout flows through a single SDK with cross-chain execution, gasless transactions, and the ability to pay gas with any token including USDC. To get started, visit the [documentation](https://docs.trails.build/) . ### [​](https://docs.monad.xyz/tooling-and-infra/cross-chain#trustware) Trustware [Trustware](https://trustware.io/) is a chain abstraction platform that acts as a Universal Deposit Layer, letting apps accept any asset on any chain and settle to any destination. It handles routing, swaps, and settlement under the hood, so users on Monad can deposit from another chain or token without manual bridging or chain-switching. Trustware can be integrated via a drop-in React widget, a hosted wallet bridge, or a headless REST API for backend control. To get started, visit the [documentation](https://docs.trustware.io/) . ### [​](https://docs.monad.xyz/tooling-and-infra/cross-chain#wormhole) Wormhole [Wormhole](https://wormhole.com/) is a cross-chain interoperability protocol that provides secure communication between blockchains. Monad uses two Wormhole products: **Messaging** and **NTT (Native Token Transfers)**. By integrating Wormhole, a Monad application can access users and liquidity on > 30 chains and > 7 different platforms. #### [​](https://docs.monad.xyz/tooling-and-infra/cross-chain#wormhole-messaging) Wormhole Messaging Wormhole Messaging is a generic messaging protocol that enables secure cross-chain communication and arbitrary data transfer between blockchains. To get started with Wormhole Messaging: * [Quickstart Guide](https://wormhole.com/docs/products/messaging/get-started/) * [GitHub Examples](https://github.com/wormhole-foundation/demo-wormhole-messaging) #### [​](https://docs.monad.xyz/tooling-and-infra/cross-chain#wormhole-ntt-native-token-transfers) Wormhole NTT (Native Token Transfers) Wormhole NTT (Native Token Transfer) framework enables seamless cross-chain token movement without wrapping or liquidity pools, allowing projects to maintain token ownership and customize their cross-chain token deployment. To get started with Wormhole NTT: * [Quickstart Guide](https://wormhole.com/docs/products/token-transfers/native-token-transfers/get-started/) * [GitHub Examples](https://github.com/wormhole-foundation/demo-ntt-connect) For end-users looking to bridge assets, you can use [Wormhole Portal Bridge](https://portalbridge.com/) . For more information on integrating Wormhole, visit their [documentation](https://wormhole.com/docs/) . Contract Addresses for Monad Testnet: * Core: [`0xBB73cB66C26740F31d1FabDC6b7A46a038A300dd`](https://testnet.monadvision.com/address/0xBB73cB66C26740F31d1FabDC6b7A46a038A300dd) * Relayer: [`0x362fca37E45fe1096b42021b543f462D49a5C8df`](https://testnet.monadvision.com/address/0x362fca37E45fe1096b42021b543f462D49a5C8df) [Block Explorers\ \ Previous](https://docs.monad.xyz/tooling-and-infra/block-explorers) [Custody\ \ Next](https://docs.monad.xyz/tooling-and-infra/custody) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Why Monad: Decentralization + Performance - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/introduction/why-monad#content-area) [​](https://docs.monad.xyz/introduction/why-monad#decentralization-matters) Decentralization matters ------------------------------------------------------------------------------------------------------- A blockchain has several major components: * Consensus mechanism for achieving agreement on transactions to append to the ledger * Execution/storage system for maintaining the active state In increasing the performance of these components, one could cut corners, for example by requiring all of the nodes to be physically close to each other (to save on the overhead of consensus), or by requiring a huge amount of RAM (to keep much or all of the state in memory), but it would be at a significant cost to decentralization. And decentralization is the whole point! As discussed in [Why Blockchain?](https://docs.monad.xyz/introduction/why-blockchain) , decentralized shared global state allows many parties to coordinate while relying on a single, shared, objective source of truth. Decentralization is key to the matter; a blockchain maintained by a small group of node operators (or in the extreme case, a single operator!) would not offer benefits such as trustlessness, credible neutrality, and censorship-resistance. For any blockchain network, decentralization should be the principal concern. Performance improvements should not come at the expense of decentralization. [​](https://docs.monad.xyz/introduction/why-monad#today%E2%80%99s-performance-bottlenecks) Today’s performance bottlenecks ----------------------------------------------------------------------------------------------------------------------------- Ethereum’s current execution limits (2.5M gas per second) are set conservatively, but for several good reasons: * Inefficient storage access patterns * Single-threaded execution * Very limited execution budget, because consensus can’t proceed without execution * Concerns about state growth, and the effect of state growth on future state access costs Monad addresses these limitations through algorithmic improvements and architectural changes, pioneering several innovations that will hopefully become standard in Ethereum in the years to come. Maintaining a high degree of decentralization, while making material performance improvements, is the key consideration. [​](https://docs.monad.xyz/introduction/why-monad#addressing-these-bottlenecks-through-optimization) Addressing these bottlenecks through optimization --------------------------------------------------------------------------------------------------------------------------------------------------------- Monad enables pipelining and other optimizations in four major areas to enable exceptional Ethereum Virtual Machine performance and materially advance the decentralization/scalability tradeoff. Subsequent pages describe these major areas of improvement: * [MonadBFT](https://docs.monad.xyz/monad-arch/consensus/monad-bft) , a frontier BFT consensus mechanism solving the [tail-forking](https://www.category.xyz/blogs/monadbft-fast-responsive-fork-resistant-streamlined-consensus) problem * [RaptorCast](https://docs.monad.xyz/monad-arch/consensus/raptorcast) for efficient block transmission * [Asynchronous Execution](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution) for pipelining consensus and execution to raise the time budget for execution * [Parallel Execution](https://docs.monad.xyz/monad-arch/execution/parallel-execution) and [JIT Compilation](https://docs.monad.xyz/monad-arch/execution/native-compilation) for efficient transaction execution * [MonadDb](https://docs.monad.xyz/monad-arch/execution/monaddb) for efficient storage of Ethereum state [Why Blockchain?\ \ Previous](https://docs.monad.xyz/introduction/why-blockchain) [Monad for Users\ \ Next](https://docs.monad.xyz/introduction/monad-for-users) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Frequently Asked Questions - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/faq#content-area) [​](https://docs.monad.xyz/faq#execution) Execution ------------------------------------------------------ Are there any differences in opcode pricing? A few opcodes and precompiles have been repriced to more correclty account for their relative cost. See details [here](https://docs.monad.xyz/developer-essentials/opcode-pricing) . How does Monad's optimistic parallel execution manage interdependent transactions? In Monad, like in Ethereum, transactions are ordered linearly within a block. The guarantee that Monad provides is that the result at the end of each block will be as if the transactions were executed serially, even though under the hood there was work done in parallel.Monad handles interdependent transactions gracefully by separating the concerns of **computation** (which can be done in parallel) from **commitment** (which is still done serially).Transactions are computed in parallel optimistically (i.e. assuming that any storage slots read in during execution are correct), generating a **pending result** for each transaction. A pending result consists of the set of input storage slots (and their values) and output storage slots (and their values).Pending results are committed **serially** in the original order of the transactions, checking each input for correctness at the time of commitment. (An input will be incorrect if it was mutated by one of the previously-committed pending results.) If a pending result has any incorrect inputs, it will be re-executed; no other pending results can be committed until that completes.Committing pending results serially ensures that correctness is always preserved. An example illustrates this best. Suppose that at the start of a block, Alice, Bob, and Charlie each have a balance of 100 USDC. These are the first two transactions: | Transaction # | What happens | | --- | --- | | 0 | Alice sends Bob 5 USDC | | 1 | Bob sends Charlie 10 USDC | When transactions 0 and 1 are executed in parallel, they produce the following pending results: | Pending Result # | Inputs | Outputs | | --- | --- | --- | | 0 | Alice: 100
Bob: 100 | Alice: 95
Bob: 105 | | 1 | Bob: 100
Charlie: 100 | Bob: 90
Charlie: 110 | Now we commit the pending results serially. Pending result 0 gets committed. When we try to commit pending result 1, we notice that one of the inputs is wrong - Bob’s balance was expected to be 100, but it is actually 105. This re-triggers execution for transaction 1. No other transactions can be committed until transaction 1 is re-executed. In optimistic parallel execution, transactions get re-executed if their first execution was done with inputs that subsequently were mutated. What if there is a long list of serially dependent transactions? _(Note: This question is asking about re-execution as discussed [here](https://docs.monad.xyz/monad-arch/execution/parallel-execution#optimistic-execution) .)_While it’s true that having to re-execute a pending result is slower than immediately committing it, re-execution is also typically much faster than the original execution because inputs are stored in cache (RAM). Also note that every transaction will be executed at most twice: once initially, and once on re-execution.More generally, you can think of optimistic parallel execution as a two-pass strategy. The first pass begins executing many transactions in parallel, thus surfacing many storage slot dependencies in parallel and pulling them all into cache. The second pass iterates over the transactions serially, either committing the pending result immediately or re-executing it (but from a position where most storage slots are cached). This strategy, combined with efficient SSD lookups from [MonadDb](https://docs.monad.xyz/monad-arch/execution/monaddb) , delivers a workload that uses the full SSD throughput more efficiently. Do I need to change my code to take advantage of Monad’s parallelism? Would it make sense to split my contract into many contracts to reduce the probability of two transactions touching the same contract? No, no need! Transactions interacting with your smart contract behave as if every transaction is being executed serially. Parallel execution is strictly an implementation detail.Also, it is important to note that all state contention is evaluated on a slot-by-slot basis. So for example, suppose that transaction 1 involves Alice sending USDC to Bob, and transaction 2 involves Charlie sending USDC to David. It doesn’t matter that both transactions involve the same smart contract (the USDC ERC-20 contract); the two affected storage slots in transaction 1 are completely independent from the two affected storage slots in transaction 2. What specific optimizations does MonadDB introduce over traditional databases for EVM state storage? MonadDb stores Merkle Patricia Trie data natively, rather than embedding the trie inside a generic database (like LevelDB or RocksDB) which have their own logic for mapping database entries to locations on disk. This eliminates a level of indirection and substantially reduces the number of IOPS and page reads to look up one value. Trie operations such as recomputing the merkle root at the end of each block are much more efficient.MonadDb further reduces latency and increases throughput by implementing asynchronous I/O using `io_uring` and by bypassing the filesystem. `io_uring` is a new linux kernel technology that allows execution threads to issue I/O requests without stalling or tieing up threads. This allows many I/O requests to be issued in parallel, sequenced by the kernel, and serviced by the first available thread on return.Finally, in MonadDb, each node in the trie is versioned, allowing for intuitive maintenance of the merkle trie and efficient state synchronization algorithms. Only the necessary trie components are sent during statesync, making bootstrapping and recovery faster. Why doesn't Monad make EIP-2930 access lists mandatory? Wouldn’t it make execution more efficient? 1. Usage of access lists generally increases the size of transactions; long-term we think that bandwidth is the biggest bottleneck 2. In Ethereum, the workflow for a user to submit using access lists is: simulate the transaction, note which storage slots are accessed, then submit the transaction with these slots mentioned in the access list. However, the state of the world may change between simulation and the real execution; we feel that it’s the job of the system to handle this gracefully under the hood. 3. It would break integrations with existing wallets which don’t support EIP-2930. 4. Note that EIP-2930 access lists are actually underspecified, at least from the perspective of anticipating state contention. If two transactions both read from the same storage slot (but neither writes to it) then, with respect to that storage slot, there is no state contention - neither transaction can invalidate the other’s computation. Contention only occurs when an earlier transaction writes to a storage slot that a later transaction will read. EIP-2930 access lists mention which storage slots are accessed, but don’t make note of whether the transaction will read from or write to that storage slot. [​](https://docs.monad.xyz/faq#consensus) Consensus ------------------------------------------------------ How are leaders selected? The leader schedule is constructed by a deterministic, stake-weighted process that is computed once per epoch: * An epoch occurs roughly every 5.5 hours (50000 blocks). Validator stake weights are locked in one epoch ahead (i.e. any changes for epoch N+1 must be registered prior to the start of epoch N). * At the start of each epoch, each validator computes the leader schedule based on running a deterministic pseudorandom function on the stake weights. Since the function is deterministic, everyone arrives at the same leader schedule. How many nodes can participate in consensus? Is participation permissionless? The client codebase has a parameter called [`ACTIVE_VALSET_SIZE`](https://docs.monad.xyz/monad-arch/consensus/staking#constants) which is currently set to 200. Thus, the top 200 validators (ordered by stake weight) can participate directly in consensus. This parameter is likely to change over time.Participation is permissionless; one simply needs to be in the top `ACTIVE_VALSET_SIZE` validators. ### [​](https://docs.monad.xyz/faq#raptorcast) Raptorcast Where can I find a detailed description of RaptorCast? Check [this](https://www.category.xyz/blogs/raptorcast-designing-a-messaging-layer) blog post! Why was UDP chosen instead of TCP in RaptorCast? See the discussion in [this](https://www.category.xyz/blogs/raptorcast-designing-a-messaging-layer) blog post. UDP was selected, accepting lossyness but alleviating it by adding additional data integrity (Raptor codes) and message authentication (signatures over merkle roots), because the combination of those strategies over UDP is substantially more efficient than using TCP. What is the difference between Raptorcast and the propagation methods in Ethereum, Solana, or L2s? Ethereum is using [libp2p](https://blog.libp2p.io/libp2p-and-ethereum/) . It is gossip based (each node propagates its message to a set of peers) which is a lot less efficient (more duplicate messages and a more meandering process for getting the word out). As a result, Ethereum budgets several seconds for the block to propagate throughout the network.Solana uses [Turbine](https://www.helius.dev/blog/turbine-block-propagation-on-solana) . Turbine and RaptorCast are similar in the sense that they both use erasure coding, cut packets into MTU-sized chunks, and send transactions through a broadcast tree for efficiency. Some of the differences include: * Monad uses Raptor codes while Turbine uses Reed-Solomon * Monad uses a 2-level broadcast tree with every other validator as a level-1 node while Solana uses a deeper, less structured broadcast tree with fewer level-1 nodes and more complex logic for determining the broadcast tree. There aren’t BFT guarantees on block delivery the way that there are for Monad. In L2s there’s only 1 sequencer so there isn’t a notion of block propagation for consensus. The sequencer just pushes transaction batches occasionally to L1. ### [​](https://docs.monad.xyz/faq#mempool) Mempool If there is a gap in nonces, will transactions after the gap be preserved in the mempool? For example, if my EOA currently has nonce 0, and I send a transaction with nonce 3, then I send transactions with nonce 0, 1, and 2. Will the transaction with nonce 3 be executed or dropped?Answer: Transaction 3 will be executed. [​](https://docs.monad.xyz/faq#block-states-and-finality) Block States and Finality -------------------------------------------------------------------------------------- When can a node start executing a block? A node can start executing [speculatively](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution#speculative-execution) as soon as a new block proposal is received. Executing a block just generates new states and a new merkle trie root - but the official pointer is still to the old one. This is like receiving a possible piece of homework from your teacher which will be finalized soon - you can start working on it on a new piece of paper, and just throw it away if it turns out that the homework isn’t needed. When can a node be sure about the state? As soon as a block enters the [Finalized](https://docs.monad.xyz/monad-arch/consensus/block-states) state, the merkle root for the speculative execution of that block becomes the official local merkle root for that block. That merkle root won’t be verified by consensus for another `D=3` blocks, but it is still known locally because state is deterministic given a fixed ordering of transactions.If you want to be certain that your local node did not make a computation error (e.g. due to cosmic rays), you may wait `D=3` blocks for the delayed merkle root, which makes the block in question enter the [Verified](https://docs.monad.xyz/monad-arch/consensus/block-states) state. [​](https://docs.monad.xyz/faq#rpc) RPC ------------------------------------------ When calling \`eth\_call\` with an old block number, I received this response: \`Block requested not found. Request might be querying historical state that is not available. If possible, reformulate query to point to more recent blocks\`. What's going on? Due to Monad’s high throughput, full nodes do not provide access to arbitrarily old state, as this would require too much storage. See [Historical Data](https://docs.monad.xyz/developer-essentials/historical-data) for a fuller discussion.When writing smart contracts, it is recommended to use events to log any state that will be needed later, or use a [smart contract indexer](https://docs.monad.xyz/tooling-and-infra/indexers/indexing-frameworks) to compute it off-chain. [​](https://docs.monad.xyz/faq#features) Features ---------------------------------------------------- Is EIP-7702 supported? Yes, EIP-7702 is supported.Note that when accounts are delegated under EIP-7702, their treatment under Monad’s [Reserve Balance](https://docs.monad.xyz/developer-essentials/reserve-balance) rules changes slightly. You can learn more about it [here](https://docs.monad.xyz/developer-essentials/eip-7702) . Is EIP-7951 (or RIP-7212) supported? Yes, it is the precompile at `0x0100` following EIP-7951. This enables on-chain verification of WebAuthn/passkey signatures using the P256 curve. See [Precompiles](https://docs.monad.xyz/developer-essentials/precompiles#p256-signature-verification) for usage details and a Solidity example. [​](https://docs.monad.xyz/faq#miscellaneous) Miscellaneous -------------------------------------------------------------- What is the point of low validator hardware requirements (32 GB RAM, 2x 2TB SSD, 16-core CPU), if there will only be 100-200 voting nodes? Monad’s north star is decentralization. If it’s really expensive to run a node, only professional validation companies with a large amount of stake will be able to justify the cost. Making nodes economical is crucial to making it feasible for anyone to run a full node, as well as to supporting a large validator set - the Day-1 mainnet target of 100-200 nodes is just a starting point. Why was rust chosen for the consensus client and C++ for execution? Rust and C++ are both great high-performance languages. C++ was selected for the database and execution system to get finer control over the filesystem and to use libraries like `io_uring` and `boost::fibers`. Rust was selected for consensus to take advantage of stricter memory safety given that consensus concerns itself with slightly higher-level systems engineering problems. [How to use the Next.js Serwist Thirdweb embedded wallet template\ \ Previous](https://docs.monad.xyz/templates/next-serwist-thirdweb) [Official Links\ \ Next](https://docs.monad.xyz/official-links) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Network Information - Mainnet - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/developer-essentials/network-information#content-area) | Name | Value | | --- | --- | | Network Name | | | Chain ID | | | Currency Symbol | | | RPC URL | [see below](https://docs.monad.xyz/developer-essentials/network-information#public-rpc-endpoints) | | Block Explorer (MonadVision) | | | Block Explorer (Monadscan) | | | Network Visualization | | | Current version / revision | [`v0.15.1`](https://docs.monad.xyz/developer-essentials/changelog/releases#v0-15-1)
/ [`MONAD_NINE`](https://docs.monad.xyz/developer-essentials/changelog#revisions) | Other [block explorers](https://docs.monad.xyz/tooling-and-infra/block-explorers) supported: * Detailed traces: [Phalcon Explorer](https://blocksec.com/explorer) and [Tenderly](https://dashboard.tenderly.co/explorer) * UserOps: [Jiffyscan](https://jiffyscan.xyz/?network=monad) ### [​](https://docs.monad.xyz/developer-essentials/network-information#public-rpc-endpoints) Public RPC Endpoints Public RPC endpoints are rate-limited but should be sufficient for basic usage. If you need a higher-limit RPC endpoint, please see [RPC Providers](https://docs.monad.xyz/tooling-and-infra/rpc-providers) . Websocket endpoints start with `wss://`. See [Websocket Reference](https://docs.monad.xyz/reference/websockets) for further information. | RPC URL | Provider | Rate Limits | Batch Call Limit | Notes | | --- | --- | --- | --- | --- | | | QuickNode | 25 rps | 100 | | | | Alchemy | 15 rps | 100 | `debug_` and `trace_` methods disabled | | | Goldsky Edge | 300 per 10s | 10 | historical state lookups (e.g. `eth_call`) supported; see [discussion](https://docs.monad.xyz/developer-essentials/historical-data) | | | Ankr | 300 per 10s | 10 | `debug_` methods disabled | | | MF | 20 rps | 1 | historical state lookups (e.g. `eth_call`) supported; see [discussion](https://docs.monad.xyz/developer-essentials/historical-data) | See [RPC Limits](https://docs.monad.xyz/reference/rpc-limits) for additional detail on method-specific limits. ### [​](https://docs.monad.xyz/developer-essentials/network-information#supported-infrastructure) Supported Infrastructure See the [Tooling and Infrastructure](https://docs.monad.xyz/tooling-and-infra) page for a list of providers supporting mainnet. ### [​](https://docs.monad.xyz/developer-essentials/network-information#canonical-contracts) Canonical Contracts | Name | Address | | --- | --- | | Wrapped MON | | | [Create2Deployer](https://github.com/pcaversaccio/create2deployer) | | | [CreateX](https://github.com/pcaversaccio/createx) | | | [ERC-2470 Singleton Factory](https://eips.ethereum.org/EIPS/eip-2470) | | | [ERC-4337 EntryPoint v0.6](https://github.com/eth-infinitism/account-abstraction/blob/v0.6.0/contracts/core/EntryPoint.sol) | | | [ERC-4337 SenderCreator v0.6](https://github.com/eth-infinitism/account-abstraction/blob/v0.6.0/contracts/core/SenderCreator.sol) | | | [ERC-4337 EntryPoint v0.7](https://github.com/eth-infinitism/account-abstraction/releases) | | | [ERC-4337 SenderCreator v0.7](https://github.com/eth-infinitism/account-abstraction/blob/v0.7.0/contracts/core/SenderCreator.sol) | | | [ERC-4337 EntryPoint v0.8](https://github.com/eth-infinitism/account-abstraction/blob/v0.8.0/contracts/core/EntryPoint.sol) | | | [ERC-4337 SenderCreator v0.8](https://github.com/eth-infinitism/account-abstraction/blob/v0.8.0/contracts/core/SenderCreator.sol) | | | [ERC-6492 UniversalSigValidator](https://eips.ethereum.org/EIPS/eip-6492) | | | [Foundry Deterministic Deployer](https://getfoundry.sh/guides/deterministic-deployments-using-create2/) | | | [Multicall3](https://www.multicall3.com/) | | | [MultiSend](https://github.com/safe-fndn/safe-smart-account/blob/v1.3.0/contracts/libraries/MultiSend.sol) | | | [MultiSendCallOnly](https://github.com/safe-fndn/safe-smart-account/blob/v1.3.0/contracts/libraries/MultiSendCallOnly.sol) | | | [Permit2](https://github.com/Uniswap/permit2) | | | [Safe](https://github.com/safe-fndn/safe-smart-account/blob/v1.3.0/contracts/GnosisSafe.sol) | | | [SafeL2](https://github.com/safe-fndn/safe-smart-account/blob/v1.3.0/contracts/GnosisSafeL2.sol) | | | [SafeSingletonFactory](https://github.com/safe-fndn/safe-singleton-factory/blob/main/source/deterministic-deployment-proxy.yul) | | | [SimpleAccount](https://github.com/eth-infinitism/account-abstraction/blob/develop/contracts/accounts/SimpleAccount.sol) | | | [Simple7702Account](https://github.com/eth-infinitism/account-abstraction/blob/develop/contracts/accounts/Simple7702Account.sol) | | | [Sub Zero VanityMarket](https://github.com/Philogy/sub-zero-contracts) | | | [x402 ExactPermit2Proxy](https://github.com/x402-foundation/x402/blob/main/contracts/evm/src/x402ExactPermit2Proxy.sol) | | | [x402 UptoPermit2Proxy](https://github.com/x402-foundation/x402/blob/main/contracts/evm/src/x402UptoPermit2Proxy.sol) | | | [Zoltu Deterministic Deployment Proxy](https://github.com/Zoltu/deterministic-deployment-proxy) | | ### [​](https://docs.monad.xyz/developer-essentials/network-information#ecosystem-contract-addresses) Ecosystem contract addresses See the [protocols](https://github.com/monad-crypto/protocols) repo. ### [​](https://docs.monad.xyz/developer-essentials/network-information#tokens) Tokens See [Tokens and Bridges](https://docs.monad.xyz/developer-essentials/network-information/tokens-and-bridges) or the [token-list](https://github.com/monad-crypto/token-list) repo. [Developer Essentials\ \ Previous](https://docs.monad.xyz/developer-essentials) [Tokens and Bridges\ \ Next](https://docs.monad.xyz/developer-essentials/network-information/tokens-and-bridges) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Monad Solonet - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/tooling-and-infra/toolkits/monad-solonet#content-area) [Monad Solonet](https://github.com/monad-crypto/monad-solonet) is an official tool for running a local Monad network. Unlike `anvil --monad`, which simulates Monad EVM behavior, Solonet runs actual Monad nodes — giving you a local environment that more closely matches testnet and mainnet. Use Solonet when you need full node behavior locally: consensus, staking, or accurate block production timing. [​](https://docs.monad.xyz/tooling-and-infra/toolkits/monad-solonet#installation-&-usage) Installation & usage ----------------------------------------------------------------------------------------------------------------- See the [Monad Solonet README](https://github.com/monad-crypto/monad-solonet#readme) for setup instructions and configuration options. [Hardhat\ \ Previous](https://docs.monad.xyz/tooling-and-infra/toolkits/hardhat) [Wallets\ \ Next](https://docs.monad.xyz/tooling-and-infra/wallets) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Toolkits - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/tooling-and-infra/toolkits#content-area) Development toolkits for building on Monad. [​](https://docs.monad.xyz/tooling-and-infra/toolkits#summary) Summary ------------------------------------------------------------------------- | Toolkit | Description | | --- | --- | | [Monad Foundry](https://docs.monad.xyz/tooling-and-infra/toolkits/monad-foundry) | Custom fork of Foundry with Monad EVM, staking precompile support, and human-readable trace decoding. **Recommended for Solidity development.** | | [Hardhat](https://docs.monad.xyz/tooling-and-infra/toolkits/hardhat) | JavaScript-based Solidity development framework with Monad compatibility. | | [Monad Solonet](https://docs.monad.xyz/tooling-and-infra/toolkits/monad-solonet) | Run a local Monad network for development and testing. | [RPC Providers\ \ Previous](https://docs.monad.xyz/tooling-and-infra/rpc-providers) [Monad Foundry\ \ Next](https://docs.monad.xyz/tooling-and-infra/toolkits/monad-foundry) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Indexing Frameworks - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/tooling-and-infra/indexers/indexing-frameworks#content-area) [​](https://docs.monad.xyz/tooling-and-infra/indexers/indexing-frameworks#background) Background --------------------------------------------------------------------------------------------------- **Smart contract indexers** are off-chain calculators that compute additional metrics specific to one smart contract. Calculators can be thought of as extensions to a smart contract that do additional off-chain computation and maintain additional off-chain state. _Simple example:_ the [UniswapV2Pair contract](https://github.com/Uniswap/v2-core/blob/master/contracts/UniswapV2Pair.sol) maintains minimal state for the pool and emits `Mint`, `Burn`, and `Swap` events. If we wanted to know the cumulative number and volume of swaps on the pair, we could write and deploy a custom indexer instead of adding additional state variables and computation to the contract. Smart contract indexers typically produce object schemas using the [GraphQL](https://graphql.org/) schema language. Smart contract indexing services usually provide a hosted service so that users can deploy their indexers without having to run their own infrastructure. [​](https://docs.monad.xyz/tooling-and-infra/indexers/indexing-frameworks#provider-summary) Provider Summary --------------------------------------------------------------------------------------------------------------- * Mainnet * Testnet | Provider | Status | Docs | Language | Framework | Known for | Hosted service | Decen- tralized hosted service | Onchain & offchain data | Web- socket subscr- iptions | Query layer | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | [Envio](https://envio.dev/) | ✅ | [Docs](https://docs.envio.dev/docs/HyperIndex/overview) | JavaScript, TypeScript, Rescript | [HyperIndex](https://github.com/enviodev/hyperindex) | Performance and scale | ✅ | ❌ | ✅ | ✅ | GraphQL | | [Ghost](https://tryghost.xyz/) | ✅ | [Docs](https://docs.tryghost.xyz/ghostgraph/overview) | Solidity | GhostGraph | Solidity development | ✅ | ❌ | ❌ | ❌ | GraphQL | | [Goldsky](https://goldsky.com/) | ✅ | [Docs](https://docs.goldsky.com/) | AssemblyScript, SQL, TypeScript | [subgraph](https://github.com/graphprotocol/graph-node)
, [ETL pipelines](https://docs.goldsky.com/mirror/introduction) | Real-time data streaming | ✅ | ❌ | ✅ (with [Compose](https://docs.goldsky.com/compose/introduction)
) | ❌ | GraphQL and SQL ([in your db](https://docs.goldsky.com/mirror/sinks/postgres)
) | | [Ormi](https://ormilabs.com/) | ✅ | [Docs](https://docs.ormilabs.com/) | Assembly- Script | [subgraph](https://github.com/graphprotocol/graph-node) | High performance and custom environments | ✅ | ❌ | ❌ | ❌ | Custom GraphQL | | [Sentio](https://www.sentio.xyz/) | ✅ | [Docs](https://docs.sentio.xyz/docs/quickstart) | JavaScript, TypeScript | [sentio-sdk](https://github.com/sentioxyz/sentio-sdk) | Performance; integrated alerting and visualization | ✅ | ❌ | ✅ | ❌ | GraphQL & SQL | | [SQD](https://sqd.ai/) | ✅ | [Docs](https://docs.sqd.ai/) | TypeScript | [squid-sdk](https://github.com/subsquid/squid-sdk) | Performance, decentralization | ✅ | Partial[1](https://docs.monad.xyz/tooling-and-infra/indexers/indexing-frameworks#user-content-fn-1) | ✅ | ✅ | GraphQL | | [Streamingfast](https://thegraph.market/) | ✅ | [Docs](https://docs.substreams.dev/tutorials/intro-to-tutorials/monad) | Rust | [Substreams](https://substreams.dev/) | Performance, low latency and custom sinks | ✅ | ❌ | ❌ | ✅ (gRPC subscription) | gRPC, 20+ db types supported | | [SubQuery](https://subquery.network/) | ✅ | [Docs](https://academy.subquery.network/) | TypeScript | [subql](https://github.com/subquery/subql) | Decentral- ization | ✅ | ✅ | ✅ | ❌ | GraphQL | | [The Graph](https://thegraph.com/) | ✅ | [Docs](https://thegraph.com/docs/en/subgraphs/quick-start/) | Assembly- Script | [subgraph](https://github.com/graphprotocol/graph-node) | The original indexer | ✅ | ✅ | ❌ | ❌ | Custom GraphQL | _✅ = supported, ⌛️ = in progress, ❓ = unknown, ❌ = won’t support_ | Provider | Status | Docs | Language | Framework | Known for | Hosted service | Decen- tralized hosted service | Onchain & offchain data | Web- socket subscr- iptions | Query layer | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | [Envio](https://envio.dev/) | ✅ | [Docs](https://docs.envio.dev/docs/HyperIndex/overview) | JavaScript, TypeScript, Rescript | [HyperIndex](https://github.com/enviodev/hyperindex) | Performance and scale | ✅ | ❌ | ✅ | ✅ | GraphQL | | [Ghost](https://tryghost.xyz/) | ✅ | [Docs](https://docs.tryghost.xyz/ghostgraph/overview) | Solidity | GhostGraph | Solidity development | ✅ | ❌ | ❌ | ❌ | GraphQL | | [Goldsky](https://goldsky.com/) | ✅ | [Docs](https://docs.goldsky.com/) | AssemblyScript, SQL, TypeScript | [subgraph](https://github.com/graphprotocol/graph-node)
, [ETL pipelines](https://docs.goldsky.com/mirror/introduction) | Real-time data streaming | ✅ | ❌ | ✅ (with [Compose](https://docs.goldsky.com/compose/introduction)
) | ❌ | GraphQL and SQL ([in your db](https://docs.goldsky.com/mirror/sinks/postgres)
) | | [Ormi](https://ormilabs.com/) | ✅ | [Docs](https://docs.ormilabs.com/) | Assembly- Script | [subgraph](https://github.com/graphprotocol/graph-node) | High performance and custom environments | ✅ | ❌ | ❌ | ❌ | Custom GraphQL | | [SQD](https://sqd.ai/) | ✅ | [Docs](https://docs.sqd.ai/) | TypeScript | [squid-sdk](https://github.com/subsquid/squid-sdk) | Performance, decentralization | ✅ | Partial[1](https://docs.monad.xyz/tooling-and-infra/indexers/indexing-frameworks#user-content-fn-1) | ✅ | ✅ | GraphQL | | [SubQuery](https://subquery.network/) | ✅ | [Docs](https://academy.subquery.network/) | TypeScript | [subql](https://github.com/subquery/subql) | Decentral- ization | ✅ | ✅ | ✅ | ❌ | GraphQL | | [The Graph](https://thegraph.com/) | ✅ | [Docs](https://thegraph.com/docs/en/subgraphs/quick-start/) | Assembly- Script | [subgraph](https://github.com/graphprotocol/graph-node) | The original indexer | ✅ | ✅ | ❌ | ❌ | Custom GraphQL | _✅ = supported, ⌛️ = in progress, ❓ = unknown, ❌ = won’t support_ [​](https://docs.monad.xyz/tooling-and-infra/indexers/indexing-frameworks#provider-details) Provider Details --------------------------------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/tooling-and-infra/indexers/indexing-frameworks#envio) Envio [Envio](https://envio.dev/) is a full-featured data indexing solution that provides application developers with a seamless and efficient way to index and aggregate real-time and historical blockchain data for Monad Testnet. The indexed data is easily accessible through custom GraphQL queries, providing developers with the flexibility and power to retrieve specific information. [Envio HyperSync](https://docs.envio.dev/docs/HyperIndex/hypersync) is an indexed layer of the Monad Testnet blockchain for the hyper-speed syncing of historical data (JSON-RPC bypass). What would usually take hours to sync ~100,000 events can now be done in the order of less than a minute. Designed to optimize the user experience, Envio offers automatic code generation, flexible language support, multi-chain data aggregation, and a reliable, cost-effective hosted service. To get started, visit the [documentation](https://docs.envio.dev/docs/HyperIndex/overview) or follow the [quickstart](https://docs.envio.dev/docs/HyperIndex/contract-import) guide. ### [​](https://docs.monad.xyz/tooling-and-infra/indexers/indexing-frameworks#ghost) Ghost With [GhostGraph](https://tryghost.xyz/graph) , you can write your indexers in the same language as your contracts: Solidity. This means less context switching and faster time to market. To get started, visit the [documentation](https://docs.tryghost.xyz/ghostgraph/overview/) or check out the [tutorial](https://docs.monad.xyz/guides/indexers/ghost) . Services supported: * GhostGraph ### [​](https://docs.monad.xyz/tooling-and-infra/indexers/indexing-frameworks#goldsky) Goldsky [Goldsky](https://goldsky.com/) handles the hard parts of building on crypto rails: real-time data and reliable connectivity, so you can ship better products, faster. Goldsky offers two core self-serve products that can be used independently or in conjunction to power your data stack. * [**Subgraphs**](https://docs.goldsky.com/subgraphs/deploying-subgraphs) : Instant GraphQL APIs for Monad data with zero maintenance. * [**Mirror**](https://docs.goldsky.com/mirror/create-a-pipeline) : Stream realtime Monad data directly into your database. To take your app to the next level, build using Goldsky’s next gen data pipeline engine: * [**Turbo**](https://docs.goldsky.com/turbo-pipelines/introduction) : _Really fast decoding_, infinite filters, dynamic tables, and live data inspection. To get started, visit the [documentation](https://docs.goldsky.com/introduction) for guided walkthroughs. ### [​](https://docs.monad.xyz/tooling-and-infra/indexers/indexing-frameworks#ormi) Ormi [Ormi](https://ormilabs.com/) delivers real-time blockchain data that is fast, accurate, and ready for production. It keeps data synced to the tip of the chain and makes it instantly accessible through Subgraphs and APIs without the need to manage indexing infrastructure. Ormi provides two core products: * **Subgraphs**: Smart contract data at sub-second latency with zero throttling. * **Data API**: Real-time and historical blockchain data delivered through flexible, high-speed API endpoints. Ormi supports shared, dedicated, and fully custom environments that provide isolated performance for high-demand workloads. Start building by exploring the [documentation](https://docs.ormilabs.com/) or following the [Quickstart Guide](https://docs.ormilabs.com/subgraphs/quickstart) . ### [​](https://docs.monad.xyz/tooling-and-infra/indexers/indexing-frameworks#sentio) Sentio [Sentio](https://www.sentio.xyz/) offers blazing-fast native processors and seamless subgraph hosting on Monad. With powerful database capabilities, intuitive dashboards, and comprehensive API functionalities, Sentio is built to provide an exceptional developer experience. To get started, check out the [docs](https://docs.sentio.xyz/docs/readme) or visit the [quickstart](https://docs.sentio.xyz/docs/quickstart) guide. ### [​](https://docs.monad.xyz/tooling-and-infra/indexers/indexing-frameworks#sqd) SQD [SQD](https://sqd.ai/) enables permissionless, cost-efficient access to petabytes of high-value Web3 data. SQD is a decentralized hyper-scalable data platform optimized for providing efficient, permissionless access to large volumes of data. It currently serves historical on-chain data, including event logs, transaction receipts, traces, and per-transaction state diffs. To get started, visit the [documentation](https://docs.sqd.ai/) or see this [quickstart](https://docs.sqd.ai/sdk/quickstart/) with [examples](https://docs.sqd.ai/sdk/examples) on how to easily create subgraphs via Subsquid. ### [​](https://docs.monad.xyz/tooling-and-infra/indexers/indexing-frameworks#streamingfast) Streamingfast [Streamingfast](https://thegraph.market/) builds massively scalable software for processing and indexing blockchain data. StreamingFast has built two foundational technologies: * [Firehose](https://firehose.streamingfast.io/) : a blockchain data extraction layer designed to process complete blockchain histories using a files-based and streaming-first approach. * [Substreams](https://docs.substreams.dev/) : a data transformation layer which allows developers to write rust modules that can be composed like building blocks, building upon community-developed modules. Substreams can output data to various destinations including PosgreSQL, MongoDB< Kafka, and flat files. To get started, check out the [docs](https://docs.substreams.dev/) , or visit the [tutorial](https://docs.substreams.dev/tutorials/intro-to-tutorials/monad) for generating your first substream on Monad. ### [​](https://docs.monad.xyz/tooling-and-infra/indexers/indexing-frameworks#subquery) SubQuery [SubQuery](https://subquery.network/) is a leading blockchain data indexer that provides developers with fast, flexible, universal, open source and decentralised APIs for web3 projects. SubQuery SDK allows developers to get rich indexed data and build intuitive and immersive decentralised applications in a faster and more efficient way. SubQuery supports many ecosystems including Monad, Ethereum, Cosmos, Near, Polygon, Polkadot, Algorand, and more. One of SubQuery’s advantages is the ability to aggregate data not only within a chain but across multiple blockchains all within a single project. This allows the creation of feature-rich dashboard analytics and multi-chain block scanners. #### [​](https://docs.monad.xyz/tooling-and-infra/indexers/indexing-frameworks#useful-resources) Useful resources: * [SubQuery Academy (Documentation)](https://academy.subquery.network/) * [Monad Testnet Starter](https://github.com/subquery/ethereum-subql-starter/tree/main/Monad/monad-testnet-starter) * [Monad Testnet Quick Start Guide](https://academy.subquery.network/indexer/quickstart/quickstart_chains/monad.html) For technical questions and support reach out to us `start@subquery.network` ### [​](https://docs.monad.xyz/tooling-and-infra/indexers/indexing-frameworks#the-graph) The Graph [The Graph](https://thegraph.com/) is an indexing protocol that provides an easy way to query blockchain data through APIs known as subgraphs. With The Graph, you can benefit from: * **Decentralized Indexing**: Enables indexing blockchain data through multiple indexers, thus eliminating any single point of failure * **GraphQL Queries**: Provides a powerful GraphQL interface for querying indexed data, making data retrieval super simple. * **Customization**: Define your own logic for transforming & storing blockchain data. Reuse subgraphs published by other developers on The Graph Network. Follow this [quick-start](https://thegraph.com/docs/en/subgraphs/quick-start/) guide to create, deploy, and query a subgraph within 5 minutes. Footnotes --------- 1. SQD hosted service is semi-decentralized: the data lake is decentralized, but indexers run on proprietary infra. [↩](https://docs.monad.xyz/tooling-and-infra/indexers/indexing-frameworks#user-content-fnref-1) [↩2](https://docs.monad.xyz/tooling-and-infra/indexers/indexing-frameworks#user-content-fnref-1-2) [Common Data\ \ Previous](https://docs.monad.xyz/tooling-and-infra/indexers/common-data) [Onramps\ \ Next](https://docs.monad.xyz/tooling-and-infra/onramps) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Monad for Users - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/introduction/monad-for-users#content-area) Monad is a high-performance Ethereum-compatible L1, offering users the best of both worlds: **portability** and **performance**. From a portability perspective, Monad offers **full bytecode compatibility** for the Ethereum Virtual Machine (EVM), so that applications built for Ethereum can be ported to Monad without code changes, and **full Ethereum RPC compatibility**, so that infrastructure like Etherscan or The Graph can be used seamlessly. From a performance perspective, Monad offers **10,000 tps** of throughput, i.e. 1 billion transactions per day, while offering **300ms block frequency** and **600ms finality**. This allows Monad to support many more users and far more interactive experiences than existing blockchains, while offering far cheaper per-transaction costs. [​](https://docs.monad.xyz/introduction/monad-for-users#what%E2%80%99s-familiar-about-monad) What’s familiar about Monad? ---------------------------------------------------------------------------------------------------------------------------- From a user perspective, Monad behaves very similarly to Ethereum. You can use the same wallets (e.g. MetaMask) or block explorers (e.g. Etherscan) to sign or view transactions. The same apps built for Ethereum can be ported to Monad without code changes, so it is expected that you’ll be able to use many of your favorite apps from Ethereum on Monad. The address space in Monad is the same as in Ethereum, so you can reuse your existing keys. Like Ethereum, Monad features linear blocks, and linear ordering of transactions within a block. Like Ethereum, Monad is a proof-of-stake network maintained by a decentralized set of validators. Anyone can run a node to independently verify transaction execution, and significant care has been taken to keep hardware requirements minimal. [​](https://docs.monad.xyz/introduction/monad-for-users#what%E2%80%99s-different-about-monad) What’s different about Monad? ------------------------------------------------------------------------------------------------------------------------------ Monad makes exceptional performance possible by introducing **parallel execution** and **superscalar pipelining** to the Ethereum Virtual Machine. **Parallel execution** is the practice of utilizing multiple cores and threads to strategically execute work in parallel while still committing the results in the original order. Although transactions are executed in parallel “under the hood”, from the user and developer perspective they are executed serially; the result of a series of transactions is always the same as if the transactions had been executed one after another. **Superscalar pipelining** is the practice of creating stages of work and executing the stages in parallel. A simple diagram tells the story: ![Pipelining, Laundry Day](https://mintcdn.com/monadfoundation-40611fb6/-TCPhWHMfGzx9j3a/static/img/pipelining.png?w=2500&fit=max&auto=format&n=-TCPhWHMfGzx9j3a&q=85&s=fc5d1dfbe3a6ed66c63833a65d59670d) Pipelining laundry day. Top: Naive; Bottom: Pipelined. Credit: Prof. Lois Hawkes, FSU When doing four loads of laundry, the naive strategy is to wash, dry, fold, and store the first load of laundry before starting on the second one. The pipelined strategy is to start washing load 2 when load 1 goes into the dryer. Pipelining gets work done more efficiently by utilizing multiple resources simultaneously. **Monad** introduces pipelining to address existing bottlenecks in state storage, transaction processing, and distributed consensus. In particular, Monad introduces pipelining and other optimizations in five major areas: * [MonadBFT](https://docs.monad.xyz/monad-arch/consensus/monad-bft) for performant, tail-fork-resistant BFT consensus * [RaptorCast](https://docs.monad.xyz/monad-arch/consensus/raptorcast) for efficient block transmission * [Asynchronous Execution](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution) for pipelining consensus and execution to raise the time budget for execution * [Parallel Execution](https://docs.monad.xyz/monad-arch/execution/parallel-execution) and [JIT Compilation](https://docs.monad.xyz/monad-arch/execution/native-compilation) for efficient transaction execution * [MonadDb](https://docs.monad.xyz/monad-arch/execution/monaddb) for efficient state access Monad’s client, which was written from scratch in C++ and Rust, reflect these architectural improvements and result in a platform for decentralized apps that can truly scale to world adoption. [​](https://docs.monad.xyz/introduction/monad-for-users#why-should-i-care) Why should I care? ------------------------------------------------------------------------------------------------ Decentralized apps are replacements for centralized services with several significant advantages: * **Open APIs / composability**: decentralized apps can be called atomically by other decentralized apps, allowing developers to build more complex functionality by stacking existing components. * **Transparency**: app logic is expressed purely through code, so anyone can review the logic for side effects. State is transparent and auditable; proof of reserves in DeFi is the default. * **Censorship-resistance and credible neutrality:** anyone can submit transactions or upload applications to a permissionless network. * **Global reach**: anyone with access to the internet can access crucial financial services, including unbanked/underbanked users. However, decentralized apps need cheap, performant infrastructure to reach their intended level of impact. A single app with 1 million daily active users (DAUs) and 10 transactions per user per day would require 10 million transactions per day, or 100 tps. A quick glance at [L2Beat](https://l2beat.com/scaling/activity) - a useful website summarizing the throughput and decentralization of existing EVM-compatible L1s and L2s - shows that no EVM blockchain supports even close to that level of throughput right now. Monad materially improves on the performance of an EVM-compatible blockchain network, pioneering several innovations that will hopefully become standard in Ethereum in the years to come. With Monad, developers, users, and researchers can reuse the wealth of existing applications, libraries, and applied cryptography research that have all been built for the EVM. [​](https://docs.monad.xyz/introduction/monad-for-users#testnet) Testnet --------------------------------------------------------------------------- Monad’s public testnet is live. Head to [Network Information](https://docs.monad.xyz/developer-essentials/network-information) to get started. [Why Monad: Decentralization + Performance\ \ Previous](https://docs.monad.xyz/introduction/why-monad) [Monad for Developers\ \ Next](https://docs.monad.xyz/introduction/monad-for-developers) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Verify a smart contract on Monad using Hardhat - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/guides/verify-smart-contract/hardhat#content-area) Once your contract is deployed to a live network, the next step is to verify its source code on the block explorer. Verifying a contract means uploading its source code, along with the settings used to compile the code, to a repository (typically maintained by a block explorer). This allows anyone to compile it and compare the generated bytecode with what is deployed on chain. Doing this is extremely important in an open platform like Monad. In this guide we’ll explain how to do this using [Hardhat](https://hardhat.org/) . The verification command may show an error message, but this is often misleading - the contract is usually verified successfully on both Sourcify and MonadScan. Check the explorer links to confirm verification. * Hardhat 2 * Hardhat 3 [​](https://docs.monad.xyz/guides/verify-smart-contract/hardhat#hardhat-2-verification) Hardhat 2 Verification ----------------------------------------------------------------------------------------------------------------- The `hardhat-monad` template is pre-configured to verify contracts on both MonadVision (Sourcify) and Monadscan (Etherscan) simultaneously.If you’re using the template, your `hardhat.config.ts` should already have: import type { HardhatUserConfig } from "hardhat/config"; import "@nomicfoundation/hardhat-toolbox-viem"; import "@nomicfoundation/hardhat-ignition-viem"; import "dotenv/config"; const PRIVATE_KEY = process.env.PRIVATE_KEY || ""; const ETHERSCAN_API_KEY = process.env.ETHERSCAN_API_KEY || ""; const config: HardhatUserConfig = { solidity: { version: "0.8.28", settings: { metadata: { bytecodeHash: "ipfs", // Required for Sourcify verification }, }, }, networks: { monadTestnet: { url: "https://testnet-rpc.monad.xyz", accounts: [PRIVATE_KEY], chainId: 10143, }, monadMainnet: { url: "https://rpc.monad.xyz", accounts: [PRIVATE_KEY], chainId: 143, }, }, sourcify: { enabled: true, apiUrl: "https://sourcify-api-monad.blockvision.org", browserUrl: "https://monadvision.com", }, etherscan: { enabled: true, apiKey: { monadMainnet: ETHERSCAN_API_KEY, monadTestnet: ETHERSCAN_API_KEY, }, customChains: [\ {\ network: "monadMainnet",\ chainId: 143,\ urls: {\ apiURL: "https://api.etherscan.io/v2/api?chainid=143",\ browserURL: "https://monadscan.com",\ },\ },\ {\ network: "monadTestnet",\ chainId: 10143,\ urls: {\ apiURL: "https://api.etherscan.io/v2/api?chainid=10143",\ browserURL: "https://testnet.monadscan.com",\ },\ },\ ], }, }; export default config; **Verify on Mainnet:** npx hardhat verify --network monadMainnet **Verify on Testnet:** npx hardhat verify --network monadTestnet This will verify your contract on both MonadVision and Monadscan. Once verified, you can view your contract on the respective explorers. [​](https://docs.monad.xyz/guides/verify-smart-contract/hardhat#hardhat-3-verification) Hardhat 3 Verification ----------------------------------------------------------------------------------------------------------------- The verification command may show an error message, but this is often misleading - the contract is usually verified successfully on both Sourcify and MonadScan. Check the explorer links to confirm verification. The `hardhat3-monad` template is pre-configured to verify contracts on both MonadVision (Sourcify) and Monadscan (Etherscan). Hardhat 3 uses a different configuration structure with the `verify` key and `chainDescriptors`.If you’re using the template, your `hardhat.config.ts` should already have: import hardhatToolboxViemPlugin from "@nomicfoundation/hardhat-toolbox-viem"; import { defineConfig } from "hardhat/config"; import "dotenv/config"; const PRIVATE_KEY = process.env.PRIVATE_KEY || ""; const ETHERSCAN_API_KEY = process.env.ETHERSCAN_API_KEY || ""; export default defineConfig({ plugins: [hardhatToolboxViemPlugin], solidity: { version: "0.8.28", settings: { optimizer: { enabled: true, runs: 200, }, }, }, networks: { hardhat: { type: "edr-simulated", }, monadTestnet: { type: "http", url: "https://testnet-rpc.monad.xyz", accounts: [PRIVATE_KEY], chainId: 10143, }, monadMainnet: { type: "http", url: "https://rpc.monad.xyz", accounts: [PRIVATE_KEY], chainId: 143, }, }, verify: { blockscout: { enabled: false, }, etherscan: { enabled: true, apiKey: ETHERSCAN_API_KEY, }, sourcify: { enabled: true, apiUrl: "https://sourcify-api-monad.blockvision.org", }, }, chainDescriptors: { 143: { name: "MonadMainnet", blockExplorers: { etherscan: { name: "Monadscan", url: "https://monadscan.com", apiUrl: "https://api.etherscan.io/v2/api", }, }, }, }, }); **Verify on Mainnet:** npx hardhat verify --network monadMainnet **Verify on Testnet:** npx hardhat verify --network monadTestnet This will verify your contract on both MonadVision and Monadscan. Once verified, you can view your contract on the respective explorers. [Verify a smart contract on Monad using Foundry\ \ Previous](https://docs.monad.xyz/guides/verify-smart-contract/foundry) [Use an Indexer\ \ Next](https://docs.monad.xyz/guides/indexers) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # MPP Overview - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/reference/mpp/overview#content-area) The [`@monad-crypto/mpp`](https://www.npmjs.com/package/@monad-crypto/mpp) package implements Monad payments for the [Machine Payments Protocol](https://mpp.dev/) (MPP). It enables one-time payment processing through ERC-20 token transfers on Monad. This guide covers the Monad-specific `@monad-crypto/mpp` package. For general MPP concepts, see the [MPPX documentation](https://mpp.sh/docs) . [​](https://docs.monad.xyz/reference/mpp/overview#installation) Installation ------------------------------------------------------------------------------- Install the package and its peer dependencies: * npm * pnpm * yarn * bun npm install @monad-crypto/mpp mppx viem pnpm add @monad-crypto/mpp mppx viem yarn add @monad-crypto/mpp mppx viem bun add @monad-crypto/mpp mppx viem [​](https://docs.monad.xyz/reference/mpp/overview#server) Server ------------------------------------------------------------------- The server defines what payment is required and verifies credentials submitted by clients. Import `monad` from the server entrypoint and pass it to `Mppx.create`. server.ts import { monad } from "@monad-crypto/mpp/server"; import { Mppx } from "mppx"; import { privateKeyToAccount } from "viem/accounts"; const account = privateKeyToAccount(process.env.SERVER_PRIVATE_KEY as `0x${string}`); const mppx = Mppx.create({ methods: [\ monad({\ account,\ recipient: account.address,\ }),\ ], }); ### [​](https://docs.monad.xyz/reference/mpp/overview#gate-an-endpoint) Gate an endpoint Use `mppx.charge()` as middleware to require payment before serving a response. server.ts import { Hono } from "hono"; const app = new Hono(); app.get("/premium", mppx.charge(), async (ctx) => { return ctx.json({ message: "Premium content" }); }); export default app; When a client requests `/premium` without a valid payment credential, the server responds with a `402 Payment Required` status and a challenge describing the payment requirements. The client then submits a credential (transaction hash or signed authorization) to complete the payment. ### [​](https://docs.monad.xyz/reference/mpp/overview#testnet) Testnet By default, the package connects to Monad mainnet (chain ID `143`). To use testnet, set `testnet: true`. monad({ account, recipient: account.address, testnet: true, }) [​](https://docs.monad.xyz/reference/mpp/overview#client) Client ------------------------------------------------------------------- The client handles wallet interactions and credential creation. Import `monad` from the client entrypoint. With a local private key, the client defaults to **pull mode** — it signs an ERC-3009 authorization without broadcasting a transaction. client.ts import { monad } from "@monad-crypto/mpp/client"; import { Mppx } from "mppx/client"; import { privateKeyToAccount } from "viem/accounts"; const account = privateKeyToAccount(process.env.CLIENT_PRIVATE_KEY as `0x${string}`); const mppx = Mppx.create({ methods: [monad({ account })], }); // Make a paid request const response = await fetch("http://localhost:3000/premium"); const data = await response.json(); console.log(data); ### [​](https://docs.monad.xyz/reference/mpp/overview#push-vs-pull-mode) Push vs pull mode | | Push | Pull | | --- | --- | --- | | **Who pays gas** | Client | Server | | **Transaction** | Client broadcasts ERC-20 `transfer` | Server calls `transferWithAuthorization` | | **Credential** | Transaction hash | Signed ERC-3009 authorization | | **Default for** | JSON-RPC accounts (browser wallets) | Local accounts (private keys) | | **Trade-off** | Client needs gas tokens | Server needs gas tokens | ### [​](https://docs.monad.xyz/reference/mpp/overview#overriding-the-mode) Overriding the mode Use the `mode` option to set the payment mode explicitly, regardless of account type. monad({ account, mode: "push", // Always broadcast a transaction }) monad({ account, mode: "pull", // Always sign an authorization }) ### [​](https://docs.monad.xyz/reference/mpp/overview#monkey-patch) Monkey patch The client `Mppx.create()` function [monkey patches](https://en.wikipedia.org/wiki/Monkey_patch) the Web `fetch` API to use the configured payment method whenever it receives a `402 Payment Required` HTTP response. You can also use `mppx.fetch` directly. client.ts import { monad } from "@monad-crypto/mpp/client"; import { Mppx } from "mppx/client"; import { privateKeyToAccount } from "viem/accounts"; const account = privateKeyToAccount(process.env.CLIENT_PRIVATE_KEY as `0x${string}`); const mppx = Mppx.create({ methods: [monad({ account })], polyfill: false, }); const response = await mppx.fetch("http://localhost:3000/premium"); const data = await response.json(); console.log(data); [​](https://docs.monad.xyz/reference/mpp/overview#links) Links ----------------------------------------------------------------- * NPM package: [@monad-crypto/mpp](https://www.npmjs.com/package/@monad-crypto/mpp) * GitHub repository: [monad-crypto/monad-ts](https://github.com/monad-crypto/monad-ts) [Staking API Reference\ \ Previous](https://docs.monad.xyz/reference/staking/api) [MPP API Reference\ \ Next](https://docs.monad.xyz/reference/mpp/api) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Guides - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/guides#content-area) Start building smart contracts and applications on Monad with our quickstart guides. [​](https://docs.monad.xyz/guides#get-a-wallet) Get a wallet --------------------------------------------------------------- MetaMask -------- MetaMask browser wallet Software Wallets ---------------- Select a browser wallet [​](https://docs.monad.xyz/guides#deploy-smart-contract) Deploy Smart Contract --------------------------------------------------------------------------------- Foundry ------- Deploy a smart contract on Monad using Foundry Hardhat ------- Deploy a smart contract on Monad using Hardhat Remix ----- Deploy a smart contract on Monad using Remix [​](https://docs.monad.xyz/guides#verify-smart-contract) Verify Smart Contract --------------------------------------------------------------------------------- Foundry ------- Verify a smart contract on Monad using Foundry Hardhat ------- Verify a smart contract on Monad using Hardhat [​](https://docs.monad.xyz/guides#indexing) Indexing ------------------------------------------------------- GhostGraph ---------- Index transfers with GhostGraph Envio ----- Index transfers for a telegram bot using Envio QuickNode Streams ----------------- Index transfers using QuickNode Streams [​](https://docs.monad.xyz/guides#connectivity) Connectivity --------------------------------------------------------------- Reown AppKit ------------ Connect a wallet to your app with Reown AppKit [​](https://docs.monad.xyz/guides#ai) AI ------------------------------------------- MCP Server ---------- Build an MCP server to interact with Monad Testnet x402 on Monad ------------- How to setup x402-enabled endpoints with Monad support [​](https://docs.monad.xyz/guides#execution-events) Execution Events ----------------------------------------------------------------------- Set up Execution Events ----------------------- Configure your Monad node to enable execution events Consume Events in Rust ---------------------- Build a Rust application to read execution events [MPP API Reference\ \ Previous](https://docs.monad.xyz/reference/mpp/api) [Add Monad to Wallet\ \ Next](https://docs.monad.xyz/guides/add-monad-to-wallet) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Agentic Payments - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/tooling-and-infra/agentic-payments#content-area) See also the [x402 guide](https://docs.monad.xyz/guides/x402) for a step-by-step tutorial on building x402-enabled endpoints. [​](https://docs.monad.xyz/tooling-and-infra/agentic-payments#overview) Overview ----------------------------------------------------------------------------------- Agentic payments enable autonomous, machine-to-machine transactions over HTTP. Rather than requiring accounts, subscriptions, or API keys, any HTTP endpoint can become instantly payable using onchain payment authorization. Monad’s high throughput, sub-second finality, and low fees make it an ideal settlement layer for micropayments and agent-to-agent commerce. [​](https://docs.monad.xyz/tooling-and-infra/agentic-payments#provider-summary) Provider summary --------------------------------------------------------------------------------------------------- | Service | Protocol | Supported (Mainnet) | Docs | Notes | | --- | --- | --- | --- | --- | | Monad x402 Facilitator | [x402](https://www.x402.org/) | ✅ | [Guide](https://docs.monad.xyz/guides/x402) | URL: | | MPP SDK | [MPP](https://mpp.dev/) | ✅ | [Reference](https://docs.monad.xyz/reference/mpp/overview) | NPM: [`@monad-crypto/mpp`](https://www.npmjs.com/package/@monad-crypto/mpp) | [​](https://docs.monad.xyz/tooling-and-infra/agentic-payments#provider-details) Provider details --------------------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/tooling-and-infra/agentic-payments#monad-x402-facilitator) Monad x402 Facilitator The Monad x402 Facilitator is a hosted service that simplifies [x402](https://www.x402.org/) payment flows on Monad. x402 brings the HTTP 402 “Payment Required” status code to life as a minimal protocol for internet-native micropayments. **How it works:** 1. A client requests a resource from a server. 2. The server responds with HTTP 402 and a JSON payment requirement. 3. The client signs a payment authorization (no onchain transaction needed from the client). 4. The server verifies the signature and serves the content. 5. The facilitator settles the payment onchain, covering gas fees. **Facilitator URL:** **Key features:** * Supports Monad mainnet and testnet * Handles payment verification and onchain settlement * Covers gas fees on behalf of clients * Enables usage-based billing and per-call micropayments * Works with USDC on Monad **Facilitator API endpoints:** * `GET /supported` — Returns supported networks, schemes, and signer addresses * `POST /verify` — Verifies a payment signature before serving content * `POST /settle` — Executes the payment onchain after content is served To get started building x402-enabled endpoints on Monad, see the [x402 guide](https://docs.monad.xyz/guides/x402) . Learn more at [x402.org](https://www.x402.org/) . ### [​](https://docs.monad.xyz/tooling-and-infra/agentic-payments#mpp-sdk) MPP SDK The MPP SDK ([`@monad-crypto/mpp`](https://www.npmjs.com/package/@monad-crypto/mpp) ) is a TypeScript/JavaScript library for integrating [Machine Payments Protocol](https://mpp.dev/) into your applications on Monad. It provides utilities for constructing and managing payment transactions programmatically. * **NPM package:** [`@monad-crypto/mpp`](https://www.npmjs.com/package/@monad-crypto/mpp) * **Reference docs:** [`@monad-crypto/mpp` Reference](https://docs.monad.xyz/reference/mpp/overview) [Tooling and Infrastructure\ \ Previous](https://docs.monad.xyz/tooling-and-infra) [Analytics\ \ Next](https://docs.monad.xyz/tooling-and-infra/analytics) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Network Information - Testnet - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/developer-essentials/testnet#content-area) `testnet` was [reset from genesis on 2025-12-16](https://docs.monad.xyz/developer-essentials/changelog/releases#v0-12-5) . | Name | Value | | --- | --- | | Chain ID | | | Network Name | | | Currency Symbol | | | RPC URL | [see below](https://docs.monad.xyz/developer-essentials/testnet#public-rpc-endpoints) | | Block Explorer (MonadVision) | | | Block Explorer (Monadscan) | | | Network visualization | | | App hub | [https://testnet.monad.xyz/](https://testnet.monad.xyz/) | | Faucet | [https://faucet.monad.xyz](https://faucet.monad.xyz/) | | Current version / revision | [`v0.15.2`](https://docs.monad.xyz/developer-essentials/changelog/releases#v0-15-2)
/ [`MONAD_NINE`](https://docs.monad.xyz/developer-essentials/changelog#revisions) | | Changelog | [(link)](https://docs.monad.xyz/developer-essentials/changelog/releases) | [​](https://docs.monad.xyz/developer-essentials/testnet#public-rpc-endpoints) Public RPC Endpoints ----------------------------------------------------------------------------------------------------- Websocket endpoints start with `wss://`. See [Websocket Reference](https://docs.monad.xyz/reference/websockets) for further information. | RPC URL | Provider | Rate Limits | Batch Requests | Archive Support | Notes | | --- | --- | --- | --- | --- | --- | | | QuickNode | 50 rps | 100 | ✅ | 25 rps for `eth_call` and `eth_estimateGas` | | | Ankr | 300 reqs / 10s

12000 reqs / 10 min | 100 | ❌ | `debug_*` methods are not allowed | | | Monad Foundation | 20 rps | not allowed | ✅ | | See [RPC Limits](https://docs.monad.xyz/reference/rpc-limits) for additional detail on method-specific limits. [​](https://docs.monad.xyz/developer-essentials/testnet#canonical-contracts) Canonical Contracts --------------------------------------------------------------------------------------------------- | Name | Address | | --- | --- | | Wrapped MON | | | CreateX | | | Foundry Deterministic Deployer | | | [ERC-6492 UniversalSigValidator](https://eips.ethereum.org/EIPS/eip-6492) | | | EntryPoint v0.6 | | | EntryPoint v0.7 | | | EntryPoint v0.8 | | | Multicall3 | | | Permit2 | | | SafeSingletonFactory | | | [x402 ExactPermit2Proxy](https://github.com/x402-foundation/x402/blob/main/contracts/evm/src/x402ExactPermit2Proxy.sol) | | | [x402 UptoPermit2Proxy](https://github.com/x402-foundation/x402/blob/main/contracts/evm/src/x402UptoPermit2Proxy.sol) | | ### [​](https://docs.monad.xyz/developer-essentials/testnet#safe-v1-4-1-contracts) Safe v1.4.1 Contracts | Name | Address | | --- | --- | | Safe | | | SafeL2 | | | SafeProxyFactory | | | MultiSend | | | MultiSendCallOnly | | | CompatibilityFallbackHandler | | | SignMessageLib | | | CreateCall | | | SimulateTxAccessor | | [​](https://docs.monad.xyz/developer-essentials/testnet#testnet-tokens-partial-list) Testnet Tokens (partial list) --------------------------------------------------------------------------------------------------------------------- See [tokenlist-testnet.json](https://github.com/monad-crypto/token-list/blob/main/tokenlist-testnet.json) . [Tokens and Bridges\ \ Previous](https://docs.monad.xyz/developer-essentials/network-information/tokens-and-bridges) [Deployment Summary for Developers\ \ Next](https://docs.monad.xyz/developer-essentials/summary) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # MIP-8 Activation and Page Storage Migration - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/node-ops/upgrade-instructions/page-storage-mip-8-migration#content-area) [​](https://docs.monad.xyz/node-ops/upgrade-instructions/page-storage-mip-8-migration#introduction) Introduction ------------------------------------------------------------------------------------------------------------------- This document covers the operational side of activating MIP-8: migrating a node’s database from **slot to page encoding**, live and without resyncing from genesis. Each node **dual-writes** both encodings until the fork flips the network to **page-encoded** database, then drops the old **slot-encoded** database. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/page-storage-mip-8-migration#background) Background --------------------------------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/page-storage-mip-8-migration#mip-8) MIP-8 [MIP-8](https://monad.xyz/blog/mip-8) reorganizes the EVM state trie to be page-aware: storage slots are grouped into 4 KB pages instead of being scattered independently across disk by hashing. For node operators, what matters is that this changes the on-disk trie layout — which is why a migration is required. ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/page-storage-mip-8-migration#triedb-timelines) TrieDB timelines A **timeline** is a full copy of the trie state on disk, built by writing every committed block into it in a given encoding. A node can run one or two timelines at once, each in its own encoding: * **Slot-encoded timeline** uses the current trie layout, where each storage slot’s disk location is determined independently by hashing. This is the pre-MIP-8 format. * **Page-encoded timeline** uses the MIP-8 layout, where slots are packed into pages of 128 consecutive slots. This is the post-MIP-8 format. **Dual mode** is a transitional state where a node runs both encodings at once, as two timelines on disk, and writes every committed block to both. A node stays in dual mode for the whole window between activating the page timeline and decommissioning the slot timeline. **Primary** and **secondary** just label the two timelines on disk. They have no effect on execution or consensus. Over the course of the migration, primary and secondary swap, then the secondary is dropped (see [Migration plan](https://docs.monad.xyz/node-ops/upgrade-instructions/page-storage-mip-8-migration#migration-plan) ). ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/page-storage-mip-8-migration#state-machine-kinds) State machine kinds The node’s database tooling (`monad-mpt`, `monad-cli`) refers to slot and page encoding as state-machine kinds: | Kind on CLI | Encoding | | --- | --- | | `ethereum` | slot | | `monad` | page | What matters for execution is which timeline is **canonical** versus **shadow**. The canonical timeline is the one whose `state_root` is used for blocks on the canonical chain; the shadow timeline computes the same blocks on the other encoding in parallel, without its `state_root` being used anywhere. MIP-8 activation is exactly the flip between the two: * before activation, `ethereum` (slot) is canonical and `monad` (page) is the shadow * this swaps at the hard fork, `monad` (page) becomes canonical and `ethereum` (slot) becomes the shadow. This is why activation happens by network-wide consensus. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/page-storage-mip-8-migration#migration-plan) Migration plan ----------------------------------------------------------------------------------------------------------------------- The migration runs in three phases: two operator actions and one hard fork. Phase A activates the page timeline on each node. Phase B is the MIP-8 hard fork: at a fixed timestamp, the canonical chain switches from the slot timeline to the page timeline. Phase C decommissions the now-legacy slot timeline. ![](https://mintcdn.com/monadfoundation-40611fb6/BP6rYLBOYSsAWjlK/static/img/node-ops/upgrade-instructions/mip8-migration-timeline.svg?w=2500&fit=max&auto=format&n=BP6rYLBOYSsAWjlK&q=85&s=b56a562f77d84a8978f3b33d1be289de) 1 Initial DB mode is Legacy/Slot — a single slot timeline. Execution is Pre MIP-8 Activation. 2 Phase A — Page activation Operators activate the page secondary, bringing DB mode to Dual. Execution is still Pre MIP-8 Activation — nothing changes at the execution level yet. 3 Phase B — Hard fork At the fork timestamp, MIP-8 activates network-wide: the page timeline becomes canonical and the slot timeline becomes its shadow. The node stays in Dual mode. 4 Phase C — Slot decommission (Final) Operators promote the page timeline as primary, and decommission the now secondary slot timeline. DB mode flips to Page — a single page timeline. The node is now fully migrated. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/page-storage-mip-8-migration#operations) Operations --------------------------------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/page-storage-mip-8-migration#network-status) Network status | Network | Phase | Current release | Hard fork timestamp | MIP-8 activated | | --- | --- | --- | --- | --- | | Testnet | A - Dual-db activation | `0.15.2` | TBD | No | | Mainnet | Initial | TBD | TBD | No | ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/page-storage-mip-8-migration#get-the-current-status) Get the current status Check a node’s current on-disk state directly with `monad-mpt`: monad-mpt --storage /dev/triedb **Legacy/Slot** — migration not started: Active timelines: Primary: State machine kind: ethereum **Dual** — migration in progress: Active timelines: Primary: State machine kind: ethereum Secondary: State machine kind: monad **Page** — migration complete: Active timelines: Primary: State machine kind: monad ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/page-storage-mip-8-migration#prometheus-metrics) Prometheus Metrics You can monitor the dual-DB migration phase via the Prometheus metric `monad_triedb_migration_phase`: * `0`: slot-encoded (expected value during Init phase) * `1`: dual-mode (expected value during Phase A and Phase B) * `2`: page-encoded (expected value during Phase C) ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/page-storage-mip-8-migration#monad-status) Monad Status The [`monad-status`](https://docs.monad.xyz/node-ops/general-operations#node-status-with-monad-status) script has been updated to reflect the TrieDB mode, e.g.: triedb: model: SAMSUNG MZQL21T9HCJR-00A07 device: nvme0n1p1 mode: dual-timeline timelines: primary: ethereum secondary: monad ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/page-storage-mip-8-migration#hard-reset-a-node) Hard reset a node The hard reset process itself doesn’t change — still follow the [Hard Reset Instructions](https://docs.monad.xyz/node-ops/node-recovery/hard-reset) . The DB mode logic below happens automatically inside that same `restore-from-snapshot` step; there’s no new manual procedure to learn. A hard reset doesn’t migrate your existing database — it wipes it and rebuilds from a snapshot. That means the reset tooling can’t look at your node’s prior on-disk state to decide what to rebuild (the reset truncates the DB before anything else runs), so it picks the target DB mode with this logic: * If the MIP-8 hard fork has already passed, it creates a page timeline only, and imports the snapshot into it. * If the fork hasn’t passed yet and it can also create a page timeline, the result is Dual mode, with the snapshot imported into both timelines. * If the fork hasn’t passed yet and it can’t create a page timeline, the result is Legacy/Slot, with the snapshot imported into the slot timeline only. | MIP-8 Activation timestamp | Page timeline creation supported | Resulting DB mode | | --- | --- | --- | | MIP-8 Active | — | Page | | Inactive | Yes | Dual | | Inactive | No | Legacy/Slot | The first row is deliberate: once MIP-8 is active on the network, there’s no reason to stand up a slot timeline just to decommission it again in the very next phase — a reset node goes straight to page-only. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/page-storage-mip-8-migration#migration-tasks) Migration tasks ------------------------------------------------------------------------------------------------------------------------- This applies to both full nodes and validators. The migration runs in three phases. Phases A and C are actions you take on each node; phase B is a network-wide hard fork that happens on a schedule. ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/page-storage-mip-8-migration#phase-a-page-activation) Phase A - Page activation **Do not run this procedure. Wait for the official Monad Foundation announcement.****Validators migration will occur in cohorts.** Ensure you know which cohort you are in, and only action these steps when your cohort is announced. Deployment dates and cohorts will be communicated via official channels. This process is supported starting from `0.15.2`. This step uses the new `monad-mpt` and `monad-cli` binaries starting from this version. **Stop the monad services:** sudo systemctl stop monad-bft monad-execution monad-rpc The snapshot dump will open many file descriptors (8 per shard). If your system’s open-file limit is at the default 1024, the dump will crash. **Raise the limit before running:** ulimit -n 65536 **Prepare the snapshot folder and clean up any pre-existing secondary timeline:** SNAP_DIR="/home/monad/monad-bft/snapshots/page-migration" rm -rf "$SNAP_DIR" && mkdir -p "$SNAP_DIR" monad-mpt --storage /dev/triedb --deactivate-secondary || true **Activate the secondary timeline:** monad-mpt --storage /dev/triedb --repair monad-mpt --storage /dev/triedb --activate-secondary --state-machine monad Expected output: `Activated secondary timeline; stamped state-machine kind.` **Dump a snapshot of the current primary:** monad-cli --db /dev/triedb --version latest_finalized --dump-binary-snapshot "$SNAP_DIR" Expected output: `snapshot dump success=true`. Takes approximately 5 minutes. **Load the snapshot into the page secondary:** monad-cli --db /dev/triedb --version latest_finalized --load-binary-snapshot "$SNAP_DIR" --secondary Expected output: `load_to_secondary=true`. Takes approximately 3 minutes. **Clean up the snapshot:** rm -rf "$SNAP_DIR" **Verify the status of TrieDB:** monad-mpt --storage /dev/triedb The command should print output similar to the following: MPT database on storages: Capacity Used % Path 1.75 Tb 24.05 Gb 1.34% "/dev/nvme0n1p1" MPT database internal lists: Fast: 1 chunks with capacity 256.00 Mb used 61.34 Mb Slow: 95 chunks with capacity 23.75 Gb used 23.74 Gb Free: 7040 chunks with capacity 1.72 Tb used 0.00 bytes MPT database has been configured to retain no more than 134217728 versions. Latest proposed is (18446744073709551615, 0000000000000000000000000000000000000000000000000000000000000000). Latest voted is (18446744073709551615, 0000000000000000000000000000000000000000000000000000000000000000). Latest finalized is 47536183, latest verified is 18446744073709551615 Active timelines: Primary: State machine kind: ethereum History: 19513 versions, earliest is 47516671, latest is 47536183 Auto expire version: 47516671 Secondary: State machine kind: monad History: 256 versions, earliest is 47535928, latest is 47536183 Auto expire version: 47535929 Verify that the `latest` values for both timelines are close (`47536183` in this example): * Primary: `latest is 47536183` * Secondary: `latest is 47536183` A difference of a few blocks (up to ~10) is normal. **Start the Monad services:** sudo systemctl start monad-bft monad-execution monad-rpc sudo systemctl status monad-bft monad-execution monad-rpc --no-pager -l All services should show Active: `active (running)`. Confirm the node rejoins and advances blocks. Once complete, the node is in dual-write mode — it will commit every new block to both timelines on next start. The `monad-execution` logs would print `state_root primary= secondary=`, both timelines should appear for each block. Run this on every node to bring the node into dual mode. Every node must complete this phase before the MIP-8 hard fork timestamp. ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/page-storage-mip-8-migration#phase-b-mip-8-hardfork) Phase B - MIP-8 Hardfork **MIP-8 activation** Phase B is a scheduled protocol upgrade, not an operator action. Its timestamp is encoded in a chain-wide release and is identical for every node — it only ships once the whole network has completed phase A. At that timestamp, MIP-8 activates at the execution level and the canonical `state_root` flips from the slot timeline to the page timeline, network-wide, in the same block: * **Before the fork** — the slot timeline is canonical; the page timeline shadows it. * **At and after the fork** — the page timeline is canonical; the slot timeline shadows it. Which timeline is on-disk primary is independent of which one is canonical. ### [​](https://docs.monad.xyz/node-ops/upgrade-instructions/page-storage-mip-8-migration#phase-c-slot-decommission) Phase C - Slot decommission **Historical / State Archive nodes**Node storing the all state from genesis in TrieDB will keep the `slot-encoded` timeline active.Therefore, these node will not proceed through the Phase C, and not decommission the `slot-encoded` timeline. **Decommission the slot timeline** Run this on each node any time after the fork. 1. Stop the Monad services. 2. Promote the page secondary to primary. 3. Deactivate the now-stale slot timeline, reclaiming its disk space. 4. Restart the Monad services. It’s now a single page timeline. Future releases of Monad will enforce having the slot-encoded timeline decommissioned. [​](https://docs.monad.xyz/node-ops/upgrade-instructions/page-storage-mip-8-migration#further-reading) Further reading ------------------------------------------------------------------------------------------------------------------------- * [Engineering runbook](https://github.com/category-labs/monad/blob/max/page-store-migration-runbook/docs/page_store_migration_runbook.md) — full operator procedure, including failure handling, rollback, and guard rails * [Network info](https://docs.monad.xyz/networks.json) — current network status and fork timestamps * [MIP-8](https://monad.xyz/blog/mip-8) — the proposal behind page-aware storage * [Mipland](https://mipland.com/mip-8) — MIP-8 tracking and discussion * [MIP-8: page-ified storage state](https://forum.monad.xyz/t/mip-8-page-ified-storage-state/407) — forum discussion [Upgrade Instructions\ \ Previous](https://docs.monad.xyz/node-ops/upgrade-instructions) [v0.15.2 Upgrade Instructions\ \ Next](https://docs.monad.xyz/node-ops/upgrade-instructions/v0.15.2) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Other Languages - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/guides/evm-resources/other-languages#content-area) Alternative smart contract languages for the EVM beyond Solidity. Vyper ----- A Python-like language for EVM smart contracts Huff ---- Low-level EVM assembly language Yul --- Intermediate assembly language for the EVM [Solidity Resources\ \ Previous](https://docs.monad.xyz/guides/evm-resources/solidity-resources) [Vyper\ \ Next](https://docs.monad.xyz/guides/evm-resources/other-languages/vyper) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Yul - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/guides/evm-resources/other-languages/yul#content-area) [Yul](https://docs.soliditylang.org/en/latest/yul.html) is a intermediate language for Solidity that can generally be thought of as inline assembly for the EVM. It is not quite pure assembly, providing control flow constructs and abstracting away the inner working of the stack while still exposing the raw memory backend to developers. Yul is targeted at developers needing exposure to the EVM’s raw memory backend to build high performance gas optimized EVM code. [Vyper\ \ Previous](https://docs.monad.xyz/guides/evm-resources/other-languages/vyper) [Huff\ \ Next](https://docs.monad.xyz/guides/evm-resources/other-languages/huff) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Solidity Resources - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/guides/evm-resources/solidity-resources#content-area) Monad is fully EVM bytecode-compatible, with all supported opcodes and precompiles as of the [Osaka fork](https://www.evm.codes/?fork=osaka) . Monad also preserves the standard Ethereum JSON-RPC interfaces. As such, most development resources for Ethereum Mainnet apply to development on Monad. This page suggests a **minimal** set of resources for getting started with building a decentralized app for Ethereum. Child pages provide additional detail or options. As [Solidity](https://docs.soliditylang.org/) is the most popular language for Ethereum smart contracts, the resources on this page focus on Solidity; alternatively see resources on [Vyper](https://docs.monad.xyz/guides/evm-resources/other-languages/vyper) or [Huff](https://docs.monad.xyz/guides/evm-resources/other-languages/huff) . Note that since smart contracts are composable, contracts originally written in one language can still make calls to contracts in another language. [​](https://docs.monad.xyz/guides/evm-resources/solidity-resources#ides) **IDEs** ------------------------------------------------------------------------------------ * [Remix](https://remix.ethereum.org/#lang=en&optimize=false&runs=200&evmVersion=null) is an interactive Solidity IDE. It is the easiest and fastest way to get started coding and compiling Solidity smart contracts without the need for additional tool installations. * [VSCode](https://code.visualstudio.com/) + [Solidity extension](https://marketplace.visualstudio.com/items?itemName=NomicFoundation.hardhat-solidity) [​](https://docs.monad.xyz/guides/evm-resources/solidity-resources#basic-solidity) **Basic Solidity** -------------------------------------------------------------------------------------------------------- * [CryptoZombies](https://cryptozombies.io/en/course) is a great end-to-end introduction to building dApps on the EVM. It provides resources and lessons for anyone from someone who has never coded before, to experienced developers in other disciplines looking to explore blockchain development. * [Solidity by Example](https://solidity-by-example.org/) introduces concepts progressively through simple examples; best for developers who already have basic experience with other languages. * [Blockchain Basics course by Cyfrin Updraft](https://updraft.cyfrin.io/courses/blockchain-basics) teaches the fundamentals of blockchain, DeFi, and smart contracts. * [Solidity Smart Contract Development by Cyfrin Updraft](https://updraft.cyfrin.io/courses/solidity) will teach you how to become a smart contract developer. Learn to build with projects and get hands-on experience. * [Ethereum Developer Degree by LearnWeb3](https://learnweb3.io/degrees/ethereum-developer-degree/) is the a good course to go from no background knowledge in web3 to being able to build multiple applications and understanding several key protocols, frameworks, and concepts in the web3 space. [​](https://docs.monad.xyz/guides/evm-resources/solidity-resources#intermediate-solidity) **Intermediate Solidity** ---------------------------------------------------------------------------------------------------------------------- * [The Solidity Language](https://docs.soliditylang.org/en/v0.8.21/introduction-to-smart-contracts.html) official documentation is an end-to-end description of Smart Contracts and blockchain basics centered on EVM environments. In addition to Solidity Language documentation, it covers the basics of compiling your code for deployment on an EVM as well as the basic components relevant to deploying a Smart Contract on an EVM. * [Solidity Patterns](https://github.com/fravoll/solidity-patterns) repository provides a library of code templates and explanation of their usage. * The [Uniswap V2](https://github.com/Uniswap/v2-core) contract is a professional yet easy to digest smart contract that provides a great overview of an in-production Solidity dApp. A guided walkthrough of the contract can be found [here](https://ethereum.org/en/developers/tutorials/uniswap-v2-annotated-code/) . * [Cookbook.dev](https://www.cookbook.dev/search?q=cookbook&categories=Contracts&sort=popular&filter=&page=1) provides a set of interactive example template contracts with live editing, one-click deploy, and an AI chat integration to help with code questions. * [OpenZeppelin](https://www.openzeppelin.com/contracts) provides customizable template contract library for common Ethereum token deployments such as ERC20, ERC712, and ERC1155. Note, they are not gas optimized. * [Rareskills Blog](https://www.rareskills.io/category/solidity) has some great in-depth articles on various concepts in Solidity. * [Foundry Fundamentals course by Cyfrin Updraft](https://updraft.cyfrin.io/courses/foundry) is a comprehensive web3 development course designed to teach you about Foundry the industry-standard framework to build, deploy, and test your smart contracts. * [Smart Contract Programmer YT channel](https://www.youtube.com/@smartcontractprogrammer) has a plenty of in-depth videos about various Solidity concepts like ABI encoding, EVM memory, and many more. [​](https://docs.monad.xyz/guides/evm-resources/solidity-resources#advanced-solidity) **Advanced Solidity** -------------------------------------------------------------------------------------------------------------- * The [Solmate repository](https://github.com/transmissions11/solmate) and [Solady repository](https://github.com/Vectorized/solady/tree/main) provide gas-optimized contracts utilizing Solidity or Yul. * [Yul](https://docs.soliditylang.org/en/latest/yul.html) is a intermediate language for Solidity that can generally be thought of as inline assembly for the EVM. It is not quite pure assembly, providing control flow constructs and abstracting away the inner working of the stack while still exposing the raw memory backend to developers. Yul is targeted at developers needing exposure to the EVM’s raw memory backend to build high performance gas optimized EVM code. * [Huff](https://docs.huff.sh/get-started/overview/) is most closely described as EVM assembly. Unlike Yul, Huff does not provide control flow constructs or abstract away the inner working of the program stack. Only the most upmost performance sensitive applications take advantage of Huff, however it is a great educational tool to learn how the EVM interprets instructions its lowest level. * [Advanced Foundry course by Cyfrin Updraft](https://updraft.cyfrin.io/courses/advanced-foundry) teaches you about Foundry, how to develop a DeFi protocol and a stablecoin, how to develop a DAO, advanced smart contract development, advanced smart contracts testing and fuzzing and manual verification. * [Smart Contract Security course by Cyfrin Updraft](https://updraft.cyfrin.io/courses/security) will teach you everything you need to know to get started auditing and writing secure protocols. * [Assembly and Formal Verification course by Cyfrin Updraft](https://updraft.cyfrin.io/courses/formal-verification) teaches you about Assembly, writing smart contracts using Huff and Yul, Ethereum Virtual Machine OPCodes, Formal verification testing, Smart contract invariant testing and tools like Halmos, Certora, Kontrol. * [Smart Contract DevOps course by Cyfrin Updraft](https://updraft.cyfrin.io/courses/wallets) teaches about access control best practices when working with wallets, post-deployment security, smart contract and web3 devOps and live protocols maintenance and monitoring. * [Secureum YT Channel](https://www.youtube.com/@SecureumVideos/videos) has plenty videos about Solidity from Solidity Basics to all the way to advanced concepts like Fuzzing and Solidity auditing. [​](https://docs.monad.xyz/guides/evm-resources/solidity-resources#tutorials) Tutorials ------------------------------------------------------------------------------------------ * [Ethernaut](https://ethernaut.openzeppelin.com/) : learn by solving puzzles * [Damn Vulnerable DeFi](https://www.damnvulnerabledefi.xyz/) : DVD is a series of smart contract challenges which consists of vulnerable contracts and you are supposed to be able to hack it. These challenges are a good way to practice and apply the Solidity skills you have acquired. [​](https://docs.monad.xyz/guides/evm-resources/solidity-resources#best-practices/patterns) Best practices/patterns ---------------------------------------------------------------------------------------------------------------------- * [DeFi developer roadmap](https://github.com/OffcierCia/DeFi-Developer-Road-Map) * [RareSkills Book of Gas Optimization](https://www.rareskills.io/post/gas-optimization) [​](https://docs.monad.xyz/guides/evm-resources/solidity-resources#testing) Testing -------------------------------------------------------------------------------------- * [Echidna](https://github.com/crytic/echidna) : fuzz testing * [Slither](https://github.com/crytic/slither) : static analysis for vulnerability detection * [solidity-coverage](https://github.com/sc-forks/solidity-coverage/tree/master) : code coverage for Solidity testing [​](https://docs.monad.xyz/guides/evm-resources/solidity-resources#smart-contract-archives) Smart contract archives ---------------------------------------------------------------------------------------------------------------------- * [Smart contract sanctuary](https://github.com/tintinweb/smart-contract-sanctuary) - contracts verified on Etherscan * [EVM function signature database](https://www.4byte.directory/) [EVM Behavior\ \ Previous](https://docs.monad.xyz/guides/evm-resources/evm-behavior) [Other Languages\ \ Next](https://docs.monad.xyz/guides/evm-resources/other-languages) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Multisig Wallets - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/tooling-and-infra/wallets/multisig-wallets#content-area) [​](https://docs.monad.xyz/tooling-and-infra/wallets/multisig-wallets#provider-summary) Provider Summary ----------------------------------------------------------------------------------------------------------- * Mainnet * Testnet | Wallet | Status | Contract addresses | Other Features | | --- | --- | --- | --- | | [Safe](https://safe.global/wallet) | ✅ | See [contract addresses](https://github.com/monad-crypto/protocols/blob/main/mainnet/safe.jsonc) | | _✅ = supported, ⌛️ = in progress, ❓ = unknown, ❌ = won’t support_ | Wallet | Status | Other Features | | --- | --- | --- | | [Safe](https://safe.global/wallet) | ✅ | | _✅ = supported, ⌛️ = in progress, ❓ = unknown, ❌ = won’t support_ [​](https://docs.monad.xyz/tooling-and-infra/wallets/multisig-wallets#provider-details) Provider Details ----------------------------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/tooling-and-infra/wallets/multisig-wallets#safe-wallet) Safe Wallet [Safe Wallet](https://safe.global/wallet) is a secure, non-custodial cryptocurrency wallet that allows users to manage, store, and interact with digital assets like tokens and NFTs. It is built on the Safe (formerly Gnosis Safe) smart contract infrastructure, offering advanced features like multisig control, transaction batching, and custom permissions. Designed for both individuals and organizations, Safe Wallet emphasizes security, transparency, and decentralized asset management. Access Safe Wallet [here](https://safe.global/wallet) . [safe-tx-hashes-util](https://github.com/pcaversaccio/safe-tx-hashes-util) is a tool for independently computing Safe transaction hashes based on transaction details from the Safe transaction service UI.[safe-tx-hashes-util](https://github.com/pcaversaccio/safe-tx-hashes-util) supports Monad. [Institutional Wallets\ \ Previous](https://docs.monad.xyz/tooling-and-infra/wallets/institutional-wallets) [Wallet Infrastructure\ \ Next](https://docs.monad.xyz/tooling-and-infra/wallet-infra) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Institutional Wallets - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/tooling-and-infra/wallets/institutional-wallets#content-area) See also [Custody](https://docs.monad.xyz/tooling-and-infra/custody) . [​](https://docs.monad.xyz/tooling-and-infra/wallets/institutional-wallets#provider-summary) Provider Summary ---------------------------------------------------------------------------------------------------------------- * Mainnet | Wallet | Status | | --- | --- | | [Cubist](https://cubist.dev/products/cubesigner-self-custody) | ✅ | | [Porto by Anchorage Digital](https://www.anchorage.com/platform/self-custody) | ✅ | | [Utila](https://utila.io/) | ✅ | _✅ = supported, ⌛️ = in progress, ❓ = unknown, ❌ = won’t support_ [​](https://docs.monad.xyz/tooling-and-infra/wallets/institutional-wallets#provider-details) Provider Details ---------------------------------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/tooling-and-infra/wallets/institutional-wallets#cubist) Cubist [Cubist](https://cubist.dev/products/cubesigner-self-custody) ’s CubeSigner gives teams and protocols self-custody key management backed by FIPS-certified hardware, SSO authentication, and a programmable policy engine with role-based access control and multi-party approvals. It secures treasury, trading, payments, staking and validator, and cross-chain bridge operations across Bitcoin, Ethereum and EVM chains, Solana, and Sui — and is trusted by leading institutions. ### [​](https://docs.monad.xyz/tooling-and-infra/wallets/institutional-wallets#porto-by-anchorage-digital) Porto by Anchorage Digital [Porto](https://www.anchorage.com/platform/self-custody) by Anchorage Digital empowers institutions to confidently engage with a wide variety of DeFi protocols, execute native swaps, and deploy sophisticated on-chain strategies directly from a self-custody wallet. ### [​](https://docs.monad.xyz/tooling-and-infra/wallets/institutional-wallets#utila) Utila Securely build, manage, and scale digital asset operations with [Utila](https://utila.io/) ’s enterprise-grade wallet platform. Trusted by leading institutions to power stablecoin payments, treasury, trading, and beyond. To get started, visit the [documentation](https://docs.utila.io/reference/api-overview) or follow the [quickstart](https://support.utila.io/en/collections/13931663-getting-started) guide. [Hardware Wallets\ \ Previous](https://docs.monad.xyz/tooling-and-infra/wallets/hardware-wallets) [Multisig Wallets\ \ Next](https://docs.monad.xyz/tooling-and-infra/wallets/multisig-wallets) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Hardware Wallets - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/tooling-and-infra/wallets/hardware-wallets#content-area) [​](https://docs.monad.xyz/tooling-and-infra/wallets/hardware-wallets#provider-summary) Provider Summary ----------------------------------------------------------------------------------------------------------- * Mainnet * Testnet | Wallet | Status | Other Features | | --- | --- | --- | | [Ledger](https://www.ledger.com/) | ✅ | | | [Safepal](https://www.safepal.com/) | ✅ | Support for multiple cryptocurrencies, Secure element chip | | [Tangem](https://tangem.com/en/) | ✅ | Card-shaped, self-custodial hardware wallet designed for secure, offline storage of cryptocurrencies. | _✅ = supported, ⌛️ = in progress, ❓ = unknown, ❌ = won’t support_ | Wallet | Status | Other Features | | --- | --- | --- | | [D’Cent Wallet](https://dcentwallet.com/) | ✅ | Biometric authentication, Bluetooth connectivity | | [Ledger](https://www.ledger.com/) | ❌ | | | [Safepal](https://www.safepal.com/) | ✅ | Support for multiple cryptocurrencies, Secure element chip | _✅ = supported, ⌛️ = in progress, ❓ = unknown, ❌ = won’t support_ [​](https://docs.monad.xyz/tooling-and-infra/wallets/hardware-wallets#provider-details) Provider Details ----------------------------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/tooling-and-infra/wallets/hardware-wallets#d%E2%80%99cent-wallet) D’Cent Wallet [D’Cent Wallet](https://dcentwallet.com/) is a hardware wallet featuring biometric authentication for enhanced security. It uses a secure chip to protect private keys and offers Bluetooth connectivity for convenient mobile device pairing. D’Cent provides a balance of security and usability with its fingerprint recognition technology and support for multiple cryptocurrencies. To get started, learn more about D’Cent Wallet [here](https://store.dcentwallet.com/) or visit the [user guide](https://userguide.dcentwallet.com/) . ### [​](https://docs.monad.xyz/tooling-and-infra/wallets/hardware-wallets#ledger) Ledger Ledger is a leading company in cryptocurrency security, best known for its hardware wallets that keep digital assets safe through offline (cold) storage. These wallets use a secure element chip and custom operating system to protect private keys, while requiring users to confirm transactions directly on the device for added safety. Learn more about Ledger [here](https://www.ledger.com/) . ### [​](https://docs.monad.xyz/tooling-and-infra/wallets/hardware-wallets#safepal) Safepal [Safepal](https://www.safepal.com/) offers hardware wallet solutions that combine security with user-friendly features. Their hardware wallets utilize secure element chips to protect private keys and support a wide range of cryptocurrencies. Safepal hardware wallets are designed to be affordable while maintaining high security standards, making them accessible to both new and experienced crypto users. To get started, learn more about Safepal hardware wallets [here](https://www.safepal.com/s1) or visit the [documentation](https://docs.safepal.io/) . ### [​](https://docs.monad.xyz/tooling-and-infra/wallets/hardware-wallets#tangem) Tangem [Tangem Wallet](https://tangem.com/en/) is a card-shaped, self-custodial hardware wallet designed for secure, offline storage of cryptocurrencies. It is roughly the size of a standard credit card and uses NFC (Near Field Communication) to connect to a smartphone. [Software Wallets\ \ Previous](https://docs.monad.xyz/tooling-and-infra/wallets/software-wallets) [Institutional Wallets\ \ Next](https://docs.monad.xyz/tooling-and-infra/wallets/institutional-wallets) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Account Abstraction Providers - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/tooling-and-infra/wallet-infra/account-abstraction#content-area) Account Abstraction Providers provide bundler and paymaster services, enabling features like sponsored transactions or payment via custom tokens. [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/account-abstraction#definitions) Definitions --------------------------------------------------------------------------------------------------------- | Service | Description | | --- | --- | | Bundler | Operates a custom mempool for UserOperations; simulates and assembles bundles of UserOperations | | Paymaster | Enables sponsored transactions; enables users to pay for gas with a custom token | [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/account-abstraction#provider-summary) Provider Summary ------------------------------------------------------------------------------------------------------------------- * Mainnet * Testnet | Provider | Status | Docs | Supported services | How to get started | | --- | --- | --- | --- | --- | | [Alchemy](https://www.alchemy.com/smart-wallets) | ✅ | [Docs](https://accountkit.alchemy.com/) | [Gas Manager](https://docs.alchemy.com/docs/gas-manager-services)
(aka Paymaster)
[Bundler](https://docs.alchemy.com/docs/bundler-services) | [Dashboard](https://dashboard.alchemy.com/accounts?a=smart-wallets&utm_source=chain_partner&utm_medium=referral&utm_campaign=monad) | | [Biconomy](https://biconomy.io/) | ✅ | [Docs](https://docs.biconomy.io/) | [Orchestration Infrastructure](https://docs.biconomy.io/new/learn-about-biconomy/what-is-mee) | [Getting started](https://docs.biconomy.io/supertransaction-api/getting-started) | | [FastLane](https://www.fastlane.xyz/) | ❓ | [Docs](https://docs.shmonad.xyz/) | [Paymaster and Bundler](https://github.com/FastLane-Labs/4337-bundler-paymaster-script/tree/main) | [Dashboard](https://shmonad.xyz/) | | [Pimlico](https://pimlico.io/) | ✅ | [Docs](https://docs.pimlico.io/) | [Paymaster](https://docs.pimlico.io/infra/paymaster)

[Bundler](https://docs.pimlico.io/infra/bundler) | [Tutorial](https://docs.pimlico.io/permissionless/tutorial/tutorial-1) | | [Sequence](https://sequence.xyz/) | ✅ | [Docs](https://docs.sequence.xyz/solutions/infrastructure/transaction-api) | Relayer: gasless, batched, parallelized transactions | [Quickstart](https://docs.sequence.xyz/solutions/builder/gas-sponsorship) | | [thirdweb](https://thirdweb.com/) | ✅ | [Docs](https://portal.thirdweb.com/) | [Paymaster and Bundler](https://portal.thirdweb.com/connect/account-abstraction/infrastructure) | [Quickstart](https://portal.thirdweb.com/typescript/v5/account-abstraction/get-started) | | [ZeroDev](https://zerodev.app/) | ✅ | [Docs](https://docs.zerodev.app/) | [Meta AA infrastructure](https://docs.zerodev.app/meta-infra/intro)
for bundlers and paymasters | [Dashboard](https://dashboard.zerodev.app/) | _✅ = supported, ⌛️ = in progress, ❓ = unknown, ❌ = won’t support_ | Provider | Status | Docs | Supported services | How to get started | | --- | --- | --- | --- | --- | | [Alchemy](https://www.alchemy.com/smart-wallets) | ✅ | [Docs](https://accountkit.alchemy.com/) | [Gas Manager](https://docs.alchemy.com/docs/gas-manager-services)
(aka Paymaster)
[Bundler](https://docs.alchemy.com/docs/bundler-services) | [Dashboard](https://dashboard.alchemy.com/accounts?a=smart-wallets&utm_source=chain_partner&utm_medium=referral&utm_campaign=monad) | | [Biconomy](https://biconomy.io/) | ✅ | [Docs](https://docs.biconomy.io/) | [Orchestration Infrastructure](https://docs.biconomy.io/new/learn-about-biconomy/what-is-mee) | [Getting started](https://docs.biconomy.io/supertransaction-api/getting-started) | | [FastLane](https://www.fastlane.xyz/) | ✅ | [Docs](https://docs.shmonad.xyz/) | [Paymaster and Bundler](https://github.com/FastLane-Labs/4337-bundler-paymaster-script/tree/main) | [Dashboard](https://shmonad.xyz/) | | [Gelato](https://docs.gelato.cloud/paymaster-&-bundler/introduction/overview) | ✅ | [Docs](https://docs.gelato.cloud/paymaster-&-bundler/introduction/overview) | [Paymaster and Bundler](https://docs.gelato.cloud/paymaster-&-bundler/introduction/overview) | [Quickstart](https://docs.gelato.cloud/paymaster-&-bundler/how-to-guides/overview) | | [Openfort](https://openfort.io/) | ✅ | [Docs](https://www.openfort.io/docs) | [Paymaster and Bundler](https://www.openfort.io/docs/overview) | [Quickstart](https://www.openfort.io/docs/overview/start) | | [Pimlico](https://pimlico.io/) | ✅ | [Docs](https://docs.pimlico.io/) | [Paymaster](https://docs.pimlico.io/infra/paymaster)

[Bundler](https://docs.pimlico.io/infra/bundler) | [Tutorial](https://docs.pimlico.io/permissionless/tutorial/tutorial-1) | | [Sequence](https://sequence.xyz/) | ✅ | [Docs](https://docs.sequence.xyz/solutions/infrastructure/transaction-api) | Relayer: gasless, batched, parallelized transactions | [Quickstart](https://docs.sequence.xyz/solutions/builder/gas-sponsorship) | | [thirdweb](https://thirdweb.com/) | ✅ | [Docs](https://portal.thirdweb.com/) | [Paymaster and Bundler](https://portal.thirdweb.com/connect/account-abstraction/infrastructure) | [Quickstart](https://portal.thirdweb.com/typescript/v5/account-abstraction/get-started) | | [ZeroDev](https://zerodev.app/) | ✅ | [Docs](https://docs.zerodev.app/) | [Meta AA infrastructure](https://docs.zerodev.app/meta-infra/intro)
for bundlers and paymasters | [Dashboard](https://dashboard.zerodev.app/) | _✅ = supported, ⌛️ = in progress, ❓ = unknown, ❌ = won’t support_ [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/account-abstraction#provider-details) Provider Details ------------------------------------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/account-abstraction#alchemy) Alchemy Alchemy powers the [#1 most used](https://www.bundlebear.com/erc4337-overview/all) smart accounts today with account abstraction that eliminates gas fees and signing for users. Their accounts support ERC-4337, EIP-7702, and ERC-6900, a modular account standard co-authored with the Ethereum Foundation, Circle, and Trust Wallet. To get started, sign up for an [Alchemy account](https://dashboard.alchemy.com/accounts?utm_source=chain_partner&utm_medium=referral&utm_campaign=monad) , visit the [documentation](https://accountkit.alchemy.com/) , follow the [quickstart](https://accountkit.alchemy.com/react/quickstart) guide. To learn more, check out their [smart wallets](https://www.alchemy.com/smart-wallets) and demo [here](https://demo.alchemy.com/) . ### [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/account-abstraction#biconomy) Biconomy [Biconomy](https://biconomy.io/) is the most comprehensive smart account and execution infrastructure platform that enables seamless, user-friendly experiences across single or multiple chains. With Biconomy, developers can build superior onchain UX through gas abstraction, sessions, batching, and one-click signatures for complex actions on any number of networks. To get started, visit the [documentation](https://docs.biconomy.io/) . ### [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/account-abstraction#fastlane) FastLane [FastLane](https://www.fastlane.xyz/) is an MEV protocol for validators + apps with an integrated 4337 bundler, an on-chain task scheduler, and the first holistic LST. To get started, vist the [shMonad](https://docs.shmonad.xyz/) Documentation or try the shMonad bundler using the following example [project](https://github.com/FastLane-Labs/4337-bundler-paymaster-script/tree/main) . ### [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/account-abstraction#gelato) Gelato [Gelato](https://docs.gelato.cloud/paymaster-&-bundler/introduction/overview) provides Paymaster and Bundler services that enable sponsored transactions and Account Abstraction, allowing you to cover gas costs on behalf of users and enable seamless onchain experiences. To get started, visit the [documentation](https://docs.gelato.cloud/paymaster-&-bundler/introduction/overview) or follow the [quickstart](https://docs.gelato.cloud/paymaster-&-bundler/how-to-guides/overview) guide. ### [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/account-abstraction#openfort) Openfort [Openfort](https://openfort.io/) is a developer platform that helps projects onboard and and activates wallets. It does so by creating wallets with it’s SSS and passkeys,sending transactions via sponsored paymasters and session keys or directly using backend wallets for automated onchain actions. To get started, visit the [documentation](https://www.openfort.io/docs/overview/start) or follow the [quickstart](https://www.openfort.io/docs/guides/react) guide. ### [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/account-abstraction#pimlico) Pimlico [Pimlico](https://pimlico.io/) is the world’s most advanced ERC-4337 account abstraction infrastructure platform. Pimlico provides a suite of tools and services to help you build, deploy, and manage smart accounts on Ethereum and other EVM-compatible chains. To get started, visit the [documentation](https://docs.pimlico.io/) or follow the [quickstart](https://docs.pimlico.io/permissionless/tutorial/tutorial-1) guide. ### [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/account-abstraction#sequence) Sequence The [Sequence](https://sequence.xyz/) [Transaction API](https://docs.sequence.xyz/solutions/infrastructure/transaction-api) is a unified relayer that dispatches transactions on EVM chains with: * Gas sponsorship * Fee abstraction * Batching * Parallel processing It manages nonces, estimates optimal gas, and resubmits transactions when needed, so you can focus on your business logic. [Sequence Builder](https://sequence.build/) offers a Gas Sponsorship feature that allows project owners to easily sponsor gas for their users in web3 apps. By covering transaction fees, users can enjoy a seamless experience without worrying about obtaining crypto for fees which is seamlessly integrated with our suite of smart contract wallets. To get started, visit the gas sponsorship [docs](https://docs.sequence.xyz/solutions/builder/gas-sponsorship) . ### [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/account-abstraction#thirdweb) thirdweb [thirdweb](https://portal.thirdweb.com/connect/account-abstraction/overview) offers a complete platform to leverage account abstraction. Remove the clunky user experience of requiring gas & signatures for every onchain action: * Abstract away gas * Pre-audited account factory contracts * Built-in infra: * Sponsorship policies To get started: 1. Sign up for a [free thirdweb account](https://thirdweb.com/team) 2. Visit [Account Abstraction Documentation](https://portal.thirdweb.com/connect/account-abstraction/how-it-works) and [Account Abstraction Playground](https://playground.thirdweb.com/connect/account-abstraction/connect) ### [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/account-abstraction#zerodev) Zerodev [ZeroDev](https://zerodev.app/) is the most powerful smart account development platform. With ZeroDev, you can build Web3 experiences without gas, confirmations, seed phrases, and bridging. To get started, visit the [documentation](https://docs.zerodev.app/) or follow the [quickstart](https://docs.zerodev.app/sdk/getting-started/quickstart) guide. [Embedded Wallets\ \ Previous](https://docs.monad.xyz/tooling-and-infra/wallet-infra/embedded-wallets) [Smart Account Implementations\ \ Next](https://docs.monad.xyz/tooling-and-infra/wallet-infra/smart-accounts) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Onramps - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/tooling-and-infra/onramps#content-area) Onramps are services that allow users to convert fiat currency into cryptocurrency. They serve as an entrypoint for users who want to participate in the Monad ecosystem. **See also:** [Payment Orchestrators](https://docs.monad.xyz/tooling-and-infra/payment-orchestrators) . [​](https://docs.monad.xyz/tooling-and-infra/onramps#provider-summary) Provider Summary ------------------------------------------------------------------------------------------ | Provider | Status | Docs | Support notes | Regions supported | Currencies & Countries Supported | | --- | --- | --- | --- | --- | --- | | [AhoraCrypto](https://ahoracrypto.com/) | ✅ | [Docs](https://ahoracrypto.gitbook.io/ahoracrypto) | [Onramp API](https://ahoracrypto.gitbook.io/ahoracrypto/api/payment-intent)

Offramp docs coming soon
[Widget](https://ahoracrypto.gitbook.io/ahoracrypto/widget/web-widget) | Africa, APAC, Europe, LATAM, Middle East, North America, South Asia | 14+ local payment methods, 50+ cryptocurrencies, 50+ countries | | [Alchemy Pay](https://alchemypay.org/) | ✅ | [Docs](https://alchemypay.readme.io/) | [Onramp](https://alchemypay.readme.io/docs/alchemypay-on-ramp)

[NFT Checkout](https://alchemypay.readme.io/docs/alchemy-pay-nft-checkout)

[Crypto Payment](https://alchemypay.readme.io/docs/alchemy-pay-crypto-payment) | APAC, Africa, LATAM | [Payment Methods](https://alchemypay.notion.site/Payment-Methods-Coverages-Other-Details-Table-fb3b4f5c68c04b9b8619c48aad31277d) | | [alfred](https://www.alfredpay.io/) | ⌛️ | [Docs](https://alfredpay.readme.io/docs/overview) | [API Endpoints](https://alfredpay.readme.io/reference/customers-1) | LATAM, US, EU, APAC | [Supported Currencies](https://alfredpay.readme.io/docs/payment-methods-supported) | | [Banxa](https://banxa.com/) | ✅ | [Docs](https://docs.banxa.com/) | [Onramp API](https://docs.banxa.com/docs/tutorial)

[Offramp API](https://docs.banxa.com/docs/off-ramp) | US, Canada, UK, EU, Australia | [Supported Currencies](https://support.banxa.com/en/support/solutions/articles/44002280809-which-fiat-currencies-does-banxa-support-)

[Supported Countries](https://support.banxa.com/en/support/solutions/articles/44002216505-what-countries-are-supported-by-banxa-) | | [Blink](https://blink.cash/) | ✅ | [Docs](https://docs.blink.cash/introduction) | [Quickstart](https://docs.blink.cash/quickstart)

[Web SDK + Mobile SDK](https://docs.blink.cash/integration/supported-networks-and-wallets) | Worldwide | One tap deposits for 136+ tokens across 45+ chains
[Supported Networks](https://docs.blink.cash/integration/supported-networks-and-wallets) | | [Brale](https://brale.xyz/) | ✅ | [Docs](https://docs.brale.xyz/) | [Onramp](https://docs.brale.xyz/guides/fiat-to-stablecoin-onramp)

[Offramp](https://docs.brale.xyz/guides/stablecoin-to-fiat-offramp) | | [Supported Currencies](https://docs.brale.xyz/coverage/value-types) | | [Bridge](https://www.bridge.xyz/) | ✅ | [Docs](https://apidocs.bridge.xyz/) | [Onramp](https://apidocs.bridge.xyz/get-started/guides/wallets/onramp)

[Offramp](https://apidocs.bridge.xyz/get-started/guides/wallets/offramp)

[Orchestration API](https://apidocs.bridge.xyz/platform/orchestration/overview) | US, EU, UK, LATAM, Global | USD (ACH & wire), EUR (SEPA), GBP, MXN (SPEI) & more via [virtual accounts](https://apidocs.bridge.xyz/get-started/guides/move-money/virtualaccounts) | | [BTC Direct](https://onramp.btcdirect.eu/) | ✅ | [Docs](https://developer.btcdirect.eu/) | [Onramp](https://developer.btcdirect.eu/api/v1/#/Buy)

[Offramp](https://developer.btcdirect.eu/api/v1/#/Sell)

[Widget](https://developer.btcdirect.eu/widget/getting-started) | SEPA / Europe | EUR
[Supported Cryptocurrencies](https://developer.btcdirect.eu/widget/supported-cryptocurrencies.html) | | [Capa](https://capa.fi/) | ✅ | [Docs](https://docs.capa.fi/docs/getting-started) | [Onramp API](https://docs.capa.fi/docs/on-ramp)

[Offramp API](https://docs.capa.fi/docs/off-ramp) | LATAM | [Supported Currencies](https://docs.capa.fi/docs/on-ramp#select-the-fiat-currency%3A) | | [Chainrails](https://chainrails.io/) | ✅ | [Docs](https://docs.chainrails.io/) | [API Endpoints](https://docs.chainrails.io/api-reference/introduction) | Africa, APAC, LATAM, EU, US, Australia | [Supported Currencies](https://docs.chainrails.io/essentials/integrations) | | [Coinbase Onramp & Offramp](https://docs.cdp.coinbase.com/onramp/introduction/welcome) | ✅ | [Docs](https://docs.cdp.coinbase.com/onramp/introduction/welcome) | [Onramp API](https://docs.cdp.coinbase.com/onramp-&-offramp/onramp-apis/onramp-overview)

[Offramp API](https://docs.cdp.coinbase.com/onramp-&-offramp/offramp-apis/offramp-overview) | US, Canada, Brazil, EU, Singapore, Australia, New Zealand | ACH, debit cards, Apple Pay, and cash/crypto balances are supported in the US. Debit cards and cash/crypto balances are supported everywhere else. | | [Coindisco](https://coindisco.com/) | ✅ | [Docs](https://coindisco.gitbook.io/coindisco) | [Buy\|Sell Widget](https://coindisco.gitbook.io/coindisco/widget-integration/widget-integration-methods)

[White Label API](https://coindisco.gitbook.io/coindisco/widget-integration/white-label-api-integration) | 240+ countries and territories | [Supported Payment Methods](https://coindisco.gitbook.io/coindisco/platform-support/supported-payment-methods)

[Supported Fiat Currencies](https://coindisco.gitbook.io/coindisco/supported-fiat-currencies)

[Supported Countries](https://coindisco.gitbook.io/coindisco/supported-countries) | | [Coinflow](https://coinflow.cash/) | ✅ | [Docs](https://docs.coinflow.cash/) | [API Endpoints](https://docs.coinflow.cash/guides/getting-started/getting-started-with-checkout) | APAC, LATAM, US, EU | [Supported Countries - Withdraw](https://docs.coinflow.cash/guides/payouts/available-countries)

[Supported Countries - Global Push Card](https://docs.coinflow.cash/guides/payouts/available-countries/supported-countries-for-global-push-to-card) | | [Daimo](https://daimo.com/) | ✅ | [Docs](https://docs.daimo.com/introduction) | [Quickstart](https://docs.daimo.com/quickstart) | Canada, US | [Payment Methods](https://docs.daimo.com/guides/fiat#supported-rails) | | [El Dorado](https://eldorado.io/) | ✅ | [Docs](https://api.eldorado.io/) | [API Overview](https://api.eldorado.io/#api-overview) | LATAM | [Supported Countries](https://api.eldorado.io/concepts/countries)

[Supported Currencies](https://api.eldorado.io/concepts/currencies) | | [FinchPay](https://finchpay.io/) | ✅ | [Docs](https://docs.finchpay.io/) | [Widget URL](https://docs.finchpay.io/docs/url-structure)

[API](https://docs.finchpay.io/docs/partners-api) | EU, 150+ countries | Local payment methods: Brazil (PicPay, PIX), Mexico (SPEI and OXXO), Indonesia (virtual accounts BRI & Mandiri, e-wallets DANA/OVO) | | [Flashnet](https://flashnet.xyz/) | ✅ | [Docs](https://docs.flashnet.xyz/products/orchestration/overview) | | US Only, no NY | [Supported Chains & Assets](https://docs.flashnet.xyz/products/orchestration/overview#which-chains-and-assets-are-supported) | | [Fonbnk](https://www.fonbnk.com/) | ⌛️ | [Docs](https://docs.fonbnk.com/) | [Onramp](https://docs.fonbnk.com/on-ramp)

[Offramp](https://docs.fonbnk.com/off-ramp) | Africa, LATAM | [Supported Countries & Payment Methods](https://www.fonbnk.com/) | | [Fun.xyz](https://fun.xyz/) | ✅ | [Contact](https://fun.xyz/contact) | | ✅ | | | [Guardarian](https://guardarian.com/) | ✅ | [Docs](https://guardarian.com/api-doc) | [API](https://guardarian.com/api-doc) | LATAM, EU, Africa, APAC | [Supported Countries & Payment Methods](https://guardarian.com/payment-methods)

[Supported Countries Fees](https://guardarian.notion.site/guardarian-supported-countries-fees)

[Supported Currencies](https://guardarian.com/currencies) | | [Halliday](https://halliday.xyz/) | ✅ | [Docs](https://docs.halliday.xyz/pages/home) | [API Quickstart](https://docs.halliday.xyz/pages/api-quickstart)

[Payments SDK](https://docs.halliday.xyz/pages/payments-sdk-docs) | US, EU, LATAM, APAC | Credit or debit card, ACH, Apple Pay, Google Pay, or a CEX balance | | [HoneyCoin](https://honeycoin.app/) | ✅ | [Docs](https://docs.honeycoin.app/reference/welcome) | [Onramp](https://docs.honeycoin.app/reference/onramp)

[Offramp](https://docs.honeycoin.app/reference/crypto-off-ramp) | Africa | [Supported Countries & Limits](https://docs.honeycoin.app/docs/supported-countries-limits) | | [Koywe](https://koywe.com/) | ✅ | [Docs](https://docs.koywe.com/crypto/introduction/%F0%9F%91%8B-welcome-to-koywe-%F0%9F%8C%B3) | [Widget Ramp Demo](https://widget.koywe.com/) | LATAM | [Supported Currencies](https://docs.koywe.com/documentation/supported-currencies-payment-methods#supported-currencies-by-country)

[Supported Countries](https://docs.koywe.com/documentation/supported-currencies-payment-methods#supported-payment-methods-by-country) | | [Meld](https://www.meld.io/) | ✅ | [Docs](https://docs.meld.io/docs/getting-started)
(pw protected) | | 225+ Countries | | | [Mercuryo](https://mercuryo.io/) | ✅ | [Docs](https://oor-redirect.redoc.ly/) | [Onramp API Endpoints](https://oor-redirect.redoc.ly/#section/On-Ramp.-Crypto-Purchase)

[Offramp API Endpoints](https://oor-redirect.redoc.ly/#section/Off-Ramp.-Crypto-Sell.) | US, EU | [Supported Currencies](https://help.mercuryo.io/hc/en-gb/articles/14495507502749-Which-fiat-currencies-are-supported)

[Supported Countries](https://help.mercuryo.io/hc/en-gb/articles/15265851177245-Where-does-Mercuryo-operate) | | [MoonPay](https://www.moonpay.com/) | ✅ | [Docs](https://dev.moonpay.com/) | [Onramp](https://dev.moonpay.com/docs/on-ramp-overview)

[Offramp](https://dev.moonpay.com/docs/off-ramp-overview) | US, EU, Canada, LATAM, APAC, Africa | [Supported Currencies](https://support.moonpay.com/en/articles/362475-moonpay-s-supported-currencies)

[Supported Payment Methods](https://support.moonpay.com/en/articles/380823-moonpay-s-supported-payment-methods)

[Unsupported Countries](https://support.moonpay.com/en/articles/380968-moonpay-s-unsupported-countries) | | [Onramp Money](https://onramp.money/) | ✅ | [Docs](https://docs.onramp.money/onramp/) | | APAC, Africa, EU, US, LATAM | | | [Onramper](https://www.onramper.com/) | ✅ | [Docs](https://docs.onramper.com/docs/getting-started) | [API Endpoints](https://docs.onramper.com/reference/get_supported) | 190+ Countries | [Payment Methods](https://docs.onramper.com/docs/supported-payment-methods) | | [OSL Pay](https://www.osl-pay.com/) | ✅ | [Docs](https://www.osl-pay.com/api-doc/startHere/quickStart) | [Onramp](https://www.osl-pay.com/api-doc/product/onRamp) | 134+ Countries | [Supported Currencies & Countries](https://docs.pay.osl.com/docs/overview) | | [Paj](https://paj.cash/) | ✅ | [Docs](https://github.com/paj-cash/paj_ramp/tree/main/examples) | [Support notes](https://github.com/paj-cash/paj_ramp) | Africa | [Supported Currencies & Countries](https://github.com/paj-cash/paj_ramp) | | [Peer](https://peer.xyz/) | ✅ | [Docs](https://docs.peer.xyz/) | [Onramp](https://docs.peer.xyz/developer/integrate-zkp2p/integrate-redirect-onramp)

[Offramp](https://docs.peer.xyz/developer/developer/offramp) | US, EU, Africa, LATAM, APAC | Venmo, Cash App, Wise, Revolut, PayPal, Mercado Pago, etc. | | [Ramp Network](https://rampnetwork.com/) | ✅ | [Docs](https://docs.rampnetwork.com/) | [Getting Started](https://docs.rampnetwork.com/getting-started) | US, EU, LATAM, APAC & 150+ countries | [Supported Currencies & Countries](https://support.rampnetwork.com/en/articles/433-which-countries-and-us-states-are-unsupported-for-buying-and-selling-crypto) | | [Rampnow](https://app.rampnow.io/) | ✅ | [Docs](https://docs.rampnow.io/) | | US, EU, EEA, LATAM, ASIA, South Africa, Nigeria | [Payment Methods](https://docs.rampnow.io/quickstart/onramp/payment-methods) | | [Suby](https://suby.fi/) | ✅ | [Docs](https://documentation.suby.fi/) | [Crypto Payment Link](https://documentation.suby.fi/docs/payment/stablecoins) | Global | [Supported Countries](https://documentation.suby.fi/docs/merchants/supported-countries) | | [Swapped](https://swapped.com/) | ✅ | [Docs](https://docs.swapped.com/) | [Onramp Endpoints](https://docs.swapped.com/swapped-ramp/endpoints/onramp-endpoints)

[Offramp Endpoints](https://docs.swapped.com/swapped-ramp/endpoints/offramp-endpoints) | 150+ countries | [Supported Payment Methods](https://swapped.com/payment-methods)

[Supported Countries](https://swapped.com/supported-countries) | | [Swapper Finance](https://swapper.finance/) | ✅ | [Docs](https://docs.swapper.finance/) | [Onramp Widget SDK](https://docs.swapper.finance/quick-start) | Global | ACH, credit cards, Apple Pay, Google Pay, UnionPay, and other major payment methods | | [Switch](https://onswitch.xyz/) | ✅ | [Docs](https://docs.onswitch.xyz/introduction) | [API Reference](https://docs.onswitch.xyz/api-reference/introduction) | Europe, UK, Africa, APAC, India, China | USDC and USDT0 on Monad, settled in local currency (EUR, GBP, NGN, KES, GHS, INR, CNY, etc.) via bank transfer, mobile money, and SWIFT | | [Transak](https://transak.com/) | ✅ | [Docs](https://docs.transak.com/) | [API endpoints](https://docs.transak.com/reference/end-points) | US, UK, EU, Australia, Canada, APAC | [Supported Countries](https://transak.com/global-coverage) | | [Unlimit](https://www.unlimit.com/) | ⌛️ | [Docs](https://integration.unlimit.com/doc-guides/mylvyrw7nxiom-homepage) | [API Endpoints](https://integration.unlimit.com/api-reference/6nk7rnnwnafo0-environments) | LATAM, Africa, India, EU, UK, APAC | [Payment Methods](https://integration.unlimit.com/doc-guides/ci8k5zm86k3ny-card-methods)

[Payout Methods](https://integration.unlimit.com/doc-guides/m2mtijltdzphg-card-methods) | | [UR](https://ur.app/) | ✅ | [Docs](https://docs.ur.app/) | | APAC, EU | [Supported Countries](https://support.ur.app/hc/en-us/articles/12862724456207-Countries-and-Territories-Supported-By-UR) | | [Walapay](https://www.walapay.io/) | ⌛️ | [Docs](https://docs.walapay.io/docs/introduction) | | Africa, APAC, EU, US, Canada, LATAM | [Supported Countries & Currencies](https://docs.walapay.io/docs/countries-and-rails)

[Prohibited Countries](https://docs.walapay.io/docs/onboarding-regions) | | [zerohash](https://zerohash.com/) | ✅ | [Docs](https://docs.zerohash.com/) | [On and Off Ramps](https://docs.zerohash.com/docs/convert-withdraw-1) | US, Canada, EU, Africa, Australia, APAC | [Supported Countries](https://docs.zerohash.com/docs/supported-regions) | [​](https://docs.monad.xyz/tooling-and-infra/onramps#provider-details) Provider details ------------------------------------------------------------------------------------------ ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#ahoracrypto) AhoraCrypto [AhoraCrypto](https://ahoracrypto.com/) is the crypto infrastructure built around the best-in-market UX: fast compliant KYC, responsive checkout, and 14+ local payment methods to maximize conversion. Revenue share is settled instantly to your wallet on every transaction, with no minimums, waiting periods, or fees. Supporting 14 blockchains, 50+ cryptocurrencies, and 50+ countries, go live in hours via white-label widget or REST API. To get started, visit the [documentation](https://ahoracrypto.gitbook.io/ahoracrypto) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#alchemy-pay) Alchemy Pay [Alchemy Pay](https://alchemypay.org/) is a payment gateway that seamlessly connects crypto with traditional fiat currencies for businesses, developers, and end users. With its offerings including On & Off Ramp, Crypto Card, Web3 Digital Bank, NFT Checkout, and Crypto Payments, Alchemy Pay supports payments in 173 countries. To get started, visit the [documentation](https://alchemypay.readme.io/docs/alchemypay-on-ramp) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#alfred) alfred With [alfred](https://www.alfredpay.io/) , settle international payments in real time. Move money over stablecoin rails and give your business global coverage without the use of intermediary banks resulting in faster transfers at lower costs compared to traditional banking. To get started, visit the [documentation](https://alfredpay.readme.io/docs/overview) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#banxa) Banxa [Banxa](https://banxa.com/) powers one of the largest digital asset platforms by providing payments infrastructure and regulatory compliance across global markets. Banxa’s mission and vision is to build the bridge that provides people in every part of the world access to a fairer and more equitable financial system. To get started, visit the [documentation](https://docs.banxa.com/) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#blink) Blink [Blink](https://blink.cash/) is a deposit SDK for crypto apps, letting users fund your app easily with FaceID. Blink handles auth, wallet connections, and cross-chain bridging, supporting 136+ tokens across 45+ chains with native USDC and MON routes on Monad. To get started, visit the [documentation](https://docs.blink.cash/introduction) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#brale) Brale [Brale](https://brale.xyz/) is a stablecoin infrastructure platform that enables developers to onramp fiat to stablecoins, offramp stablecoins back to fiat, swap between [stablecoins](https://docs.brale.xyz/coverage/value-types) and [networks](https://docs.brale.xyz/coverage/transfer-types) , and issue branded stablecoins, all through a single unified API. Brale handles regulatory compliance, reserves, and multi-chain orchestration so builders can focus on their product. Brale also provides payment orchestration — see [Payment Orchestrators](https://docs.monad.xyz/tooling-and-infra/payment-orchestrators) . To get started, visit the [Brale documentation](https://docs.brale.xyz/) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#bridge) Bridge [Bridge](https://www.bridge.xyz/) (a Stripe company) is a stablecoin payments platform whose orchestration APIs let developers build onramps, offramps, and crypto-to-crypto transfers, alongside virtual accounts, stablecoin issuance, wallets, and card products. Bridge also provides payment orchestration — see [Payment Orchestrators](https://docs.monad.xyz/tooling-and-infra/payment-orchestrators) . To get started, visit the [documentation](https://apidocs.bridge.xyz/) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#btc-direct) BTC Direct [BTC Direct](https://onramp.btcdirect.eu/) provides a suite of tools to integrate cryptocurrency services into your platform. Their API supports [buying (onramp)](https://developer.btcdirect.eu/api/v1/#/Buy) and [selling (offramp)](https://developer.btcdirect.eu/api/v1/#/Sell) digital assets, with support for EUR via SEPA across Europe. To get started, visit the [documentation](https://developer.btcdirect.eu/) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#capa) Capa [Capa](https://capa.fi/) is your one-stop solution to send and receive payments between Latin America and the world through their all-in-one API, making cross-border transactions fast, simple, and cost-effective. To get started, visit the [documentation](https://docs.capa.fi/docs/getting-started) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#chainrails) Chainrails [Chainrails](https://chainrails.io/) enables you to accept crypto payments/deposits from any chain, in any token or currency, instantly. To get started, visit the [documentation](https://docs.chainrails.io/) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#coinbase-onramp-&-offramp) Coinbase Onramp & Offramp [Coinbase Onramp & Offramp](https://docs.cdp.coinbase.com/onramp/introduction/welcome) by [Coinbase Developer Platform (CDP)](https://www.coinbase.com/developer-platform) empowers enterprises and developers with seamless onchain solutions. The Onramp & Offramp APIs and SDKs enable developers to move money seamlessly between fiat and onchain economies. To get started, visit the [documentation](https://docs.cdp.coinbase.com/onramp/introduction/welcome) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#coindisco) Coindisco [Coindisco](https://coindisco.com/) is an onramp aggregator that provides access to crypto purchases across 240+ countries and territories through a unified widget and white label API integration. To get started, visit the [documentation](https://coindisco.gitbook.io/coindisco) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#coinflow) Coinflow [Coinflow](https://coinflow.cash/) enables businesses to grow faster with instant settlement, fraud & chargeback indemnity, global pay-in, multi-currency FX, and unified payouts---all in one intuitive platform. To get started, visit the [documentation](https://docs.coinflow.cash/) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#daimo) Daimo [Daimo](https://daimo.com/) is the ramp for stablecoin apps. Integrate once, accept deposits from any wallet, any chain, any token. Funds arrive as the stablecoin you want, on the chain you want. To get started, visit the [documentation](https://docs.daimo.com/introduction) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#el-dorado) El Dorado [El Dorado](https://eldorado.io/) is an on/off ramp solution for Latin America, enabling seamless conversion between fiat currencies and cryptocurrency in the LATAM region. To get started, visit the [documentation](https://api.eldorado.io/) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#finchpay) FinchPay [FinchPay](https://finchpay.io/) is an EU-regulated global fiat on-ramp and payment infrastructure for Web3, that lets users buy crypto with cards or local payment methods in 150+ countries. To get started, visit the [documentation](https://docs.finchpay.io/) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#flashnet) Flashnet [Flashnet](https://flashnet.xyz/) builds Bitcoin exchange infrastructure. Its Orchestra product enables Bitcoin orchestration, moving Bitcoin to/from any asset/chain. Orchestra also powers a novel CashApp onramp, which can pull fiat and push stables on the other side. It’s instant, low-cost, and the best onramp UX for US persons. To get started, visit the [documentation](https://docs.flashnet.xyz/products/orchestration/overview) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#fonbnk) Fonbnk [Fonbnk](https://www.fonbnk.com/) bridges mobile-first, cash-based economies to Web3 by converting prepaid payments into stablecoins, enabling frictionless FX, cross-border treasury flows, and instant liquidity. To get started, visit the [documentation](https://docs.fonbnk.com/) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#fun-xyz) Fun.xyz [Fun.xyz](https://fun.xyz/) ’s platform provides API-driven deposit and withdraw flows for secure, cross-chain, programmable experiences. To get started, [contact](https://fun.xyz/contact) Fun.xyz. ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#guardarian) Guardarian [Guardarian](https://guardarian.com/) is a fully licensed, non-custodial crypto payment infrastructure provider that enables both individuals and businesses to seamlessly buy, sell, and swap 1000+ cryptocurrencies using popular payment methods like Visa, Mastercard, Apple Pay, and Google Pay, offering fast low-KYC processing and support for 50+ fiat currencies across 150+ countries. To get started, visit the [documentation](https://guardarian.com/api-doc) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#halliday) Halliday With [Halliday](https://halliday.xyz/) Payments, users can acquire any token on any chain with minimal effort. Seamlessly onramp from fiat, cross arbitrary bridges, and swap assets from an existing wallet (e.g., MetaMask), into whatever form. Connect with an exchange account (e.g., Coinbase, Binance) to transfer digital assets onto any chain. To get started, visit the [documentation](https://docs.halliday.xyz/pages/home) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#honeycoin) HoneyCoin [HoneyCoin](https://honeycoin.app/) is a crypto onramp and offramp service focused on Africa, enabling seamless conversion between fiat currencies and cryptocurrency across the African continent. To get started, visit the [documentation](https://docs.honeycoin.app/reference/welcome) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#koywe) Koywe [Koywe](https://koywe.com/) is services and interface that make it easier and simpler to buy and sell crypto in Latin America for the fairest price while using local currency and payment methods. To get started, visit the [documentation](https://docs.koywe.com/crypto/introduction/%F0%9F%91%8B-welcome-to-koywe-%F0%9F%8C%B3) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#meld) Meld [Meld](https://www.meld.io/) is an infrastructure to move money across Web2 and Web3 rails. fiat <> fiat | fiat <> crypto To get started, [contact](https://www.meld.io/contact) Meld. ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#mercuryo) Mercuryo [Mercuryo](https://mercuryo.io/) enables efficient capital flow within the DeFi ecosystem and consolidates various payment and banking solutions into a single, user-centric interface. To get started, visit the [documentation](https://oor-redirect.redoc.ly/) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#moonpay) MoonPay [MoonPay](https://www.moonpay.com/) simplifies access to buy, sell and trade crypto using everyday payment methods like cards, Apple Pay, PayPal and Venmo, while also providing simple tools to send, receive and manage stablecoins. To get started, visit the [documentation](https://dev.moonpay.com/) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#onramp-money) Onramp Money [Onramp Money](https://onramp.money/) is a comprehensive fiat-to-crypto infrastructure that empowers businesses and their users to buy and sell crypto using local fiat, swap crypto-to-crypto, spend crypto on gift cards instantly, and more. To get started, visit the [documentation](https://docs.onramp.money/onramp/) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#onramper) Onramper [Onramper](https://www.onramper.com/) is a fiat onramp aggregator. All fiat onramps in a single integration, unlocking the lowest fees and highest transaction success rates on the market. To get started, visit the [documentation](https://docs.onramper.com/docs/getting-started) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#osl-pay) OSL Pay [OSL Pay](https://www.osl-pay.com/) is the payment infrastructure arm of OSL Group, providing licensed and compliant solutions for seamless conversion between digital assets and fiat currencies. To get started, visit the [documentation](https://www.osl-pay.com/api-doc/startHere/quickStart) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#paj) Paj [Paj](https://paj.cash/) abstracts global payments into wallet addresses by representing user bank accounts on-chain. Deterministic wallet addresses derived from users’ bank accounts enable users to receive any crypto token converted directly into fiat automatically in their local bank account. This means that any bank account can receive on-chain money and anyone can send crypto to a bank account. To get started, visit the [documentation](https://github.com/paj-cash/paj_ramp/tree/main/examples) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#peer) Peer [Peer](https://peer.xyz/) (formerly ZKP2P) is the first trustless P2P on/offramping bulletin board powered by zero-knowledge proofs. This enables a fast, cheap, and DeFi-composable buying and selling crypto experience. Peer supports multiple payment methods including Venmo, Cash App, Wise, Revolut, PayPal, and Mercado Pago across 20+ chains. To get started, visit the [documentation](https://docs.peer.xyz/) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#ramp-network) Ramp Network [Ramp Network](https://rampnetwork.com/) is a non-custodial fiat<>crypto infrastructure that makes it easy for users to jump on and off of Web3 from anywhere. To get started, visit the [documentation](https://docs.rampnetwork.com/) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#rampnow) Rampnow [Rampnow](https://app.rampnow.io/) is a global blockchain on-ramp and off-ramp infrastructure provider connecting fiat and blockchain liquidity for businesses, developers, and end users. It supports 125+ blockchains, 20,000+ tokens, and major payment methods across multiple regions through a single API and widget. To get started, visit the [documentation](https://docs.rampnow.io/) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#suby) Suby [Suby](https://suby.fi/) enables merchants to accept stablecoin payments through crypto checkout payment links, with global coverage. To get started, visit the [documentation](https://documentation.suby.fi/) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#swapped) Swapped [Swapped](https://swapped.com/) offers On-Ramp, Connect, and Commerce solutions, enabling customers to move funds onchain, receive crypto payments, and build full financial platforms, games, and consumer experiences. To get started, visit the [documentation](https://docs.swapped.com/) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#swapper-finance) Swapper Finance [Swapper Finance](https://swapper.finance/) is the fiat-to-DeFi infrastructure for one-click onboarding to any protocol. Built to bring 3.5+ billion users to DeFi. To get started, visit the [documentation](https://docs.swapper.finance/) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#switch) Switch [Switch](https://onswitch.xyz/) is a stablecoin settlement layer that lets businesses accept stablecoin deposits and pay out in local currency across multiple markets via bank transfer, mobile money, and SWIFT. Switch supports USDC and USDT0 on Monad and settles in currencies including EUR, GBP, NGN, KES, GHS, INR, and CNY. To get started, visit the [documentation](https://docs.onswitch.xyz/introduction) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#transak) Transak [Transak](https://transak.com/) is a developer integration toolkit that enables you as an app developer to onboard your users to buy/sell crypto in any blockchain app, website or web plugin. With Transak you can onboard mainstream users into your dApp, protocol, game or wallet app and also increase your revenue. To get started, visit the [documentation](https://docs.transak.com/docs/what-is-transak) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#unlimit) Unlimit [Unlimit](https://www.unlimit.com/) ’s mission is to provide innovators with a convenient and simple financial interface that enables payments to flow freely and invisibly across borders. They offer a wide range of services, including payment gateway, card acquiring, business accounts, card issuing, alternative payment methods, and more. To get started, visit the [documentation](https://integration.unlimit.com/doc-guides/mylvyrw7nxiom-homepage) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#ur) UR [UR](https://ur.app/) is a borderless smart money app built on the blockchain. Your go-to unified crypto and fiat account with 0 off-ramp fees and access to multiple currencies. To get started, visit the [documentation](https://docs.ur.app/) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#walapay) Walapay [Walapay](https://www.walapay.io/) is a global money movement platform that is building the future of cross-border payments. To get started, visit the [documentation](https://www.walapay.io/) . ### [​](https://docs.monad.xyz/tooling-and-infra/onramps#zerohash) zerohash [zerohash](https://zerohash.com/) is a B2B2C embedded infrastructure platform that provides APIs and SDKs, enabling businesses to integrate digital asset trading, custody, and fiat-to-crypto on-ramps directly into their applications. zerohash also provides payment orchestration — see [Payment Orchestrators](https://docs.monad.xyz/tooling-and-infra/payment-orchestrators) . To get started, visit the [documentation](https://docs.zerohash.com/) . [Indexing Frameworks\ \ Previous](https://docs.monad.xyz/tooling-and-infra/indexers/indexing-frameworks) [Oracles\ \ Next](https://docs.monad.xyz/tooling-and-infra/oracles) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Add Monad to Wallet - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/guides/add-monad-to-wallet#content-area) Mainnet ------- Add Monad Mainnet Testnet ------- Add Monad Testnet [Guides\ \ Previous](https://docs.monad.xyz/guides) [Add Monad Mainnet to Wallet\ \ Next](https://docs.monad.xyz/guides/add-monad-to-wallet/mainnet) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Staking Overview - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/reference/staking/overview#content-area) Monad uses a [precompile](https://docs.monad.xyz/developer-essentials/precompiles) to manage validator delegation and rewards. This page covers the key concepts and workflows for interacting with the staking precompile. For the full interface reference, visit the [API](https://docs.monad.xyz/reference/staking/api) page. To learn how Monad’s staking system works, visit the [learn](https://docs.monad.xyz/monad-arch/consensus/staking) tab. The staking precompile is at address . [​](https://docs.monad.xyz/reference/staking/overview#key-concepts) Key concepts ----------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/reference/staking/overview#epochs-and-timing) Epochs and timing Staking state changes don’t take effect immediately. Monad divides time into **epochs**, and most actions only activate at the start of a new epoch. Every 50,000 blocks (~5.5 hours) is a **boundary block** that commits upcoming staking changes. After a 5,000-round delay (`EPOCH_DELAY_ROUNDS`), the new epoch starts. ![timeline showing the placement of boundary blocks within an epoch](https://mintcdn.com/monadfoundation-40611fb6/c3ZcPFY7YVeS_v57/static/img/developer-essentials/staking/staking-timeline.png?w=2500&fit=max&auto=format&n=c3ZcPFY7YVeS_v57&q=85&s=09c9c8c0b8c7423c776025bfe31493ee) This means your action activates in either: * **Epoch n+1** — if submitted before the boundary block * **Epoch n+2** — if submitted after the boundary block (in the epoch delay period) Use [`getEpoch()`](https://docs.monad.xyz/reference/staking/api#getepoch) to check the current epoch and whether the boundary has passed: (uint64 epoch, bool inEpochDelayPeriod) = IMonadStaking(STAKING_ADDRESS).getEpoch(); // If inEpochDelayPeriod is false: changes take effect in epoch + 1 // If inEpochDelayPeriod is true: changes take effect in epoch + 2 A round is not a block — rounds increment even on missed proposals. You cannot calculate epoch boundaries with modular arithmetic on block numbers. Always use `getEpoch()`. ### [​](https://docs.monad.xyz/reference/staking/overview#withdrawal-delay) Withdrawal delay Undelegated stake is not immediately available. After calling `undelegate`, you must wait `WITHDRAWAL_DELAY` (1 epoch) before calling `withdraw` to reclaim the funds. [​](https://docs.monad.xyz/reference/staking/overview#common-actions) Common actions --------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/reference/staking/overview#delegate) Delegate To delegate MON to a validator, call `delegate(validatorId)` with the amount as `msg.value`: IMonadStaking(STAKING_ADDRESS).delegate{value: amount}(validatorId); * `msg.value` must be at least `DUST_THRESHOLD` (1 gwei). * Your delegation becomes active in the next epoch (or the one after, if past the boundary block). * If this causes the validator’s total stake to meet `ACTIVE_VALIDATOR_STAKE`, the validator is added to the active set. ### [​](https://docs.monad.xyz/reference/staking/overview#undelegate-and-withdraw) Undelegate and withdraw Removing stake is a two-step process: **Step 1: Undelegate** — Initiate the withdrawal by specifying the amount and a `withdrawId` (0–255): IMonadStaking(STAKING_ADDRESS).undelegate(validatorId, amount, withdrawId); **Step 2: Withdraw** — After `WITHDRAWAL_DELAY` epochs have passed, call `withdraw` to reclaim the funds: IMonadStaking(STAKING_ADDRESS).withdraw(validatorId, withdrawId); ![timeline of undelegation and withdrawal](https://mintcdn.com/monadfoundation-40611fb6/c3ZcPFY7YVeS_v57/static/img/developer-essentials/staking/undelegate-timeline.png?w=2500&fit=max&auto=format&n=c3ZcPFY7YVeS_v57&q=85&s=6ed1e6dbd4e8bfd2ec75475172b7576b) Timeline of withdrawability of stake relative to `undelegate` * You can only undelegate **active** stake (not pending delegations). * Each `(validator, delegator)` pair supports up to 256 concurrent withdrawal requests. * `withdrawId`s can be reused after the withdrawal completes. ### [​](https://docs.monad.xyz/reference/staking/overview#claim-and-compound-rewards) Claim and compound rewards Rewards accumulate automatically as your validator produces blocks. You have two options: * **Claim rewards** — withdraw accumulated rewards to your account: IMonadStaking(STAKING_ADDRESS).claimRewards(validatorId); Claims take effect **immediately** — no epoch delay. * **Compound rewards** — re-delegate accumulated rewards, increasing your stake: IMonadStaking(STAKING_ADDRESS).compound(validatorId); Compounded rewards activate in the next epoch (following the standard timing rules). ### [​](https://docs.monad.xyz/reference/staking/overview#query-staking-state) Query staking state Key view methods for reading staking state: | Method | Purpose | | --- | --- | | [`getValidator(validatorId)`](https://docs.monad.xyz/reference/staking/api#getvalidator) | Full validator state across execution, consensus, and snapshot views | | [`getDelegator(validatorId, address)`](https://docs.monad.xyz/reference/staking/api#getdelegator) | Delegator’s stake, rewards, and pending changes for a specific validator | | [`getWithdrawalRequest(validatorId, address, withdrawId)`](https://docs.monad.xyz/reference/staking/api#getwithdrawalrequest) | Status of a pending withdrawal | | [`getEpoch()`](https://docs.monad.xyz/reference/staking/api#getepoch) | Current epoch and whether boundary has passed | | [`getConsensusValidatorSet(startIndex)`](https://docs.monad.xyz/reference/staking/api#getvalidatorset) | Current epoch’s leader validators (paginated) | | [`getSnapshotValidatorSet(startIndex)`](https://docs.monad.xyz/reference/staking/api#getvalidatorset) | Next epoch’s leader validators (paginated) | | [`getExecutionValidatorSet(startIndex)`](https://docs.monad.xyz/reference/staking/api#getvalidatorset) | All validators meeting active staking criteria (paginated) | | [`getProposerValId()`](https://docs.monad.xyz/reference/staking/api#getproposervalid) | Validator ID of the current block’s proposer | | [`getDelegations(address, startValId)`](https://docs.monad.xyz/reference/staking/api#getdelegations) | All validators a delegator has delegated to (paginated) | | [`getDelegators(validatorId, startDelegator)`](https://docs.monad.xyz/reference/staking/api#getdelegators) | All delegators for a validator (paginated) | Paginated methods return up to 100 results per call. Pass `startIndex = 0` for the first call, then use `nextIndex` for subsequent calls until `isDone` is true. [​](https://docs.monad.xyz/reference/staking/overview#constraints) Constraints --------------------------------------------------------------------------------- Because the staking system is a precompile rather than a smart contract, it has some behavioral differences. * **Only `CALL` is allowed.** `STATICCALL`, `DELEGATECALL`, and `CALLCODE` will revert. This means all view methods use `nonpayable` state mutability rather than `view`. * **No forked environment testing.** The staking system is a precompile, not a smart contract — there is no code at the address, so forked testing environments won’t work. * **Boundary block timing.** Actions submitted during the epoch delay period (after the boundary block) won’t take effect until two epochs later. Check `getEpoch()` if timing matters. * **Dust threshold.** Delegations below `DUST_THRESHOLD` (1 gwei) will revert. * **EIP-7702 caveat.** If an account delegates to the staking precompile address using EIP-7702, all calls to it will revert. [​](https://docs.monad.xyz/reference/staking/overview#further-reading) Further reading ----------------------------------------------------------------------------------------- * [API reference](https://docs.monad.xyz/reference/staking/api) — Full reference for the staking precompile with method signatures, parameters, gas costs, events, structs, and ABI * [How staking works](https://docs.monad.xyz/monad-arch/consensus/staking) — How Monad’s staking system determines validator voting weights, epoch scheduling, and reward distribution [Advanced topics\ \ Previous](https://docs.monad.xyz/execution-events/advanced) [Staking API Reference\ \ Next](https://docs.monad.xyz/reference/staking/api) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Deploy a smart contract on Monad using Remix - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/guides/deploy-smart-contract/remix#content-area) [Remix IDE](https://remix.ethereum.org/) is a browser-based IDE that can be used for the entire journey of smart contract development by users at every knowledge level. It requires no setup, fosters a fast development cycle, and has a rich set of plugins with intuitive GUIs. In this guide you will learn how to deploy and interact with a simple Greeting smart contract on Monad Testnet using [Remix IDE](https://remix.ethereum.org/) . [​](https://docs.monad.xyz/guides/deploy-smart-contract/remix#requirements) Requirements ------------------------------------------------------------------------------------------- * You need to have the Monad Testnet network added to your wallet. [​](https://docs.monad.xyz/guides/deploy-smart-contract/remix#deploying-the-smart-contract) Deploying the smart contract --------------------------------------------------------------------------------------------------------------------------- Head over to [Remix IDE](https://remix.ethereum.org/) in your browser. Click ‘Start Coding’ to create a new project template. ![remix-ide](https://mintcdn.com/monadfoundation-40611fb6/c3ZcPFY7YVeS_v57/static/img/guides/deploy-smart-contract/remix/1.png?w=2500&fit=max&auto=format&n=c3ZcPFY7YVeS_v57&q=85&s=78c85fa07c7b41c34e6f6cd2db6c1f25) Make sure the ‘contracts’ folder is selected, then create a new file using the “Create new file” button on top left corner. ![create-file](https://mintcdn.com/monadfoundation-40611fb6/c3ZcPFY7YVeS_v57/static/img/guides/deploy-smart-contract/remix/2.png?w=2500&fit=max&auto=format&n=c3ZcPFY7YVeS_v57&q=85&s=31901c26cf1cbedb7fe3b111c2fef3df) Name the new file “Gmonad.sol” and add the following code to it src/Gmonad.sol // SPDX-License-Identifier: MIT pragma solidity ^0.8.24; contract Gmonad { string public greeting; constructor(string memory _greeting) { greeting = _greeting; } function setGreeting(string calldata _greeting) external { greeting = _greeting; } } **Note:** You may see a red squiggly line underneath the `pragma solidity...` line; this is because the default compiler version is outside of the range specified in the contract. We’ll fix that in the next step. ![code](https://mintcdn.com/monadfoundation-40611fb6/c3ZcPFY7YVeS_v57/static/img/guides/deploy-smart-contract/remix/3.png?w=2500&fit=max&auto=format&n=c3ZcPFY7YVeS_v57&q=85&s=0fdb3e547bd207eb9ea13464ae6d1e64) Let’s compile the smart contract. Navigate to the compiler view by clicking the “Solidity compiler” tab on the far left. Then select the right compiler version (0.8.24). ![compiler](https://mintcdn.com/monadfoundation-40611fb6/c3ZcPFY7YVeS_v57/static/img/guides/deploy-smart-contract/remix/4.png?w=2500&fit=max&auto=format&n=c3ZcPFY7YVeS_v57&q=85&s=1c4e3ac32f1d8b890f957aae40a3ac11) Once you have the right compiler version selected, click on the “Compile Gmonad.sol” button. If succesful, you will see a green check mark on the “Solidity compiler” tab icon. ![compile](https://mintcdn.com/monadfoundation-40611fb6/c3ZcPFY7YVeS_v57/static/img/guides/deploy-smart-contract/remix/5.png?w=2500&fit=max&auto=format&n=c3ZcPFY7YVeS_v57&q=85&s=8157ca324bec0dbe707bf12c6c8fae43) Now we can deploy the smart contract! Navigate to the deploy view using the “Deploy & run transactions” tab on the far left. ![deploy](https://mintcdn.com/monadfoundation-40611fb6/c3ZcPFY7YVeS_v57/static/img/guides/deploy-smart-contract/remix/6.png?w=2500&fit=max&auto=format&n=c3ZcPFY7YVeS_v57&q=85&s=d606dc4f915c0b22f568de5514aad8ca) Using the “Environment” dropdown, select “Injected Provider” to connect to your wallet. The screenshot below says “Injected Provider - MetaMask”; in case you are using some wallet other than MetaMask you may see an appropriate option. ![environment](https://mintcdn.com/monadfoundation-40611fb6/c3ZcPFY7YVeS_v57/static/img/guides/deploy-smart-contract/remix/7.png?w=2500&fit=max&auto=format&n=c3ZcPFY7YVeS_v57&q=85&s=7eb3bbf02cc52216824a12788ba63616) Your wallet should pop up asking for permission to connect to Remix, click “Connect”. ![connect](https://mintcdn.com/monadfoundation-40611fb6/c3ZcPFY7YVeS_v57/static/img/guides/deploy-smart-contract/remix/8.png?w=2500&fit=max&auto=format&n=c3ZcPFY7YVeS_v57&q=85&s=1922d04cde6ae7a73f381a8284e2885a) Once connected you should be able to see your address with your balance in the “Account” dropdown. Make sure you also see the correct chain id under the “Environment” dropdown. Now let’s deploy the contract. `Gmonad.sol` requires a greeting message to be passed to the constructor before it can be deployed; choose the greeting message of your choice (in this example it is “gmonad”). Now you can deploy the smart contract by clicking the “Deploy” button. ![deploy](https://mintcdn.com/monadfoundation-40611fb6/c3ZcPFY7YVeS_v57/static/img/guides/deploy-smart-contract/remix/9.png?w=2500&fit=max&auto=format&n=c3ZcPFY7YVeS_v57&q=85&s=ba202e33f98f21dc639dc3343cd666c6) You should see a wallet popup asking for confirmation to deploy the smart contract. Click “Confirm”. ![confirm](https://mintcdn.com/monadfoundation-40611fb6/c3ZcPFY7YVeS_v57/static/img/guides/deploy-smart-contract/remix/10.png?w=2500&fit=max&auto=format&n=c3ZcPFY7YVeS_v57&q=85&s=67369e2be811cc2a49d128ba15b1dc32) Once the transaction is confirmed you will see the smart contract address in the “Deployed Contracts” section on the bottom left. ![deployed](https://mintcdn.com/monadfoundation-40611fb6/c3ZcPFY7YVeS_v57/static/img/guides/deploy-smart-contract/remix/11.png?w=2500&fit=max&auto=format&n=c3ZcPFY7YVeS_v57&q=85&s=1a1b2b750c0d13bba5f0ee87c02c5abd) [​](https://docs.monad.xyz/guides/deploy-smart-contract/remix#interacting-with-the-smart-contract) Interacting with the smart contract ----------------------------------------------------------------------------------------------------------------------------------------- You can expand the smart contract to see the functions available. There you will find a `greeting` button which can be used to read the current greeting message stored in the smart contract. Click the “greeting” button to call the `greeting()` method (which outputs the current greeting message). You’ll need to click the expand arrow in the terminal output to see the decoded output. This “greeting” button is a getter function which is automatically created for the _public_ `greeting` state variable in the smart contract. ![expand](https://mintcdn.com/monadfoundation-40611fb6/c3ZcPFY7YVeS_v57/static/img/guides/deploy-smart-contract/remix/12.png?w=2500&fit=max&auto=format&n=c3ZcPFY7YVeS_v57&q=85&s=7ef518724f3d0fc386215574f36a48a6) You can change the greeting message by using the `setGreeting` function. In this example, we will change the greeting message to “gmonad molandak”. Once again, click the “transact” button to initiate the transaction. You should see a wallet popup asking for confirmation to change the greeting message. Click “Confirm”. ![transact](https://mintcdn.com/monadfoundation-40611fb6/c3ZcPFY7YVeS_v57/static/img/guides/deploy-smart-contract/remix/13.png?w=2500&fit=max&auto=format&n=c3ZcPFY7YVeS_v57&q=85&s=90789c22f52614d3597a5281d4c4c76b) Once the transaction is confirmed you can view the updated greeting message using the `greeting` button. ![updated](https://mintcdn.com/monadfoundation-40611fb6/c3ZcPFY7YVeS_v57/static/img/guides/deploy-smart-contract/remix/14.png?w=2500&fit=max&auto=format&n=c3ZcPFY7YVeS_v57&q=85&s=cb9804c33579b8184a699b40bb778aad) Congratulations! You have successfully deployed and interacted with a smart contract on Monad Testnet using Remix IDE. [Deploy a smart contract on Monad using Hardhat\ \ Previous](https://docs.monad.xyz/guides/deploy-smart-contract/hardhat) [Verify a Contract\ \ Next](https://docs.monad.xyz/guides/verify-smart-contract) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Smart Account Implementations - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/tooling-and-infra/wallet-infra/smart-accounts#content-area) [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/smart-accounts#background) Background -------------------------------------------------------------------------------------------------- Under ERC-4337, smart wallets perform authentication (signature verification) inside of a smart contract. Depending on the signature scheme, signing may be done locally (on the user’s computer) or in a remote environment (e.g. TEEs). This page lists notable smart account implementations deployed to Monad. [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/smart-accounts#provider-summary) Provider Summary -------------------------------------------------------------------------------------------------------------- * Mainnet * Testnet | Provider | Status | Docs | Supported services | How to get started | | --- | --- | --- | --- | --- | | [Biconomy](https://biconomy.io/) | ✅ | [Docs](https://docs.biconomy.io/) | [Nexus: Smartest & most gas-efficient smart account](https://docs.biconomy.io/new/learn-about-biconomy/nexus)

[External Wallets](https://docs.biconomy.io/new/quickstart/external-wallets-quickstart)

Auth: [privy](https://docs.biconomy.io/new/integration-guides/wallets-and-signers/privy)
, [turnkey](https://docs.biconomy.io/new/integration-guides/wallets-and-signers/turnkey)
; [session keys](https://docs.biconomy.io/new/smart-sessions/introduction) | [Quickstart](https://docs.biconomy.io/new/getting-started/getting-started) | | [MetaMask Smart Accounts Kit](https://docs.metamask.io/smart-accounts-kit) | ✅ | [Embedded Smart Accounts (4337 & 7702)](https://docs.metamask.io/smart-accounts-kit#smart-account-implementation-types)

Auth: Signer agnostic, bring any signer
Features: WebAuthn, Multisig, [ERC-7710 delegations support](https://eips.ethereum.org/EIPS/eip-7710) | | [Quickstart](https://docs.metamask.io/smart-accounts-kit/get-started/smart-account-quickstart/) | | [Pimlico](https://pimlico.io/) | ✅ | [Docs](https://docs.pimlico.io/) | [permissionless.js](https://docs.pimlico.io/permissionless)
, a flexible SDK for interfacing with various smart accounts, bundlers/paymasters, and signers. | [Tutorial](https://docs.pimlico.io/permissionless/tutorial/tutorial-1) | | [ZeroDev](https://zerodev.app/) | ✅ | [Docs](https://docs.zerodev.app/) | [Smart contract accounts](https://docs.zerodev.app/sdk/core-api/create-account)

[Session keys](https://docs.zerodev.app/sdk/permissions/intro)
with several options for signature schemes (ECDSA, Passkey, Multisig), policies, and actions. | [Quickstart](https://docs.zerodev.app/sdk/getting-started/quickstart) | _✅ = supported, ⌛️ = in progress, ❓ = unknown, ❌ = won’t support_ | Provider | Status | Docs | Supported services | How to get started | | --- | --- | --- | --- | --- | | [Biconomy](https://biconomy.io/) | ✅ | [Docs](https://docs.biconomy.io/) | [Nexus: Smartest & most gas-efficient smart account](https://docs.biconomy.io/new/learn-about-biconomy/nexus)

[External Wallets](https://docs.biconomy.io/new/quickstart/external-wallets-quickstart)

Auth: [privy](https://docs.biconomy.io/new/integration-guides/wallets-and-signers/privy)
, [turnkey](https://docs.biconomy.io/new/integration-guides/wallets-and-signers/turnkey)
; [session keys](https://docs.biconomy.io/new/smart-sessions/introduction) | [Quickstart](https://docs.biconomy.io/new/getting-started/getting-started) | | [MetaMask Smart Accounts Kit](https://docs.metamask.io/smart-accounts-kit) | ✅ | [Embedded Smart Accounts (4337 & 7702)](https://docs.metamask.io/smart-accounts-kit#smart-account-implementation-types)

Auth: Signer agnostic, bring any signer
Features: WebAuthn, Multisig, [ERC-7710 delegations support](https://eips.ethereum.org/EIPS/eip-7710) | | [Quickstart](https://docs.metamask.io/smart-accounts-kit/get-started/smart-account-quickstart/) | | [Pimlico](https://pimlico.io/) | ✅ | [Docs](https://docs.pimlico.io/) | [permissionless.js](https://docs.pimlico.io/permissionless)
, a flexible SDK for interfacing with various smart accounts, bundlers/paymasters, and signers. | [Tutorial](https://docs.pimlico.io/permissionless/tutorial/tutorial-1) | | [ZeroDev](https://zerodev.app/) | ✅ | [Docs](https://docs.zerodev.app/) | [Smart contract accounts](https://docs.zerodev.app/sdk/core-api/create-account)

[Session keys](https://docs.zerodev.app/sdk/permissions/intro)
with several options for signature schemes (ECDSA, Passkey, Multisig), policies, and actions. | [Quickstart](https://docs.zerodev.app/sdk/getting-started/quickstart) | _✅ = supported, ⌛️ = in progress, ❓ = unknown, ❌ = won’t support_ [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/smart-accounts#provider-details) Provider Details -------------------------------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/smart-accounts#biconomy) Biconomy [Biconomy](https://biconomy.io/) is the most comprehensive smart account and execution infrastructure platform that enables seamless, user-friendly experiences across single or multiple chains. With Biconomy, developers can build superior onchain UX through gas abstraction, sessions, batching, and one-click signatures for complex actions on any number of networks. Additionally, you can use Biconomy’s [Nexus](https://docs.biconomy.io/new/learn-about-biconomy/nexus) : * Directly as a smart account with passkeys or embedded wallets * [Directly via 7702 with embedded wallets](https://docs.biconomy.io/new/quickstart/embedded-wallets-quickstart) * [With all EOA wallets such as MetaMask, Rabby and more](https://docs.biconomy.io/new/quickstart/external-wallets-quickstart) [Session keys](https://docs.biconomy.io/new/smart-sessions/introduction) are available for all the above methods. To get started, visit the [documentation](https://docs.biconomy.io/) . ### [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/smart-accounts#metamask-smart-accounts-kit) MetaMask Smart Accounts Kit The [MetaMask Smart Accounts Kit](https://docs.metamask.io/smart-accounts-kit) enables developers to create and interact with MetaMask Smart Accounts, unlocking new programmable account behaviors and granular permission sharing. The toolkit allows developers to build on embedded MetaMask Smart Accounts and request Advanced Permissions ([ERC-7715](https://eips.ethereum.org/EIPS/eip-7715) ) from MetaMask users. To get started, visit the [documentation](https://docs.metamask.io/smart-accounts-kit) or follow the [quickstart](https://docs.metamask.io/smart-accounts-kit/get-started/smart-account-quickstart/) guide. ### [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/smart-accounts#pimlico) Pimlico [Pimlico](https://pimlico.io/) is the world’s most advanced ERC-4337 account abstraction infrastructure platform. Pimlico provides a suite of tools and services to help you build, deploy, and manage smart accounts on Ethereum and other EVM-compatible chains. To get started, visit the [documentation](https://docs.pimlico.io/) or follow the [quickstart](https://docs.pimlico.io/permissionless/tutorial/tutorial-1) guide. ### [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/smart-accounts#zerodev) Zerodev [ZeroDev](https://zerodev.app/) is the most powerful smart account development platform. With ZeroDev, you can build Web3 experiences without gas, confirmations, seed phrases, and bridging. To get started, visit the [documentation](https://docs.zerodev.app/) or follow the [quickstart](https://docs.zerodev.app/sdk/getting-started/quickstart) guide. [Account Abstraction Providers\ \ Previous](https://docs.monad.xyz/tooling-and-infra/wallet-infra/account-abstraction) [JSON-RPC Overview\ \ Next](https://docs.monad.xyz/reference/json-rpc/overview) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Verify a Contract - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/guides/verify-smart-contract#content-area) Foundry ------- Verify a smart contract on Monad using Foundry Hardhat ------- Verify a smart contract on Monad using Hardhat [Deploy a smart contract on Monad using Remix\ \ Previous](https://docs.monad.xyz/guides/deploy-smart-contract/remix) [Verify a smart contract on Monad using Foundry\ \ Next](https://docs.monad.xyz/guides/verify-smart-contract/foundry) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # EVM Behavior - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/guides/evm-resources/evm-behavior#content-area) [​](https://docs.monad.xyz/guides/evm-resources/evm-behavior#evm-behavioral-specification) EVM Behavioral Specification -------------------------------------------------------------------------------------------------------------------------- * [Notes on the EVM](https://github.com/CoinCulture/evm-tools/blob/master/analysis/guide.md) : straightforward technical specification of the EVM plus some behavioral examples * [EVM: From Solidity to bytecode, memory and storage](https://www.youtube.com/watch?v=RxL_1AfV7N4) : a 90-minute talk from Peter Robinson and David Hyland-Wood * [EVM illustrated](https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf) : an excellent set of diagrams for confirming your mental model * [EVM Deep Dives: The Path to Shadowy Super-Coder](https://noxx.substack.com/p/evm-deep-dives-the-path-to-shadowy) [​](https://docs.monad.xyz/guides/evm-resources/evm-behavior#opcode-reference) Opcode Reference -------------------------------------------------------------------------------------------------- Opcode pricing on Monad has been changed to reflect their relative costs in execution, learn more about it [here](https://docs.monad.xyz/developer-essentials/opcode-pricing) [evm.codes](https://www.evm.codes/) : opcode reference and an interactive sandbox for stepping through bytecode execution [​](https://docs.monad.xyz/guides/evm-resources/evm-behavior#solidity-storage-layout) Solidity Storage Layout ---------------------------------------------------------------------------------------------------------------- The EVM allows smart contracts to store data in 32-byte words (“storage slots”), however the details of how complex datastructures such as lists or mappings is left as an implementation detail to the higher-level language. Solidity has a specific way of assigning variables to storage slots, described below: * [Official docs on storage layout](https://docs.soliditylang.org/en/latest/internals/layout_in_storage.html) * [Storage patterns in Solidity](https://programtheblockchain.com/posts/2018/03/09/understanding-ethereum-smart-contract-storage/) [EVM Resources\ \ Previous](https://docs.monad.xyz/guides/evm-resources) [Solidity Resources\ \ Next](https://docs.monad.xyz/guides/evm-resources/solidity-resources) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Indexers - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/tooling-and-infra/indexers#content-area) Common Data ----------- Raw transactional data and frequently-used derived data like balances, transfers, and DEX trades Indexing Frameworks ------------------- Tools that allow developers to build custom calculators in response to events The blockchain can be thought of as a list of blocks, transactions, and logs, as well as a series of global states. Indexers compute common transformations on this data to save downstream consumers the cost and complexity of doing so. There are two main types of indexer services: 1. **[Data for common use cases](https://docs.monad.xyz/tooling-and-infra/indexers/common-data) **: raw data (blocks, transactions, logs, traces) and derived data for common use cases (token balances, NFT holdings, DEX trades), computed across the entire blockchain 2. **[Indexing Frameworks](https://docs.monad.xyz/tooling-and-infra/indexers/indexing-frameworks) ** enable devleopers to build custom calculators for a specific smart contract [​](https://docs.monad.xyz/tooling-and-infra/indexers#data-for-common-use-cases) Data for common use cases ------------------------------------------------------------------------------------------------------------- Data providers offer raw and transformed data for common use cases via API or by streaming to your local environment. Raw data includes: * blocks, transactions, logs, traces (potentially decoded using contract ABIs) Transformed data includes: * balances (native tokens, ERC20s, NFTs) * transfers (native tokens, ERC20s, NFTs) * DEX trades * market data * and more See [Common Data](https://docs.monad.xyz/tooling-and-infra/indexers/common-data) for a fuller list of features and providers. [​](https://docs.monad.xyz/tooling-and-infra/indexers#indexing-frameworks) Indexing Frameworks ------------------------------------------------------------------------------------------------- Smart contract indexers are custom off-chain calculators for a specific smart contract. They maintain additional off-chain state and perform additional computation. Since blockchain data is public, anyone may deploy a subgraph involving state or logs from any smart contract. See [Indexing Frameworks](https://docs.monad.xyz/tooling-and-infra/indexers/indexing-frameworks) for a list of features and providers. [Earn/Yield Infrastructure\ \ Previous](https://docs.monad.xyz/tooling-and-infra/earn-yield) [Common Data\ \ Next](https://docs.monad.xyz/tooling-and-infra/indexers/common-data) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Vyper - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/guides/evm-resources/other-languages/vyper#content-area) [Vyper](https://www.quicknode.com/guides/ethereum-development/smart-contracts/how-to-write-an-ethereum-smart-contract-using-vyper) is a popular programming language for the EVM that is logically similar to Solidity and syntactically similar with Python. The [Vyper documentation](https://docs.vyperlang.org/en/stable/index.html) covers installing the Vyper language, language syntax, coding examples, compilation. A typical EVM developer looking for a Python-like experience is encouraged to use Vyper as the programming language and [ApeWorx](https://docs.apeworx.io/ape/stable/userguides/quickstart.html) , which leverages the Python language, as the testing and deployment framework. ApeWorx also allows for the use of typical Python libraries in analysis of testing results such as Pandas. Vyper and ApeWorx can be used with [Jupyter](https://jupyter.org/) , which offers an interactive environment using a web browser. A quick setup guide for working with Vyper and Jupyter for smart contract development for the EVM can be found [here](https://medium.com/deepyr/interacting-with-ethereum-using-web3-py-and-jupyter-notebooks-e4207afa0085) . [​](https://docs.monad.xyz/guides/evm-resources/other-languages/vyper#resources) Resources --------------------------------------------------------------------------------------------- * [Vyper by Example](https://vyper-by-example.org/) * [Snekmate](https://github.com/pcaversaccio/snekmate) : a Vyper library of gas-optimized smart contract building blocks * [Curve contracts](https://github.com/curvefi/curve-contract) : the most prominent example usage of Vyper [Other Languages\ \ Previous](https://docs.monad.xyz/guides/evm-resources/other-languages) [Yul\ \ Next](https://docs.monad.xyz/guides/evm-resources/other-languages/yul) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Deploy a smart contract on Monad using Hardhat - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/guides/deploy-smart-contract/hardhat#content-area) [Hardhat](https://hardhat.org/docs) is a comprehensive development environment consisting of different components for editing, compiling, debugging, and deploying your smart contracts. [​](https://docs.monad.xyz/guides/deploy-smart-contract/hardhat#requirements) Requirements --------------------------------------------------------------------------------------------- Before you begin, you need to install the following dependencies: * Node.js v18.0.0 or later If you are on Windows, we strongly recommend using [WSL 2](https://learn.microsoft.com/en-us/windows/wsl/about) when following this guide. When deploying to Monad, set `evmVersion: "prague"` in your Hardhat Solidity compiler settings. For example: solidity: { version: "0.8.28", settings: { evmVersion: "prague", }, }, * Hardhat 2 * Hardhat3 [​](https://docs.monad.xyz/guides/deploy-smart-contract/hardhat#1-create-a-new-hardhat-project) 1\. Create a new Hardhat project ----------------------------------------------------------------------------------------------------------------------------------- You can use the `hardhat-monad` template to create a new project with Monad configuration already set up._[hardhat-monad](https://github.com/monad-developers/hardhat-monad) is a Hardhat template with Monad configuration._ Clone the repository to your machine using the command below: git clone https://github.com/monad-developers/hardhat-monad.git cd hardhat-monad [​](https://docs.monad.xyz/guides/deploy-smart-contract/hardhat#2-install-dependencies) 2\. Install dependencies ------------------------------------------------------------------------------------------------------------------- npm install [​](https://docs.monad.xyz/guides/deploy-smart-contract/hardhat#3-create-an-env-file) 3\. Create an .env file ---------------------------------------------------------------------------------------------------------------- cp .env.example .env Edit the `.env` file with your private key: PRIVATE_KEY=your_private_key_here Protect your private key carefully. Never commit it to version control, share it in public repositories, or expose it in client-side code. Your private key provides full access to your funds. [​](https://docs.monad.xyz/guides/deploy-smart-contract/hardhat#4-deploy-the-smart-contract) 4\. Deploy the smart contract ----------------------------------------------------------------------------------------------------------------------------- The following commands use [Hardhat Ignition](https://hardhat.org/ignition/docs/getting-started#overview) : ### [​](https://docs.monad.xyz/guides/deploy-smart-contract/hardhat#deploying-to-the-local-hardhat-node) Deploying to the local hardhat node Run hardhat node by running: npx hardhat node To deploy the example contract to the local hardhat node, run the following command in a separate terminal: npx hardhat ignition deploy ignition/modules/Counter.ts ### [​](https://docs.monad.xyz/guides/deploy-smart-contract/hardhat#deploying-to-monad-testnet) Deploying to Monad Testnet Ensure your private key is set in the `.env` file.Deploy the contract to Monad Testnet: npx hardhat ignition deploy ignition/modules/Counter.ts --network monadTestnet Redeploy the same code to a different address: npx hardhat ignition deploy ignition/modules/Counter.ts --network monadTestnet --reset ### [​](https://docs.monad.xyz/guides/deploy-smart-contract/hardhat#deploying-to-monad-mainnet) Deploying to Monad Mainnet Ensure your private key is set in the `.env` file.Deploy the contract to Monad Mainnet: npx hardhat ignition deploy ignition/modules/Counter.ts --network monadMainnet Redeploy the same code to a different address: npx hardhat ignition deploy ignition/modules/Counter.ts --network monadMainnet --reset [​](https://docs.monad.xyz/guides/deploy-smart-contract/hardhat#1-create-a-new-hardhat3-project) 1\. Create a new Hardhat3 project ------------------------------------------------------------------------------------------------------------------------------------- You can use the `hardhat3-monad` template to create a new project with Monad configuration already set up for Hardhat3._[hardhat3-monad](https://github.com/monad-developers/hardhat3-monad) is a Hardhat3 template with Monad configuration._To learn more about Hardhat3, please visit the [Getting Started guide](https://hardhat.org/docs/getting-started#getting-started-with-hardhat-3) . Clone the repository to your machine using the command below: git clone https://github.com/monad-developers/hardhat3-monad.git cd hardhat3-monad [​](https://docs.monad.xyz/guides/deploy-smart-contract/hardhat#2-install-dependencies-2) 2\. Install dependencies --------------------------------------------------------------------------------------------------------------------- npm install [​](https://docs.monad.xyz/guides/deploy-smart-contract/hardhat#3-set-up-your-private-key) 3\. Set up your private key ------------------------------------------------------------------------------------------------------------------------- Create a `.env` file in the project root: PRIVATE_KEY=your_private_key_here ETHERSCAN_API_KEY=your_etherscan_api_key_here Protect your private key carefully. Never commit your `.env` file or expose your private key. Your private key provides full access to your funds. [​](https://docs.monad.xyz/guides/deploy-smart-contract/hardhat#4-deploy-the-smart-contract-2) 4\. Deploy the smart contract ------------------------------------------------------------------------------------------------------------------------------- The following commands use [Hardhat Ignition](https://hardhat.org/ignition/docs/getting-started#overview) : ### [​](https://docs.monad.xyz/guides/deploy-smart-contract/hardhat#deploying-to-a-local-chain) Deploying to a local chain npx hardhat ignition deploy ignition/modules/Counter.ts ### [​](https://docs.monad.xyz/guides/deploy-smart-contract/hardhat#deploying-to-monad-testnet-2) Deploying to Monad Testnet Ensure your `.env` file is set up with your private key. npx hardhat ignition deploy ignition/modules/Counter.ts --network monadTestnet ### [​](https://docs.monad.xyz/guides/deploy-smart-contract/hardhat#deploying-to-monad-mainnet-2) Deploying to Monad Mainnet Ensure your `.env` file is set up with your private key. npx hardhat ignition deploy ignition/modules/Counter.ts --network monadMainnet [​](https://docs.monad.xyz/guides/deploy-smart-contract/hardhat#next-steps) Next Steps ----------------------------------------------------------------------------------------- Check out [how to verify the deployed smart contract on MonadVision](https://docs.monad.xyz/guides/verify-smart-contract/hardhat) . [Deploy a smart contract on Monad using Monad Foundry\ \ Previous](https://docs.monad.xyz/guides/deploy-smart-contract/foundry) [Deploy a smart contract on Monad using Remix\ \ Next](https://docs.monad.xyz/guides/deploy-smart-contract/remix) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Common Data - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/tooling-and-infra/indexers/common-data#content-area) [​](https://docs.monad.xyz/tooling-and-infra/indexers/common-data#features) Features --------------------------------------------------------------------------------------- In order to improve developer understanding of feature coverage, we have collected the most common features offered by providers: | Feature | Sub-Feature | Description | | --- | --- | --- | | **Chain data** | | Raw data (blocks, transactions, logs, traces) in SQL-like format. Transactions and logs may optionally be decoded based on ABI | | **Balances** | Native | Native token holdings of an address, real-time or snapshot. May include price annotations | | | ERC20 | ERC20 holdings of an address, real-time or snapshot. May include price annotations | | | NFT | NFT (ERC721 or ERC1155) holdings of an address, real-time or snapshot | | **Transfers** | Native | Native token transfers involving a particular address. May include price annotations | | | ERC20 | ERC20 transfers involving a particular address. May include price annotations | | | NFT | NFT transfers involving a particular address | | **DEX trades** | | Normalized trade data across major DEXes | | **Market data** | | Market data for ERC20s | Balances are nontrivial because each ERC20 and NFT collection stores its balances in contract storage. Transfers are nontrivial because they frequently occur as subroutines. Annotating with prices and normalizing across DEXes add additional convenience. [​](https://docs.monad.xyz/tooling-and-infra/indexers/common-data#access-models) Access models ------------------------------------------------------------------------------------------------- * **APl**: Data lives on provider’s servers; make queries via API * **Stream**: Data is replicated to your environment [​](https://docs.monad.xyz/tooling-and-infra/indexers/common-data#provider-summary) Provider Summary ------------------------------------------------------------------------------------------------------- * Mainnet * Testnet | Provider | Status | Docs | Supported services | Access model | | --- | --- | --- | --- | --- | | [Allium](https://www.allium.so/) | ✅ | [Docs](https://docs.allium.so/) | **Chain data** (blocks, transactions, logs, traces, contracts) (via [Explorer](https://docs.allium.so/app/overview)
(historical) and [Datastreams](https://docs.allium.so/realtime/kafka-blockchains-70+)
(realtime) products)
**Transfers** (native, ERC20, and NFTs) (via [Developer](https://docs.allium.so/data-products-real-time/allium-developer/wallet-apis/activities)
(realtime) product) | API, except streaming for Datastreams product | | [Birdeye Data Services](https://bds.birdeye.so/) | ✅ | [Docs](https://docs.birdeye.so/) | [**DEX trades**](https://docs.birdeye.so/reference/get-defi-price)

[**Market data**](https://docs.birdeye.so/reference/get-defi-v3-token-market-data)
for tokens
[**Token metadata**](https://docs.birdeye.so/reference/get-defi-tokenlist)
and analytics | API | | [Codex](https://www.codex.io/) | ✅ | [Docs](https://docs.codex.io/) | Token- and trading-centric data:
[Token](https://docs.codex.io/recipes/discover-tokens)
charts, metadata, prices, events, and detailed stats
NFT metadata, events, and detailed stats | API | | [Dune Sim](https://sim.dune.com/) | ✅ | [Docs](https://docs.sim.dune.com/) | **Chain data:** Transactions, logs (raw or decoded)
**Balances:** Native, ERC20 | API | | [GoldRush](https://goldrush.dev/)
(by Covalent) | ✅ | [Docs](https://goldrush.dev/docs/overview) | **Chain data:** Blocks, enriched transactions and logs (raw and decoded)
**Balances:** native, ERC20, NFTs & Portfolio
**Transactions:** Full historical with decoded transfer events | API | | [Goldsky](https://goldsky.com/) | ✅ | [Docs](https://docs.goldsky.com/) | **Chain data:** blocks, enriched transactions, logs, and traces via [Mirror](https://docs.goldsky.com/mirror/introduction)
. [Fast scan](https://docs.goldsky.com/mirror/sources/direct-indexing#backfill-vs-fast-scan)
is supported | API; Streaming | | [Mobula](https://mobula.io/) | ✅ | [Docs](https://docs.mobula.io/introduction) | **Chain data**
**Balances:** [native, ERC20](https://docs.mobula.io/rest-api-reference/endpoint/wallet-portfolio)
and [NFT](https://docs.mobula.io/rest-api-reference/endpoint/wallet-nfts)

**Transfers:** [native, ERC20](https://docs.mobula.io/rest-api-reference/endpoint/wallet-transactions)
and NFT
[**DEX trades**](https://docs.mobula.io/rest-api-reference/endpoint/market-trades-pair)

[**Market data**](https://docs.mobula.io/rest-api-reference/endpoint/market-data)
for ERC20s | API | | [Moralis](https://moralis.com/) | ✅ | [Docs](https://docs.moralis.com/) | **Chain Data:** [blocks](https://docs.moralis.com/web3-data-api/evm/reference/blockchain-api#get-blocks)
, [transactions](https://docs.moralis.com/web3-data-api/evm/reference/blockchain-api#get-transactions)
, [logs](https://docs.moralis.com/rpc-nodes/reference/eth_getLogs)

**Balances:** [native, ERC20,](https://docs.moralis.com/web3-data-api/evm/reference/wallet-api/get-wallet-token-balances-price?address=0xcB1C1FdE09f811B294172696404e88E658659905&chain=eth&token_addresses=%5B%5D&limit=50)
[NFTs](https://docs.moralis.com/web3-data-api/evm/reference/wallet-api#get-wallet-nft-balances)
(with metadata, logos, spam / low-liquidity filtering)
[**Token Prices**](https://docs.moralis.com/web3-data-api/evm/reference/price-api#get-token-prices)
: USD valuation included
**Transfers:** [native, ERC20](https://docs.moralis.com/web3-data-api/evm/reference/wallet-api/get-transactions-by-wallet?address=0x1f9090aaE28b8a3dCeaDf281B0F12828e676c326&chain=eth&limit=50&order=DESC)
, and [NFTs](https://docs.moralis.com/web3-data-api/evm/reference/wallet-api/get-wallet-nft-transfers?address=0xcB1C1FdE09f811B294172696404e88E658659905&chain=eth&contract_addresses=%5B%5D&format=decimal&limit=25&order=DESC)
(decoded events), [wallet history](https://docs.moralis.com/web3-data-api/evm/reference/wallet-api/get-wallet-history?address=0xcB1C1FdE09f811B294172696404e88E658659905&chain=eth&order=DESC&limit=25)
(categorized transfers + approvals)
[**Streams**](https://docs.moralis.com/streams-api/evm)
: real-time address/contract monitoring via webhooks
[**Datashare**](https://moralis.com/datashare/)
: Export massive crypto datasets
[**RPC Nodes**](https://docs.moralis.com/rpc-nodes)
: Raw blockchain data access | APIs, Streaming (webhooks) | | [Quicknode](https://www.quicknode.com/) | ✅ | [Docs](https://www.quicknode.com/docs/streams/getting-started) | [**Streams**](https://www.quicknode.com/streams)
, [**Webhooks**](https://www.quicknode.com/webhooks) | Streams, Webhooks | | [Rarible](https://rarible.org/) | ✅ | [Docs](https://docs.rarible.org/) | [**NFT data**](https://docs.rarible.org/reference)
: metadata; holdings by address (current and historic); trade data; spam scoring | API | | [Sequence](https://sequence.xyz/) | ❓ | [Docs](https://docs.sequence.xyz/solutions/indexer/overview) | **Balances**: native, ERC20, and NFT
**Transfers**: native, ERC20, and NFTs
**Other:** Transaction history; webhooks | API; Streaming (webhooks) | | [SQD](https://sqd.ai/) | ✅ | [Docs](https://docs.sqd.ai/) | **Chain data:** blocks, transactions, logs, traces, state diffs (via [Portal](https://docs.sqd.dev/en/portal/evm/overview)
and [Subsquid SDK](https://github.com/subsquid/squid-sdk)
)
**Other:** [MCP server](https://docs.sqd.dev/en/ai/mcp-server)
for AI agent integration | API | | [SonarX](https://sonarx.com/) | ✅ | | **Chain data:** blocks, transactions, logs, traces
**Transfers:** tokens, NFTs, internal transfers, net internal transfers (with/without pricing)
**Balances:** PIT and current balances
**DEX trades** and balances
**Other:** Approvals and failed transactions | Cloud Platforms Data Shares (Snowflake, BigQuery, Azure, Databricks); Streaming (Kafka); File delivery (CSV, Parquet, Iceberg); API | | [thirdweb](https://thirdweb.com/) | ✅ | [Docs](https://insight-api.thirdweb.com/guide/getting-started) | **Chain data:** [blocks](https://insight-api.thirdweb.com/reference#tag/blocks)
, [transactions](https://insight-api.thirdweb.com/guide/blueprints#transactions-blueprint)
, [logs](https://insight-api.thirdweb.com/guide/blueprints#events-blueprint)
, [contracts](https://insight-api.thirdweb.com/reference#tag/contracts)

[**Balances**](https://insight-api.thirdweb.com/guide/blueprints#tokens-blueprint)
: native, ERC20, NFTs
**Other:** [NFTs](https://insight-api.thirdweb.com/reference#tag/nfts) | API | | [Unmarshal](https://unmarshal.io/) | ❓ | [Docs](https://docs.unmarshal.io/) | [**Balances**](https://docs.unmarshal.io/reference/fungibleerc20tokenbalances)
: ERC20 and NFT
[**Transactions**](https://docs.unmarshal.io/reference/get-v3-chain-address-address-transactions)
with price annotations
[**NFT API**](https://docs.unmarshal.io/reference/get-v2-chain-address-address-nft-transactions)
(transactions and metadata) | API | | [Zerion](https://zerion.io/) | ✅ | [Docs](https://zerion.io/api) | [**Wallet info**](https://developers.zerion.io/reference/wallets)

[**Balances**](https://developers.zerion.io/reference/listwalletpositions)
(native, ERC20, and NFTs)
[**Transactions**](https://developers.zerion.io/reference/listwallettransactions)
(multichain with prices)
**Other:** [Portfolio](https://developers.zerion.io/reference/getwalletportfolio)
, [PNL](https://developers.zerion.io/reference/getwalletpnl#/)
and [Historical Positions](https://developers.zerion.io/reference/getwalletchart)

[Notification Webhooks](https://developers.zerion.io/v1.0-subscriptions/reference/createsubscriptionwallettransactions) | API; Webhooks | _✅ = supported, ⌛️ = in progress, ❓ = unknown, ❌ = won’t support_ | Provider | Status | Docs | Supported services | Access model | | --- | --- | --- | --- | --- | | [Allium](https://www.allium.so/) | ✅ | [Docs](https://docs.allium.so/) | **Chain data** (blocks, transactions, logs, traces, contracts) (via [Explorer](https://docs.allium.so/app/overview)
(historical) and [Datastreams](https://docs.allium.so/realtime/kafka-blockchains-70+)
(realtime) products)
**Transfers** (native, ERC20, and NFTs) (via [Developer](https://docs.allium.so/data-products-real-time/allium-developer/wallet-apis/activities)
(realtime) product) | API, except streaming for Datastreams product | | [Codex](https://www.codex.io/) | ✅ | [Docs](https://docs.codex.io/) | Token- and trading-centric data:
[Token](https://docs.codex.io/recipes/discover-tokens)
charts, metadata, prices, events, and detailed stats (see [dashboard](https://www.defined.fi/tokens/discover?network=mon-test)
)
[NFT](https://docs.codex.io/api-reference/queries/getnftpool)
metadata, events, and detailed stats | API | | [Dune Sim](https://sim.dune.com/) | ✅ | [Docs](https://docs.sim.dune.com/) | **Chain data:** Transactions, logs (raw or decoded)
**Balances:** Native, ERC20 | API | | [GoldRush](https://goldrush.dev/)
(by Covalent) | ✅ | [Docs](https://goldrush.dev/docs/overview) | **Chain data:** Blocks, enriched transactions and logs (raw and decoded)
**Balances:** native, ERC20, NFTs & Portfolio
**Transactions:** Full historical with decoded transfer events | API | | [Goldsky](https://goldsky.com/) | ✅ | [Docs](https://docs.goldsky.com/) | **Chain data:** blocks, enriched transactions, logs, and traces via [Mirror](https://docs.goldsky.com/mirror/introduction)
. [Fast scan](https://docs.goldsky.com/mirror/sources/direct-indexing#backfill-vs-fast-scan)
is supported | API; Streaming | | [Mobula](https://mobula.io/) | ✅ | [Docs](https://docs.mobula.io/introduction) | **Chain data**
**Balances:** [native, ERC20](https://docs.mobula.io/rest-api-reference/endpoint/wallet-portfolio)
and [NFT](https://docs.mobula.io/rest-api-reference/endpoint/wallet-nfts)

**Transfers:** [native, ERC20](https://docs.mobula.io/rest-api-reference/endpoint/wallet-transactions)
and NFT
[**DEX trades**](https://docs.mobula.io/rest-api-reference/endpoint/market-trades-pair)

[**Market data**](https://docs.mobula.io/rest-api-reference/endpoint/market-data)
for ERC20s | API | | [Moralis](https://moralis.com/) | ❌ | [Docs](https://docs.moralis.com/) | **Chain data**
**Balances:** [native, ERC20](https://docs.moralis.com/web3-data-api/evm/reference/wallet-api/get-wallet-token-balances-price?address=0xcB1C1FdE09f811B294172696404e88E658659905&chain=eth&token_addresses=%5B%5D&limit=50)
and [NFT](https://docs.moralis.com/web3-data-api/evm/reference/wallet-api/get-nfts-by-wallet?address=0xff3879b8a363aed92a6eaba8f61f1a96a9ec3c1e&chain=eth&format=decimal&limit=50&token_addresses=%5B%5D&normalizeMetadata=true&media_items=false&include_prices=false)

**Transfers:** [native, ERC20](https://docs.moralis.com/web3-data-api/evm/reference/wallet-api/get-transactions-by-wallet?address=0x1f9090aaE28b8a3dCeaDf281B0F12828e676c326&chain=eth&limit=50&order=DESC) | API | | [Quicknode](https://www.quicknode.com/) | ✅ | [Docs](https://www.quicknode.com/docs/streams/getting-started) | [**Streams**](https://www.quicknode.com/streams)
, [**Webhooks**](https://www.quicknode.com/webhooks) | Streams, Webhooks | | [Sequence](https://sequence.xyz/) | ✅ | [Docs](https://docs.sequence.xyz/solutions/indexer/overview) | **Balances**: native, ERC20, and NFT
**Transfers**: native, ERC20, and NFTs
**Other:** Transaction history; webhooks | API; Streaming (webhooks) | | [SQD](https://sqd.ai/) | ✅ | [Docs](https://docs.sqd.ai/) | **Chain data:** blocks, transactions, logs, traces, state diffs (via [Portal](https://docs.sqd.dev/en/portal/evm/overview)
and [Subsquid SDK](https://github.com/subsquid/squid-sdk)
)
**Other:** [MCP server](https://docs.sqd.dev/en/ai/mcp-server)
for AI agent integration | API | | [SonarX](https://sonarx.com/) | ✅ | | **Chain data:** blocks, transactions, logs, traces
**Transfers:** tokens, NFTs, internal transfers, net internal transfers (with/without pricing)
**Balances:** PIT and current balances
**DEX trades** and balances
**Other:** Approvals and failed transactions | Cloud Platforms Data Shares (Snowflake, BigQuery, Azure, Databricks); Streaming (Kafka); File delivery (CSV, Parquet, Iceberg); API | | [thirdweb](https://thirdweb.com/) | ✅ | [Docs](https://insight-api.thirdweb.com/guide/getting-started) | **Chain data:** [blocks](https://insight-api.thirdweb.com/reference#tag/blocks)
, [transactions](https://insight-api.thirdweb.com/guide/blueprints#transactions-blueprint)
, [logs](https://insight-api.thirdweb.com/guide/blueprints#events-blueprint)
, [contracts](https://insight-api.thirdweb.com/reference#tag/contracts)

[**Balances**](https://insight-api.thirdweb.com/guide/blueprints#tokens-blueprint)
: native, ERC20, NFTs
**Other:** [NFTs](https://insight-api.thirdweb.com/reference#tag/nfts) | API | | [Zerion](https://zerion.io/) | ✅ | [Docs](https://zerion.io/api) | [**Wallet info**](https://developers.zerion.io/reference/wallets)

[**Balances**](https://developers.zerion.io/reference/listwalletpositions)
(native, ERC20, and NFTs)
[**Transactions**](https://developers.zerion.io/reference/listwallettransactions)
(multichain with prices)
**Other:** [Portfolio](https://developers.zerion.io/reference/getwalletportfolio)
, [PNL](https://developers.zerion.io/reference/getwalletpnl#/)
and [Historical Positions](https://developers.zerion.io/reference/getwalletchart)

[Notification Webhooks](https://developers.zerion.io/v1.0-subscriptions/reference/createsubscriptionwallettransactions) | API; Webhooks | _✅ = supported, ⌛️ = in progress, ❓ = unknown, ❌ = won’t support_ [​](https://docs.monad.xyz/tooling-and-infra/indexers/common-data#provider-details) Provider Details ------------------------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/tooling-and-infra/indexers/common-data#allium) Allium [Allium](https://www.allium.so/) is an Enterprise Data Platform that serves accurate, fast, and simple blockchain data. Allium offers near real-time Monad Testnet data for infrastructure needs and enriched Monad Testnet data (NFT, DEX, Decoded) for research and analytics. Allium supports data delivery to multiple [destinations](https://docs.allium.so/integrations/overview) , including Snowflake, Bigquery, Databricks, and AWS S3. To get started, contact Allium [here](https://www.allium.so/contact) . | Product | Description / mechanism | Monad Testnet data supported | | --- | --- | --- | | [Explorer](https://docs.allium.so/app/overview) | Historical data (postgres/API) | Chain data: blocks, transactions, logs, traces, contracts | | [Developer](https://docs.allium.so/data-products-real-time/allium-developer) | Real-time data (postgres/API) | [Transfers](https://docs.allium.so/products/allium-developer/wallet-apis/activities)
(native, ERC20, ERC721, ERC1155) | | [Datastreams](https://docs.allium.so/data-products-real-time/allium-datastreams) | Real-time data (streaming - Kafka, PubSub, or SNS) | Chain data: blocks, transactions, logs, traces, contracts | ### [​](https://docs.monad.xyz/tooling-and-infra/indexers/common-data#birdeye-data-services) Birdeye Data Services [Birdeye Data Services](https://bds.birdeye.so/) (BDS) provides comprehensive multi-market data APIs for cryptocurrency tokens, pulling information from decentralized exchanges (DEX). BDS offers real-time and historical token prices, market data, OHLCV charts, trade history, and token metadata. To get started, visit the [documentation](https://docs.birdeye.so/) or sign up at [bds.birdeye.so](https://bds.birdeye.so/) . ### [​](https://docs.monad.xyz/tooling-and-infra/indexers/common-data#codex) Codex [Codex](https://www.codex.io/) API provides fast and accurate enriched data, meticulously structured to easily plug straight into your application. To get started, visit the [documentation](https://docs.codex.io/) or sign up for an API key at [dashboard.codex.io](https://dashboard.codex.io/) . ### [​](https://docs.monad.xyz/tooling-and-infra/indexers/common-data#dune-sim) Dune Sim [Dune Sim](https://sim.dune.com/) makes building multi-chain application seamless. These APIs power several of the best teams building on crypto. Available APIs: * **Token Balances**: Access accurate and fast real time balances of native and ERC20 tokens of accounts on EVM blockchains. * **Transactions**: Access transactions for accounts in real time across EVM blockchains. To get started, visit the [documentation](https://docs.sim.dune.com/) . ### [​](https://docs.monad.xyz/tooling-and-infra/indexers/common-data#goldrush-by-covalent) GoldRush (by Covalent) [GoldRush](https://goldrush.dev/) provides multichain data APIs and toolkits for easy web3 development across 100+ chains including Monad. GoldRush offers structured onchain data, including multichain wallet balances, full transaction histories and decoded log events, for building apps and powering AI Agents. Join hundreds of top teams that leverage GoldRush to cut down their development time and scale their multichain offerings with enterprise-grade onchain data. To get started, visit the [documentation](https://goldrush.dev/docs/overview) or [sign up](https://goldrush.dev/platform/auth/register/) for an API key. ### [​](https://docs.monad.xyz/tooling-and-infra/indexers/common-data#goldsky) Goldsky [Goldsky](https://goldsky.com/) is the go-to data indexer for web3 builders, offering high-performance subgraph hosting and realtime data replication pipelines. Goldsky offers two core self-serve products that can be used independently or in conjunction to power your data stack. * **Subgraphs**: Flexible indexing with typescript, with support for webhooks and more. * **Mirror**: Get live blockchain data in your database or message queues with a single yaml config. To get started, visit the [documentation](https://docs.goldsky.com/) or follow the [quickstart](https://docs.goldsky.com/subgraphs/guides/create-a-no-code-subgraph) guide. ### [​](https://docs.monad.xyz/tooling-and-infra/indexers/common-data#mobula) Mobula [Mobula](https://mobula.io/) provides curated datasets for builders: market data with Octopus, wallets data, metadata with Metacore, alongside with REST, GraphSQL & SQL interfaces to query them. You can get started playing around with the [API endpoints](https://docs.mobula.io/rest-api-reference/introduction) for free, and sign-up to the API dashboard once you need API keys (queries without API keys aren’t production-ready). To get started, visit the [documentation](https://docs.mobula.io/introduction) . ### [​](https://docs.monad.xyz/tooling-and-infra/indexers/common-data#moralis) Moralis [Moralis](https://moralis.com/) is the unified way to fetch, stream, and export onchain data. Access fast, enriched Data APIs for wallets, tokens, prices, holders, NFTs, transfers, liquidity, and full transaction & wallet history - plus real-time Streams and RPC nodes. Teams use Moralis as their crypto data layer to get complete, reliable onchain data without running indexers or maintaining pipelines. To get started, visit the [documentation](https://docs.moralis.com/) or [sign up](https://admin.moralis.com/register) for a free API key. ### [​](https://docs.monad.xyz/tooling-and-infra/indexers/common-data#quicknode) Quicknode [Streams](https://www.quicknode.com/streams) is a managed, push-based service for blockchain data streaming with guaranteed delivery of live and sequential historical data. Receive raw or filtered data (e.g., specific contract events) pushed to your destination: webhook, S3, Postgres, or Snowflake. To get started, visit the [documentation](https://www.quicknode.com/docs/streams) for detailed instructions. [Webhooks](https://www.quicknode.com/webhooks) provide real-time notifications for blockchain events on Monad. Track smart contract activity, wallet transactions, and more using ready-to-use templates or your own custom JavaScript. To get started, visit the [documentation](https://www.quicknode.com/docs/webhooks) for detailed instructions. ### [​](https://docs.monad.xyz/tooling-and-infra/indexers/common-data#rarible) Rarible [Rarible](https://rarible.org/) offers an comprehensive toolkit for anyone interacting with NFTs, including marketplaces and wallets. Rarible’s API for NFT data includes collection/item metadata, trades, holdings by account (both current and historical), and spam scoring. Rarible also offers aggregated order books from major NFT marketplaces like OpenSea, Rarible, and Blur, as well as an NFT trading SDK. To get started, check out the [documentation](https://docs.rarible.org/) . ### [​](https://docs.monad.xyz/tooling-and-infra/indexers/common-data#sequence) Sequence [Sequence](https://sequence.xyz/) [Indexer](https://docs.sequence.xyz/solutions/indexer/overview) offers real-time balances, transfers, NFTs, prices, and contract events across EVM chains with webhooks and subscriptions and sub-300 ms queries. Use it as your production read layer for on-chain apps. Indexer gives you low-latency reads across EVM chains: balances and portfolio, token and NFT ownership, transfers and logs, prices, and contract events. It is built for enterprise-grade production and supports developers of all sizes. Cursor-based pagination, filters, webhooks, and event subscriptions: All in a scalable, 99.99% uptime service. To get started, visit the [quickstart](https://docs.sequence.xyz/solutions/indexer/overview#quickstart) guide. ### [​](https://docs.monad.xyz/tooling-and-infra/indexers/common-data#sqd) SQD [SQD](https://sqd.ai/) is a decentralized data indexing platform (formerly Subsquid) that provides access to onchain data through its permissionless data lake. SQD offers chain data (blocks, transactions, logs, traces, state diffs) for Monad via the [Portal API](https://docs.sqd.dev/en/portal/evm/overview) and the [Subsquid SDK](https://github.com/subsquid/squid-sdk) for building custom indexers. SQD also offers a [Portal MCP server](https://docs.sqd.dev/en/ai/mcp-server) that enables AI agents to query onchain data directly. To get started, visit the [documentation](https://docs.sqd.ai/) or explore the [Portal API](https://docs.sqd.dev/en/portal/evm/overview) . ### [​](https://docs.monad.xyz/tooling-and-infra/indexers/common-data#sonarx) SonarX [SonarX](https://sonarx.com/) delivers structured blockchain data with historical and real-time coverage across 100+ blockchains with a focus on data quality, in line with our proprietary Data Quality Framework. Enterprises, Institutions and Builders can query full historical datasets in their preferred cloud warehouse (Snowflake, BigQuery, Azure), receive file drops in csv, parquet, iceberg formats, or run real-time pipelines with Kafka streaming. Supported services include chain data (blocks, transactions, logs, traces, decoded logs and traces), staking, and DEX trades and balances. With ready-to-use tables and flexible delivery, SonarX helps power analytics, trading, accounting, and applications without the burden of maintaining indexing pipelines. To get started, visit the console at [console.sonarx.com](https://console.sonarx.com/) . ### [​](https://docs.monad.xyz/tooling-and-infra/indexers/common-data#thirdweb) thirdweb thirdweb [Insight](https://thirdweb.com/insight) is a fast, reliable and fully customizable way for developers to index, transform & query onchain data across 30+ chains. Insight includes out-of-the-box APIs for transactions, events, tokens. Developers can also define custom API schemas, or blueprints, without the need for ABIs, decoding, RPC, or web3 knowledge to fetch blockchain data. thirdweb Insight can be used to fetch: * all assets (ERC20, ERC721, ERC115) for a given wallet address * all sales of skins on your in-game marketplace * monthly protocol fees in the last 12 months * the total cost of all accounts created using ERC-4337 * metadata for a given token (ERC20, ERC721, ERC115) * daily active wallets for your application or game * and so much more To get started, sign up for a [free thirdweb account](https://thirdweb.com/team) and visit the [thirdweb Insight documentation](https://insight.thirdweb.com/reference) ### [​](https://docs.monad.xyz/tooling-and-infra/indexers/common-data#unmarshal) Unmarshal [Unmarshal](https://unmarshal.io/) is a leading decentralized multi-chain data network, enabling Web3 projects to access accurate, real-time blockchain data across 55+ chains (including Monad Testnet). Leveraging AI-driven solutions, Unmarshal enhances data accessibility and insights for RWA, DePIN, AI Agents, DeFi, NFT, and GameFi platforms. Through robust APIs, notification services, and no-code indexers, it empowers dApps to deliver seamless user experiences while ensuring transparency, scalability, and innovation at the forefront of Web3 advancements. To get started, visit the [documentation](https://docs.unmarshal.io/) or reach out at [support@unmarshal.io](mailto:support@unmarshal.io) . ### [​](https://docs.monad.xyz/tooling-and-infra/indexers/common-data#zerion) Zerion The [Zerion API](https://zerion.io/api) can be used to build feature-rich web3 apps, wallets, and protocols with ease. Across all major blockchains, you can access wallets, assets, and chain data for web3 portfolios. Zerion’s infrastructure supports all major chains! To get started, visit the [documentation](https://zerion.io/api) . [Indexers\ \ Previous](https://docs.monad.xyz/tooling-and-infra/indexers) [Indexing Frameworks\ \ Next](https://docs.monad.xyz/tooling-and-infra/indexers/indexing-frameworks) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # How to accelerate your app with Execution Events - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/guides/execution-events#content-area) Set up Execution Events ----------------------- Configure your Monad node to enable execution events Consume Events in Rust ---------------------- Build a Rust application to read execution events [How to index every WMON transfer using QuickNode Streams\ \ Previous](https://docs.monad.xyz/guides/indexers/quicknode-streams) [Set up Execution Events\ \ Next](https://docs.monad.xyz/guides/execution-events/setup) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # How to index every WMON transfer using QuickNode Streams - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/guides/indexers/quicknode-streams#content-area) In this guide, you will learn how to use QuickNode Streams to index every [WMON](https://testnet.monadvision.com/token/0xFb8bf4c1CC7a94c73D209a149eA2AbEa852BC541) transfer, including internal transactions, on Monad Testnet. [​](https://docs.monad.xyz/guides/indexers/quicknode-streams#what-is-quicknode-streams) What is QuickNode Streams? --------------------------------------------------------------------------------------------------------------------- [QuickNode Streams](https://www.quicknode.com/docs/streams/getting-started) is a web3 data streaming solution supporting real-time and historical Monad data that offers: * **Reliable Data Delivery** - Exactly-once, guaranteed delivery, seamlessly integrating with your data lake. Streams ensures every block, receipt, or trace is delivered exactly-once in the order of dataset finality, preventing issues like corrupt or missing data * **Real-Time Data Consistency** - Consistent, live data streaming * **Efficient Historical Data Handling** - Configurable date ranges and destinations for streamlined historical data management * **Easy Integration** - Simple setup through a user-friendly interface * **Transparent User Experience** - Clear logging, metrics, and usage tracking [​](https://docs.monad.xyz/guides/indexers/quicknode-streams#setup-guide) Setup Guide ---------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/guides/indexers/quicknode-streams#1-initial-setup) 1\. Initial setup 1. Sign up for [QuickNode](https://dashboard.quicknode.com/?prompt=signup) and log into your dashboard. 2. Click on “Streams” in the left sidebar. ![QuickNode Dashboard](https://mintcdn.com/monadfoundation-40611fb6/c3ZcPFY7YVeS_v57/static/img/guides/indexers/quicknode-streams/1.png?w=2500&fit=max&auto=format&n=c3ZcPFY7YVeS_v57&q=85&s=a309be943f4af7222396747fcf162cf8) 3. Click on “Create Stream”. ![Create Stream Button](https://mintcdn.com/monadfoundation-40611fb6/5Mt9_Scj9fq4fC68/static/img/guides/indexers/quicknode-streams/2.png?w=2500&fit=max&auto=format&n=5Mt9_Scj9fq4fC68&q=85&s=7e0b5f621c9205009d9b6f7a8083e68a) ### [​](https://docs.monad.xyz/guides/indexers/quicknode-streams#2-configure-stream-range) 2\. Configure Stream range 1. Give your stream a name. In this example we will name it `monad-quicknode-stream`. 2. In the “Network” section, select `Monad` from the dropdown. 3. In the “Stream Start” section you can choose to start the stream from the latest block or from a specific block number. ![Stream Configuration](https://mintcdn.com/monadfoundation-40611fb6/5Mt9_Scj9fq4fC68/static/img/guides/indexers/quicknode-streams/3.png?w=2500&fit=max&auto=format&n=5Mt9_Scj9fq4fC68&q=85&s=09db2ddea1b0eec4453feeb70b618bb9) 4. In the “Stream End” section you can choose to end the stream until manually paused or at a specific block number. 5. In the “Latest block delay” section, you can set a block number as a delay in receiving data. For this guide we will receive data as soon as it is available. For example: If the block delay is `3`, you will receive data only when there is **new data available** for `3` blocks including latest block, this helps in case there is a reorg. 6. In the “Restream on reorg” section you can decide if you would like to get updated data restreamed in case of a reorg. For this guide we will keep this off. 7. Once done click “Next”. ![Additional Settings](https://mintcdn.com/monadfoundation-40611fb6/5Mt9_Scj9fq4fC68/static/img/guides/indexers/quicknode-streams/4.png?w=2500&fit=max&auto=format&n=5Mt9_Scj9fq4fC68&q=85&s=c545f43eef86f68dab6509322617b9e1) ### [​](https://docs.monad.xyz/guides/indexers/quicknode-streams#3-set-up-dataset) 3\. Set up dataset 1. In the “Dataset” dropdown you can select the dataset of your choice according to the use case. For this guide we will select `Block with Receipts` since we want to filter logs with events emitted by WMON contract. * Optional: Enable “Batch messages” to receive multiple blocks in a single message. This can be useful when the stream is not starting from the latest block. ![Dataset Selection](https://mintcdn.com/monadfoundation-40611fb6/5Mt9_Scj9fq4fC68/static/img/guides/indexers/quicknode-streams/5.png?w=2500&fit=max&auto=format&n=5Mt9_Scj9fq4fC68&q=85&s=1cb98913eb76b3fabf23e7b3b74fbc9c) 2. Feel free to test it out by entering a block number and clicking “Fetch payload”. ![Raw Payload Example](https://mintcdn.com/monadfoundation-40611fb6/5Mt9_Scj9fq4fC68/static/img/guides/indexers/quicknode-streams/6.png?w=2500&fit=max&auto=format&n=5Mt9_Scj9fq4fC68&q=85&s=b7d0b19af97a3c660f042fb1c4080b43) ### [​](https://docs.monad.xyz/guides/indexers/quicknode-streams#4-create-wmon-transfer-filter) 4\. Create WMON Transfer filter 1. In the “Modify the stream payload” section, you can define filters by clicking **“Customize your payload”**. For this guide, we will filter to only retrieve receipts involving WMON transfers. ![modify stream image](https://mintcdn.com/monadfoundation-40611fb6/5Mt9_Scj9fq4fC68/static/img/guides/indexers/quicknode-streams/7.png?w=2500&fit=max&auto=format&n=5Mt9_Scj9fq4fC68&q=85&s=cd66138c4242f4284c557451dfd0c7be) 2. QuickNode has a set of filter templates. Select the **Decoded ERC20 transfers** template: ![image for filter](https://mintcdn.com/monadfoundation-40611fb6/5Mt9_Scj9fq4fC68/static/img/guides/indexers/quicknode-streams/8.png?w=2500&fit=max&auto=format&n=5Mt9_Scj9fq4fC68&q=85&s=2f0355ba6dd768492c6aa9028ec3c3eb) 3. The editor will appear: ![image of filter editor](https://mintcdn.com/monadfoundation-40611fb6/5Mt9_Scj9fq4fC68/static/img/guides/indexers/quicknode-streams/9.png?w=2500&fit=max&auto=format&n=5Mt9_Scj9fq4fC68&q=85&s=f25abcfc4bcfddec5e46b04890b7fb2c) The current filter allows all ERC20 transfers through. Replace the filter code with: function main(stream) { const erc20Abi = `[{\ "anonymous": false,\ "inputs": [\ {"indexed": true, "type": "address", "name": "from"},\ {"indexed": true, "type": "address", "name": "to"},\ {"indexed": false, "type": "uint256", "name": "value"}\ ],\ "name": "Transfer",\ "type": "event"\ }]`; const data = stream.data ? stream.data : stream; // Decodes logs from the receipts that match the Transfer event ABI var result = decodeEVMReceipts(data[0].receipts, [erc20Abi]); // Filter for receipts with decoded logs result = result.filter(receipt => { // Check if there are any ERC20 transfers if(receipt.decodedLogs) { // Check if there are any WMON transfers receipt.decodedLogs = receipt.decodedLogs.filter(log => log.address == "0xFb8bf4c1CC7a94c73D209a149eA2AbEa852BC541"); // Return receipt if there logs which indicate a WMON transfer. return receipt.decodedLogs.length > 0; } // Return nothing if there are no ERC20 transfers. return false; }); return { result }; } 4. Test the filter with “Run test” ![run test image](https://mintcdn.com/monadfoundation-40611fb6/c3ZcPFY7YVeS_v57/static/img/guides/indexers/quicknode-streams/10.png?w=2500&fit=max&auto=format&n=c3ZcPFY7YVeS_v57&q=85&s=393c77e484aaeee54d86a756aac6ea10) 5. “Save & close” to save the filter. ![save & close image](https://mintcdn.com/monadfoundation-40611fb6/c3ZcPFY7YVeS_v57/static/img/guides/indexers/quicknode-streams/11.png?w=2500&fit=max&auto=format&n=c3ZcPFY7YVeS_v57&q=85&s=4c4596c1a26dec948f6f4d35134e5aa9) 6. Click “Next” ### [​](https://docs.monad.xyz/guides/indexers/quicknode-streams#5-set-up-stream-destination) 5\. Set up Stream destination For this guide we will keep the stream destination simple and use `Webhook` as the “Destination Type”. 1. Let’s use a site like [Svix Play](https://www.svix.com/play/) to quickly get a webhook and test the stream. ![svix play image](https://mintcdn.com/monadfoundation-40611fb6/c3ZcPFY7YVeS_v57/static/img/guides/indexers/quicknode-streams/12.png?w=2500&fit=max&auto=format&n=c3ZcPFY7YVeS_v57&q=85&s=24466b2fa429ffe4f690da913a014ce1) 2. Copy the webhook url from Svix Play: ![svix play copy url image](https://mintcdn.com/monadfoundation-40611fb6/c3ZcPFY7YVeS_v57/static/img/guides/indexers/quicknode-streams/13.png?w=2500&fit=max&auto=format&n=c3ZcPFY7YVeS_v57&q=85&s=56d7559e1d086abc751cba8182af7196) 3. In QuickNode: * Select `Webhook` as destination type * Paste your webhook URL * We can keep the rest of the settings as default ![webhook dropdown image](https://mintcdn.com/monadfoundation-40611fb6/c3ZcPFY7YVeS_v57/static/img/guides/indexers/quicknode-streams/14.png?w=2500&fit=max&auto=format&n=c3ZcPFY7YVeS_v57&q=85&s=88ddc25fca4faf52fece0e0bd91f9d68) 4. Click on “Check Connection” to test the webhook url. Check if you received the “PING” message in the Svix Play dashboard. ![check connection image](https://mintcdn.com/monadfoundation-40611fb6/c3ZcPFY7YVeS_v57/static/img/guides/indexers/quicknode-streams/15.png?w=2500&fit=max&auto=format&n=c3ZcPFY7YVeS_v57&q=85&s=f13a8f431769aec0c072c6404a5fca1d) ![ping message image](https://mintcdn.com/monadfoundation-40611fb6/c3ZcPFY7YVeS_v57/static/img/guides/indexers/quicknode-streams/16.png?w=2500&fit=max&auto=format&n=c3ZcPFY7YVeS_v57&q=85&s=d55545590ad81f4fdc6bbda61cf0f24b) 5. Click “Send Payload” to send a test payload to the webhook. ![add send payload image](https://mintcdn.com/monadfoundation-40611fb6/5Mt9_Scj9fq4fC68/static/img/guides/indexers/quicknode-streams/17.png?w=2500&fit=max&auto=format&n=5Mt9_Scj9fq4fC68&q=85&s=ca7780f6e13a2dfecc070db399d74903) ![svix payload image](https://mintcdn.com/monadfoundation-40611fb6/5Mt9_Scj9fq4fC68/static/img/guides/indexers/quicknode-streams/18.png?w=2500&fit=max&auto=format&n=5Mt9_Scj9fq4fC68&q=85&s=b7bb6f8302c255ff0f6ca6350a294a15) 6. Finally click “Create a Stream” to create the stream. ![create stream image](https://mintcdn.com/monadfoundation-40611fb6/5Mt9_Scj9fq4fC68/static/img/guides/indexers/quicknode-streams/19.png?w=2500&fit=max&auto=format&n=5Mt9_Scj9fq4fC68&q=85&s=37d28f6a07d9fd909bdf9f8bf419bf15) ### [​](https://docs.monad.xyz/guides/indexers/quicknode-streams#6-launch-and-monitor) 6\. Launch and Monitor You should now be able to see the stream delivering the messages to the webhook! ![stream delivering image](https://mintcdn.com/monadfoundation-40611fb6/5Mt9_Scj9fq4fC68/static/img/guides/indexers/quicknode-streams/20.png?w=2500&fit=max&auto=format&n=5Mt9_Scj9fq4fC68&q=85&s=3cd600dff981b535741def293dc0b5e9) ![svix streaming receiving message video](https://mintcdn.com/monadfoundation-40611fb6/c3ZcPFY7YVeS_v57/static/img/guides/indexers/quicknode-streams/1.gif?s=77b30c3b9d9d3bdc444270b3b7eebeed) You can pause the stream by clicking the switch in the top right corner. ![pause switch image](https://mintcdn.com/monadfoundation-40611fb6/5Mt9_Scj9fq4fC68/static/img/guides/indexers/quicknode-streams/21.png?w=2500&fit=max&auto=format&n=5Mt9_Scj9fq4fC68&q=85&s=af03c9e3a15f2a7d876b9e2e584d2d0c) [​](https://docs.monad.xyz/guides/indexers/quicknode-streams#next-steps) Next Steps -------------------------------------------------------------------------------------- * Monitor your stream’s performance in the QuickNode dashboard * Adjust filter parameters as needed * Connect to your production webhook endpoint when ready Your stream will now track all WMON transfers until manually paused or until reaching your specified end block. [How to query token data with Envio HyperSync\ \ Previous](https://docs.monad.xyz/guides/indexers/token-snapshot-hypersync) [How to accelerate your app with Execution Events\ \ Next](https://docs.monad.xyz/guides/execution-events) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Monad Foundry - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/tooling-and-infra/toolkits/monad-foundry#content-area) [Monad Foundry](https://github.com/category-labs/foundry/tree/monad) is a custom fork of [Foundry](https://book.getfoundry.sh/) that integrates Monad features directly into the familiar Foundry developer workflow. It uses [monad-revm](https://github.com/category-labs/monad-revm) , to ensure that `forge test`, `forge script`, `cast`, `anvil`, and `chisel` all execute with Monad’s gas model, opcode pricing, and precompile behavior — so your local development environment matches Monad’s on-chain behavior. For general Foundry usage (writing tests, scripts, deployments, configuration, cheatcodes), refer to the [Foundry Docs](https://book.getfoundry.sh/) . [​](https://docs.monad.xyz/tooling-and-infra/toolkits/monad-foundry#installation) Installation ------------------------------------------------------------------------------------------------- Install the Monad Foundry installer: curl -L https://foundry.category.xyz | bash Then install Monad Foundry: foundryup --network monad This installs all four binaries — `forge`, `cast`, `anvil`, and `chisel` — with Monad support. The same installer also supports standard Foundry. Running `foundryup` without `--network monad` will install the official upstream Foundry release, so you can use both side by side. [​](https://docs.monad.xyz/tooling-and-infra/toolkits/monad-foundry#features) Features ----------------------------------------------------------------------------------------- | Feature | Description | | --- | --- | | **Monad EVM Execution** | Monad gas model, 128KB code size limit, no gas refunds, repriced precompiles | | **Staking Precompile** | All staking view functions work locally at address `0x1000` | | **Human-Readable Traces** | Staking calls decoded with function names; address labeled “Staking” in traces | | **Anvil with Monad** | `anvil --monad` for a local Monad EVM node | | **Contract Verification** | `forge verify-contract` uses Monad EVM for bytecode comparison | [​](https://docs.monad.xyz/tooling-and-infra/toolkits/monad-foundry#monad-evm-execution) Monad EVM Execution --------------------------------------------------------------------------------------------------------------- `forge test` and `forge script` execute with Monad EVM by default. The following differences from Ethereum are applied automatically: * **Gas charging**: Gas is charged based on `gas_limit`, not `gas_used`. There are no gas refunds. See [Gas Pricing](https://docs.monad.xyz/developer-essentials/gas-pricing) for details. * **Contract size**: Max contract size is 128KB * **Initcode size**: Max initcode size is 256KB * **Precompile gas costs**: See [Opcode Pricing](https://docs.monad.xyz/developer-essentials/opcode-pricing) . * **No blob transactions**: EIP-4844 (type 3) transactions are not supported. For the complete list of differences, see [Differences between Monad and Ethereum](https://docs.monad.xyz/developer-essentials/differences) . [​](https://docs.monad.xyz/tooling-and-infra/toolkits/monad-foundry#staking-precompile-support) Staking Precompile Support ----------------------------------------------------------------------------------------------------------------------------- All [staking precompile](https://docs.monad.xyz/reference/staking/api) view functions work in `forge test` at address `0x1000`: ### [​](https://docs.monad.xyz/tooling-and-infra/toolkits/monad-foundry#trace-decoding) Trace Decoding When running tests with verbose output (`forge test -vvvv`), staking calls are decoded with human-readable function names and parameters. The address `0x1000` is labeled as **“Staking”** in trace output. All staking state-changing functions (`addValidator`, `delegate`, `undelegate`, `withdraw`, `compound`, `claimRewards`, `changeCommission`, `externalReward`) and events (`ValidatorRewarded`, `Delegate`, `Undelegate`, `Withdraw`, `ClaimRewards`, `CommissionChanged`, `EpochChanged`, `ValidatorStatusChanged`) are decoded in traces. Example trace output: ├─ [16200] Staking::getEpoch() │ └─ ← [Return] 42, false [​](https://docs.monad.xyz/tooling-and-infra/toolkits/monad-foundry#anvil-with-monad-evm) Anvil with Monad EVM ----------------------------------------------------------------------------------------------------------------- Use `anvil --monad` to run a local development node with Monad EVM: # Local Monad node anvil --monad # Fork Monad Testnet anvil --fork-url https://testnet-rpc.monad.xyz # Fork Monad Mainnet anvil --fork-url https://rpc.monad.xyz Monad EVM activates automatically when forking a Monad RPC endpoint (detected via chain ID), so you don’t need the `--monad` flag when forking. [​](https://docs.monad.xyz/tooling-and-infra/toolkits/monad-foundry#cast-&-chisel) Cast & Chisel --------------------------------------------------------------------------------------------------- `cast` and `chisel` execute with Monad EVM by default. All standard commands work the same as upstream Foundry. [​](https://docs.monad.xyz/tooling-and-infra/toolkits/monad-foundry#ci-integration) CI Integration ----------------------------------------------------------------------------------------------------- Use the [Monad Foundry GitHub Action](https://github.com/category-labs/foundry-toolchain) to install Monad Foundry in your CI workflows: - name: Install Monad Foundry uses: category-labs/foundry-toolchain@v1 This installs the latest stable Monad Foundry (`stable-monad`) by default. You can also pin a specific version: - name: Install Monad Foundry uses: category-labs/foundry-toolchain@v1 with: version: v1.5.0-monad.0.1.0 Full workflow example: name: CI on: [push, pull_request] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 with: submodules: recursive - name: Install Monad Foundry uses: category-labs/foundry-toolchain@v1 - name: Run tests run: forge test -vvv The action supports caching and works on all platforms (Linux, macOS, Windows). See the [foundry-toolchain repo](https://github.com/category-labs/foundry-toolchain) for all available options. [​](https://docs.monad.xyz/tooling-and-infra/toolkits/monad-foundry#releases-&-versioning) Releases & Versioning ------------------------------------------------------------------------------------------------------------------- Monad Foundry uses a `v{upstream}-monad.{monad_version}` versioning scheme. For example, `v1.5.0-monad.0.1.0` is based on upstream Foundry v1.5.0 with Monad fork version 0.1.0. See the [GitHub Releases](https://github.com/category-labs/foundry/releases) for full release history. [Toolkits\ \ Previous](https://docs.monad.xyz/tooling-and-infra/toolkits) [Hardhat\ \ Next](https://docs.monad.xyz/tooling-and-infra/toolkits/hardhat) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Deploy a Contract - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/guides/deploy-smart-contract#content-area) Foundry ------- Deploy a smart contract on Monad using Foundry Hardhat ------- Deploy a smart contract on Monad using Hardhat Remix ----- Deploy a smart contract on Monad using Remix [Add Monad Testnet to Wallet\ \ Previous](https://docs.monad.xyz/guides/add-monad-to-wallet/testnet) [Deploy a smart contract on Monad using Monad Foundry\ \ Next](https://docs.monad.xyz/guides/deploy-smart-contract/foundry) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Release notes - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/execution-events/release-notes#content-area) ### [​](https://docs.monad.xyz/execution-events/release-notes#v1-1) v1.1 * The execution events Rust SDK was moved from the [consensus repository](https://github.com/category-labs/monad-bft) to the [execution repository](https://github.com/category-labs/monad) * The `eventcap` program was renamed to `monad-event-cli` * General improvements to the documentation ### [​](https://docs.monad.xyz/execution-events/release-notes#v1-0) v1.0 Initial release of the execution event SDK [Execution Events\ \ Previous](https://docs.monad.xyz/execution-events) [Getting started\ \ Next](https://docs.monad.xyz/execution-events/getting-started) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # How to Consume Execution Events in Rust - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/guides/execution-events/consume-rust#content-area) [​](https://docs.monad.xyz/guides/execution-events/consume-rust#how-to-consume-execution-events-in-rust-a-basic-example) How to Consume Execution Events in Rust: A Basic Example ==================================================================================================================================================================================== This guide walks through building a minimal Rust application that reads execution events from a live Monad node. By the end of this guide, you’ll have a working event consumer that prints each EVM action as it happens. [​](https://docs.monad.xyz/guides/execution-events/consume-rust#prerequisites) Prerequisites ----------------------------------------------------------------------------------------------- This guide assumes you have: * A running Monad node with execution events enabled ([setup guide](https://docs.monad.xyz/guides/execution-events/setup) ) [​](https://docs.monad.xyz/guides/execution-events/consume-rust#project-setup) Project Setup ----------------------------------------------------------------------------------------------- Here is the [repo with the code](https://github.com/portdeveloper/simple-execution-events) . Create a new Rust project: cargo new --bin exec-events-demo cd exec-events-demo Replace `Cargo.toml` with: [package] name = "exec-events-demo" version = "0.1.0" edition = "2021" [dependencies] monad-exec-events = { git = "https://github.com/category-labs/monad-bft", tag = "release/exec-events-sdk-v1.0" } monad-event-ring = { git = "https://github.com/category-labs/monad-bft", tag = "release/exec-events-sdk-v1.0" } [​](https://docs.monad.xyz/guides/execution-events/consume-rust#the-code) The Code ------------------------------------------------------------------------------------- Replace `src/main.rs` with: src/main.rs use std::time::Duration; use monad_event_ring::{DecodedEventRing, EventNextResult, EventPayloadResult, EventRingPath}; use monad_exec_events::{ExecEvent, ExecEventReaderExt, ExecEventRing, ExecEventType}; /// Default path for the execution event ring const EVENT_RING_PATH: &str = "/var/lib/hugetlbfs/user/monad/pagesize-2MB/event-rings/monad-exec-events"; fn main() { // Resolve the event ring path (full path bypasses hugetlbfs lookup) let event_ring_path = EventRingPath::resolve(EVENT_RING_PATH).expect("Failed to resolve path"); // Open the live event ring let ring = ExecEventRing::new(&event_ring_path).expect("Failed to open event ring"); println!("Connected to event ring"); println!("Waiting for events...\n"); // Create a reader and rewind to the start of the current block let mut reader = ring.create_reader(); reader.consensus_prev(Some(ExecEventType::BlockStart)); loop { match reader.next_descriptor() { EventNextResult::Ready(event) => { let seqno = event.info().seqno; // Try to read the event payload match event.try_read() { EventPayloadResult::Ready(exec_event) => { print_event(&exec_event, seqno); } EventPayloadResult::Expired => { eprintln!("[{}] Payload expired!", seqno); reader.reset(); } } } EventNextResult::Gap => { eprintln!("Warning: event gap occurred (reader too slow)"); reader.reset(); } EventNextResult::NotReady => { // No events available, wait briefly std::thread::sleep(Duration::from_millis(10)); } } } } fn print_event(event: &ExecEvent, seqno: u64) { match event { ExecEvent::BlockStart(block) => { println!( "[{}] BLOCK_START: number={}", seqno, block.block_tag.block_number ); } ExecEvent::BlockEnd(_) => { println!("[{}] BLOCK_END", seqno); } ExecEvent::TxnHeaderStart { txn_index, .. } => { println!("[{}] TXN_START: index={}", seqno, txn_index); } ExecEvent::TxnEvmOutput { txn_index, output } => { println!( "[{}] TXN_OUTPUT: index={} gas_used={}", seqno, txn_index, output.receipt.gas_used ); } ExecEvent::TxnLog { txn_index, txn_log, .. } => { println!( "[{}] LOG: txn={} topics={}", seqno, txn_index, txn_log.topic_count ); } ExecEvent::TxnEnd => { println!("[{}] TXN_END", seqno); } // Silently ignore other events (call frames, storage access, etc.) _ => {} } } [​](https://docs.monad.xyz/guides/execution-events/consume-rust#build-and-run) Build and Run ----------------------------------------------------------------------------------------------- cargo build --release ./target/release/exec-events-demo [​](https://docs.monad.xyz/guides/execution-events/consume-rust#expected-output) Expected Output --------------------------------------------------------------------------------------------------- You’ll see a stream of events as your node processes transactions: Connected to event ring Waiting for events... [508183802] BLOCK_START: number=45199825 [508183811] TXN_START: index=0 [508183822] TXN_OUTPUT: index=0 gas_used=0 [508183823] LOG: txn=0 topics=3 [508183838] TXN_END [508183942] BLOCK_END [​](https://docs.monad.xyz/guides/execution-events/consume-rust#key-concepts) Key Concepts --------------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/guides/execution-events/consume-rust#event-ring) Event Ring The event ring is a shared memory buffer where the execution daemon writes events. Multiple readers can consume from it simultaneously, each maintaining their own position. ### [​](https://docs.monad.xyz/guides/execution-events/consume-rust#eventnextresult) EventNextResult * **Ready**: An event is available to process * **NotReady**: No new events yet (daemon hasn’t written any) * **Gap**: Reader fell behind and events were overwritten - call `reset()` to recover ### [​](https://docs.monad.xyz/guides/execution-events/consume-rust#event-types) Event Types Common events you’ll see: * `BlockStart` / `BlockEnd` - Block boundaries * `TxnHeaderStart` / `TxnEnd` - Transaction boundaries * `TxnEvmOutput` - Transaction execution result (contains receipt with gas\_used) * `TxnLog` - EVM log emission (Solidity events) * `AccountAccess` - Account touched during execution * `StorageAccess` - Contract storage read/write [​](https://docs.monad.xyz/guides/execution-events/consume-rust#next-steps) Next Steps ----------------------------------------------------------------------------------------- * See the full [eventwatch.rs](https://github.com/category-labs/monad-bft/blob/release/exec-events-sdk-v1.0/monad-exec-events/examples/eventwatch.rs) example for production patterns (timestamps, timeout detection, CLI args) * Read the [Rust API docs](https://docs.monad.xyz/execution-events/rust-api) for detailed type information * Explore the [event ring internals](https://docs.monad.xyz/execution-events/event-ring) to understand the shared memory protocol [Set up Execution Events\ \ Previous](https://docs.monad.xyz/guides/execution-events/setup) [EVM Resources\ \ Next](https://docs.monad.xyz/guides/evm-resources) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # How to build a transfer notification bot with Envio HyperIndex - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/guides/indexers/tg-bot-using-envio#content-area) In this guide, you will learn how to use [Envio](https://envio.dev/) HyperIndex to create a Telegram bot that sends notifications whenever WMON tokens are transferred on the Monad Testnet. We’ll walk through setting up both the indexer and the Telegram bot. Envio HyperIndex is an open development framework for building blockchain application backends. It offers real-time indexing, automatic indexer generation from contract addresses, and triggers for external API calls. [​](https://docs.monad.xyz/guides/indexers/tg-bot-using-envio#prerequisites) Prerequisites --------------------------------------------------------------------------------------------- You’ll need the following installed: * Node.js v18 or newer * pnpm v8 or newer * Docker Desktop (required for running the Envio indexer locally) [​](https://docs.monad.xyz/guides/indexers/tg-bot-using-envio#setting-up-the-project) Setting up the project --------------------------------------------------------------------------------------------------------------- First, create and enter a new directory: mkdir envio-mon && cd envio-mon ### [​](https://docs.monad.xyz/guides/indexers/tg-bot-using-envio#get-the-contract-abi) Get the contract ABI 1. Create an `abi.json` file: touch abi.json 2. Copy the [WrappedMonad](https://testnet.monadvision.com/token/0xFb8bf4c1CC7a94c73D209a149eA2AbEa852BC541?tab=Contract) ABI from the explorer ![image of explorer](https://mintcdn.com/monadfoundation-40611fb6/5Mt9_Scj9fq4fC68/static/img/guides/indexers/tg-bot-using-envio/1.png?w=2500&fit=max&auto=format&n=5Mt9_Scj9fq4fC68&q=85&s=f35e8c11d1e1e0569b305a32dae1aebb) 3. Paste the ABI into your `abi.json` file ### [​](https://docs.monad.xyz/guides/indexers/tg-bot-using-envio#initialize-the-project) Initialize the project Run the initialization command: pnpx envio init Follow the prompts: 1. Press Enter when asked for a folder name (to use current directory) 2. Select `TypeScript` as your language 3. Choose `Evm` as the blockchain ecosystem 4. Select `Contract Import` for initialization 5. Choose `Local ABI` as the import method 6. Enter `./abi.json` as the path to your ABI file 7. Select only the `Transfer` event to index 8. Choose `` and input `10143` (Monad Testnet chain ID) 9. Enter `WrappedMonad` as the contract name 10. Input the contract address: `0xFb8bf4c1CC7a94c73D209a149eA2AbEa852BC541` 11. Select `I'm finished` since we’re only indexing one contract 12. Choose whether to create or add an existing API token. If you choose to create a new token, you’ll be taken to a page that looks like this: ![new API token view](https://mintcdn.com/monadfoundation-40611fb6/5Mt9_Scj9fq4fC68/static/img/guides/indexers/tg-bot-using-envio/2.png?w=2500&fit=max&auto=format&n=5Mt9_Scj9fq4fC68&q=85&s=55f396dfb6fbb83c9485c7b02eea9d4c) Once the project is initialized, you should see the following project structure in your project directory. ![envio dashboard](https://mintcdn.com/monadfoundation-40611fb6/5Mt9_Scj9fq4fC68/static/img/guides/indexers/tg-bot-using-envio/3.png?w=2500&fit=max&auto=format&n=5Mt9_Scj9fq4fC68&q=85&s=ea14c2be6f87fda3db7ccc7263a82180) Add the following code to `config.yaml` file, to make transaction hash available in event handler: config.yaml # default config... field_selection: transaction_fields: - hash _More details about the `field_selection` config [here](https://docs.envio.dev/docs/HyperIndex/configuration-file#field-selection) _ [​](https://docs.monad.xyz/guides/indexers/tg-bot-using-envio#starting-the-indexer) Starting the indexer ----------------------------------------------------------------------------------------------------------- Start Docker Desktop. To start the indexer run the following command in the project directory: pnpx envio dev You should see something similar to the below image in your terminal; this means that the indexer is syncing and will eventually reach the tip of the chain. ![envio indexer syncing](https://mintcdn.com/monadfoundation-40611fb6/5Mt9_Scj9fq4fC68/static/img/guides/indexers/tg-bot-using-envio/4.png?w=2500&fit=max&auto=format&n=5Mt9_Scj9fq4fC68&q=85&s=fead9d7b92addfed711ba39e60461e8c) You will also see this page open in your browser automatically, the password is `testing`. ![hasura local page](https://mintcdn.com/monadfoundation-40611fb6/5Mt9_Scj9fq4fC68/static/img/guides/indexers/tg-bot-using-envio/5.png?w=2500&fit=max&auto=format&n=5Mt9_Scj9fq4fC68&q=85&s=139b0767abc1099429a0cc44452295c0) We can use this interface to query the indexer using GraphQL. Results will depend on the sync progress: ![query interface](https://mintcdn.com/monadfoundation-40611fb6/5Mt9_Scj9fq4fC68/static/img/guides/indexers/tg-bot-using-envio/6.png?w=2500&fit=max&auto=format&n=5Mt9_Scj9fq4fC68&q=85&s=4bf0caeb5b7383047be5d22ebdb00963) Currently, the indexer is catching up to the tip of the chain. Once syncing is complete the indexer will be able to identify latest WMON transfers. We can shut down the indexer for now, so we can proceed with Telegram integration. [​](https://docs.monad.xyz/guides/indexers/tg-bot-using-envio#creating-the-telegram-bot) Creating the Telegram bot --------------------------------------------------------------------------------------------------------------------- 1. Visit [BotFather](https://t.me/botfather) to create your bot and get an API token 2. Add these environment variables to your `.env` file: ENVIO_BOT_TOKEN= ENVIO_TELEGRAM_CHAT_ID= To get your chat ID: 1. Create a Telegram group and add your bot 2. Send `/start` to the bot: `@YourBot /start` 3. Visit `https://api.telegram.org/bot/getUpdates` 4. Look for the channel chat ID (it should start with ”-”) If you don’t see the chat ID, try removing and re-adding the bot to the group. The Telegram bot is now ready. [​](https://docs.monad.xyz/guides/indexers/tg-bot-using-envio#integrating-telegram-api-to-hyperindex-event-handler) Integrating Telegram API to HyperIndex Event Handler --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Create a folder `libs` inside `src` folder in the project directory, create a file inside it `telegram.ts` and add the following code src/libs/telegram.ts import axios from "axios"; import { CHAT_ID, BOT_TOKEN } from "../constants"; export const sendMessageToTelegram = async (message: string): Promise => { try { const apiUrl = `https://api.telegram.org/bot${BOT_TOKEN}/sendMessage`; await axios.post(apiUrl, { chat_id: CHAT_ID, text: message, parse_mode: "HTML", }); } catch (error) { console.error("Error sending message:", error); } }; You will come across some errors, let’s fix them. Install `axios` package pnpm i axios Create a file in `src` folder called `constants.ts` and add the following code: src/constants.ts export const EXPLORER_URL_MONAD = "https://testnet.monadvision.com/"; // Threshold for WMON transfer amount above which the bot sends a notification export const THRESHOLD_WEI: string = process.env.ENVIO_THRESHOLD_WEI ?? "1000000000000000000"; // in wei export const BOT_TOKEN = process.env.ENVIO_BOT_TOKEN; // Telegram bot token export const CHAT_ID = process.env.ENVIO_TELEGRAM_CHAT_ID; // WMON Transfers Notification Channel ID // Function to get explorer url for the provided address export const explorerUrlAddress = (address: string) => EXPLORER_URL_MONAD + "address/" + address; // Function to get explorer url for the provided transaction hash export const explorerUrlTx = (txHash: string) => EXPLORER_URL_MONAD + "tx/" + txHash; We can now edit the `EventHandlers.ts` in `src` folder, to add the code for sending the telegram message: src/EventHandlers.ts import { WrappedMonad, } from "generated"; import { isIndexingAtHead, weiToEth } from "./libs/helpers"; import { sendMessageToTelegram } from "./libs/telegram"; import { THRESHOLD_WEI, explorerUrlAddress, explorerUrlTx } from "./constants"; // Other event handlers can be removed... WrappedMonad.Transfer.handler(async ({ event, context }) => { const from_address = event.params.src; const to_address = event.params.dst; if (isIndexingAtHead(event.block.timestamp) && event.params.wad >= BigInt(THRESHOLD_WEI)) { // Only send a message when the indexer is indexing event from the time it was started and not historical transfers, and only message if the transfer amount is greater than or equal to THRESHOLD_WEI. // Example message // WMON Transfer ALERT: A new transfer has been made by 0x65C3564f1DD63eA81C11D8FE9a93F8FFb5615233 to 0xBA5Cf1c0c1238F60832618Ec49FC81e8C7C0CF01 for 2.0000 WMON! 🔥 - View on Explorer const msg = `WMON Transfer ALERT: A new transfer has been made by ${from_address} to ${to_address} for ${weiToEth(event.params.wad)} WMON! 🔥 - View on Explorer`; await sendMessageToTelegram(msg); } }); Let us now fix the import error. Create a file called `helpers.ts` in `src/libs` folder, paste the following code in it: src/libs/helpers.ts // Used to ensure notifications are only sent while indexing at the head and not historical sync const INDEXER_START_TIMESTAMP = Math.floor(new Date().getTime() / 1000); export const isIndexingAtHead = (timestamp: number): boolean => { return timestamp >= INDEXER_START_TIMESTAMP; } // Convert wei to ether for human readability export const weiToEth = (bigIntNumber: bigint): string => { // Convert BigInt to string const numberString = bigIntNumber.toString(); const decimalPointsInEth = 18; // Extract integer part and decimal part const integerPart = numberString.substring( 0, numberString.length - decimalPointsInEth ); const decimalPart = numberString.slice(-decimalPointsInEth); // Insert decimal point const decimalString = (integerPart ? integerPart : "0") + "." + decimalPart.padStart(decimalPointsInEth, "0"); // Add negative sign if necessary return decimalString.slice(0, -14); }; That’s it! We can now run the indexer, and the telegram bot will start sending messages in the telegram channel when the indexer detects a WMON transfer! ![example bot message](https://mintcdn.com/monadfoundation-40611fb6/5Mt9_Scj9fq4fC68/static/img/guides/indexers/tg-bot-using-envio/9.png?w=2500&fit=max&auto=format&n=5Mt9_Scj9fq4fC68&q=85&s=64eed1204aca6207bcea7146aa2e7442) _Note: Screenshot was taken before message format was changed. The message will be slightly different if you followed the guide._ You may not immediately start seeing messages because the indexer take some time to catch up to the tip of the the recent blocks.The bot will only send notifications for transfers when the indexer detects a WMON transfer in finalized blocks, with timestamp greater than or equal to the indexer start time. [How to index token transfers with GhostGraph\ \ Previous](https://docs.monad.xyz/guides/indexers/ghost) [How to query token data with Envio HyperSync\ \ Next](https://docs.monad.xyz/guides/indexers/token-snapshot-hypersync) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Deploy a smart contract on Monad using Monad Foundry - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/guides/deploy-smart-contract/foundry#content-area) [Monad Foundry](https://docs.monad.xyz/tooling-and-infra/toolkits/monad-foundry) is a custom fork of [Foundry](https://book.getfoundry.sh/) with Monad-native EVM execution, staking precompile support, and human-readable trace decoding. [​](https://docs.monad.xyz/guides/deploy-smart-contract/foundry#1-installing-monad-foundry) 1\. Installing Monad Foundry --------------------------------------------------------------------------------------------------------------------------- Install the Monad Foundry installer: curl -L https://foundry.category.xyz | bash Then install the binaries: foundryup --network monad This installs `forge`, `cast`, `anvil`, and `chisel` with Monad support. If you’re on Windows, you’ll need to use WSL, since Foundry currently doesn’t work natively on Windows. Please follow [this link](https://learn.microsoft.com/en-us/windows/wsl/install) to learn more about WSL. [​](https://docs.monad.xyz/guides/deploy-smart-contract/foundry#2-create-a-new-foundry-project) 2\. Create a new foundry project ----------------------------------------------------------------------------------------------------------------------------------- You can use `foundry-monad` template to create a new project._[Foundry-Monad](https://github.com/monad-developers/foundry-monad) is a Foundry template with Monad configuration._ The below command uses `foundry-monad` to create a new foundry project: forge init --template monad-developers/foundry-monad [project_name] Alternatively, you can create a foundry project using the command below: forge init [project_name] [​](https://docs.monad.xyz/guides/deploy-smart-contract/foundry#3-modify-foundry-configuration) 3\. Modify Foundry configuration ----------------------------------------------------------------------------------------------------------------------------------- Update the `foundry.toml` file to add Monad Testnet configuration. foundry.toml [profile.default] src = "src" out = "out" libs = ["lib"] # Monad Testnet Configuration eth-rpc-url = "https://testnet-rpc.monad.xyz" chain_id = 10143 [​](https://docs.monad.xyz/guides/deploy-smart-contract/foundry#4-write-a-smart-contract) 4\. Write a smart contract ----------------------------------------------------------------------------------------------------------------------- You can write your smart contracts under the `src` folder. There is already a `Counter` contract in the project located at `src/Counter.sol`. src/Counter.sol // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; contract Counter { uint256 public number; function setNumber(uint256 newNumber) public { number = newNumber; } function increment() public { number++; } } [​](https://docs.monad.xyz/guides/deploy-smart-contract/foundry#5-compile-the-smart-contract) 5\. Compile the smart contract ------------------------------------------------------------------------------------------------------------------------------- forge compile Compilation process output can be found in the newly created `out` directory, which includes contract ABI and bytecode. [​](https://docs.monad.xyz/guides/deploy-smart-contract/foundry#6-deploy-the-smart-contract) 6\. Deploy the smart contract ----------------------------------------------------------------------------------------------------------------------------- For deploying contracts, we recommend using keystores instead of private keys. ### [​](https://docs.monad.xyz/guides/deploy-smart-contract/foundry#get-testnet-funds) Get testnet funds Deploying smart contracts requires testnet funds. Claim testnet funds via a [faucet](https://testnet.monad.xyz/) . ### [​](https://docs.monad.xyz/guides/deploy-smart-contract/foundry#deploy-smart-contract) Deploy smart contract * Using a Keystore (Recommended) * Using a Private Key (Not Recommended) Using a keystore is much safer than using a private key because keystore encrypts the private key and can later be referenced in any commands that require a private key.Create a new keystore by importing a newly generated private key with the command below. cast wallet import monad-deployer --private-key $(cast wallet new | grep 'Private key:' | awk '{print $3}') Here is what the command above does, step by step: * Generates a new private key * Imports the private key into a keystore file named `monad-deployer` * Prints the address of the newly created wallet to the console After creating the keystore, you can read its address using: cast wallet address --account monad-deployer Provide a password to encrypt the keystore file when prompted and do not forget it.Run the below command to deploy your smart contracts forge create src/Counter.sol:Counter --account monad-deployer --broadcast Use the below command to deploy a smart contract by directly pasting the private key in the terminal. Using a private key is not recommended. You should not be copying and pasting private keys into your terminal. Please use a keystore instead. forge create --private-key src/Counter.sol:Counter --broadcast On successful deployment of the smart contract, the output should be similar to the following: [⠊] Compiling... Deployer: 0xB1aB62fdFC104512F594fCa0EF6ddd93FcEAF67b Deployed to: 0x67329e4dc233512f06c16cF362EC3D44Cdc800e0 Transaction hash: 0xa0a40c299170c9077d321a93ec20c71e91b8aff54dd9fa33f08d6b61f8953ee0 ### [​](https://docs.monad.xyz/guides/deploy-smart-contract/foundry#next-steps) Next Steps Check out [how to verify the deployed smart contract on MonadVision](https://docs.monad.xyz/guides/verify-smart-contract/foundry) . [Deploy a Contract\ \ Previous](https://docs.monad.xyz/guides/deploy-smart-contract) [Deploy a smart contract on Monad using Hardhat\ \ Next](https://docs.monad.xyz/guides/deploy-smart-contract/hardhat) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Embedded Wallets - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/tooling-and-infra/wallet-infra/embedded-wallets#content-area) [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/embedded-wallets#background) Background ---------------------------------------------------------------------------------------------------- Some developers want to “embed” a wallet into their application. Here are a few possible reasons they might want to do this: * to allow users to sign in with email or another social sign-in method * to allow users to take actions within the app without signing a new transaction each time. Generally speaking, embedded wallet services provide this by utilizing advanced cryptographic techniques to shard keys. Some keys are stored user-side while others are stored on the application developer’s server or the embedded wallet provider’s server. This page attempts a toplogy of authentication and key management features over the set of providers supporting Monad. ### [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/embedded-wallets#authentication-features) Authentication Features | Features | Description | | --- | --- | | Passkey sign-in | Authentication with [WebAuthn](https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API)
(passkey) | | Social sign-in | Authentication with social accounts (google, X, etc) | | Email sign-in | Authentication with OTP via email | | SMS sign-in | Authentication with OTP via SMS | ### [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/embedded-wallets#key-management-features) Key Management Features | Features | Description | | --- | --- | | MPC | Multi-party computation | | SSS | Shamir’s Secret Sharing | | TEE | Storage of private keys in a cloud-based Trusted Execution Environment, like AWS Nitro Enclaves | | TSS | Threshold Signature Scheme | | Embedded wallet | A wallet interface local to a website or mobile app, utilizing browser session keys for signing | | Server-delegated actions | Allow app to request permission to sign on the user’s behalf | | Session keys | Scoped keys that grant access only for specific apps, useful for bots/AI agents | [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/embedded-wallets#provider-summary) Provider Summary ---------------------------------------------------------------------------------------------------------------- * Mainnet * Testnet | Provider | Status | Docs | Supported services | Security Method | How to get started | | --- | --- | --- | --- | --- | --- | | [Alchemy](https://www.alchemy.com/smart-wallets) | ✅ | [Docs](https://accountkit.alchemy.com/) | [Embedded wallets](https://accountkit.alchemy.com/react/quickstart)

Auth: [passkey](https://accountkit.alchemy.com/signer/authentication/passkey-signup)
, [social](https://accountkit.alchemy.com/signer/authentication/social-login)
, [email](https://accountkit.alchemy.com/signer/authentication/email-otp)
sign-in | | [Quickstart](https://accountkit.alchemy.com/react/quickstart) | | [Coinbase Developer Platform (CDP)](https://www.coinbase.com/developer-platform/products/embeddedwallets) | ✅ | [Docs](https://docs.cdp.coinbase.com/embedded-wallets/welcome) | [Embedded wallets](https://docs.cdp.coinbase.com/embedded-wallets/welcome)

Auth: [email/social/SMS](https://docs.cdp.coinbase.com/embedded-wallets/authentication-methods) | Device-based secure enclaves | [Quickstart](https://docs.cdp.coinbase.com/embedded-wallets/quickstart) | | [Crossmint](https://www.crossmint.com/) | ✅ | [Docs](https://docs.crossmint.com/) | [Embedded wallets](https://docs.crossmint.com/wallets/overview)
(smart contract wallets with modular signers)
Auth: [device](https://docs.crossmint.com/wallets/concepts/signers#device-signer)
, [passkey](https://docs.crossmint.com/wallets/concepts/signers#passkey-signer)
, [server](https://docs.crossmint.com/wallets/concepts/signers#server-signer)
, [email](https://docs.crossmint.com/wallets/concepts/signers#email-otp-signer)
, [SMS](https://docs.crossmint.com/wallets/concepts/signers#sms--phone-otp-signer)
sign-in | Smart wallets; device secure enclave | [Quickstart](https://docs.crossmint.com/wallets/quickstarts/react) | | [Cubist](https://cubist.dev/) | ✅ | | [Embedded wallets](https://cubist.dev/products/cubesigner-end-user-custody)
(CubeSigner); non-custodial signing & key management
Auth: social (Google, Apple, X, Telegram) sign-in; MFA: passkeys, YubiKeys, authenticator apps | HSM + TEE (Nitro Enclaves) | [Quickstart](https://github.com/cubist-labs/CubeSigner-TypeScript-SDK) | | [Dynamic](https://dynamic.xyz/) | ✅ | [Docs](https://docs.dynamic.xyz/) | [Embedded wallets](https://docs.dynamic.xyz/wallets/embedded-wallets/dynamic-embedded-wallets)

Auth: [passkey](https://docs.dynamic.xyz/wallets/v1-embedded/transactional-mfa/passkeys#passkeys)
, [email/social/SMS](https://docs.dynamic.xyz/authentication-methods/email-social-sms)
sign-in | TEE; TSS-MPC (just added) | [Get started](https://www.dynamic.xyz/get-started) | | [Fordefi](https://fordefi.com/) | ✅ | [Docs](https://docs.fordefi.com/) | [Products and Services](https://docs.fordefi.com/user-guide/welcome/products-and-services) | MPC | [Quickstart](https://docs.fordefi.com/user-guide/quickstart) | | [Mera](https://mera.category.xyz/) | ✅ | [Docs](https://mera.category.xyz/) | Passkey wallets — self-custodial BIP-44 EOAs (EVM + Solana), no seed phrase
Auth: [passkey](https://mera.category.xyz/authenticator-support/)
(WebAuthn PRF) sign-in | Passkey-derived key (WebAuthn PRF); non-custodial, no server storage | [Guide](https://docs.monad.xyz/guides/mera) | | [MetaMask Embedded Wallet](https://docs.metamask.io/embedded-wallets/) | ✅ | [Docs](https://docs.metamask.io/embedded-wallets/) | Embedded wallet
Auth: [passkey](https://docs.metamask.io/embedded-wallets/authentication/)
, [social](https://docs.metamask.io/embedded-wallets/authentication/social-logins/google/)
, [email](https://docs.metamask.io/embedded-wallets/authentication/basic-logins/email-passwordless/)
, [SMS](https://docs.metamask.io/embedded-wallets/authentication/basic-logins/sms-otp/) | MPC-SSS/TSS | [Quickstart](https://docs.metamask.io/embedded-wallets/connect-blockchain/evm/monad) | | [Openfort](https://openfort.io/) | ✅ | [Docs](https://www.openfort.io/docs) | [Embedded wallets](https://www.openfort.io/docs/guides/react/configuration)
, [Backend wallets](https://www.openfort.io/docs/guides/server/dev)
, [Ecosystem wallets](https://www.openfort.io/docs/guides/ecosystem)

Auth: [passkeys](https://www.openfort.io/docs/products/embedded-wallet/react/auth)
, [social](https://www.openfort.io/docs/products/embedded-wallet/react/auth)
, [email](https://www.openfort.io/docs/products/embedded-wallet/react/auth) | SSS | [Quickstart](https://www.openfort.io/docs/guides/react) | | [Para](https://www.getpara.com/) | ✅ | [Docs](https://docs.getpara.com/) | [Embedded wallets](https://docs.getpara.com/getting-started/initial-setup/react-nextjs)
; robust policy engine for sessions
Auth: [email and phone](https://docs.getpara.com/v2/swift/guides/email-phone-login#email-and-phone-login)
, [social](https://docs.getpara.com/customize-para/oauth-social-logins)
, [SMS](https://docs.getpara.com/customize-para/phone-login)
sign-in | MPC + DKG | [Quickstart](https://docs.getpara.com/v1/web/guides/evm/overview#evm-overview) | | [Portal](https://www.portalhq.io/) | ✅ | [Docs](https://docs.portalhq.io/) | [Integration overview](https://docs.portalhq.io/integrations) | TSS MPC | [API Quickstart](https://docs.portalhq.io/apis/quickstart)
, [SDK Quickstart](https://docs.portalhq.io/sdks/quickstart) | | [Privy](https://privy.io/) | ✅ | [Docs](https://docs.privy.io/) | [Embedded wallets](https://docs.privy.io/guide/embedded-wallets)
, [server wallets](https://docs.privy.io/guide/overview-server-wallets)
, server-delegated actions
Auth: [passkey](https://docs.privy.io/guide/authentication)
, [social](https://docs.privy.io/guide/authentication)
, [email](https://docs.privy.io/guide/authentication)
, [SMS](https://docs.privy.io/guide/authentication) | TEE + SSS | [Quickstart](https://docs.privy.io/guide/react/quickstart) | | [Reown](https://reown.com/)
(formerly WalletConnect) | ✅ | [Docs](https://docs.reown.com/) | Popular UI component for selecting a wallet
Embedded wallet with social/email sign-in | | [Overview](https://docs.reown.com/appkit/overview) | | [Sequence](https://sequence.xyz/) | ✅ | [Docs](https://docs.sequence.xyz/solutions/wallets/overview) | [Embedded wallets](https://docs.sequence.xyz/solutions/wallets/developers/embedded-wallet/overview)
, [ecosystem wallets](https://docs.sequence.xyz/solutions/wallets/developers/overview)

Auth: Passkey, Google, Apple, Twitter, email, Facebook, Twitch, Epic Games, Playfab, Stych, Standard OAuth | TEE; Sandboxed Smart Sessions | [Ecosystem quickstart](https://docs.sequence.xyz/solutions/wallets/developers/overview)


[Embedded quickstart](https://docs.sequence.xyz/solutions/wallets/developers/embedded-wallet/quickstart) | | [thirdweb](https://thirdweb.com/) | ✅ | [Docs](https://portal.thirdweb.com/connect/wallet/overview) | Embedded wallets
Auth: [passkey](https://portal.thirdweb.com/connect/wallet/sign-in-methods/configure)
, [social](https://portal.thirdweb.com/connect/wallet/sign-in-methods/configure)
, [email](https://portal.thirdweb.com/connect/wallet/sign-in-methods/configure)
, [SMS](https://portal.thirdweb.com/connect/wallet/sign-in-methods/configure)
, OIDC, or generic auth | | [Quickstart](https://portal.thirdweb.com/connect/wallet/get-started) | | [Turnkey](https://www.turnkey.com/) | ✅ | [Docs](https://docs.turnkey.com/) | [Embedded wallet](https://docs.turnkey.com/reference/embedded-wallet-kit)
, [policy engine](https://docs.turnkey.com/concepts/policies/overview)
, [delegated access](https://docs.turnkey.com/concepts/policies/delegated-access-frontend)
, [signing automation](https://docs.turnkey.com/signing-automation/overview)
, [sessions](https://docs.turnkey.com/authentication/sessions)

[Server-side SDKs](https://docs.turnkey.com/sdks/introduction)
for auth, wallet management, and policies
Auth: [passkey](https://docs.turnkey.com/authentication/passkeys/introduction)
, [social](https://docs.turnkey.com/authentication/social-logins)
, [email](https://docs.turnkey.com/authentication/email)
, [SMS](https://docs.turnkey.com/authentication/sms)
login | TEE | [Quickstart](https://docs.turnkey.com/getting-started/quickstart) | _✅ = supported, ⌛️ = in progress, ❓ = unknown, ❌ = won’t support_ | Provider | Status | Docs | Supported services | Security Method | How to get started | | --- | --- | --- | --- | --- | --- | | [Alchemy](https://www.alchemy.com/smart-wallets) | ✅ | [Docs](https://accountkit.alchemy.com/) | [Embedded wallets](https://accountkit.alchemy.com/react/quickstart)

Auth: [passkey](https://accountkit.alchemy.com/signer/authentication/passkey-signup)
, [social](https://accountkit.alchemy.com/signer/authentication/social-login)
, [email](https://accountkit.alchemy.com/signer/authentication/email-otp)
sign-in | | [Quickstart](https://accountkit.alchemy.com/react/quickstart) | | [Coinbase Developer Platform (CDP)](https://www.coinbase.com/developer-platform/products/embeddedwallets) | ✅ | [Docs](https://docs.cdp.coinbase.com/embedded-wallets/welcome) | [Embedded wallets](https://docs.cdp.coinbase.com/embedded-wallets/welcome)

Auth: [email/social/SMS](https://docs.cdp.coinbase.com/embedded-wallets/authentication-methods) | Device-based secure enclaves | [Quickstart](https://docs.cdp.coinbase.com/embedded-wallets/quickstart) | | [Crossmint](https://www.crossmint.com/) | ✅ | [Docs](https://docs.crossmint.com/) | [Embedded wallets](https://docs.crossmint.com/wallets/overview)
(smart contract wallets with modular signers)
Auth: [device](https://docs.crossmint.com/wallets/concepts/signers#device-signer)
, [passkey](https://docs.crossmint.com/wallets/concepts/signers#passkey-signer)
, [server](https://docs.crossmint.com/wallets/concepts/signers#server-signer)
, [email](https://docs.crossmint.com/wallets/concepts/signers#email-otp-signer)
, [SMS](https://docs.crossmint.com/wallets/concepts/signers#sms--phone-otp-signer)
sign-in | Smart wallets; device secure enclave | [Quickstart](https://docs.crossmint.com/wallets/quickstarts/react) | | [Cubist](https://cubist.dev/) | ✅ | | [Embedded wallets](https://cubist.dev/products/cubesigner-end-user-custody)
(CubeSigner); non-custodial signing & key management
Auth: social (Google, Apple, X, Telegram) sign-in; MFA: passkeys, YubiKeys, authenticator apps | HSM + TEE (Nitro Enclaves) | [Quickstart](https://github.com/cubist-labs/CubeSigner-TypeScript-SDK) | | [Dynamic](https://dynamic.xyz/) | ✅ | [Docs](https://docs.dynamic.xyz/) | [Embedded wallets](https://docs.dynamic.xyz/wallets/embedded-wallets/dynamic-embedded-wallets)

Auth: [passkey](https://docs.dynamic.xyz/wallets/v1-embedded/transactional-mfa/passkeys#passkeys)
, [email/social/SMS](https://docs.dynamic.xyz/authentication-methods/email-social-sms)
sign-in | TEE; TSS-MPC (just added) | [Get started](https://www.dynamic.xyz/get-started) | | [Fordefi](https://fordefi.com/) | ✅ | [Docs](https://docs.fordefi.com/) | [Products and Services](https://docs.fordefi.com/user-guide/welcome/products-and-services) | MPC | [Quickstart](https://docs.fordefi.com/user-guide/quickstart) | | [Mera](https://mera.category.xyz/) | ✅ | [Docs](https://mera.category.xyz/) | Passkey wallets — self-custodial BIP-44 EOAs (EVM + Solana), no seed phrase
Auth: [passkey](https://mera.category.xyz/authenticator-support/)
(WebAuthn PRF) sign-in | Passkey-derived key (WebAuthn PRF); non-custodial, no server storage | [Guide](https://docs.monad.xyz/guides/mera) | | [MetaMask Embedded Wallet](https://docs.metamask.io/embedded-wallets/) | ✅ | [Docs](https://docs.metamask.io/embedded-wallets/) | Embedded wallet
Auth: [passkey](https://docs.metamask.io/embedded-wallets/authentication/)
, [social](https://docs.metamask.io/embedded-wallets/authentication/social-logins/google/)
, [email](https://docs.metamask.io/embedded-wallets/authentication/basic-logins/email-passwordless/)
, [SMS](https://docs.metamask.io/embedded-wallets/authentication/basic-logins/sms-otp/) | MPC-SSS/TSS | [Quickstart](https://docs.metamask.io/embedded-wallets/connect-blockchain/evm/monad) | | [Openfort](https://openfort.io/) | ✅ | [Docs](https://www.openfort.io/docs) | [Embedded wallets](https://www.openfort.io/docs/guides/react/configuration)
, [Backend wallets](https://www.openfort.io/docs/guides/server/dev)
, [Ecosystem wallets](https://www.openfort.io/docs/guides/ecosystem)

Auth: [passkeys](https://www.openfort.io/docs/products/embedded-wallet/react/auth)
, [social](https://www.openfort.io/docs/products/embedded-wallet/react/auth)
, [email](https://www.openfort.io/docs/products/embedded-wallet/react/auth) | SSS | [Quickstart](https://www.openfort.io/docs/guides/react) | | [Para](https://www.getpara.com/) | ✅ | [Docs](https://docs.getpara.com/) | [Embedded wallets](https://docs.getpara.com/getting-started/initial-setup/react-nextjs)
; robust policy engine for sessions
Auth: [email and phone](https://docs.getpara.com/v2/swift/guides/email-phone-login#email-and-phone-login)
, [social](https://docs.getpara.com/customize-para/oauth-social-logins)
, [SMS](https://docs.getpara.com/customize-para/phone-login)
sign-in | MPC + DKG | [Quickstart](https://docs.getpara.com/v1/web/guides/evm/overview#evm-overview) | | [Portal](https://www.portalhq.io/) | ✅ | [Docs](https://docs.portalhq.io/) | [Integration overview](https://docs.portalhq.io/integrations) | TSS MPC | [API Quickstart](https://docs.portalhq.io/apis/quickstart)
, [SDK Quickstart](https://docs.portalhq.io/sdks/quickstart) | | [Privy](https://privy.io/) | ✅ | [Docs](https://docs.privy.io/) | [Embedded wallets](https://docs.privy.io/guide/embedded-wallets)
, [server wallets](https://docs.privy.io/guide/overview-server-wallets)
, server-delegated actions
Auth: [passkey](https://docs.privy.io/guide/authentication)
, [social](https://docs.privy.io/guide/authentication)
, [email](https://docs.privy.io/guide/authentication)
, [SMS](https://docs.privy.io/guide/authentication) | TEE + SSS | [Quickstart](https://docs.privy.io/guide/react/quickstart) | | [Reown](https://reown.com/)
(formerly WalletConnect) | ✅ | [Docs](https://docs.reown.com/) | Popular UI component for selecting a wallet
Embedded wallet with social/email sign-in | | [Overview](https://docs.reown.com/appkit/overview) | | [Sequence](https://sequence.xyz/) | ✅ | [Docs](https://docs.sequence.xyz/solutions/wallets/overview) | [Embedded wallets](https://docs.sequence.xyz/solutions/wallets/developers/embedded-wallet/overview)
, [ecosystem wallets](https://docs.sequence.xyz/solutions/wallets/developers/overview)

Auth: Passkey, Google, Apple, Twitter, email, Facebook, Twitch, Epic Games, Playfab, Stych, Standard OAuth | TEE; Sandboxed Smart Sessions | [Ecosystem quickstart](https://docs.sequence.xyz/solutions/wallets/developers/overview)


[Embedded quickstart](https://docs.sequence.xyz/solutions/wallets/developers/embedded-wallet/quickstart) | | [thirdweb](https://thirdweb.com/) | ✅ | [Docs](https://portal.thirdweb.com/connect/wallet/overview) | Embedded wallets
Auth: [passkey](https://portal.thirdweb.com/connect/wallet/sign-in-methods/configure)
, [social](https://portal.thirdweb.com/connect/wallet/sign-in-methods/configure)
, [email](https://portal.thirdweb.com/connect/wallet/sign-in-methods/configure)
, [SMS](https://portal.thirdweb.com/connect/wallet/sign-in-methods/configure)
, OIDC, or generic auth | | [Quickstart](https://portal.thirdweb.com/connect/wallet/get-started) | | [Turnkey](https://www.turnkey.com/) | ✅ | [Docs](https://docs.turnkey.com/) | [Embedded wallet](https://docs.turnkey.com/reference/embedded-wallet-kit)
, [policy engine](https://docs.turnkey.com/concepts/policies/overview)
, [delegated access](https://docs.turnkey.com/concepts/policies/delegated-access-frontend)
, [signing automation](https://docs.turnkey.com/signing-automation/overview)
, [sessions](https://docs.turnkey.com/authentication/sessions)

[Server-side SDKs](https://docs.turnkey.com/sdks/introduction)
for auth, wallet management, and policies
Auth: [passkey](https://docs.turnkey.com/authentication/passkeys/introduction)
, [social](https://docs.turnkey.com/authentication/social-logins)
, [email](https://docs.turnkey.com/authentication/email)
, [SMS](https://docs.turnkey.com/authentication/sms)
login | TEE | [Quickstart](https://docs.turnkey.com/getting-started/quickstart) | _✅ = supported, ⌛️ = in progress, ❓ = unknown, ❌ = won’t support_ [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/embedded-wallets#providers-offering-subsidized-usage) Providers Offering Subsidized Usage ------------------------------------------------------------------------------------------------------------------------------------------------------ These WaaS providers are subsidizing usage on Monad Testnet: | Provider | How to access | | --- | --- | | [Privy](https://privy.io/) | Sign up, then email the Privy team at `monad@privy.io` | | [Para](https://www.getpara.com/) | Sign up via the [Developer Portal](https://developer.getpara.com/)
and reach out to the team at `ops@getpara.com` | | [Turnkey](https://www.turnkey.com/) | Turnkey is free for developers building on Monad Testnet. All you need to do is sign up! | [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/embedded-wallets#provider-details) Provider Details ---------------------------------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/embedded-wallets#alchemy) Alchemy [Account Kit](https://accountkit.alchemy.com/) is a complete solution for account abstraction. Using Account Kit, you can create a smart contract wallet for every user that leverages account abstraction to simplify every step of your app’s onboarding experience. It also offers Gas Manager and Bundler APIs for sponsoring gas and batching transactions. To get started, sign up for an [Alchemy account](https://www.alchemy.com/) , visit the [documentation](https://accountkit.alchemy.com/) , follow the [quickstart](https://accountkit.alchemy.com/react/quickstart) guide or check out the demo [here](https://demo.alchemy.com/) . Alchemy helps you to replace 3rd-party pop-up wallets with native in-app auth. Drop in branded sign-in modals for email, passkeys, and social logins with plug-n-play components. To get started, sign up for an [Alchemy account](https://dashboard.alchemy.com/accounts?utm_source=chain_partner&utm_medium=referral&utm_campaign=monad) , visit the [documentation](https://accountkit.alchemy.com/) , follow the [quickstart](https://accountkit.alchemy.com/react/quickstart) guide. To further streamline UX with no gas fees or signing for users, see Alchemy’s [AA infra offering](https://docs.monad.xyz/tooling-and-infra/wallet-infra/account-abstraction#alchemy) and a demo [here](https://demo.alchemy.com/) . ### [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/embedded-wallets#coinbase-developer-platform) Coinbase Developer Platform [Coinbase Developer Platform](https://www.coinbase.com/developer-platform/) allows developers to build next-gen on-chain apps. CDP simplifies development by providing services for creating smart wallets, processing payments, and integrating crypto into existing apps. With CDP Embedded Wallets, your users can access the full power of blockchains through familiar authentication methods like email and social logins (no seed phrases, browser extensions, or pop-ups required). To get started, visit the [documentation](https://docs.cdp.coinbase.com/embedded-wallets/welcome) or follow the [quickstart](https://docs.cdp.coinbase.com/embedded-wallets/quickstart) guide. ### [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/embedded-wallets#crossmint) Crossmint [Crossmint](https://www.crossmint.com/) provides smart contract wallets with a modular signer architecture, abstracting away blockchain complexity so you can spin up embedded, invisible wallets for your users, high-throughput treasury wallets, and wallets for AI agents — all from a single SDK and API. Wallets support email, Google/social, passkey, and SMS sign-in. The default device signer keeps a non-extractable P256 key inside the device’s secure hardware (iOS Secure Enclave, Android Keystore, or the browser’s Web Crypto API), so the private key never leaves the device. To get started, visit the [documentation](https://docs.crossmint.com/wallets/overview) or follow the [React quickstart](https://docs.crossmint.com/wallets/quickstarts/react) guide. ### [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/embedded-wallets#cubist) Cubist [Cubist](https://cubist.dev/) builds [CubeSigner](https://cubist.dev/products/cubesigner-end-user-custody) , hardware-backed wallet-as-a-service and embedded wallet infrastructure. Keys are generated and used inside HSM-sealed AWS Nitro Enclaves, combining cold-wallet security with hot-wallet speed — keys never leave secure hardware. CubeSigner provides non-custodial embedded wallets with social login (Google, Apple, X, Telegram), multi-factor authentication via passkeys, YubiKeys, and authenticator apps, and programmable, policy-based signing for sessions and automation. To get started, follow the [TypeScript SDK quickstart](https://github.com/cubist-labs/CubeSigner-TypeScript-SDK) . ### [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/embedded-wallets#dynamic) Dynamic [Dynamic](https://dynamic.xyz/) offers smart and beautiful login flows for crypto-native users, simple onboarding flows for everyone else, and powerful developer tools that go beyond authentication. To get started, visit the [documentation](https://docs.dynamic.xyz/) or follow the [quickstart](https://docs.dynamic.xyz/docs/quickstart) guide. ### [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/embedded-wallets#fordefi) Fordefi [Fordefi](https://fordefi.com/) is the first institutional MPC wallet and security platform built for decentralized finance (DeFi), offering MPC key management, self-serve DeFi policy controls, time-of-transaction smart contract insights, transaction simulation, and real-time risk alerts, alongside a full-stack developer suite of native APIs and SDKs. To get started, visit the [documentation](https://docs.fordefi.com/) or follow the [quickstart](https://docs.fordefi.com/user-guide/quickstart) guide. ### [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/embedded-wallets#mera) Mera Mera is free to use and open source. Check out the code on [GitHub](https://github.com/category-labs/mera) . [mera](https://mera.category.xyz/) , built by Category Labs, derives standard EVM accounts directly from a passkey using the [WebAuthn PRF extension](https://mera.category.xyz/authenticator-support/) — with no seed phrase, bundler, MPC service, or backend custody. Users create and recover accounts with Face ID, Touch ID, or a security key, and the same passkey reproduces the same accounts across a web app and its native iOS or Android counterpart. The derived accounts are ordinary BIP-44 EOAs, so an exported mnemonic imports cleanly into wallets like MetaMask or Rabby, and the library can derive Solana accounts from the same passkey as well. For keys that come from elsewhere (such as a recovery phrase the user already has), [secret vaults](https://mera.category.xyz/concepts/secret-vaults/) encrypt them once and decrypt them with the passkey. To get started, follow the [How to create passkey accounts with Mera](https://docs.monad.xyz/guides/mera) guide, try the [demo](https://mera-demo.up.railway.app/) , or read the [mera docs](https://mera.category.xyz/) . ### [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/embedded-wallets#metamask-embedded-wallet) MetaMask Embedded Wallet [MetaMask Embedded Wallets](https://docs.metamask.io/embedded-wallets/) brings one-click, OAuth-based onboarding to Monad. Users can log in with Google or Apple and get a non-custodial wallet instantly connected to the network — with no setup or seed phrase required. Setup is entirely handled in the MetaMask Dashboard — developers just enable Monad, and it works out of the box. Learn more at [docs.metamask.io/embedded-wallets](https://docs.metamask.io/embedded-wallets/) . To get started, visit the [Monad integration guide](https://docs.metamask.io/embedded-wallets/connect-blockchain/evm/monad) . ### [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/embedded-wallets#para) Para Para is free for developers building on Monad Testnet!Sign up via the [Developer Portal](https://developer.getpara.com/) and reach out to the team via the below email.`ops@getpara.com` [Para](https://www.getpara.com/) is the easiest and most secure way to onboard all your users and support them throughout their crypto journey. We support projects throughout their growth, ranging from personal projects to many of the most trusted teams in crypto and beyond. Para’s cross-app embedded wallets work universally across apps, chains, and ecosystem, so whether users start transacting on EVM, Solana, or Cosmos, they can onboard once and transact forever, all with the same wallet. To get started, visit the [documentation](https://docs.getpara.com/v1/introduction/welcome#welcome) or follow the [quickstart](https://docs.getpara.com/v2/introduction/welcome) guide. ### [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/embedded-wallets#portal) Portal [Portal](https://www.portalhq.io/) is a fast, flexible, and secure stablecoin finance developer platform. Create wallets, move stablecoins, and scale on-chain operations — all with simple SDKs and APIs. To get started, visit the [documentation](https://docs.portalhq.io/) or follow the [quickstart](https://docs.portalhq.io/apis/quickstart) guide. ### [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/embedded-wallets#privy) Privy Privy is subsidizing all Monad Testnet usage!For more details reach out to the Privy team via the below email.`monad@privy.io` [Privy](https://privy.io/) helps you onboard any user to crypto no matter how familiar they are with the space. Power flexible, powerful wallets under the hood for any application, securely. To get started, visit the [documentation](https://docs.privy.io/) or follow the [quickstart](https://docs.privy.io/guide/react/quickstart) guide. ### [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/embedded-wallets#reown) Reown [Reown](https://reown.com/) gives developers the tools to build user experiences that make digital ownership effortless, intuitive, and secure. #### [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/embedded-wallets#appkit) AppKit AppKit is a powerful, free, and fully open-source SDK for developers looking to integrate wallet connections and other Web3 functionalities into their apps on any EVM and non-EVM chain. In just a few simple steps, you can provide your users with seamless wallet access, one-click authentication, social logins, and notifications—streamlining their experience while enabling advanced features like on-ramp functionality, in-app token swaps and smart accounts. To get started, visit the [documentation](https://docs.reown.com/) or follow the [quickstart](https://reown.com/blog/how-to-get-started-with-reown-appkit-on-monad-testnet) guide. ### [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/embedded-wallets#sequence) Sequence [Sequence](https://sequence.xyz/) provides the industry gold standard in robust open-source, non-custodial [Embedded](https://docs.sequence.xyz/solutions/wallets/developers/embedded-wallet/overview) and [Ecosystem](https://docs.sequence.xyz/solutions/wallets/developers/overview) Wallets.Sequence is the originator of non-custodial smart contract wallets, and authors of ERC-1271 and ERC-6492. Embedded and Ecosystem Wallets enable seamless onboarding with user-friendly email, social, passkey, and guest account logins. Invisible onchain transactions; secure and compliant non-custodial sovereignty; and cross-platform integrations with SDKs for Unity, Unreal, Web, and mobile. Fully customizable for developers and ecosystems. To get started, visit the [Ecosystem Wallet Quickstart](https://docs.sequence.xyz/solutions/wallets/developers/overview#ecosystem-wallet-quickstarts) . ### [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/embedded-wallets#thirdweb) thirdweb [thirdweb](https://thirdweb.com/) provides client-side SDKs for user onboarding, identity and transactions. * Onboard new users to your apps with every wallet & login method * create a complete picture of all your users via user analytics & identity linking * facilitate onchain transactions via onramps, swaps & bridging To get started: 1. Sign up for a [free thirdweb account](https://thirdweb.com/team) 2. Visit [Connect Documentation](https://portal.thirdweb.com/connect/sign-in/ConnectButton) and [Connect Playground](https://playground.thirdweb.com/connect/sign-in/button) ### [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra/embedded-wallets#turnkey) Turnkey Turnkey is free for developers building on Monad Testnet! [Turnkey](https://www.turnkey.com/) is secure, flexible, and scalable wallet infrastructure. Create millions of embedded wallets, eliminate manual transaction flows, and automate onchain actions - all without compromising on security. To get started, visit the [documentation](https://docs.turnkey.com/) or follow the [quickstart](https://docs.turnkey.com/getting-started/embedded-wallet-quickstart) guide. [Wallet Infrastructure\ \ Previous](https://docs.monad.xyz/tooling-and-infra/wallet-infra) [Account Abstraction Providers\ \ Next](https://docs.monad.xyz/tooling-and-infra/wallet-infra/account-abstraction) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Use an Indexer - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/guides/indexers#content-area) GhostGraph ---------- Index transfers with GhostGraph Envio ----- Index transfers for a telegram bot using Envio Envio HyperSync --------------- Query token data with Envio HyperSync QuickNode Streams ----------------- Index transfers using QuickNode Streams [Verify a smart contract on Monad using Hardhat\ \ Previous](https://docs.monad.xyz/guides/verify-smart-contract/hardhat) [How to index token transfers with GhostGraph\ \ Next](https://docs.monad.xyz/guides/indexers/ghost) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Event rings in detail - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/execution-events/event-ring#content-area) [​](https://docs.monad.xyz/execution-events/event-ring#event-ring-files-and-content-types) Event ring files and content types -------------------------------------------------------------------------------------------------------------------------------- Event rings are made up of four shared memory segments. Two of these — the event descriptor array and payload buffer — are described in the [overview documentation](https://docs.monad.xyz/execution-events/overview) . The third shared memory segment contains a header that describes metadata about the event ring. The fourth (the “context area”) is a special feature that is not needed for execution events. The shared memory segments are mapped into a process’ address space using [mmap(2)](https://man7.org/linux/man-pages/man2/mmap.2.html) . This means that the event ring’s data structures live in a file somewhere, and that shared access to it is obtained by creating shared memory mappings of that file. Most of the time an event ring is a regular file, created on a special in-memory file system called [hugetlbfs](https://lwn.net/Articles/375096/) . hugetlbfs is similar to the [tmpfs](https://man7.org/linux/man-pages/man5/tmpfs.5.html) in-memory filesystem, but supports the creation of files backed by large page sizes. The use of large pages is just an [optimization](https://lwn.net/Articles/374424/) : event ring files may be created on any file system. If the execution daemon is told to create an event ring file on a filesystem without hugetlb mmap support, it will log a performance warning but will still create the file. To learn more about hugetlbfs and how it is used, read [this page](https://docs.monad.xyz/execution-events/advanced#location-of-event-ring-files) . ### [​](https://docs.monad.xyz/execution-events/event-ring#event-ring-configuration) Event ring configuration To use execution events, the execution daemon must be started with the command line parameter: --exec-event-ring [] Without this command line parameter, execution will not publish any events. This command line parameter (and mounting a hugetlbfs filesystem, for that matter) are not part of the default configuration instructions for the execution daemon. A [separate guide](https://validator-docs.vercel.app/docs/full_node/events-and-websockets) covers mounting a hugetlbfs filesystem and modifying the command line in the systemd unit configuration files. Note that the configuration string is optional; if you pass `--exec-event-ring` without an argument (which is the recommended thing to do), this is equivalent to passing `--exec-event-ring monad-exec-events`, where `monad-exec-events` is the default execution event ring file name. The event ring configuration string has the form: [::] In other words, the configuration string consists of three `:`\-separated fields; the first field is required but the second two are optional. Here is an example of the command line parameter, with just the first field: --exec-event-ring /var/lib/hugetlbfs/user/monad/pagesize-2MB/event-rings/monad-exec-events and another example, with all three: --exec-event-ring monad-exec-events:21:29 The first field is the name of the event ring file. The execution daemon interprets this field in two different ways: * If it is purely a file name — i.e., if the path does not contain any `/` characters — then it is interpreted as a file living in the default event ring file directory; this is the directory returned by the API function `monad_event_open_ring_dir_fd`; it uses [libhugetlbfs](https://github.com/libhugetlbfs/libhugetlbfs) to locate the most suitable mount point for a hugetlbfs file system, and automatically creates subdirectory called `event-rings` underneath that, if it does not already exist (see [here](https://docs.monad.xyz/execution-events/advanced#location-of-event-ring-files) for more information); the event ring file will be created in that `event-rings` subdirectory * If the path has multiple path components — i.e., if it contains at least one `/` character — then this path will be used as written _even if_ it is not resident on a hugetlbfs file system; the rationale for why someone might want this is explained below The “shift” parameters are power-of-two exponents that determine the event ring’s size.[1](https://docs.monad.xyz/execution-events/event-ring#user-content-fn-1) A `` of 21 means there will be 2^21 descriptors in the ring’s event descriptor array. This means approximately 2 million events can be written before the descriptor ring buffer wraps around and overwrites older event descriptors. A `` of 29 means there will be 2^29 bytes in the payload buffer array. This means 512 MiB worth of event payloads can be recorded before the payload buffer wraps around and overwrites an older event’s payload. If the event ring size parameters are not specified, then default values are used. Why might you increase these values from their defaults? If your reader program crashes, but execution does not, then you will likely miss some events during the time when your program is not running. Your application might not care about lost events for old blocks, but if it does, you’ll need to retrieve them somehow. If not much time has gone by, chances are good that the events you are missing are still sitting there in the event ring memory, i.e., are not overwritten yet. The default sizes are large enough to hold several minutes worth of blocks at 10k TPS. Increasing these values allows you to rewind further back in time. Be aware that there is a fixed-size pool of huge pages. The pool size can be changed by modifying the system’s configuration, see the discussion of `/proc/sys/vm/nr_hugepages` [here](https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt) . If an event ring is created on a hugetlbfs mount, and its size exceeds the number of available huge pages, then the execution daemon will exit with an error message that reports a “no space left on device” error. For example, here we tried to allocate an event ring with a one terabyte payload buffer: LOG_ERROR event library error -- monad_event_ring_init_simple@event_ring_util.c:78: posix_fallocate failed for event ring file `/dev/hugepages/monad-exec-events`, size 1099647942656: No space left on device (28) If you happen to have multiple terabytes of main memory available, you could pass a file path containing a `/` character to a file on a tmpfs mount and it would work, e.g., `--exec-event-ring /my-giant-tmpfs/monad-exec-events`. If you need to rewind back especially far — or if you are missing events because execution itself has crashed — then you will need to use alternative recovery methods described elsewhere.[2](https://docs.monad.xyz/execution-events/event-ring#user-content-fn-2) ### [​](https://docs.monad.xyz/execution-events/event-ring#event-ring-file-format) Event ring file format The event ring file format is simple: all four sections are laid out sequentially and aligned to a large page boundary, and the header describes the size of each section. ╔═Event ring file══╗ ║ ┌──────────────┐ ║ ║ │ │ ║ ║ │ Header │ ║ ║ │ │ ║ ║ ├──────────────┤ ║ ║ │ │ ║ ║ │ Event │ ║ ║ │ Descriptor │ ║ ║ │ Array │ ║ ║ │ │ ║ ║ ├──────────────┤ ║ ║ │ │ ║ ║ │ │ ║ ║ │ │ ║ ║ │ │ ║ ║ │ Payload │ ║ ║ │ Buffer │ ║ ║ │ │ ║ ║ │ │ ║ ║ │ │ ║ ║ │ │ ║ ║ │ │ ║ ║ ├──────────────┤ ║ ║ │ │ ║ ║ │ Context │ ║ ║ │ Area │ ║ ║ │ │ ║ ║ └──────────────┘ ║ ╚══════════════════╝ The descriptor array is a just an array of `struct monad_event_descriptor` objects, and the payload buffer is a flat byte array (i.e., it has type `uint8_t[]`). The header structure is defined this way: /// Event ring shared memory files start with this header structure struct monad_event_ring_header { char magic[6]; ///< 'RINGvv', vv = version number enum monad_event_content_type content_type; ///< Kind of events in this ring uint8_t schema_hash[32]; ///< Ensure event definitions match struct monad_event_ring_size size; ///< Size of following structures struct monad_event_ring_control control; ///< Tracks ring's state/status }; ### [​](https://docs.monad.xyz/execution-events/event-ring#event-content-types) Event content types The `content_type` header field is needed because the event ring library — both the reader and writer APIs — performs unstructured I/O: the functions read and write raw `uint8_t[]` event payloads, and the event descriptors contain plain `uint16_t` numerical event codes. Much like the UNIX `read(2)` and `write(2)` file I/O system calls, the event ring API functions do not inherently know the format of data they are working with. This is the reason why the `event_type` field in the event descriptor is the generic integer type `uint16_t` instead of `enum monad_exec_event_type`. The assumption here is that the reader and writer know the binary format of the data they’re both working with, and they treat the raw data as if it has this format by type-casting it when needed, e.g., const struct monad_exec_block_start *block_start = nullptr; // We assume that the event ring file we opened contains execution events, // and thus further assume that it makes sense to compare `event->event_type` // to a value of type `enum monad_exec_event_type` if (event->event_type == MONAD_EXEC_BLOCK_START) { // Since this is MONAD_EXEC_BLOCK_START, we can cast the `const void *` // payload to a `const struct monad_exec_block_start *` payload. // Note: implicit type-casting from `void *` is allowed in C, but not C++ block_start = monad_event_ring_payload_peek(event_ring, event); } We need some kind of error-detection mechanism to ensure this is safe to do. The event ring file header contains a “content type” enumeration constant explaining what kind of event data it contains: enum monad_event_content_type : uint16_t { MONAD_EVENT_CONTENT_TYPE_NONE, ///< An invalid value MONAD_EVENT_CONTENT_TYPE_TEST, ///< Used in simple automated tests MONAD_EVENT_CONTENT_TYPE_EXEC, ///< Core execution events MONAD_EVENT_CONTENT_TYPE_PERF, ///< Performance tracer events MONAD_EVENT_CONTENT_TYPE_COUNT ///< Total number of known event rings }; The execution events are always recorded to a ring with `content_type` equal to `MONAD_EVENT_CONTENT_TYPE_EXEC`. ### [​](https://docs.monad.xyz/execution-events/event-ring#binary-schema-versioning-the-schema_hash-field) Binary schema versioning: the `schema_hash` field If `content_type` is equal to `MONAD_EVENT_CONTENT_TYPE_EXEC`, then we know a ring is supposed to execution events, but what if the event payload definitions change? Or what if the enumeration constants in `enum monad_exec_event_type` change? Suppose that a user compiles their application with a particular version of `exec_event_ctypes.h`, the file which defines the execution event payloads and the event type enumeration. Now imagine that some time later, the user deploys a new version of the execution node, which was compiled with a different version of `exec_event_ctypes.h`, causing the memory representation of the event payloads to be different. If the reader does not remember to recompile their application with the new header, it could misinterpret the bytes in the event payloads, assuming they have the old layout from their old (compile-time) version of `exec_event_ctypes.h`. To prevent these kinds of errors, the binary layout of all event payloads is summarized by a hash value which changes any time a change is made to any event payload for that content type. In addition to payload changes, any change to `enum monad_exec_event_type` will also generate a new hash. This mechanism is called the “schema hash”, and the hash value is present as a global, read-only byte array inside the library code (defined in `exec_event_ctypes_metadata.c`). If the hash value in this array does not match the hash value in the event ring file header, then the binary formats are incompatible. A helper function called `monad_event_ring_check_content_type` is used to check that an event ring file has both the expected content type, and the expected schema hash for that content type. Here is an example of it being called in the `eventwatch.c` sample program: struct monad_event_ring exec_ring; /* initialization of `exec_ring` not shown */ if (monad_event_ring_check_content_type( &exec_ring, MONAD_EVENT_CONTENT_TYPE_EXEC, g_monad_exec_event_schema_hash) != 0) { errx(EX_SOFTWARE, "event library error -- %s", monad_event_ring_get_last_error()); } If the type of event ring is not `MONAD_EVENT_CONTENT_TYPE_EXEC` or if the `schema_hash` in the file header does not match the value contained in the global array `uint8_t g_monad_exec_event_schema_hash[32]`, this function will return the `errno(3)` domain code `EPROTO`. [​](https://docs.monad.xyz/execution-events/event-ring#event-descriptors-in-detail) Event descriptors in detail ------------------------------------------------------------------------------------------------------------------ ### [​](https://docs.monad.xyz/execution-events/event-ring#binary-format) Binary format The event descriptor is defined this way: struct monad_event_descriptor { alignas(64) uint64_t seqno; ///< Sequence number, for gap/liveness check uint16_t event_type; ///< What kind of event this is uint16_t : 16; ///< Unused tail padding uint32_t payload_size; ///< Size of event payload uint64_t record_epoch_nanos; ///< Time event was recorded uint64_t payload_buf_offset; ///< Unwrapped offset of payload in p. buf uint64_t content_ext[4]; ///< Extensions for particular content types }; ### [​](https://docs.monad.xyz/execution-events/event-ring#flow-tags-the-content_ext-fields-in-execution-event-rings) Flow tags: the `content_ext` fields in execution event rings For each content type, we may want to publish additional data directly in the event descriptor, e.g., if that data is common to every payload type or if it would help the reader quickly filter out events they are not interested in, without needing to examine the event payload. This additional data is stored in the `content_ext` (“content extensions”) array, and its meaning is defined by the `content_type`. For execution event rings, the first three values of the `content_ext` array are sometimes filled in. The value at each index in the array has the semantic meaning described by the following enumeration type, which is defined in `exec_event_ctypes.h`: /// Stored in event descriptor's `content_ext` array to tag the /// block & transaction context of event enum monad_exec_flow_type : uint8_t { MONAD_FLOW_BLOCK_SEQNO = 0, MONAD_FLOW_TXN_ID = 1, MONAD_FLOW_ACCOUNT_INDEX = 2, }; For example, if we have an event descriptor struct monad_event_descriptor event; And its contents are initialized by a call to `monad_event_iterator_try_next`, then `event.content_ext[MONAD_FLOW_TXN_ID]` will contains the “transaction ID” for that event. The transaction ID is equal to the transaction index plus one, and it is zero if the event has no associated transaction (e.g., the start of a new block). The idea behind the “flow” tags is that they tag events with the context they belong to. For example, when a transaction accesses a particular account storage key, a `STORAGE_ACCESS` event is emitted. By looking at the `content_ext` array for the `STORAGE_ACCESS` event descriptor, the reader can tell it is a storage access made (1) by the transaction with index `event.content_ext[MONAD_FLOW_TXN_ID] - 1` and (2) to the account with index `event.content_ext[MONAD_FLOW_ACCOUNT_INDEX]` (this index is related to an earlier `ACCOUNT_ACCESS` event series that will have already been seen). Flow tags are used for two reasons: 1. **Fast filtering** - if we are processing 10,000 transactions per second, and there are at least a dozen events per transaction, then we only have about 10 microseconds to process each event or we’ll eventually fall behind and gap. At timescales like these, even touching the memory containing the event payload is expensive, on a relative basis. The event payload lives on a different cache line — one that is not yet warm in the reader’s CPU — and the cache line ownership must first be changed in the cache coherence protocol (because it was recently exclusively owned by the writer, and now must be shared with the reading CPU, causing cross-core bus traffic). For most applications, the user can identify transactions IDs they are interested in at the time of the `TXN_HEADER_START` event, and then any event without an interesting ID can be ignored. Because the IDs are a dense set of integers, a simple array of type `bool[TXN_COUNT + 1]` can be used to efficiently look up whether subsequent events associated with that transaction are interesting (this can be made even more efficient using a single bit instead of a full `bool` per transaction) 2. **Compression** - the account of a `STORAGE_ACCESS` is referred to by an index (which refers to an earlier `ACCOUNT_ACCESS` event) because an account address is 20 bytes: large enough that it cannot fit in the two remaining `content_ext` array slots The compression technique is also used for storing the block associated with an event, in `event.content_ext[MONAD_FLOW_BLOCK_SEQNO]`. The flow tag in this case is the _sequence number_ of the `BLOCK_START` event that started the associated block. A few things to note about this flow tag: * Sometimes it is zero (an invalid sequence number), which means the event is not associated with any block; although most events are scoped to a block, the consensus state change events (`BLOCK_QC`, `BLOCK_FINALIZED`, and `BLOCK_VERIFIED`) do not occur inside a block * Note that the block flow tag is _not_ the block number. This is because at the time events are seen, the blocks are in the “proposed” state, and the consensus algorithm has not finished voting on whether or not the block will be included in the canonical blockchain (this is discussed extensively in the next section). Until a block becomes finalized, the only unambiguous way to refer to it is by its unique ID, which is 32-byte hash value (which can be read from the `BLOCK_START` payload); thus the block flow tag is also a form of compression * Having the sequence number allows us to rewind the iterator to the start of the block, if we start observing the event sequence in the middle of a block (e.g., if the reader starts up after the execution daemon). An example of this (and a detailed explanation of it) can be found in the `eventwatch.c` example program, in the `find_initial_iteration_point` function Footnotes --------- 1. They are called “shifts” because `1UL << x` is equal to `2^x` [↩](https://docs.monad.xyz/execution-events/event-ring#user-content-fnref-1) 2. The alternative recovery methods are still in development and will be available in the next SDK release [↩](https://docs.monad.xyz/execution-events/event-ring#user-content-fnref-2) [Execution events overview\ \ Previous](https://docs.monad.xyz/execution-events/overview) [C API\ \ Next](https://docs.monad.xyz/execution-events/c-api) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Hardhat - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/tooling-and-infra/toolkits/hardhat#content-area) [Hardhat](https://hardhat.org/docs) is a Solidity development framework paired with a JavaScript testing framework. When configuring your Hardhat project for Monad, set the EVM version to `prague` in your `hardhat.config.js`: module.exports = { solidity: { version: "0.8.28", settings: { evmVersion: "prague", }, }, }; For deployment and verification guides using Hardhat, see: * [Deploy a Contract with Hardhat](https://docs.monad.xyz/guides/deploy-smart-contract/hardhat) * [Verify a Contract with Hardhat](https://docs.monad.xyz/guides/verify-smart-contract/hardhat) [Monad Foundry\ \ Previous](https://docs.monad.xyz/tooling-and-infra/toolkits/monad-foundry) [Monad Solonet\ \ Next](https://docs.monad.xyz/tooling-and-infra/toolkits/monad-solonet) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Advanced topics - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/execution-events/advanced#content-area) [​](https://docs.monad.xyz/execution-events/advanced#when-are-events-published) When are events published? ------------------------------------------------------------------------------------------------------------- Execution events are recorded roughly “as they are happening” inside the execution daemon: you see a `BLOCK_START` event at roughly the same moment that the execution daemon beings processing a new block, followed by the start of the first transaction (a `TXN_HEADER_START` event) about 1 millisecond later. Most transaction-related events are recorded less than one microsecond after the transaction they describe has completed. Execution of a typical transaction will emit a few dozen events, but large transactions can emit hundreds of events. The `TXN_EVM_OUTPUT` event — which is recorded as soon as the transaction is finished — provides a summary accounting of how many more events related to that transaction will follow (how many logs, how many call frames, etc.), so that memory to store the subsequent event data can be preallocated. For example in Rust, [`Vec::reserve`](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.reserve) is often called here. An event like `TXN_EVM_OUTPUT` is referred as a “header event” in the documentation: it is an event whose content describes some summary information and the number of subsequent, related events that will be recorded later with more details. All these events are recorded as soon as the transaction is “committed” to the currently-executing block. This happens before the block has finished executing, and should not be confused with the unrelated notion of “commitment” in the consensus algorithm. Although there are complex speculative execution optimizations inside the execution daemon, the recording of a transaction takes place when all work on a particular transaction has finished. This is referred to as “transaction commit” time. This is a different than the block-at-a-time style update you would see in, for example, the Geth real-time events WebSocket protocol (which our RPC server also [supports](https://docs.monad.xyz/reference/websockets) ). Certain properties of the block (its hash, its state root, etc.) are not known at the time you see a transaction’s events, because the rest of the block is still executing. If you would like block-at-a-time updates, the Rust SDK contains [some utilities](https://docs.monad.xyz/execution-events/rust-api#block-level-utilities) which will aggregate the events back into complete, block-oriented updates. One thing to be careful of: although transactions are always committed to a block in index order, they might be recorded out of order. That is, you must assume that the set of execution events that make up transactions 2 and 3 could be “mixed together” in any order. This is because of optimizations in the event recording code path. However, _for a particular transaction_ (e.g., transaction 3) events pertaining to that transaction are always recorded in the same order: first all of the logs, then all the call frames, then all the state access records. Each of these is recorded in _index order_, i.e., log 2 is always recorded before log 3. Consider the following diagram: ╔═Events═════════════════════════════╗ ║ ║ ║ ┌───────────────────────────────┐ ║ ║ │ event type: TXN_EVM_OUTPUT │ ║ ║ │ transaction: 1 │ ║ ║ │ log count: 2 │ ║ ║ └───────────────────────────────┘ ║ ║ ║ ║ ┌───────────────────────────────┐ ║ ║ │ event type: TXN_LOG │ ║ ║ │ transaction: 1 │ ║ ║ │ log index: 0 │ ║ ║ │ │ ║ ║ └───────────────────────────────┘ ║ ║ ║ ║ ┌───────────────────────────────┐ ║ ║ │ event type: TXN_EVM_OUTPUT │ ║ ║ │ transaction: 0 │ ║ ║ │ log count: 3 │ ║ ║ └───────────────────────────────┘ ║ ║ ║ ║ ┌───────────────────────────────┐ ║ ║ │ event type: TXN_LOG │ ║ ║ │ transaction: 0 │ ║ ║ │ log index: 0 │ ║ ║ │ │ ║ ║ └───────────────────────────────┘ ║ ║ ║ ║ ┌───────────────────────────────┐ ║ ║ │ event type: TXN_LOG │ ║ ║ │ transaction: 0 │ ║ ║ │ log index: 1 │ ║ ║ │ │ ║ ║ └───────────────────────────────┘ ║ ║ ║ ║ ┌───────────────────────────────┐ ║ ║ │ event type: TXN_LOG │ ║ ║ │ transaction: 1 │ ║ ║ │ log index: 1 │ ║ ║ │ │ ║ ║ └───────────────────────────────┘ ║ ║ ║ ║ ┌───────────────────────────────┐ ║ ║ │ event type: TXN_LOG │ ║ ║ │ transaction: 0 │ ║ ║ │ log index: 2 │ ║ ║ │ │ ║ ║ └───────────────────────────────┘ ║ ║ ║ ╚════════════════════════════════════╝ A few things to note here: * Unlike most diagrams in the documentation, the events are shown in a simplified, “merged” form; in real events, some of this information is stored in the event descriptor and some is stored in the event payload, but they’re combined to make the diagram simpler * It shows two transactions, with transaction indices 0 and 1. Although transaction 0 completes first in the EVM, its `TXN_EVM_OUTPUT` event is recorded _after_ than the `TXN_EVM_OUTPUT` of transaction 1 * Events from the transactions are interleaved: sometimes the next one relates to transaction 0, sometimes to transaction 1, and there is no meaningful order between them * Despite the transactions being out-of-order with respect to each other, all the events associated with a particular transaction are always in relative order, i.e., the log indicies for a particular transaction will always be seen in `log_index` order, as above This is easy to understand if you imagine all of a transaction’s events being recorded by a different thread. For a particular transaction, its thread always records that transaction’s events in order, but the “transaction threads” themselves race against each other, recording in a non-deterministic order. This is similar to what really happens, except the transactions are recorded on [fibers](https://en.wikipedia.org/wiki/Fiber_(computer_science)) rather than full threads. [​](https://docs.monad.xyz/execution-events/advanced#sequence-numbers-and-the-lifetime-detection-algorithm) Sequence numbers and the lifetime detection algorithm -------------------------------------------------------------------------------------------------------------------------------------------------------------------- All event descriptors are tagged with an incrementing sequence number starting at 1. Sequence numbers are 64-bit unsigned integers which do not repeat unless the execution daemon is restarted. Zero is not valid sequence number. Also note that the sequence number modulo the descriptor array size equals the array index where the _next_ event descriptor will be located. This is shown below with a concrete example where the descriptor array size is 64. Note that the last valid index in the array is 63, then access wraps around to the beginning of the array at index 0. ◇ │ ╔═...═════════════════════════Event descriptor array═══╬═══════════════════...═╗ ║ │ ║ ║ ┌─Event────────┐┌─Event────────┐┌─Event────────┐ │ ┌─Event─────────┐ ║ ║ │ ││ ││ │ │ │ │ ║ ║ │ seqnum = 318 ││ seqnum = 319 ││ seqnum = 320 │ │ │ seqnum = 256 │ ║ ║ │ ││ ││ │ │ │ │ ║ ║ └──────────────┘└──▲───────────┘└──────────────┘ │ └───────────────┘ ║ ║ 61 │ 62 63 │ 0 ║ ╚═...════════════════════╬═════════════════════════════╬═══════════════════...═╝ │ │ ■ ◇ Next event Ring buffer wrap-around to ┌──────────────────────────────┐ zero is here │last read sequence number │ │(last_seqno) is initially 318 │ └──────────────────────────────┘ In this example: * We keep track of the “last seen sequence number” (`last_seqno`) which has value `318` to start; being the “last” sequence number means we have already finished reading the event with this sequence number, which lives at array index `61` * `318 % 64` is `62`, so we will find the potential next event at that index _if_ it has been produced * Observe that the sequence number of the item at index `62` is `319`, which is the last seen sequence number plus 1 (`319 == 318 + 1`). This means that event `319` has been produced, and its data can be safely read from that slot * When we’re ready to advance to the next event, the last seen sequence number will be incremented to `319`. As before, we can find the _next_ event (if it has been produced) at `319 % 64 == 63`. The event at this index bears the sequence number `320`, which is again the last seen sequence number + 1, therefore this event is also valid * When advancing a second time, we increment the last seen sequence number to `320`. This time, the event at index `320 % 64 == 0` is _not_ `321`, but is a smaller number, `256`. This means the next event has not been written yet, and we are seeing an older event in the same slot. We’ve seen all of the currently available events, and will need to check again later once a new event is written * Alternatively we might have seen a much larger sequence number, like `384` (`320 + 64`). This would mean that we consumed events too slowly, so slowly that the 63 events in the range `[321, 384)` were produced in the meantime. These were subsequently overwritten, and are now lost. They can be replayed using services external to event ring API, but _within_ the event ring API itself there is no way to recover them\ \ [​](https://docs.monad.xyz/execution-events/advanced#lifetime-of-an-event-payload-zero-copy-vs-memcpy-apis)\ \ Lifetime of an event payload, zero copy vs. memcpy APIs\ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------\ \ Because of the descriptor overwrite behavior, an event descriptor might be overwritten by the execution daemon while a reader is still examining its data. To deal with this, the reader API makes a copy of the event descriptor. If it detects that the event descriptor changed during the copy operation, it reports a gap. Copying an event descriptor is fast, because it is only a single cache line in size. This is not the case for event payloads, which could potentially be very large. This means a `memcpy(3)` of an event payload could be expensive, and it would be advantageous to read the payload bytes directly from the payload buffer’s shared memory segment: a “zero-copy” API. This exposes the user to the possibility that the event payload could be overwritten while still using it, so two solutions are provided:\ \ 1. A simple detection mechanism allows payload overwrite to be detected at any time: the writer keeps track of the minimum payload offset value (_before_ modular arithmetic is applied) that is still valid. If the offset value in the event descriptor is smaller than this, it is no longer safe to read the event payload\ 2. A payload `memcpy`\-style API is also provided. This uses the detection mechanism above in the following way: first, the payload is copied to a user-provided buffer. Before returning, it checks if the lifetime remained valid after the copy finished. If so, then an overwrite did not occur during the copy, so the copy must be valid. Otherwise, the copy is invalid\ \ The reason to prefer the zero-copy APIs is that they do less work. The reason to prefer memcpy APIs is that it is not always easy (or possible) to “undo” the work you did if you find out later that the event payload was corrupted by an overwrite while you were working with it. The most logical thing to do in that case is start by copying the data to stable location, and if the copy isn’t valid, to never start the operation. An example user of the zero-copy API is the `eventwatch` example C program, which can turn events into printed strings that are sent to `stdout`. The expensive work of formatting a hexdump of the event payload is performed using the original payload memory. If an overwrite happened during the string formatting, the hexdump output buffer will be wrong, but that is OK: it will not be sent to `stdout` until the end. Once formatting is complete, `eventwatch` checks if the payload expired and if so, writes an error to `stderr` instead of writing the formatted buffer to `stdout`. Whether you should copy or not depends on the characteristics of the reader, namely how easily it can deal with “aborting” processing.\ \ [​](https://docs.monad.xyz/execution-events/advanced#location-of-event-ring-files)\ \ Location of event ring files\ ------------------------------------------------------------------------------------------------------------------\ \ For performance reasons, we prefer that event ring files be created on a [hugetlbfs](https://www.kernel.org/doc/html/v4.18/admin-guide/mm/hugetlbpage.html#hugetlbpage)\ in-memory filesystem. Files created on such a filesystem will be backed by physically-contiguous large pages, which improves performance by about 15% in internal benchmarks. This can be a hassle though: it is unusual for a program to require that a file be placed on a _particular kind_ of filesystem, and this requirement adds some overhead. In practice, this means additional configuration steps that a system administrator must perform when setting up a Monad node, and some additional concepts that SDK users must learn about. The issues are:\ \ 1. A hugetlbfs filesystem must be mounted somewhere on the host; usually by default (e.g., on a Ubuntu default installation) there will not be a hugetlbfs filesystem already present\ 2. Whomever configures a hugetlbfs filesystem must make sure that any user that needs to open the event ring file has the appropriate permissions\ 3. The path to the event ring file (which will be somewhere on that filesystem) must be passed into all programs that need to open it; since we don’t know where the administrator will mount the filesystem, we can’t easily hard-code a location for it in either the documentation or the source code\ \ To simplify the developer experience as much as possible, we follow three conventions. Each convention adds more “convenience default behavior” so that everything will “just work” for most users, but you are free to ignore any of the conventions and do things in your own way.\ \ The event ring library does not require a hugetlbfs filesystem: it can work with _any_ kind of regular file. The C function that maps an event ring’s shared memory segments — `monad_event_ring_mmap` — only takes a file descriptor, and does not know or care where this descriptor comes from. The only constraints on it are those placed by the `mmap(2)` system call itself.These conventions are about adding a reasonable default for how the mount point is set up, and helper functions for finding event ring files in that location. You should try to use them because they provide a performance benefit, but you are free to come up with a file descriptor in any way you wish and it will work with `monad_event_ring_mmap`.\ \ ### \ \ [​](https://docs.monad.xyz/execution-events/advanced#convention-1-libhugetlbfs-in-the-node-setup-guide)\ \ Convention 1: libhugetlbfs in the node setup guide\ \ The [official guide](https://validator-docs.vercel.app/docs/full_node/events-and-websockets)\ for setting up a local Monad node for execution events recommends the use of `libhugetlbfs`. `libhugetlbfs` is both a C library and a set of admin tools using that library that follow a particular configuration convention. The idea is to standardize some rules for how mount points and permissions are managed for hugetlbfs filesystems. There are three parts to the basic idea:\ \ 1. Each user (or group if you want to do it that way) gets its own separately-mounted hugetlbfs filesystem. The mount point is located in a well-defined place under `/var/lib/hugetlbfs/user/`[1](https://docs.monad.xyz/execution-events/advanced#user-content-fn-1)\ \ 2. `hugeadm`, a program that a system administrator runs, is a configuration front-end for tasks like listing hugetlbfs mounts, creating new mounts, etc.\ 3. The C library, `libhugetlbfs`, helps client programs “find” hugetlbfs mounts that the current user has permission to access\ \ The setup guide for the Monad node tells the user to install the `libhugetlbfs` command line tools and to set up a “user mount” for the `monad` user. The guide also recommends that all users be given access to enter this directory, so that data consumer applications that run as non-`monad` users can open the file.\ \ ### \ \ [​](https://docs.monad.xyz/execution-events/advanced#convention-2-%E2%80%9Cdefault%E2%80%9D-event-ring-directory)\ \ Convention 2: “default” event ring directory\ \ The event ring library introduces the concept of a “default event ring directory.” This is the default directory where event ring files should be created, and thus where reader applications should look for them. This default can come from one of two places:\ \ 1. You can provide it manually OR\ 2. If you don’t provide it, the library will use a conventional location\ \ The conventional location is a subdirectory called `event-rings`, created directly under whatever hugetlbfs mount point is returned by `libhugeltbfs`[2](https://docs.monad.xyz/execution-events/advanced#user-content-fn-2)\ , i.e., it is:\ \ /event-rings\ \ \ If you follow the setup guide to the letter, this should be:\ \ /var/lib/hugetlbfs/user/monad/pagesize-2MB/event-rings\ \ \ But depending on how your system is setup, `libhugetlbfs` could return a different path. For example, you might see something like this:\ \ /dev/hugepages/event-rings\ \ \ This is because `libhugeltbfs` scrapes the contents of `/proc/mounts` and returns only one path that the current user has [access](https://man7.org/linux/man-pages/man2/access.2.html)\ to. What if the user has access to multiple hugetlbfs mounts? There is no logic to prefer one flavor of path over another, it only depends on their relative ordering in the `/proc/mounts` file.\ \ #### \ \ [​](https://docs.monad.xyz/execution-events/advanced#providing-the-default-event-ring-directory-manually)\ \ Providing the default event ring directory manually\ \ You may wish to use this “open from the default directory” configuration idiom while by-passing libhugetlbfs. The two reasons to do that are:\ \ 1. If you don’t want the event ring file to be present on a hugetlbfs file system at all; this is usually when you want to create an event ring file larger than the hugetlbfs mount point (or the system’s underlying pool of huge pages) would allow\ 2. If you do not want to use libhugetlbfs as a library dependency of your project, in which case you will want to set the CMake `MONAD_EVENT_USE_LIBHUGETLBFS` option to `OFF`\ \ ### \ \ [​](https://docs.monad.xyz/execution-events/advanced#convention-3-event-ring-filename-resolution)\ \ Convention 3: event ring filename resolution\ \ The “default directory” concept is used in the final convention, which is a “convenience” API call for turning user input for an event ring file into the path where your program will attempt to open that file. It allows users to specify a filename such as `xyz` and have it be translated to a full (and ugly) path like this:\ \ /var/lib/hugetlbfs/user/monad/pagesize-2MB/event-rings/xyz\ \ \ while still allowing the user to be able to specify _any_ file, including one not in the default directory, if they wish. Here is how event ring file inputs are resolved by the the C function `monad_event_ring_resolve_file` and the Rust function `EventRingPath::resolve`:\ \ * If a “pure” filename is provided (i.e., a filename with no `/` character), it is resolved relative to a provided `default_path` directory\ * Otherwise (i.e., if the file contains any `/` character), it is resolved relative to the current working directory; if `/` is the first character, it is resolved as an absolute path\ \ This is similar to how a UNIX shell resolves a command name. A “pure” name with no path characters is resolved relative to the entries in the `$PATH` environment variable (i.e., it searches the default command directories). The presence of a path-separator character causes the input to be treated like a specific path relative to the current directory, which disables this “search”. This familiar principal applies here. Furthermore:\ \ * In C you usually pass the sentinel value `MONAD_EVENT_DEFAULT_HUGETLBFS` (which is just an alias for `nullptr`) as the `default_path` parameter; this causes `libhugetlbfs` to figure out what the default hugetlbfs root path should be[3](https://docs.monad.xyz/execution-events/advanced#user-content-fn-3)\ ; in Rust this is just `EventRingPath::resolve`\ * You can provide your own `default_path` value, which can be on any path on any filesystem; this is required if you don’t want `libhugetlbfs` as a dependency; in Rust this is `EventRingPath::resolve_with_default_path`\ \ Resolution does not try to open a file: it just standardizes the convention for how to build a path string from the two inputs. Namely, it does not check whether the computed file path exists or not.Remember that the event ring library itself only cares about file descriptors, and none of its APIs (even the “helper” APIs) attempt to [open(2)](https://man7.org/linux/man-pages/man2/open.2.html)\ a file. They just provide “reasonable default” ways of locating files that programs can opt into. If your host needs to set up your filesystem mounts differently, you are free to do that.\ \ #### \ \ [​](https://docs.monad.xyz/execution-events/advanced#examples)\ \ Examples\ \ The table below shows how the C function `monad_event_ring_resolve_file` behaves. `` is the process’ current working directory and `` is the mount point returned by `libhugetlbfs`.\ \ | `default_path` value | `input` value | resolve file returns… | Notes |\ | --- | --- | --- | --- |\ | `MONAD_EVENT_DEFAULT_HUGETLBFS` | `"xyz"` | `"/event-rings/xyz"` | |\ | `MONAD_EVENT_DEFAULT_HUGETLBFS` | `"a/b/c"` | `"/a/b/c"` | `default_path` only affects “pure” file names |\ | `MONAD_EVENT_DEFAULT_HUGETLBFS` | `"/d/e/f"` | `"/d/e/f"` | absolute paths always remain absolute |\ | `MONAD_EVENT_DEFAULT_HUGETLBFS` | `"monad-exec-events"` | `"/event-rings/monad-exec-events"` | the default event ring file name used by the execution daemon |\ | `"/tmp/my-event-ring-path"` | `"xyz"` | `"/tmp/my-event-ring-path/xyz"` | intermediate directories will be created if not existing |\ | `"/tmp/my-event-ring-path"` | `"a/b/c"` | `"/a/b/c"` | |\ | `"/tmp/my-event-ring-path"` | `"/d/e/f"` | `"/d/e/f"` | |\ \ In Rust, `EventRingPath::resolve` behaves like the `MONAD_EVENT_DEFAULT_HUGETLBFS` rows, and `EventRingPath::resolve_with_default_path` takes an explicit `basepath` argument and behaves like the bottom three rows.\ \ Footnotes\ ---------\ \ 1. Other configuration schemes are possible too, see [`man hugeadm`](https://linux.die.net/man/8/hugeadm)\ [↩](https://docs.monad.xyz/execution-events/advanced#user-content-fnref-1)\ \ 2. The exact path might be user-dependent, and is determined by the function `hugetlbfs_find_path_for_size` [↩](https://docs.monad.xyz/execution-events/advanced#user-content-fnref-2)\ \ 3. The actual function used is the event ring library’s utility function `monad_event_open_hugetlbfs_dir_fd`, which adds in the `event-rings` subdirectory path component and creates it if it does not already exist [↩](https://docs.monad.xyz/execution-events/advanced#user-content-fnref-3)\ \ \ [Consensus events\ \ Previous](https://docs.monad.xyz/execution-events/consensus-events)\ [Staking Overview\ \ Next](https://docs.monad.xyz/reference/staking/overview)\ \ ⌘I\ \ Assistant\ \ Responses are generated using AI and may contain mistakes. --- # Software Wallets - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/tooling-and-infra/wallets/software-wallets#content-area) [​](https://docs.monad.xyz/tooling-and-infra/wallets/software-wallets#provider-summary) Provider Summary ----------------------------------------------------------------------------------------------------------- Monad is supported on most EVM-compatible wallets, including the below. To add Monad to an EVM-compatible wallet, use the wallet’s network selector, or use [this tool](https://docs.monad.xyz/guides/add-monad-to-wallet/mainnet) . * Mainnet * Testnet | Wallet | Status | Available on | Autodetect Tokens and NFTs | Other Features | | --- | --- | --- | --- | --- | | [Ambire Wallet](https://www.ambire.com/) | ✅ | Desktop, Mobile | Tokens | Smart accounts (EIP-7702), Open source, Gas Tank, DApp connectivity | | [Backpack](https://backpack.app/) | ✅ | Desktop, Mobile | Tokens, NFTs | DApp browser, Built-in exchange, Futures trading, Portfolio tracking | | [Binance Wallet](https://www.binance.com/en/web3wallet) | ✅ | Desktop, Mobile | Tokens, NFTs | DApp browser, Token swaps, Multi-chain support, Binance exchange integration | | [Bitget Wallet](https://web3.bitget.com/en?source=bitget) | ✅ | Desktop, Mobile | Tokens | DApp browser, NFT Market, DApp Browser, and Launchpad | | [Coin98 Wallet](https://coin98.com/) | ✅ | Desktop, Mobile | Tokens, NFTs | Multi-chain support, DApp browser, Cross-chain swaps, NFT Gallery | | [Exodus](https://www.exodus.com/) | ✅ | Desktop, Mobile | Tokens, NFTs | Token swaps, Staking, Portfolio tracking, NFT support, Buy crypto | | [imToken](https://token.im/) | ✅ | Mobile | Tokens | Multi-chain support, DApp browser, Token swaps, Staking | | [Infinex](https://infinex.xyz/) | ✅ | Desktop, Mobile | Tokens | Passkey login (no seed phrase), Smart accounts, Cross-chain swaps, Spot and perps trading, NFT support | | [Keplr](https://www.keplr.app/) | ✅ | Desktop, Mobile | None | Multi-chain support, Open source, Portfolio tracking, Transaction History, In-app browser | | [MetaMask](https://metamask.io/) | ✅ | Desktop, Mobile | Tokens, NFTs | NFT support, DApp browser, Open source, Token swaps, portfolio tracking | | [OKX Wallet](https://web3.okx.com/) | ✅ | Desktop, Mobile | Tokens, NFTs | DApp browser, Portfolio tracking, Cross-chain swaps, Biometric Login | | [Rabby Wallet](https://rabby.io/) | ✅ | Desktop, Mobile | Tokens, NFTs | Portfolio tracking, Biometric login | | [Rainbow](https://rainbow.me/) | ✅ | Desktop, Mobile | Tokens, NFTs | Token swaps, Cross-chain bridging, NFT support, Hardware wallet support, Open source | | [Safepal](https://www.safepal.com/) | ✅ | Desktop, Mobile | Tokens, NFTs | NFT support, DApp browser, Token swaps, Hardware wallet support | | [Trust Wallet](https://trustwallet.com/) | ✅ | Desktop, Mobile | Tokens, NFTs | Multi-chain support, NFT support, DApp browser, Token swaps, Staking, Buy crypto | | [Uniswap Wallet](https://wallet.uniswap.org/) | ✅ | Desktop, Mobile | Tokens | Token swaps, Built-in bridge, DApp connectivity | | [Zerion](https://zerion.io/) | ✅ | Desktop, Mobile | Tokens, NFTs | Portfolio tracking, DeFi, DApp browser, NFT support | | Wallet | Status | Available on | Autodetect Tokens and NFTs | Other Features | | --- | --- | --- | --- | --- | | [Backpack](https://backpack.app/) | ✅ | Desktop, Mobile | Tokens, NFTs | DApp browser, Built-in exchange, Futures trading, Portfolio tracking | | [Bitget Wallet](https://web3.bitget.com/en?source=bitget) | ✅ | Desktop, Mobile | Tokens | DApp browser, NFT Market, DApp Browser, and Launchpad | | [Coin98 Wallet](https://coin98.com/) | ✅ | Desktop, Mobile | Tokens, NFTs | Multi-chain support, DApp browser, Cross-chain swaps, NFT Gallery | | [imToken](https://token.im/) | ✅ | Mobile | Tokens | Multi-chain support, DApp browser, Token swaps, Staking | | [MetaMask](https://metamask.io/) | ✅ | Desktop, Mobile | NFTs | NFT support, DApp browser, Open source, Token swaps, portfolio tracking | | [OKX Wallet](https://www.okx.com/en-us/help/section/faq-web3-wallet) | ✅ | Desktop, Mobile | Tokens, NFTs | DApp browser, Portfolio tracking, Cross-chain swaps, Biometric Login | | [Rabby Wallet](https://rabby.io/) | ✅ | Desktop, Mobile | Tokens, NFTs | Portfolio tracking, Biometric login | | [Safepal](https://www.safepal.com/) | ✅ | Desktop, Mobile | Tokens, NFTs | NFT support, DApp browser, Token swaps, Hardware wallet support | | [Trust Wallet](https://trustwallet.com/) | ✅ | Desktop, Mobile | Tokens, NFTs | Multi-chain support, NFT support, DApp browser, Token swaps, Staking, Buy crypto | | [Uniswap Wallet](https://wallet.uniswap.org/) | ✅ | Desktop, Mobile | Tokens | Token swaps, Built-in bridge, DApp connectivity | | [Zerion](https://zerion.io/) | ✅ | Desktop, Mobile | Tokens, NFTs | Portfolio tracking, DeFi, DApp browser, NFT support | [​](https://docs.monad.xyz/tooling-and-infra/wallets/software-wallets#provider-details) Provider Details ----------------------------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/tooling-and-infra/wallets/software-wallets#ambire-wallet) Ambire Wallet [Ambire Wallet](https://www.ambire.com/) is an open-source, self-custodial wallet with smart-account features via EIP-7702, supporting EOAs, smart accounts, and hardware wallets across many EVM networks. It includes a Gas Tank and built-in DApp connectivity. To get started, get Ambire Wallet [here](https://www.ambire.com/) or visit the [documentation](https://help.ambire.com/) . ### [​](https://docs.monad.xyz/tooling-and-infra/wallets/software-wallets#backpack) Backpack [Backpack](https://backpack.app/) is a next-level wallet and exchange. Buy tokens, trade futures, and explore on-chain apps—seamlessly and securely. 🎒 To get started, download the Backpack wallet [here](https://backpack.app/) or visit the [documentation](https://docs.backpack.app/) . ### [​](https://docs.monad.xyz/tooling-and-infra/wallets/software-wallets#binance-wallet) Binance Wallet [Binance Wallet](https://www.binance.com/en/web3wallet) is a self-custodial Web3 wallet built into the Binance app and browser extension. It uses keyless (MPC) security and lets users hold assets, swap tokens, and explore DApps across multiple chains, with easy transfers to and from the Binance exchange. To get started, get the Binance Wallet [here](https://www.binance.com/en/web3wallet) . ### [​](https://docs.monad.xyz/tooling-and-infra/wallets/software-wallets#bitget-wallet) Bitget Wallet [Bitget Wallet](https://web3.bitget.com/en?source=bitget) is a non-custodial wallet with advanced multi-chain capabilities and powerful swap function To get started, download the Bitget wallet [here](https://web3.bitget.com/en/wallet-download?type=2) or visit the [documentation](https://web3.bitget.com/en/docs/) . ### [​](https://docs.monad.xyz/tooling-and-infra/wallets/software-wallets#coin98-wallet) Coin98 Wallet [Coin98 Wallet](https://coin98.com/) is a multi-chain wallet that connects users to numerous blockchains, allowing for seamless asset management and DeFi interactions. It features cross-chain swaps, an integrated DApp browser, and comprehensive portfolio tracking across multiple networks. To get started, download Coin98 Wallet [here](https://coin98.com/wallet) or visit the [documentation](https://docs.coin98.com/) . ### [​](https://docs.monad.xyz/tooling-and-infra/wallets/software-wallets#exodus) Exodus [Exodus](https://www.exodus.com/) is a multi-asset, self-custodial wallet available on desktop, mobile, and as a browser extension. It supports thousands of assets across many networks, with built-in swaps, staking, and NFT support. To get started, download Exodus [here](https://www.exodus.com/download) or visit the [documentation](https://www.exodus.com/support) . ### [​](https://docs.monad.xyz/tooling-and-infra/wallets/software-wallets#imtoken) imToken [imToken](https://token.im/) is a widely used multi-chain, self-custodial wallet with native Monad support alongside many other networks. It offers asset management, a built-in DApp browser, token swaps, and staking. To get started, download imToken [here](https://token.im/) or visit the [documentation](https://support.token.im/) . ### [​](https://docs.monad.xyz/tooling-and-infra/wallets/software-wallets#infinex) Infinex [Infinex](https://infinex.xyz/) is a non-custodial, cross-chain DeFi platform available as a webapp and browser extension. It replaces seed phrases with passkeys and smart-account security, letting users trade spot and perpetuals, swap and bridge assets, earn yield, and interact with NFTs across many chains including Monad — all in an exchange-like interface while retaining full self-custody. To get started, get Infinex [here](https://app.infinex.xyz/) or visit the [documentation](https://support.infinex.xyz/) . ### [​](https://docs.monad.xyz/tooling-and-infra/wallets/software-wallets#keplr-wallet) Keplr Wallet [Keplr Wallet](https://www.keplr.app/) is an open-source, multichain wallet supporting Cosmos, Bitcoin, Ethereum, Starknet, and more. Download Keplr [here](https://www.keplr.app/get) or visit the [documentation](https://docs.keplr.app/api/intro) . ### [​](https://docs.monad.xyz/tooling-and-infra/wallets/software-wallets#metamask) MetaMask [MetaMask](https://metamask.io/) is a secure and easy-to-use wallet with native support for Monad, letting you swap and bridge on Monad directly in the wallet. To get started, download the MetaMask wallet [here](https://metamask.io/download) or visit the [documentation](https://docs.metamask.io/) . ### [​](https://docs.monad.xyz/tooling-and-infra/wallets/software-wallets#okx-wallet) OKX Wallet [OKX Wallet](https://www.okx.com/en-us/help/section/faq-web3-wallet) is your all-in-one gateway to the Web3 world. To get started, download the OKX Wallet [here](https://chromewebstore.google.com/detail/okx-wallet/mcohilncbfahbmgdjkbpemcciiolgcge) or visit the [documentation](https://www.okx.com/web3/build/docs/sdks/okx-wallet-integration-introduction) . ### [​](https://docs.monad.xyz/tooling-and-infra/wallets/software-wallets#rabby-wallet) Rabby Wallet [Rabby Wallet](https://rabby.io/) is a non-custodial, multi-chain Web3 wallet created by DeBank that makes using decentralized apps easier and safer. It supports Monad and many other blockchains, automatically detects networks, and shows transaction simulations with risk alerts to help prevent mistakes or scams. Users keep full control of their keys. Download Rabby wallet and learn more about it [here](https://rabby.io/) . ### [​](https://docs.monad.xyz/tooling-and-infra/wallets/software-wallets#rainbow) Rainbow [Rainbow](https://rainbow.me/) is a self-custodial, open-source Ethereum wallet available as a mobile app and browser extension, supporting Monad alongside many other EVM networks. Known for its polished design, it offers built-in token swaps and cross-chain bridging, rich NFT support, hardware wallet integration, and multi-wallet management. To get started, download Rainbow [here](https://rainbow.me/en/download) or visit the [documentation](https://rainbow.me/en/support) . ### [​](https://docs.monad.xyz/tooling-and-infra/wallets/software-wallets#safepal) Safepal [Safepal](https://www.safepal.com/) is a cryptocurrency wallet that offers both software and hardware wallet solutions. It provides secure storage for digital assets with features like token swaps, NFT management, and DApp browsing. Safepal emphasizes security while maintaining user-friendly access to DeFi and Web3 applications. To get started, download the Safepal wallet [here](https://www.safepal.com/download) or visit the [documentation](https://docs.safepal.io/) . ### [​](https://docs.monad.xyz/tooling-and-infra/wallets/software-wallets#trust-wallet) Trust Wallet [Trust Wallet](https://trustwallet.com/) is a popular multi-chain cryptocurrency wallet that supports millions of assets and blockchains. It provides a secure, decentralized platform for storing, sending, and receiving cryptocurrencies, with built-in features for staking, NFT management, and accessing DApps. To get started, download Trust Wallet [here](https://trustwallet.com/download) or visit the [documentation](https://developer.trustwallet.com/) . ### [​](https://docs.monad.xyz/tooling-and-infra/wallets/software-wallets#uniswap-wallet) Uniswap Wallet [Uniswap Wallet](https://wallet.uniswap.org/) is the self-custodial wallet from Uniswap, available on mobile and as a browser extension, with built-in token swapping and bridging across supported networks including Monad. To get started, get the Uniswap Wallet [here](https://wallet.uniswap.org/) . ### [​](https://docs.monad.xyz/tooling-and-infra/wallets/software-wallets#zerion) Zerion [Zerion](https://zerion.io/) is a self-custodial wallet and DeFi portfolio manager supporting Monad and many other networks, with full portfolio tracking, swaps, and DApp access. To get started, download Zerion [here](https://zerion.io/) or visit the [documentation](https://help.zerion.io/) . [Wallets\ \ Previous](https://docs.monad.xyz/tooling-and-infra/wallets) [Hardware Wallets\ \ Next](https://docs.monad.xyz/tooling-and-infra/wallets/hardware-wallets) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # JSON-RPC Overview - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/reference/json-rpc/overview#content-area) Monad supports a [JSON-RPC](https://www.jsonrpc.org/specification) interface for interacting with the blockchain. Monad aims to match the RPC behavior of [Geth](https://geth.ethereum.org/docs/interacting-with-geth/rpc) as closely as possible, but due to fundamental architectural differences, some behaviors deviate from Ethereum. [​](https://docs.monad.xyz/reference/json-rpc/overview#supported-methods) Supported methods ---------------------------------------------------------------------------------------------- | Method | Notes | | --- | --- | | [`eth_blockNumber`](https://docs.monad.xyz/reference/json-rpc/api#eth_blocknumber) | | | [`eth_call`](https://docs.monad.xyz/reference/json-rpc/api#eth_call) | [Gas limits](https://docs.monad.xyz/reference/json-rpc/overview#eth_call--eth_estimategas)
, [state availability limits](https://docs.monad.xyz/reference/json-rpc/overview#state-availability) | | [`eth_chainId`](https://docs.monad.xyz/reference/json-rpc/api#eth_chainid) | | | [`eth_createAccessList`](https://docs.monad.xyz/reference/json-rpc/api#eth_createaccesslist) | | | [`eth_estimateGas`](https://docs.monad.xyz/reference/json-rpc/api#eth_estimategas) | [Gas limits](https://docs.monad.xyz/reference/json-rpc/overview#eth_call--eth_estimategas) | | [`eth_feeHistory`](https://docs.monad.xyz/reference/json-rpc/api#eth_feehistory) | [Difference from Ethereum](https://docs.monad.xyz/reference/json-rpc/overview#fee-estimation) | | [`eth_fillTransaction`](https://docs.monad.xyz/reference/json-rpc/api#eth_filltransaction) | | | [`eth_gasPrice`](https://docs.monad.xyz/reference/json-rpc/api#eth_gasprice) | | | [`eth_getBalance`](https://docs.monad.xyz/reference/json-rpc/api#eth_getbalance) | | | [`eth_getBlockByHash`](https://docs.monad.xyz/reference/json-rpc/api#eth_getblockbyhash) | | | [`eth_getBlockByNumber`](https://docs.monad.xyz/reference/json-rpc/api#eth_getblockbynumber) | | | [`eth_getBlockReceipts`](https://docs.monad.xyz/reference/json-rpc/api#eth_getblockreceipts) | | | [`eth_getBlockTransactionCountByHash`](https://docs.monad.xyz/reference/json-rpc/api#eth_getblocktransactioncountbyhash) | | | [`eth_getBlockTransactionCountByNumber`](https://docs.monad.xyz/reference/json-rpc/api#eth_getblocktransactioncountbynumber) | | | [`eth_getCode`](https://docs.monad.xyz/reference/json-rpc/api#eth_getcode) | | | [`eth_getLogs`](https://docs.monad.xyz/reference/json-rpc/api#eth_getlogs) | [Block range limits](https://docs.monad.xyz/reference/json-rpc/overview#eth_getlogs) | | [`eth_getStorageAt`](https://docs.monad.xyz/reference/json-rpc/api#eth_getstorageat) | | | [`eth_getTransactionByBlockHashAndIndex`](https://docs.monad.xyz/reference/json-rpc/api#eth_gettransactionbyblockhashandindex) | | | [`eth_getTransactionByBlockNumberAndIndex`](https://docs.monad.xyz/reference/json-rpc/api#eth_gettransactionbyblocknumberandindex) | | | [`eth_getTransactionByHash`](https://docs.monad.xyz/reference/json-rpc/api#eth_gettransactionbyhash) | [Does not return pending txs](https://docs.monad.xyz/reference/json-rpc/overview#transaction-lifecycle) | | [`eth_getTransactionCount`](https://docs.monad.xyz/reference/json-rpc/api#eth_gettransactioncount) | | | [`eth_getTransactionReceipt`](https://docs.monad.xyz/reference/json-rpc/api#eth_gettransactionreceipt) | | | [`eth_maxPriorityFeePerGas`](https://docs.monad.xyz/reference/json-rpc/api#eth_maxpriorityfeepergas) | [Returns hardcoded value](https://docs.monad.xyz/reference/json-rpc/overview#fee-estimation) | | [`eth_sendRawTransaction`](https://docs.monad.xyz/reference/json-rpc/api#eth_sendrawtransaction) | [Async validation behavior](https://docs.monad.xyz/reference/json-rpc/overview#transaction-lifecycle) | | [`eth_sendRawTransactionSync`](https://docs.monad.xyz/reference/json-rpc/api#eth_sendrawtransactionsync) | [Async validation behavior](https://docs.monad.xyz/reference/json-rpc/overview#transaction-lifecycle) | | [`eth_syncing`](https://docs.monad.xyz/reference/json-rpc/api#eth_syncing) | | | `eth_subscribe` | WebSocket only, see [WebSocket subscriptions](https://docs.monad.xyz/reference/json-rpc/overview#websocket-subscriptions) | | [`debug_getRawBlock`](https://docs.monad.xyz/reference/json-rpc/api#debug_getrawblock) | | | [`debug_getRawHeader`](https://docs.monad.xyz/reference/json-rpc/api#debug_getrawheader) | | | [`debug_getRawReceipts`](https://docs.monad.xyz/reference/json-rpc/api#debug_getrawreceipts) | | | [`debug_getRawTransaction`](https://docs.monad.xyz/reference/json-rpc/api#debug_getrawtransaction) | | | [`debug_traceBlockByHash`](https://docs.monad.xyz/reference/json-rpc/api#debug_traceblockbyhash) | [Trace options required](https://docs.monad.xyz/reference/json-rpc/overview#debug--trace) | | [`debug_traceBlockByNumber`](https://docs.monad.xyz/reference/json-rpc/api#debug_traceblockbynumber) | [Trace options required](https://docs.monad.xyz/reference/json-rpc/overview#debug--trace) | | [`debug_traceCall`](https://docs.monad.xyz/reference/json-rpc/api#debug_tracecall) | [Trace options required](https://docs.monad.xyz/reference/json-rpc/overview#debug--trace) | | [`debug_traceTransaction`](https://docs.monad.xyz/reference/json-rpc/api#debug_tracetransaction) | [Trace options required](https://docs.monad.xyz/reference/json-rpc/overview#debug--trace) | | [`admin_ethCallStatistics`](https://docs.monad.xyz/reference/json-rpc/api#admin_ethcallstatistics) | Monad-specific | | [`net_version`](https://docs.monad.xyz/reference/json-rpc/api#net_version) | | | [`txpool_statusByAddress`](https://docs.monad.xyz/reference/json-rpc/api#txpool_statusbyaddress) | Monad-specific | | [`txpool_statusByHash`](https://docs.monad.xyz/reference/json-rpc/api#txpool_statusbyhash) | Monad-specific | | [`web3_clientVersion`](https://docs.monad.xyz/reference/json-rpc/api#web3_clientversion) | | [​](https://docs.monad.xyz/reference/json-rpc/overview#differences-from-ethereum) Differences from Ethereum -------------------------------------------------------------------------------------------------------------- Monad is Geth-compatible, but its architecture — including [asynchronous execution](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution) and sub-second block times — introduces behavioral differences in several areas. ### [​](https://docs.monad.xyz/reference/json-rpc/overview#transaction-lifecycle) Transaction lifecycle **Deferred nonce/balance validation.** `eth_sendRawTransaction` may not immediately reject transactions with a nonce gap or insufficient gas balance. Because Monad’s RPC server is designed for asynchronous execution, it may not have the latest account state at the time of submission. These transactions are initially accepted because they may become valid during block creation. **No pending transaction queries.** `eth_getTransactionByHash` only returns transactions that have been included in a block. Querying a transaction that is still in the mempool returns `null`. ### [​](https://docs.monad.xyz/reference/json-rpc/overview#state-availability) State availability `eth_call` invocations that reference old state (i.e. with an old block number) may fail, because full nodes do not provide access to arbitrary historic state. See [Historical Data](https://docs.monad.xyz/developer-essentials/historical-data) for details on what state is available and how to access it. ### [​](https://docs.monad.xyz/reference/json-rpc/overview#fee-estimation) Fee estimation **`eth_maxPriorityFeePerGas`** currently returns a hardcoded suggested fee of 2 gwei. This is temporary. **`eth_feeHistory`** with `newest_block = latest`: by convention, this method returns the fee history for the requested range _plus_ one extra projected fee for the next block. Monad does not have all the inputs required to compute the next block’s base fee, so when the newest requested block is `latest`, the latest `baseFeePerGas` is returned twice. ### [​](https://docs.monad.xyz/reference/json-rpc/overview#debug-/-tracing) Debug / tracing **Trace options parameter is required.** `debug_traceCall`, `debug_traceTransaction`, and related `debug_trace*` methods require the trace options object to be explicitly provided. Unlike standard EVM clients where this parameter is optional, Monad RPC returns error `-32602 Invalid params` if it is omitted. Always include the parameter, even if empty: { "method": "debug_traceCall", "params": [\ {\ "to": "0x6b175474e89094c44da98b954eedeac495271d0f"\ },\ "latest",\ {}\ ] } **Default tracer is `callTracer`.** When an empty trace options object `{}` is provided, Monad defaults to the `callTracer` instead of the struct logs tracer typical in other EVM clients. Monad does not currently support opcode-level struct logs at the VM level. ### [​](https://docs.monad.xyz/reference/json-rpc/overview#unsupported-features) Unsupported features | Feature | Affected methods | Details | | --- | --- | --- | | EIP-4844 (blob transactions) | `eth_sendRawTransaction`, `eth_call`, `eth_estimateGas` | Blob transaction type is rejected | | `"syncing"` subscription | `eth_subscribe` | Not supported | | `"newPendingTransactions"` subscription | `eth_subscribe` | Not supported | [​](https://docs.monad.xyz/reference/json-rpc/overview#block-tags) Block tags -------------------------------------------------------------------------------- Monad blocks progress through four [commitment states](https://docs.monad.xyz/monad-arch/consensus/block-states) : `Proposed`, `Voted`, `Finalized`, and `Verified`. The JSON-RPC API exposes these through standard Ethereum-compatible block tags. | Block tag | Monad state | Guidance | | --- | --- | --- | | `"latest"` | `Proposed` | Lowest-latency view, but backed by [speculative execution](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution#speculative-execution)
— no consensus vote yet. Use for read-heavy UIs where freshness matters more than certainty. | | `"safe"` | `Voted` | Backed by a supermajority vote. Reverts require extremely [unlikely conditions](https://docs.monad.xyz/monad-arch/consensus/monad-bft#the-only-loophole)
. | | `"finalized"` | `Finalized` | Irreversible without a hard fork. Use for value settlement: bridges, deposits, payment crediting. | The `"pending"` tag is supported but behaves the same as `"latest"`. [Learn more](https://docs.monad.xyz/monad-arch/consensus/local-mempool) . ### [​](https://docs.monad.xyz/reference/json-rpc/overview#unfinalized-data) Unfinalized data Any RPC response that includes data from a non-finalized block can change on a subsequent identical request. * **Methods with a block number/tag parameter** (`eth_call`, `eth_getBalance`, `eth_getLogs`, etc.) — can return non-finalized data when called with `"latest"` or a non-finalized block number. * **Transaction-hash lookups** (`eth_getTransactionByHash`, `eth_getTransactionReceipt`) — can match a transaction in a non-finalized block. The returned `blockNumber`, log indices, or even the result itself (`null`) can change. * **Implicit-latest methods** (`eth_gasPrice`, `eth_maxPriorityFeePerGas`) — always return non-finalized data using the `"latest"` tag. Treat data from non-finalized blocks as provisional. For transaction-hash lookups, compare the returned `blockNumber` against the `"finalized"` block height (tracked client-side) before acting on the result. [​](https://docs.monad.xyz/reference/json-rpc/overview#limits) Limits ------------------------------------------------------------------------ ### [​](https://docs.monad.xyz/reference/json-rpc/overview#eth_call-/-eth_estimategas) `eth_call` / `eth_estimateGas` #### [​](https://docs.monad.xyz/reference/json-rpc/overview#gas-limit-per-call) Gas limit per call | Provider | Public RPC | Gas limit | | --- | --- | --- | | QuickNode | `rpc.monad.xyz` | 200M gas | | Alchemy | `rpc1.monad.xyz` | 200M gas | | Ankr | `rpc3.monad.xyz` | 1B gas | | Monad Foundation | `rpc-mainnet.monadinfra.com` | 200M gas | **Node operators**. Use `--eth-call-provider-gas-limit` (default 30M) and `--eth-estimate-gas-provider-gas-limit` (default 30M) to configure these limits. #### [​](https://docs.monad.xyz/reference/json-rpc/overview#gas-limit-resolution) Gas limit resolution When the caller specifies a gas **price** (`gasPrice` or `maxFeePerGas`), the effective gas limit is `min(gas limit allowance, provider gas limit)`, where the gas limit allowance is the maximum gas given the caller’s balance and specified price. When no gas price is specified, the provider gas limit applies directly. This is consistent with Geth’s behavior. #### [​](https://docs.monad.xyz/reference/json-rpc/overview#dual-pool-execution-model) Dual-pool execution model `eth_call` and `eth_estimateGas` requests are routed to one of two execution pools based on the caller-specified gas limit: | Pool | Gas limit | Purpose | | --- | --- | --- | | Low-gas | ≤ 8,100,000 | Most calls; higher throughput | | High-gas | \> 8,100,000 | Large simulations; limited concurrency | When the caller does not specify a gas limit, the request is first attempted in the low-gas pool. If it runs out of gas, it is automatically retried in the high-gas pool. **Node operators**. Use `--eth-call-max-concurrent-requests` (default 1000) and `--eth-call-high-max-concurrent-requests` (default 20) to configure pool concurrency. ### [​](https://docs.monad.xyz/reference/json-rpc/overview#eth_getlogs) `eth_getLogs` #### [​](https://docs.monad.xyz/reference/json-rpc/overview#block-range-limit-per-call) Block range limit per call | Provider | Public RPC | Block range limit | | --- | --- | --- | | QuickNode | `rpc.monad.xyz` | 100 blocks | | Alchemy | `rpc1.monad.xyz` | 1,000 blocks and 10,000 logs (whichever is more constraining) | | Ankr | `rpc3.monad.xyz` | 1,000 blocks | | Monad Foundation | `rpc-mainnet.monadinfra.com` | 100 blocks | **Node operators**. Use `--eth-get-logs-max-block-range` to configure the block range limit. #### [​](https://docs.monad.xyz/reference/json-rpc/overview#why-are-block-range-limits-low) Why are block range limits low? Monad produces a block every 300ms and can accommodate up to 5,000 transactions per block with computation up to 200M gas. Blocks are both extremely frequent and significantly larger than Ethereum blocks, which is the main motivation for keeping per-call block range limits low. [​](https://docs.monad.xyz/reference/json-rpc/overview#errors) Errors ------------------------------------------------------------------------ Monad’s JSON-RPC error codes aim to be equivalent to Ethereum’s, but some codes deviate due to lack of standardization across Ethereum clients. ### [​](https://docs.monad.xyz/reference/json-rpc/overview#request-level-errors-32601) Request-level errors (-32601) | Message | Explanation | Common cause | | --- | --- | --- | | Parse error | Unable to parse the JSON-RPC request | Malformed JSON | | Invalid request | The request is structurally invalid | Request exceeds size limit | | Method not found | The method is not part of the JSON-RPC spec | Typo in method name | | Method not supported | The method exists in the spec but is not yet supported by Monad | Calling an unimplemented method | ### [​](https://docs.monad.xyz/reference/json-rpc/overview#parameter-errors-32602) Parameter errors (-32602) | Message | Explanation | Common cause | | --- | --- | --- | | Invalid block range | The requested `eth_getLogs` block range exceeds the provider limit | See [block range limits](https://docs.monad.xyz/reference/json-rpc/overview#block-range-limit-per-call) | | Invalid params | Incorrect parameters for the method | Wrong types, missing required fields, omitted trace options | ### [​](https://docs.monad.xyz/reference/json-rpc/overview#execution-errors-32603) Execution errors (-32603) | Message | Explanation | Common cause | | --- | --- | --- | | Internal error | The request could not be fulfilled | Server-side failure | | Execution reverted | The simulated transaction reverted | Failed `eth_call` or `eth_estimateGas` | | Transaction decoding error | The raw transaction could not be decoded | Invalid RLP in `eth_sendRawTransaction` | [​](https://docs.monad.xyz/reference/json-rpc/overview#websocket-subscriptions) WebSocket subscriptions ---------------------------------------------------------------------------------------------------------- Monad’s RPC server supports JSON-RPC over WebSocket connections, enabling persistent connections and real-time data via `eth_subscribe`. See the [Geth documentation](https://geth.ethereum.org/docs/interacting-with-geth/rpc/pubsub) for general `eth_subscribe` behavior. Monad extends the standard subscription types with two speculative variants (`monadNewHeads` and `monadLogs`) that publish data sooner — approximately one second earlier on average — on a speculative basis. See [Speculative Real-Time Data](https://docs.monad.xyz/monad-arch/realtime-data/spec-realtime) for background on speculative execution and [Block States](https://docs.monad.xyz/monad-arch/consensus/block-states) for the full block lifecycle. ### [​](https://docs.monad.xyz/reference/json-rpc/overview#subscription-types) Subscription types | Type | Fires when | | --- | --- | | `newHeads` | A new header is appended, once the block is `Voted` | | `logs` | Matching logs appear in a new block, once the block is `Voted` | | `monadNewHeads` | A new header is available, once the block is `Proposed` and [speculatively executed](https://docs.monad.xyz/monad-arch/realtime-data/spec-realtime) | | `monadLogs` | Matching logs are available, once the block is `Proposed` and [speculatively executed](https://docs.monad.xyz/monad-arch/realtime-data/spec-realtime) | The subscription types `syncing` and `newPendingTransactions` are not supported. ### [​](https://docs.monad.xyz/reference/json-rpc/overview#speculative-subscription-behavior) Speculative subscription behavior `monadNewHeads` and `monadLogs` updates include two additional fields not present in the standard variants: * **`blockId`** — a unique identifier for this specific block proposal (distinct from block number, since multiple proposals can exist for the same height). * **`commitState`** — the block’s current [commit state](https://docs.monad.xyz/monad-arch/consensus/block-states) : `Proposed`, `Voted`, `Finalized`, or `Verified`. The same block will typically produce multiple updates as its `commitState` advances through the lifecycle. A block may skip `Voted` and go directly from `Proposed` to `Finalized` when consensus is ahead of execution. When a block fails to finalize, it is abandoned implicitly — the finalization of a different block at the same height supersedes it, but no explicit abandonment event is published. [Smart Account Implementations\ \ Previous](https://docs.monad.xyz/tooling-and-infra/wallet-infra/smart-accounts) [JSON-RPC Playground\ \ Next](https://docs.monad.xyz/reference/json-rpc/playground) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Consensus events - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/execution-events/consensus-events#content-area) As explained [here](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution) , Monad’s consensus and execution services are decoupled, and execution is asynchronous with the respect to consensus: the two don’t have to move in lock step, and can working on different blocks. Also, execution can [speculatively execute](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution#speculative-execution) blocks whose consensus outcome is not yet known. Execution events are “trace” information reported directly from the EVM during execution, so they report real-time data on _speculative_ basis: the event data may relate to a block that is never finalized. Dealing with real-time data on a speculative basis is discussed in detail on [this page](https://docs.monad.xyz/monad-arch/realtime-data/spec-realtime) . The “takeaway” from that part of the documentation is the following: if you consume speculative real-time data, then you need to understand [block commit states](https://docs.monad.xyz/monad-arch/consensus/block-states) and how the real-time data protocol you’re using communicates the changes in block states. For example, for the Monad WebSocket extension feeds, [this section](https://docs.monad.xyz/reference/websockets#monadnewheads-and-monadlogs) explains how the block IDs and commit states are announced for the `monadNewHeads` subscription. This documentation page explains how it is done with execution events. [​](https://docs.monad.xyz/execution-events/consensus-events#block-tags) Block tags -------------------------------------------------------------------------------------- As explained [here](https://docs.monad.xyz/monad-arch/realtime-data/spec-realtime#block-numbers-and-block-ids) , blocks must be identified by their unique ID prior to finalization. Even so, it is often useful to know what the proposed block number is, even before we know if the block will committed with that number or not. The following structure — called a “block tag” — appears as a field in several execution event payload types, to communicate the block ID and the (proposed) block number together. struct monad_exec_block_tag { monad_c_bytes32 id; ///< Monad consensus unique ID for block uint64_t block_number; ///< Proposal is to become this block }; [​](https://docs.monad.xyz/execution-events/consensus-events#the-four-consensus-events) The four consensus events -------------------------------------------------------------------------------------------------------------------- The four [block commit states](https://docs.monad.xyz/monad-arch/consensus/block-states) correspond to four execution event types. Events of these types are published to announce that a particular block is moving to a new commit state. ### [​](https://docs.monad.xyz/execution-events/consensus-events#first-consensus-event-block_start-proposed-state) First consensus event: **`BLOCK_START`** (_proposed_ state) /// Event recorded at the start of block execution struct monad_exec_block_start { struct monad_exec_block_tag block_tag; ///< Execution is for this block uint64_t block_round; ///< Round when block was proposed uint64_t epoch; ///< Epoch when block was proposed monad_c_bytes32 parent_eth_hash; ///< Hash of Ethereum parent block monad_c_uint256_ne chain_id; ///< Block chain we're associated with struct monad_c_eth_block_exec_input exec_input; ///< Ethereum execution inputs }; The first event recorded by the EVM is a `BLOCK_START` event, whose event payload contains a `block_tag` field that introduces the unique ID for the block and the block number it will eventually have, if it gets finalized. Almost all execution events (transaction logs, call frames, receipts, etc.) occur between the `BLOCK_START` and `BLOCK_END` events. In the current implementation, block execution is never pipelined, so all events between `BLOCK_START` and `BLOCK_END` pertain to a single block, and there will not be another `BLOCK_START` until the current block is ended. Unlike the other events in this list, `BLOCK_START` is both a “consensus event” (it means the associated block is in proposed state) and an “EVM event,” because execution information about the block is being made available to you. The other events in this list are not like that. They are “pure” consensus events: they tell you what happened to a proposed block in the consensus algorithm, after you’ve already seen all of its EVM events. To understand the implications of this state, see [here](https://docs.monad.xyz/monad-arch/realtime-data/spec-realtime#first-commit-state-proposed) . There’s no reason why a block _has_ to start in the proposed state. If execution is lagging behind consensus, it’s possible that a block might have advanced to a later state in the consensus algorithm. For example, suppose consensus has been working on a block for a while, and by the time execution finally sees it, perhaps consensus knows that it has progressed to voted.In the current implementation, however, execution will not know this. It implicitly considers everything it executes to only be proposed. This is only literally true if execution is not lagging behind. ### [​](https://docs.monad.xyz/execution-events/consensus-events#second-consensus-event-block_qc-voted-state) Second consensus event: **`BLOCK_QC`** (_voted_ state) /// Event recorded when a proposed block obtains a quorum certificate struct monad_exec_block_qc { struct monad_exec_block_tag block_tag; ///< QC for proposal with this block uint64_t round; ///< Round of proposal vote uint64_t epoch; ///< Epoch of proposal vote }; When a block with the given tag is voted, an event of this type is published to announce it. To understand all the implications of seeing this event, see [here](https://docs.monad.xyz/monad-arch/realtime-data/spec-realtime#second-commit-state-voted) . ### [​](https://docs.monad.xyz/execution-events/consensus-events#third-consensus-event-block_finalized) Third consensus event: **`BLOCK_FINALIZED`** /// Event recorded when consensus finalizes a block typedef struct monad_exec_block_tag monad_exec_block_finalized; The finalized event payload does not have any information that isn’t already part of the block tag, so the payload is just the tag of the block that gets finalized. To understand all the implications of seeing this event, see [here](https://docs.monad.xyz/monad-arch/realtime-data/spec-realtime#third-commit-state-finalized) . ### [​](https://docs.monad.xyz/execution-events/consensus-events#fourth-consensus-event-block_verified) Fourth consensus event: **`BLOCK_VERIFIED`** /// Event recorded when consensus verifies the state root of a finalized block struct monad_exec_block_verified { uint64_t block_number; ///< Number of verified block }; The consensus algorithm produces one last event for a block, called `BLOCK_VERIFIED`. This time, it is sufficient to identify the block only by its block number. Because verified blocks are already finalized, they are part of the canonical blockchain and cannot be reverted without a hard fork. Thus, we no longer need the block tag. To understand all the implications of seeing this event, see [here](https://docs.monad.xyz/monad-arch/realtime-data/spec-realtime#fourth-commit-state-verified) . [Rust API\ \ Previous](https://docs.monad.xyz/execution-events/rust-api) [Advanced topics\ \ Next](https://docs.monad.xyz/execution-events/advanced) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # C API - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/execution-events/c-api#content-area) [​](https://docs.monad.xyz/execution-events/c-api#core-concepts) Core concepts --------------------------------------------------------------------------------- There are two central objects in the event ring C API. They are: 1. **struct `monad_event_ring`** - represents an event ring whose shared memory segments have been mapped into the address space of the current process; the primary thing the client does with this object is use it to initialize iterators that point into the event ring, using the `monad_event_ring_init_iterator` function 2. **struct `monad_event_iterator`** - the star of the show: this iterator object is used to read sequential events. The iterator’s `try_next` operation copies the current event descriptor (if it is available) and if successful, advances the iterator. Conceptually, it behaves like the expression `descriptor = *i++`, if an event descriptor is ready immediately (it does nothing otherwise) The easiest way to understand the API is to compile and run the included `eventwatch` example program. This program dumps ASCII representations of execution events to `stdout`, as they are written by a execution daemon running on the same host. In `eventwatch`, the event descriptors are fully decoded, but the event payloads are only shown in hexdump form, because this simple program that does not include pretty-printing logic for all event payload types. The program is only 250 lines of code, and reading through it should explain how the various API calls fit together. The SDK also includes C++20 [`std::formatter`](https://en.cppreference.com/w/cpp/utility/format/formatter.html) specializations which can fully decode event payloads into human-readable form. These are used by the `monad-event-cli` utility program. [​](https://docs.monad.xyz/execution-events/c-api#using-the-api-in-your-project) Using the API in your project ----------------------------------------------------------------------------------------------------------------- `libmonad_event` is designed for third party integration, so it does not have any library dependencies aside from a recent version of glibc. This also means it has no dependency on the rest of the monad repository or on its build system: the sole requirement is a C compiler supporting C23. The “Getting start” guide to building the C example program [discusses several ways](https://docs.monad.xyz/execution-events/getting-started/c#how-can-my-code-use-libmonad_eventa) to use the SDK library as a third-party dependency in your code. Alternatively, the source files that make up the library target can be copied into your own codebase. A Rust client library is [also available](https://docs.monad.xyz/execution-events/rust-api) . [​](https://docs.monad.xyz/execution-events/c-api#api-overview) API overview ------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/execution-events/c-api#event-ring-apis) Event ring APIs | API | Purpose | | --- | --- | | `monad_event_ring_mmap` | Given a file descriptor to an open event ring file, map its shared memory segments into the current process, initializing a `struct monad_event_ring` | | `monad_event_ring_init_iterator` | Given a pointer to a `struct monad_event_ring`, initialize an iterator that can read from the event ring | | `monad_event_ring_try_copy` | Given a specific sequence number, try to copy the event descriptor for it, if it hasn’t been overwritten | | `monad_event_ring_payload_peek` | Get a zero-copy pointer to an event payload | | `monad_event_ring_payload_check` | Check if an event payload referred to by a zero-copy pointer has been overwritten | | `monad_event_ring_memcpy` | `memcpy` the event payload to a buffer, succeeding only if the payload is not expired | | `monad_event_ring_get_last_error` | Return a human-readable string describing the last error that occurred on this thread | All functions which can fail will return an `errno(3)` domain error code diagnosing the reason for failure. The function `monad_event_ring_get_last_error` can be called to provide a human-readable string explanation of what failed. ### [​](https://docs.monad.xyz/execution-events/c-api#event-iterator-apis) Event iterator APIs | API | Purpose | | --- | --- | | `monad_event_iterator_try_next` | If an event descriptor if is available, copy it and advance the iterator; behaves like `*i++`, but only if `*i` is ready | | `monad_event_iterator_try_copy` | Copy the event descriptor at the current iteration point, without advancing the iterator | | `monad_event_iterator_reset` | Reset the iterator to point to the most recently produced event descriptor; used for gap recovery | | `monad_exec_iter_consensus_prev` | Rewinds an iterator to the previous consensus event (`BLOCK_START`, `BLOCK_QC`, `BLOCK_FINALIZED`, or `BLOCK_VERIFIED`) | | `monad_exec_iter_block_number_prev` | Rewinds an iterator to the previous consensus event for the given block number | | `monad_exec_iter_block_id_prev` | Rewinds an iterator to the previous consensus event for the given block ID | | `monad_exec_iter_rewind_for_simple_replay` | Rewinds an iterator to replay events you may have missed, based on the last finalized block you saw | ### [​](https://docs.monad.xyz/execution-events/c-api#event-ring-utility-apis) Event ring utility APIs | API | Purpose | | --- | --- | | `monad_event_ring_check_content_type` | Check if the binary layouts of event definitions used by the library match what is recorded in a mapped event ring | | `monad_event_ring_find_writer_pids` | Find processes that have opened an event ring file descriptor for writing; used for detecting publisher exit | | `monad_check_path_supports_map_hugetlb` | Check if a path is on a filesystem that allows its files to be mmap’ed with `MAP_HUGETLB` | | `monad_event_open_hugetlbfs_dir_fd` | Open the default hugetlbfs directory where event ring files are created[1](https://docs.monad.xyz/execution-events/c-api#user-content-fn-1) | | `monad_event_resolve_ring_file` | If a path contains no `/` character (i.e., if it is a “pure” filename), resolve it relative to some default event ring directory[2](https://docs.monad.xyz/execution-events/c-api#user-content-fn-2) | | `monad_event_is_snapshot_file` | Check if a path refers to an event ring snapshot file | | `monad_event_decompress_snapshot_fd` | Decompress the event ring snapshot contained in the given file descriptor | | `monad_event_decompress_snapshot_mem` | Decompress the event ring snapshot contained in the given memory buffer | [​](https://docs.monad.xyz/execution-events/c-api#library-organization) Library organization ----------------------------------------------------------------------------------------------- Event ring files in `libmonad_event`: | File | Contains | | --- | --- | | `event_ring.{h,c}` | Definitions of core shared memory structures for event rings, and the API that initializes and mmaps event ring files | | `event_iterator.h` | Defines the basic event iterator object and its API | | `event_iterator_inline.h` | Definitions of the `event_iterator.h` functions, all of which are inlined for performance reasons | | `event_metadata.h` | Structures that describe event metadata (string names of events, descriptions of events, etc.) | | `exec_iter_help.h` | API for rewinding the the iterator to point to block executions or consensus events | Execution event files in `libmonad_event`: | File | Contains | | --- | --- | | `base_ctypes.h` | Definitions of basic vocabulary types common in Ethereum data (e.g., 256 bit integer types, etc). | | `eth_ctypes.h` | Definitions of structures used in the Ethereum virtual machine | | `exec_event_ctypes.h` | Definition of execution event payload structures, and the event type enumeration `enum monad_exec_event_type` | | `exec_event_ctypes_metadata.c` | Defines static metadata about execution events, and the schema hash value array | | `monad_ctypes.h` | Definitions of Monad blockchain extensions to Ethereum | Supporting files in `libmonad_event`: | File | Contains | | --- | --- | | `event_ring_util.{h,c}` | Convenience functions that are useful in most event ring programs, but which are not part of the core API | | `format_err.{h,c}` | Helper utility from the execution codebase used to implement the `monad_event_ring_get_last_error()` function | | `srcloc.h` | Helper utility used with the `format_err.h` API, for capturing source code locations in C | Other files in the SDK: | File | Contents | | --- | --- | | `eventwatch.c` | A sample program that shows how to use the API | | `*_fmt.hpp` files | Files ending in `_fmt.hpp` are used with C++ `` and contain `std::formatter` specializations for SDK types | | `hex.hpp` | `` hexdump utility used by the `_fmt.hpp` files to dump `uint8_t[]` values | Footnotes --------- 1. By default, this returns the a path on a hugetlbfs mount, as computed by libhugetlbfs [↩](https://docs.monad.xyz/execution-events/c-api#user-content-fnref-1) 2. If compiling with `MONAD_EVENT_USE_LIBHUGETLBFS=OFF`, a default event ring directory must be specified; see [here](https://docs.monad.xyz/execution-events/advanced#location-of-event-ring-files) for details [↩](https://docs.monad.xyz/execution-events/c-api#user-content-fnref-2) [Event rings in detail\ \ Previous](https://docs.monad.xyz/execution-events/event-ring) [Rust API\ \ Next](https://docs.monad.xyz/execution-events/rust-api) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Huff - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/guides/evm-resources/other-languages/huff#content-area) [Huff](https://docs.huff.sh/) is most closely described as EVM assembly. Unlike Yul, Huff does not provide control flow constructs or abstract away the inner working of the program stack. Only the most upmost performance sensitive applications take advantage of Huff, however it is a great educational tool to learn how the EVM interprets instructions its lowest level. * [Huff resources](https://docs.huff.sh/resources/overview/) provides additional resources [Yul\ \ Previous](https://docs.monad.xyz/guides/evm-resources/other-languages/yul) [How to build a basic dApp with Scaffold-ETH\ \ Next](https://docs.monad.xyz/guides/scaffold-eth) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Monad for Developers - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/introduction/monad-for-developers#content-area) This page summarizes “Why Monad” for developers. For a summary of what you need to know in order to develop or redeploy on Monad, see [Deployment Summary for Developers](https://docs.monad.xyz/developer-essentials/summary) . Monad is an Ethereum-compatible Layer-1 blockchain with 10,000 tps of throughput, 300ms block frequency, and 600ms finality. Monad’s implementation of the Ethereum Virtual Machine complies with the Fusaka fork. The Monad client has been simulated with historical Ethereum transactions and produces identical merkle roots. Monad also offers full Ethereum RPC compatibility so that users can interact with Monad using familiar tools like Etherscan or MetaMask. Monad accomplishes these performance improvements, while preserving backward compatibility, through the introduction of several major innovations: * [MonadBFT](https://docs.monad.xyz/monad-arch/consensus/monad-bft) , a frontier BFT consensus mechanism solving the [tail-forking](https://www.category.xyz/blogs/monadbft-fast-responsive-fork-resistant-streamlined-consensus) problem * [RaptorCast](https://docs.monad.xyz/monad-arch/consensus/raptorcast) for efficient block transmission * [Asynchronous Execution](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution) for pipelining consensus and execution to raise the time budget for execution * [Parallel Execution](https://docs.monad.xyz/monad-arch/execution/parallel-execution) and [JIT Compilation](https://docs.monad.xyz/monad-arch/execution/native-compilation) for efficient transaction execution * [MonadDb](https://docs.monad.xyz/monad-arch/execution/monaddb) for efficient storage of Ethereum state Although Monad features parallel execution and pipelining, it’s important to note that blocks in Monad are linear, and transactions are linearly ordered within each block. The first Monad client is built by [Category Labs](https://www.category.xyz/) and is written from scratch in C++ and Rust. The code is open-source under `GPL-3.0` here: * [`monad-bft`](https://github.com/category-labs/monad-bft) * [`monad`](https://github.com/category-labs/monad) [​](https://docs.monad.xyz/introduction/monad-for-developers#transactions) Transactions ------------------------------------------------------------------------------------------ | | | | --- | --- | | Address space | Same address space as Ethereum (20-byte addresses using ECDSA) | | Transaction format/types | [Same as Ethereum](https://ethereum.org/en/developers/docs/transactions/)
. Monad transactions use the same typed transaction envelope introduced in [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718)
, encoded with [RLP](https://ethereum.org/en/developers/docs/data-structures-and-encoding/rlp/)
. Transaction type 0 (“legacy”), 1 (“EIP-2930”), 2 (“EIP-1559”; now the default in Ethereum), and 4 (“EIP-7702”) are supported. See [transaction type reference](https://ethereum.org/en/developers/docs/transactions/#typed-transaction-envelope)
. See [Transactions](https://docs.monad.xyz/developer-essentials/transactions)
for more details. | | EIP-7702 | Supported. See [EIP-7702 on Monad](https://docs.monad.xyz/developer-essentials/eip-7702) | | EIP-155 replay protection | Note that pre [EIP-155](https://eips.ethereum.org/EIPS/eip-155)
transactions are allowed on the protocol level on Monad, therefore it’s discouraged to use an Ethereum account that had previously made pre EIP-155 transactions. [Discussion](https://docs.monad.xyz/developer-essentials/transactions#transactions-without-a-chain_id) | | Wallet compatibility | Monad is compatible with standard Ethereum wallets such as MetaMask. The only change required is to alter the RPC URL and chain id. | | Gas pricing | Monad is EIP-1559-compatible; base fee and priority fee work as in Ethereum. Base fee follows a dynamic controller, similar to the EIP-1559 controller but with slower increases and faster decreases. [Details](https://docs.monad.xyz/developer-essentials/gas-pricing#base_price_per_gas-controller)
. **Transactions are charged based on gas limit rather than gas usage**, i.e. total tokens deducted from the sender’s balance is `value + gas_price * gas_limit`. This is a DOS-prevention measure for asynchronous execution. See [Gas in Monad](https://docs.monad.xyz/developer-essentials/gas-pricing)
for more details. | [​](https://docs.monad.xyz/introduction/monad-for-developers#smart-contracts) Smart contracts ------------------------------------------------------------------------------------------------ | | | | --- | --- | | Opcodes | Monad is bytecode-compatible with Ethereum (Fusaka fork). All [opcodes](https://www.evm.codes/)
as of the Fusaka fork are supported. | | Opcode pricing | Opcode pricing is the same as Ethereum, except for a few repricings needed to reweight relative scarcities of resources due to optimizations. [Details](https://docs.monad.xyz/developer-essentials/opcode-pricing) | | Precompiles | All Ethereum precompiles as of the Fusaka fork (`0x01` to `0x11`), plus P256 signature verification at `0x0100` ([EIP-7951](https://eips.ethereum.org/EIPS/eip-7951)
) and the staking precompile at `0x1000`. See [Precompiles](https://docs.monad.xyz/developer-essentials/precompiles) | | Max contract size | 128 kb (up from 24.5 kb in Ethereum) | [​](https://docs.monad.xyz/introduction/monad-for-developers#consensus) Consensus ------------------------------------------------------------------------------------ | | | | --- | --- | | Sybil resistance mechanism | Proof-of-Stake (PoS) | | Delegation | Allowed (in-protocol) | | Consensus mechanism | Monad’s consensus mechanism, [MonadBFT](https://docs.monad.xyz/monad-arch/consensus/monad-bft)
, represents a major leap in Byzantine Fault-Tolerant (BFT) consensus. It is the first BFT consensus mechanism to address the critical problem of [tail forking](https://www.category.xyz/blogs/monadbft-fast-responsive-fork-resistant-streamlined-consensus)
in pipelined HotStuff-style consensus. Accomplishing this allows MonadBFT to achieve high throughput (10,000+ tps), frequent block times (300 ms), fast finality (600 ms), linear messaging complexity, and large validator sets (200+) without being susceptible to tail forking, a critical weakness in prior protocols where a leader can fork away its predecessor’s block. | | Block propagation mechanism | [RaptorCast](https://docs.monad.xyz/monad-arch/consensus/raptorcast) | | Block frequency | 300 ms | | Finality | [Speculative finality](https://docs.monad.xyz/monad-arch/consensus/monad-bft)
at 300 ms; full finality at 600 ms | | Mempool | Leaders maintain a [local mempool](https://docs.monad.xyz/monad-arch/consensus/local-mempool)
. When an RPC receives a transaction, it [forwards](https://docs.monad.xyz/monad-arch/consensus/local-mempool#transaction-lifecycle-in-monad)
it to the next 3 leaders who keep it in their local mempool. If the RPC node doesn’t observe the transaction getting included, it repeats this process of forwarding to the next 3 leaders 2 more times. Additional forwarding may be added at a later time. | | Consensus participants | Direct consensus participants vote on block proposals and serve as leaders. To serve as a direct participant, a node must have at least `MinStake` staked and be in the top `MaxConsensusNodes` participants by stake weight. These parameters are set in code. | | Asynchronous execution | In Monad, consensus and execution occur in a pipelined fashion. Nodes come to consensus on the official transaction order _prior_ to executing that ordering ([Asynchronous Execution](https://docs.monad.xyz/monad-arch/consensus/asynchronous-execution)
); the outcome of execution is _not_ a prerequisite to consensus. In blockchains where execution _is_ a prerequisite to consensus, the time budget for execution is a small fraction of the block time. Pipelining consensus and execution allows Monad to expend the full block time on _both_ consensus and execution. Block proposals consist of an ordered list of transactions and a delayed state merkle root from `k=3` blocks ago. Monad introduces the [Reserve Balance](https://docs.monad.xyz/developer-essentials/reserve-balance)
system to ensure that nodes at consensus time only include (or vote to include) transactions whose senders have sufficient balance to fund their execution. | | State determinism | Finality occurs at consensus time; the official ordering of transactions is enshrined at this point, and the outcome is fully deterministic for any full node, who will generally execute the transactions for that new block in under 800 ms. The `D`\-block delay for state merkle roots is only for state root verification, for example for allowing a node to ensure that it didn’t make a computation error. | [​](https://docs.monad.xyz/introduction/monad-for-developers#execution) Execution ------------------------------------------------------------------------------------ The execution phase for each block begins after consensus is reached on that block, allowing the node to proceed with consensus on subsequent blocks. ### [​](https://docs.monad.xyz/introduction/monad-for-developers#parallel-execution) Parallel Execution Transactions are linearly ordered; the job of execution is to arrive at the state that results from executing that list of transactions serially. The naive approach is just to execute the transactions one after another. Can we do better? Yes we can! Monad implements [parallel execution](https://docs.monad.xyz/monad-arch/execution/parallel-execution) : * An executor is a virtual machine for executing transactions. Monad runs many executors in parallel. * An executor takes a transaction and produces a **result**. A result is a list of **inputs** to and **outputs** of the transactions, where inputs are (ContractAddress, Slot, Value) tuples that were SLOADed in the course of execution, and outputs are (ContractAddress, Slot, Value) tuples that were SSTOREd as a result of the transaction. * Results are initially produced in a pending state; they are then committed in the original order of the transactions. When a result is committed, its outputs update the current state. When it is a result’s turn to be committed, Monad checks that its inputs still match the current state; if they don’t, Monad reschedules the transaction. As a result of this concurrency control, Monad’s execution is guaranteed to produce the same result as if transactions were run serially. * When transactions are rescheduled, many or all of the required inputs are cached, so re-execution is generally relatively inexpensive. Note that upon re-execution, a transaction may produce a different set of Inputs than the previous execution did; ### [​](https://docs.monad.xyz/introduction/monad-for-developers#monaddb-high-performance-state-backend) MonadDb: high-performance state backend All active state is stored in [MonadDb](https://docs.monad.xyz/monad-arch/execution/monaddb) , a storage backend for solid-state drives (SSDs) that is optimized for storing merkle trie data. Updates are batched so that the merkle root can be updated efficiently. MonadDb implements in-memory caching and uses [asio](https://think-async.com/Asio/) for efficient asynchronous reads and writes. Nodes should have 32 GB of RAM for optimal performance. [​](https://docs.monad.xyz/introduction/monad-for-developers#comparison-to-ethereum-user%E2%80%99s-perspective) Comparison to Ethereum: User’s Perspective ------------------------------------------------------------------------------------------------------------------------------------------------------------- | Attribute | Ethereum | Monad | | --- | --- | --- | | **Transactions/second** (smart contract calls and transfers) | ~10 | ~10,000 | | **Block Frequency** | 12 seconds | 300 ms | | **Finality** | [2 epochs](https://hackmd.io/@prysmaticlabs/finality)
(12-18 min) | 600 ms | | **Bytecode standard** | EVM ([Fusaka fork](https://www.evm.codes/)
) | EVM ([Fusaka fork](https://www.evm.codes/)
) | | **Precompiles** | `0x01` to `0x11` (Fusaka fork) | `0x01` to `0x11` (Fusaka fork) plus `0x0100` (P256, [EIP-7951](https://eips.ethereum.org/EIPS/eip-7951)
) and `0x1000` (staking). See [Precompiles](https://docs.monad.xyz/developer-essentials/precompiles) | | **Max contract size** | 24.5 kb | 128 kb | | **RPC API** | [Ethereum RPC API](https://ethereum.org/en/developers/docs/apis/json-rpc/) | [Monad RPC API](https://docs.monad.xyz/reference/json-rpc)
(generally identical to Ethereum RPC API, see [differences](https://docs.monad.xyz/reference/rpc-differences)
) | | **Cryptography** | ECDSA | ECDSA | | **Accounts** | Last 20 bytes of keccak-256 of public key under ECDSA | Last 20 bytes of keccak-256 of public key under ECDSA | | **Consensus mechanism** | Gasper (Casper-FFG finality gadget + LMD-GHOST fork-choice rule) | [MonadBFT](https://docs.monad.xyz/monad-arch/consensus/monad-bft)
(tail-fork-resistant pipelined consensus with linear messaging complexity in the common case) | | **Mempool** | Global | [Local](https://docs.monad.xyz/monad-arch/consensus/local-mempool) | | **Transaction ordering** | Leader’s discretion (in practice, PBS) | Leader’s discretion (default behavior: priority gas auction) | | **Sybil-resistance mechanism** | PoS | PoS | | **Delegation allowed** | No; pseudo-delegation through LSTs | Yes; see [Staking](https://docs.monad.xyz/monad-arch/consensus/staking) | | **Hardware Requirements** (full node) | 4-core CPU, 32 GB RAM, 4 TB SSD NVMe, 25 Mbit/s bandwidth ([reference](https://eips.ethereum.org/EIPS/eip-7870)
) | 16-core CPU, 32 GB RAM, 2 x 2 TB SSD NVMe, 100 Mbit/s bandwidth ([more info](https://docs.monad.xyz/node-ops/hardware-requirements)
) | [​](https://docs.monad.xyz/introduction/monad-for-developers#tooling-and-infrastructure) Tooling and Infrastructure ---------------------------------------------------------------------------------------------------------------------- Many leading Ethereum developer tools support Monad testnet. See [Tooling and Infrastructure](https://docs.monad.xyz/tooling-and-infra) for a list of supported providers by category. [​](https://docs.monad.xyz/introduction/monad-for-developers#next-steps) Next Steps -------------------------------------------------------------------------------------- Monad’s public testnet is live. Head to [Network Information](https://docs.monad.xyz/developer-essentials/network-information) to get started. Now that you are familiar with Monad’s architecture and features, head to [Deployment Summary for Developers](https://docs.monad.xyz/developer-essentials/summary) for everything you need to know to deploy. [Monad for Users\ \ Previous](https://docs.monad.xyz/introduction/monad-for-users) [Developer Essentials\ \ Next](https://docs.monad.xyz/developer-essentials) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # How to use the Next.js Serwist Thirdweb embedded wallet template - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/templates/next-serwist-thirdweb#content-area) This guide walks you through using the [template](https://github.com/monad-developers/next-serwist-thirdweb) which uses [Next.js](https://nextjs.org/docs) , [Serwist](https://serwist.pages.dev/) (offline capabilities), and [Thirdweb](https://portal.thirdweb.com/) embedded wallet to build a Progressive Web Application (PWA) on Monad. [​](https://docs.monad.xyz/templates/next-serwist-thirdweb#prerequisites) Prerequisites ------------------------------------------------------------------------------------------ * [Node.js](https://nodejs.org/) (v18 or higher) * a [Thirdweb account](https://thirdweb.com/) [​](https://docs.monad.xyz/templates/next-serwist-thirdweb#setup) Setup -------------------------------------------------------------------------- 1. Clone the repository: git clone https://github.com/monad-developers/next-serwist-thirdweb.git 2. `cd` into the project directory: cd next-serwist-thirdweb 3. Install dependencies: npm install 4. Create a `.env.local` file in the root directory: cp .env.example .env.local 5. Start adding your environment variables to the `.env.local` file: # Thirdweb Configuration (Required) NEXT_PUBLIC_THIRDWEB_CLIENT_ID=your_thirdweb_client_id_here # Web Push (Required) WEB_PUSH_EMAIL=user@example.com WEB_PUSH_PRIVATE_KEY=your_vapid_private_key NEXT_PUBLIC_WEB_PUSH_PUBLIC_KEY=your_vapid_public_key If you lost your Thirdweb Client ID, you can find it in the Thirdweb dashboard. 6. Generate VAPID keys for web push notifications: npx web-push generate-vapid-keys --json Copy the generated keys to your .env.local file (replace the placeholder values from step 5). 7. Running the Application: **Development Mode**: npm run dev The application will be available at [http://localhost:3000](http://localhost:3000/) . **Production Mode:** For full PWA functionality (including install prompts): npm run build && npm run start [​](https://docs.monad.xyz/templates/next-serwist-thirdweb#folder-structure-of-the-template) Folder structure of the template -------------------------------------------------------------------------------------------------------------------------------- next-serwist-thirdweb/ ├── app/ │ ├── components/ # React components │ │ ├── InstallPWA.tsx # PWA install prompt │ │ └── ... │ ├── ~offline/ # Offline page │ └── ... ├── public/ # Static assets └── ... [​](https://docs.monad.xyz/templates/next-serwist-thirdweb#changing-the-app-name) Changing the app name ---------------------------------------------------------------------------------------------------------- * Edit [`public/manifest.json`](https://github.com/monad-developers/next-serwist-thirdweb/blob/main/public/manifest.json) : * Change the `name` and `short_name` fields * Run `npm run build` to update the app [​](https://docs.monad.xyz/templates/next-serwist-thirdweb#notification-setup) Notification Setup ---------------------------------------------------------------------------------------------------- To receive push notifications from this app, you need to enable notifications in your browser and/or system settings. ### [​](https://docs.monad.xyz/templates/next-serwist-thirdweb#browser-settings) Browser Settings Chrome/Edge 1. Click the lock icon 🔒 in the address bar 2. Set “Notifications” to “Allow” 3. Or go to Settings → Privacy and security → Site Settings → Notifications Firefox 1. Click the shield icon 🛡️ in the address bar 2. Turn off “Enhanced Tracking Protection” for this site (if needed) 3. Allow notifications when prompted 4. Or go to Settings → Privacy & Security → Permissions → Notifications Safari 1. Go to Safari → Settings → Websites → Notifications 2. Find your site and set it to “Allow” ### [​](https://docs.monad.xyz/templates/next-serwist-thirdweb#system-settings) System Settings macOS 1. System Preferences → Notifications & Focus 2. Find your browser and ensure notifications are enabled 3. Check “Allow notifications from websites” in browser settings Windows 1. Settings → System → Notifications & actions 2. Ensure your browser can send notifications 3. Check browser notification settings iOS 1. Settings → Notifications → \[Your Browser\] 2. Enable “Allow Notifications” 3. Also enable in browser settings Android 1. Settings → Apps → \[Your Browser\] → Notifications 2. Enable notifications 3. Check browser notification permissions ### [​](https://docs.monad.xyz/templates/next-serwist-thirdweb#backend-integration-required) Backend Integration Required [`SendNotification.tsx`](https://github.com/monad-developers/next-serwist-thirdweb/blob/main/app/components/SendNotification.tsx) requires backend implementation: * **Save subscription data** when users subscribe (see TODO comments in code) * **Delete subscription data** when users unsubscribe * **Implement `/notification` endpoint** to send actual push notifications * **Use `web-push` library** or similar for server-side notification delivery ### [​](https://docs.monad.xyz/templates/next-serwist-thirdweb#customizing-notification-content) Customizing Notification Content To customize your push notification content, edit [`app/notification/route.ts`](https://github.com/monad-developers/next-serwist-thirdweb/blob/main/app/notification/route.ts) and modify the `title`, `message`, `icon`, and other properties in the `sendNotification` call. [​](https://docs.monad.xyz/templates/next-serwist-thirdweb#modifying-the-app-icon-&-splash-screen) Modifying the App Icon & Splash Screen -------------------------------------------------------------------------------------------------------------------------------------------- ### [​](https://docs.monad.xyz/templates/next-serwist-thirdweb#app-icons) App Icons Replace the icon files in the [`public/icons/`](https://github.com/monad-developers/next-serwist-thirdweb/tree/main/public/icons) directory with your custom icons: * **`icon-512x512.png`** - Main app icon (512×512px) * **`android-chrome-192x192.png`** - Android icon (192×192px) * **`apple-touch-icon.png`** - iOS home screen icon (180×180px) Also update the favicon: * **`public/favicon.ico`** - Browser favicon * **`app/favicon.ico`** - Next.js app favicon ### [​](https://docs.monad.xyz/templates/next-serwist-thirdweb#splash-screen) Splash Screen Splash screens are automatically generated from your app icon and theme colors defined in [`public/manifest.json`](https://github.com/monad-developers/next-serwist-thirdweb/blob/main/public/manifest.json) . To customize: 1. Update the `theme_color` and `background_color` in [`public/manifest.json`](https://github.com/monad-developers/next-serwist-thirdweb/blob/main/public/manifest.json) 2. Ensure your main icon (`icon-512x512.png`) represents your brand 3. Run `npm run build` to apply changes Use tools like [PWA Asset Generator](https://www.pwabuilder.com/imageGenerator) to create all required icon sizes from a single source image. [​](https://docs.monad.xyz/templates/next-serwist-thirdweb#deploying-to-vercel) Deploying to Vercel ------------------------------------------------------------------------------------------------------ ### [​](https://docs.monad.xyz/templates/next-serwist-thirdweb#using-vercel-dashboard) Using Vercel Dashboard 1. **Connect your repository**: * Push your code to GitHub * Visit [vercel.com](https://vercel.com/) and import your repository 2. **Configure environment variables**: * In your Vercel project dashboard, go to Settings → Environment Variables * Add the same variables from your `.env.local`: NEXT_PUBLIC_THIRDWEB_CLIENT_ID WEB_PUSH_EMAIL WEB_PUSH_PRIVATE_KEY NEXT_PUBLIC_WEB_PUSH_PUBLIC_KEY 3. **Deploy**: Vercel will automatically build and deploy your app 4. **Update Thirdweb settings**: In your Thirdweb dashboard, add your Vercel domain (e.g., `your-app.vercel.app`) to the allowed origins PWA features (install prompts, offline support, push notifications) work automatically on HTTPS domains like Vercel deployments. ### [​](https://docs.monad.xyz/templates/next-serwist-thirdweb#using-vercel-cli) Using Vercel CLI Alternatively, deploy using the Vercel CLI: 1. **Install Vercel CLI**: npm i -g vercel 2. **Login to Vercel**: vercel login 3. **Deploy**: vercel Follow the prompts to configure your project. 4. **Add environment variables**: vercel env add NEXT_PUBLIC_THIRDWEB_CLIENT_ID vercel env add WEB_PUSH_EMAIL vercel env add WEB_PUSH_PRIVATE_KEY vercel env add NEXT_PUBLIC_WEB_PUSH_PUBLIC_KEY Or you can go to the Vercel dashboard and add the environment variables there. 5. **Redeploy with environment variables**: vercel --prod [​](https://docs.monad.xyz/templates/next-serwist-thirdweb#learn-more) Learn more ------------------------------------------------------------------------------------ * Serwist: [docs](https://serwist.pages.dev/) | [guides](https://serwist.pages.dev/docs/next/getting-started) * Thirdweb: [docs](https://portal.thirdweb.com/) | [guides](https://portal.thirdweb.com/docs/quick-start) * Monad: [supported tooling and infra](https://docs.monad.xyz/tooling-and-infra) [How to use the Next.js Serwist 0x Privy embedded wallet template\ \ Previous](https://docs.monad.xyz/templates/next-serwist-0x-privy-embedded-wallet) [Frequently Asked Questions\ \ Next](https://docs.monad.xyz/faq) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Wallets - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/tooling-and-infra/wallets#content-area) Software Wallets ---------------- Browser extension wallets and mobile wallets Hardware Wallets ---------------- Offline wallets Institutional Wallets --------------------- Multisig Wallets ---------------- For developers looking for advanced functionality such as embedded wallets or account abstraction, see [Wallet Infrastructure](https://docs.monad.xyz/tooling-and-infra/wallet-infra) . [Monad Solonet\ \ Previous](https://docs.monad.xyz/tooling-and-infra/toolkits/monad-solonet) [Software Wallets\ \ Next](https://docs.monad.xyz/tooling-and-infra/wallets/software-wallets) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Wallet Infrastructure - Monad Documentation > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/llms.txt](https://docs.monad.xyz/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://docs.monad.xyz/tooling-and-infra/wallet-infra#content-area) [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra#summary) Summary ----------------------------------------------------------------------------- Monad features excellent support for developers looking to refine their users’ experience by utilizing modular wallet infrastructure. These pages survey the supported infrastructure: * [Embedded Wallets](https://docs.monad.xyz/tooling-and-infra/wallet-infra/embedded-wallets) * [Account Abstraction Providers](https://docs.monad.xyz/tooling-and-infra/wallet-infra/account-abstraction) * [Smart Account Implementations](https://docs.monad.xyz/tooling-and-infra/wallet-infra/smart-accounts) The landscape can be confusing, even to an experienced developer; therefore we include a rough topology below. [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra#background) Background ----------------------------------------------------------------------------------- Wallets allow users to store private keys and sign transactions. The basic setup involves separation between the wallet and the application: the application presents a transaction to the wallet for signing, and the wallet submits the transaction to the network, paying for inclusion and execution with native tokens deducted from its balance. However, increasingly, developers wish to customize their users’ experience, for example by sponsoring gas for their users or by allowing users to pay fees in an alternate currency. Other developers want to embed the “wallet” into the app and give the app signing power over that wallet, so that users don’t have to sign a transaction with each action that they take. Modular wallet infrastructure enables these and other features. A number of providers are solving for this experience. To simplify understanding of the options, we suggest the following two-dimensional matrix: | | Freestanding | Embedded | | --- | --- | --- | | **EOA** | See [Simple Wallets](https://docs.monad.xyz/tooling-and-infra/wallets) | See [Embedded Wallets](https://docs.monad.xyz/tooling-and-infra/wallet-infra/embedded-wallets)
.
Typically utilizes key sharding, e.g. using MPC, SSS, or TEE | | **Smart Account** | Utilizes Account Abstraction, i.e. developer needs to choose:

* [AA Providers](https://docs.monad.xyz/tooling-and-infra/wallet-infra/account-abstraction)

* [Smart Accounts](https://docs.monad.xyz/tooling-and-infra/wallet-infra/smart-accounts) | See [Embedded Wallets](https://docs.monad.xyz/tooling-and-infra/wallet-infra/embedded-wallets)
and look for “Embedded Smart Accounts” | [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra#eoa-based-approach) EOA-based approach --------------------------------------------------------------------------------------------------- **(EOA, freestanding)** is the traditional wallet experience powered by browser extension wallets, mobile wallets, and hardware wallets. It involves a single private key stored within the wallet. See [Wallets](https://docs.monad.xyz/tooling-and-infra/wallets) for a survey. **(EOA, embedded)**: typically uses cryptographic techniques (MPC, SSS, etc) to shard the signing keys, implementing additional authorization or access control features off-chain, while presenting to the blockchain as an ordinary EOA. See [Embedded Wallets](https://docs.monad.xyz/tooling-and-infra/wallet-infra/embedded-wallets) for a list of providers. [​](https://docs.monad.xyz/tooling-and-infra/wallet-infra#smart-account-account-abstraction-approach) Smart account (account abstraction) approach ----------------------------------------------------------------------------------------------------------------------------------------------------- Account Abstraction means using smart contracts in place of simple EOAs. The smart contract implements the authorization / access control logic, i.e. the logic is on chain. Historically, smart contracts could not pay for their own transaction costs (although EIP-7702 introduces an exception to this rule). Therefore, the account abstraction path requires users to sign pseudo-transactions (UserOperations) and submit them to a custom mempool. Then, a service called the Bundler/Relayer submits UserOperations in a normal Monad transaction and pays for the execution. Thus, there are at least two considerations for developers building with smart accounts: * the Bundler/Relayer service; see [Account Abstraction Providers](https://docs.monad.xyz/tooling-and-infra/wallet-infra/account-abstraction) for a list * the [Smart Account Implementation](https://docs.monad.xyz/tooling-and-infra/wallet-infra/smart-accounts) Some embedded wallet providers support smart accounts. See [Embedded Wallets](https://docs.monad.xyz/tooling-and-infra/wallet-infra/embedded-wallets) and look out for “Embedded Smart Accounts”. [Multisig Wallets\ \ Previous](https://docs.monad.xyz/tooling-and-infra/wallets/multisig-wallets) [Embedded Wallets\ \ Next](https://docs.monad.xyz/tooling-and-infra/wallet-infra/embedded-wallets) ⌘I Assistant Responses are generated using AI and may contain mistakes. ---