megaeth-developer
End-to-end MegaETH development playbook (Feb 2026). Covers wallet operations, token swaps (Kyber Network), eth_sendRawTransactionSync (EIP-7966) for instant receipts, JSON-RPC batching, real-time mini-block subscriptions, storage-aware contract patterns (Solady RedBlackTreeLib), MegaEVM gas model, WebSocket keepalive, bridging from Ethereum, and debugging with mega-evme. Use when building on MegaETH, managing wallets, sending transactions, or deploying contracts.
Packaged view
This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.
Install command
npx @skill-hub/cli install openclaw-skills-megaeth
Repository
Skill path: skills/0xguardbot/megaeth
End-to-end MegaETH development playbook (Feb 2026). Covers wallet operations, token swaps (Kyber Network), eth_sendRawTransactionSync (EIP-7966) for instant receipts, JSON-RPC batching, real-time mini-block subscriptions, storage-aware contract patterns (Solady RedBlackTreeLib), MegaEVM gas model, WebSocket keepalive, bridging from Ethereum, and debugging with mega-evme. Use when building on MegaETH, managing wallets, sending transactions, or deploying contracts.
Open repositoryBest for
Primary workflow: Run DevOps.
Technical facets: Full Stack, DevOps.
Target audience: everyone.
License: Unknown.
Original source
Catalog source: SkillHub Club.
Repository owner: openclaw.
This is still a mirrored public skill entry. Review the repository before installing into production workflows.
What it helps with
- Install megaeth-developer into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
- Review https://github.com/openclaw/skills before adding megaeth-developer to shared team environments
- Use megaeth-developer for development workflows
Works across
Favorites: 0.
Sub-skills: 0.
Aggregator: No.
Original source / Raw SKILL.md
---
name: megaeth-developer
description: End-to-end MegaETH development playbook (Feb 2026). Covers wallet operations, token swaps (Kyber Network), eth_sendRawTransactionSync (EIP-7966) for instant receipts, JSON-RPC batching, real-time mini-block subscriptions, storage-aware contract patterns (Solady RedBlackTreeLib), MegaEVM gas model, WebSocket keepalive, bridging from Ethereum, and debugging with mega-evme. Use when building on MegaETH, managing wallets, sending transactions, or deploying contracts.
---
# MegaETH Development Skill
## What this Skill is for
Use this Skill when the user asks for:
- Wallet setup and management on MegaETH
- Sending transactions, checking balances, token operations
- Token swaps via Kyber Network aggregator
- MegaETH dApp frontend (React / Next.js with real-time updates)
- RPC configuration and transaction flow optimization
- Smart contract development with MegaEVM considerations
- Storage optimization (avoiding expensive SSTORE costs)
- Gas estimation and fee configuration
- Testing and debugging MegaETH transactions
- WebSocket subscriptions and mini-block streaming
- Bridging ETH from Ethereum to MegaETH
## Chain Configuration
| Network | Chain ID | RPC | Explorer |
|---------|----------|-----|----------|
| Mainnet | 4326 | `https://mainnet.megaeth.com/rpc` | `https://mega.etherscan.io` |
| Testnet | 6343 | `https://carrot.megaeth.com/rpc` | `https://megaeth-testnet-v2.blockscout.com` |
## Default stack decisions (opinionated)
### 1. Transaction submission: eth_sendRawTransactionSync first
- Use `eth_sendRawTransactionSync` (EIP-7966) — returns receipt in <10ms
- Eliminates polling for `eth_getTransactionReceipt`
- Docs: https://docs.megaeth.com/realtime-api
### 2. RPC: Multicall for eth_call batching (v2.0.14+)
- Prefer Multicall (`aggregate3`) for batching multiple `eth_call` requests
- As of v2.0.14, `eth_call` is 2-10x faster; Multicall amortizes per-RPC overhead
- Still avoid mixing slow methods (`eth_getLogs`) with fast ones in same request
**Note:** Earlier guidance recommended JSON-RPC batching over Multicall for caching benefits. With v2.0.14's performance improvements, Multicall is now preferred.
### 3. WebSocket: keepalive required
- Send `eth_chainId` every 30 seconds
- 50 connections per VIP endpoint, 10 subscriptions per connection
- Use `miniBlocks` subscription for real-time data
### 4. Storage: slot reuse patterns
- SSTORE 0→non-zero costs 2M gas × multiplier (expensive)
- Use Solady's RedBlackTreeLib instead of Solidity mappings
- Design for slot reuse, not constant allocation
### 5. Gas: skip estimation when possible
- Base fee stable at 0.001 gwei, no EIP-1559 adjustment
- Ignore `eth_maxPriorityFeePerGas` (returns 0)
- Hardcode gas limits to save round-trip
- Always use remote `eth_estimateGas` (MegaEVM costs differ from standard EVM)
### 6. Debugging: mega-evme CLI
- Replay transactions with full traces
- Profile gas by opcode
- https://github.com/megaeth-labs/mega-evm
## Operating procedure
### 1. Classify the task layer
- Frontend/WebSocket layer
- RPC/transaction layer
- Smart contract layer
- Testing/debugging layer
### 2. Pick the right patterns
- Frontend: single WebSocket → broadcast to users (not per-user connections)
- Transactions: sign locally → `eth_sendRawTransactionSync` → done
- Contracts: check SSTORE patterns, avoid volatile data access limits
- Testing: use mega-evme for replay, Foundry with `--skip-simulation`
### 3. Implement with MegaETH-specific correctness
Always be explicit about:
- Chain ID (4326 mainnet, 6343 testnet)
- Gas limit (hardcode when possible)
- Base fee (0.001 gwei, no buffer)
- Storage costs (new slots are expensive)
- Volatile data limits (20M gas after block.timestamp access)
### 4. Deliverables expectations
When implementing changes, provide:
- Exact files changed + diffs
- Commands to build/test/deploy
- Gas cost notes for storage-heavy operations
- RPC optimization notes if applicable
## Progressive disclosure (read when needed)
- Wallet operations: [wallet-operations.md](wallet-operations.md)
- Frontend patterns: [frontend-patterns.md](frontend-patterns.md)
- RPC methods reference: [rpc-methods.md](rpc-methods.md)
- Smart contract patterns: [smart-contracts.md](smart-contracts.md)
- Storage optimization: [storage-optimization.md](storage-optimization.md)
- Gas model: [gas-model.md](gas-model.md)
- Testing & debugging: [testing.md](testing.md)
- Security considerations: [security.md](security.md)
- Reference links: [resources.md](resources.md)
---
## Referenced Files
> The following files are referenced in this skill and included for context.
### wallet-operations.md
```markdown
# Wallet Operations on MegaETH
## Chain Configuration
| Parameter | Mainnet | Testnet |
|-----------|---------|---------|
| Chain ID | 4326 | 6343 |
| RPC | `https://mainnet.megaeth.com/rpc` | `https://carrot.megaeth.com/rpc` |
| Native Token | ETH | ETH |
| Explorer | `https://mega.etherscan.io` | `https://megaeth-testnet-v2.blockscout.com` |
## Wallet Setup
### Using viem
```typescript
import { createWalletClient, http } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { megaeth } from './chains'; // See frontend-patterns.md
const account = privateKeyToAccount('0x...');
const client = createWalletClient({
account,
chain: megaeth,
transport: http('https://mainnet.megaeth.com/rpc')
});
```
### Using ethers.js
```typescript
import { ethers } from 'ethers';
const provider = new ethers.JsonRpcProvider('https://mainnet.megaeth.com/rpc');
const wallet = new ethers.Wallet('0x...privateKey', provider);
```
### Using evm-wallet-skill (CLI)
```bash
# Generate wallet (one-time)
node src/setup.js --json
# Stores key at ~/.evm-wallet.json (chmod 600)
```
## Check Balance
### Native ETH
```typescript
// viem
const balance = await publicClient.getBalance({ address: '0x...' });
// ethers
const balance = await provider.getBalance('0x...');
```
```bash
# CLI
node src/balance.js megaeth --json
```
### ERC20 Tokens
```typescript
const balance = await publicClient.readContract({
address: tokenAddress,
abi: erc20Abi,
functionName: 'balanceOf',
args: [walletAddress]
});
```
```bash
# CLI (WETH example)
node src/balance.js megaeth 0x4200000000000000000000000000000000000006 --json
```
## Send Transactions
### Instant Receipts
MegaETH supports synchronous transaction submission — get receipts in <10ms.
**Two equivalent methods:**
- `realtime_sendRawTransaction` — MegaETH original
- `eth_sendRawTransactionSync` — EIP-7966 standard (recommended)
MegaETH created `realtime_*` first; `*Sync` was later standardized as EIP-7966. Both are proxied and functionally identical. Use `eth_sendRawTransactionSync` for cross-chain compatibility.
```typescript
// Sign transaction
const signedTx = await wallet.signTransaction({
to: recipient,
value: parseEther('0.1'),
gas: 60000n, // MegaETH intrinsic gas (not 21000)
maxFeePerGas: 1000000n, // 0.001 gwei
maxPriorityFeePerGas: 0n
});
// Send with instant receipt
const receipt = await client.request({
method: 'eth_sendRawTransactionSync',
params: [signedTx]
});
console.log('Confirmed in block:', receipt.blockNumber);
```
### Standard Send (polling)
```typescript
// viem
const hash = await walletClient.sendTransaction({
to: recipient,
value: parseEther('0.1')
});
const receipt = await publicClient.waitForTransactionReceipt({ hash });
// ethers
const tx = await wallet.sendTransaction({
to: recipient,
value: parseEther('0.1')
});
const receipt = await tx.wait();
```
```bash
# CLI
node src/transfer.js megaeth 0xRecipient 0.1 --yes --json
```
## Gas Configuration
MegaETH has stable, low gas costs but different intrinsic gas than standard EVM:
```typescript
const tx = {
to: recipient,
value: parseEther('0.1'),
gas: 60000n, // MegaETH intrinsic gas (not 21000!)
maxFeePerGas: 1000000n, // 0.001 gwei (base fee)
maxPriorityFeePerGas: 0n // Not needed unless congested
};
```
**Tips:**
- Base fee is stable at 0.001 gwei
- Simple ETH transfers need **60,000 gas** on MegaETH (not 21,000)
- Don't add buffers (viem adds 20% by default — override it)
- When in doubt, use `eth_estimateGas` — MegaEVM costs differ from standard EVM
- Hardcode gas limits for known operations
## Token Operations
### Token Addresses
**Official token list:** https://github.com/megaeth-labs/mega-tokenlist
Common tokens (Mainnet):
| Token | Address |
|-------|---------|
| WETH | `0x4200000000000000000000000000000000000006` |
| MEGA | `0x28B7E77f82B25B95953825F1E3eA0E36c1c29861` |
| USDM | `0xFAfDdbb3FC7688494971a79cc65DCa3EF82079E7` |
For the full list of verified tokens, logos, and metadata, see the [mega-tokenlist](https://github.com/megaeth-labs/mega-tokenlist) repo.
### Transfer ERC20
```typescript
const hash = await walletClient.writeContract({
address: tokenAddress,
abi: erc20Abi,
functionName: 'transfer',
args: [recipient, amount]
});
```
```bash
# CLI (send 100 USDM)
node src/transfer.js megaeth 0xRecipient 100 0xFAfDdbb3FC7688494971a79cc65DCa3EF82079E7 --yes --json
```
### Approve Spending
```typescript
const hash = await walletClient.writeContract({
address: tokenAddress,
abi: erc20Abi,
functionName: 'approve',
args: [spenderAddress, maxUint256]
});
```
## Token Swaps (Kyber Network)
MegaETH uses **Kyber Network** as the DEX aggregator for best-route swaps.
### API Integration
```typescript
const KYBER_API = 'https://aggregator-api.kyberswap.com/megaeth/api/v1';
// Get quote
const quoteRes = await fetch(
`${KYBER_API}/routes?` + new URLSearchParams({
tokenIn: '0x...', // or 'ETH' for native
tokenOut: '0x...',
amountIn: amount.toString(),
gasInclude: 'true'
})
);
const quote = await quoteRes.json();
// Build transaction
const buildRes = await fetch(`${KYBER_API}/route/build`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
routeSummary: quote.data.routeSummary,
sender: walletAddress,
recipient: walletAddress,
slippageTolerance: 50 // 0.5% = 50 bips
})
});
const { data } = await buildRes.json();
// Execute swap
const hash = await walletClient.sendTransaction({
to: data.routerAddress,
data: data.data,
value: data.value,
gas: BigInt(data.gas)
});
```
### Kyber Resources
- **Docs**: https://docs.kyberswap.com/kyberswap-solutions/kyberswap-aggregator
- **MegaETH Router**: Check Kyber docs for current address
## Bridging ETH to MegaETH
### Canonical Bridge (from Ethereum)
Send ETH directly to the bridge contract on Ethereum mainnet:
```typescript
// On Ethereum mainnet
const bridgeAddress = '0x0CA3A2FBC3D770b578223FBB6b062fa875a2eE75';
const tx = await wallet.sendTransaction({
to: bridgeAddress,
value: parseEther('0.1') // Will appear on MegaETH
});
```
For programmatic bridging with gas control:
```typescript
const iface = new ethers.Interface([
'function depositETH(uint32 _minGasLimit, bytes _extraData) payable'
]);
const data = iface.encodeFunctionData('depositETH', [
61000, // Gas limit on MegaETH side
'0x' // Extra data (optional)
]);
const tx = await wallet.sendTransaction({
to: bridgeAddress,
value: parseEther('0.1'),
data
});
```
## Transaction Confirmation
MegaETH has ~10ms block times. Transactions confirm almost instantly.
```typescript
// With eth_sendRawTransactionSync — instant
const receipt = await client.request({
method: 'eth_sendRawTransactionSync',
params: [signedTx]
});
// receipt is immediately available
// Standard — still very fast
const hash = await wallet.sendTransaction(tx);
const receipt = await tx.wait(); // ~100-200ms total
```
## Error Handling
| Error | Cause | Solution |
|-------|-------|----------|
| "nonce too low" | Tx already executed | Check receipt, don't retry |
| "already known" | Tx pending | Wait for confirmation |
| "insufficient funds" | Not enough ETH | Check balance, fund wallet |
| "intrinsic gas too low" | Gas limit too low | Increase gas or use remote estimation |
## Security Notes
1. **Never expose private keys** — store at `~/.evm-wallet.json` with chmod 600
2. **Confirm before sending** — always show recipient, amount, gas before execution
3. **Use hardware wallets** for large amounts
4. **Verify contract addresses** — check explorer before interacting
```
### frontend-patterns.md
```markdown
# Frontend Patterns (React / Next.js)
## Architecture Principle
**Never open per-user WebSocket connections.** Use one connection, broadcast to users.
```
❌ Wrong: Each user → WebSocket → MegaETH
✅ Right: Server → WebSocket → MegaETH, Server → broadcast → Users
```
## Real-time Data Flow
### Server-Side WebSocket Manager
```typescript
// lib/megaeth-stream.ts
import WebSocket from 'ws';
class MegaETHStream {
private ws: WebSocket | null = null;
private subscribers = new Set<(data: any) => void>();
private keepaliveInterval: NodeJS.Timeout | null = null;
connect() {
this.ws = new WebSocket('wss://mainnet.megaeth.com/ws');
this.ws.on('open', () => {
// Subscribe to mini-blocks
this.ws!.send(JSON.stringify({
jsonrpc: '2.0',
method: 'eth_subscribe',
params: ['miniBlocks'],
id: 1
}));
// Keepalive every 30s
this.keepaliveInterval = setInterval(() => {
this.ws!.send(JSON.stringify({
jsonrpc: '2.0',
method: 'eth_chainId',
params: [],
id: Date.now()
}));
}, 30000);
});
this.ws.on('message', (data) => {
const parsed = JSON.parse(data.toString());
if (parsed.method === 'eth_subscription') {
this.subscribers.forEach(fn => fn(parsed.params.result));
}
});
this.ws.on('close', () => {
if (this.keepaliveInterval) clearInterval(this.keepaliveInterval);
setTimeout(() => this.connect(), 1000); // Reconnect
});
}
subscribe(callback: (data: any) => void) {
this.subscribers.add(callback);
return () => this.subscribers.delete(callback);
}
}
export const megaStream = new MegaETHStream();
```
### Client-Side Hook
```typescript
// hooks/useMiniBlocks.ts
import { useEffect, useState } from 'react';
import { io } from 'socket.io-client';
export function useMiniBlocks() {
const [latestBlock, setLatestBlock] = useState<MiniBlock | null>(null);
const [tps, setTps] = useState(0);
useEffect(() => {
const socket = io('/api/stream');
socket.on('miniBlock', (block: MiniBlock) => {
setLatestBlock(block);
setTps(block.transactions.length * 100); // ~100 mini-blocks/sec
});
return () => { socket.disconnect(); };
}, []);
return { latestBlock, tps };
}
```
## Connection Warmup
First HTTP request to an RPC endpoint incurs connection overhead (DNS + TCP + TLS handshake). For latency-sensitive apps, warm up the connection on startup:
```typescript
// On app init or wallet connect — before user needs to transact
async function warmupRpcConnection(client: PublicClient) {
await client.getChainId(); // Cheap call to establish connection
}
// Now first real transaction won't have cold-start latency
```
**Why it matters:** MegaETH has <10ms block times. A cold connection can add 50-200ms of overhead on the first request. Warming up ensures the connection pool is ready when users transact.
**Best practice:** Call `eth_chainId` or `eth_blockNumber` on:
- App initialization
- Wallet connection
- Network switch
## Transaction Submission
### Optimized Flow
```typescript
// lib/submit-tx.ts
import { createWalletClient, http, custom } from 'viem';
import { megaeth } from './chains';
export async function submitTransaction(signedTx: `0x${string}`) {
const client = createWalletClient({
chain: megaeth,
transport: http('https://mainnet.megaeth.com/rpc')
});
// Use sync method for instant receipt
const receipt = await client.request({
method: 'eth_sendRawTransactionSync',
params: [signedTx]
});
return receipt; // Receipt available immediately
}
```
### Chain Configuration (viem)
```typescript
// lib/chains.ts
import { defineChain } from 'viem';
export const megaeth = defineChain({
id: 4326,
name: 'MegaETH',
nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
rpcUrls: {
default: { http: ['https://mainnet.megaeth.com/rpc'] }
},
blockExplorers: {
default: { name: 'Etherscan', url: 'https://mega.etherscan.io' }
}
});
export const megaethTestnet = defineChain({
id: 6343,
name: 'MegaETH Testnet',
nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
rpcUrls: {
default: { http: ['https://carrot.megaeth.com/rpc'] }
},
blockExplorers: {
default: { name: 'Blockscout', url: 'https://megaeth-testnet-v2.blockscout.com' }
}
});
```
## Gas Configuration
```typescript
// ❌ Wrong: viem adds 20% buffer
const gasPrice = await publicClient.getGasPrice();
// ✅ Right: use base fee directly
const gasPrice = 1000000n; // 0.001 gwei
// ✅ Right: hardcode gas for known operations
const tx = await walletClient.sendTransaction({
to: recipient,
value: amount,
gas: 21000n,
maxFeePerGas: 1000000n,
maxPriorityFeePerGas: 0n
});
```
## RPC Request Batching (v2.0.14+)
As of v2.0.14, **Multicall is preferred** for batching `eth_call` requests. The `eth_call` implementation is now 2-10x faster, and Multicall amortizes per-RPC overhead.
```typescript
// ✅ Preferred: Multicall (v2.0.14+)
import { multicall } from 'viem/actions';
const results = await multicall(client, {
contracts: [
{ address: token1, abi: erc20Abi, functionName: 'balanceOf', args: [user] },
{ address: token2, abi: erc20Abi, functionName: 'balanceOf', args: [user] },
{ address: pool, abi: poolAbi, functionName: 'getReserves' },
]
});
// ❌ Still avoid: mixing slow with fast
// Don't batch eth_getLogs with eth_call — logs are always slower
```
**Note:** Earlier guidance recommended JSON-RPC batching over Multicall for caching benefits. With v2.0.14's performance improvements, Multicall is now the preferred approach.
## Historical Data
Never block UX waiting for historical queries:
```typescript
// Load historical in background
useEffect(() => {
// Don't await - let it load async
fetchHistoricalTrades().then(setTrades);
}, []);
// Use indexers for heavy queries
// Recommended: Envio HyperSync
// https://docs.envio.dev/docs/HyperSync/overview
```
## Error Handling
```typescript
const TX_ERRORS = {
'nonce too low': 'Transaction already executed',
'already known': 'Transaction pending',
'intrinsic gas too low': 'Increase gas limit',
'insufficient funds': 'Not enough ETH for gas'
};
function handleTxError(error: Error) {
for (const [pattern, message] of Object.entries(TX_ERRORS)) {
if (error.message.includes(pattern)) {
return message;
}
}
return 'Transaction failed';
}
```
```
### rpc-methods.md
```markdown
# RPC Reference
## Endpoints
| Type | Mainnet | Testnet |
|------|---------|---------|
| HTTP | `https://mainnet.megaeth.com/rpc` | `https://carrot.megaeth.com/rpc` |
| WebSocket | `wss://mainnet.megaeth.com/ws` | `wss://carrot.megaeth.com/ws` |
Third-party providers: Alchemy, QuickNode (recommended for geo-distributed access)
## MegaETH-Specific Methods
### Instant Transaction Receipts
MegaETH supports synchronous transaction submission — get your receipt in <10ms instead of polling.
**Two equivalent methods:**
| Method | Origin | Status |
|--------|--------|--------|
| `realtime_sendRawTransaction` | MegaETH original | Supported |
| `eth_sendRawTransactionSync` | EIP-7966 standard | Supported (proxied) |
**History:** MegaETH created `realtime_sendRawTransaction` first. Later, `eth_sendRawTransactionSync` was standardized as EIP-7966. MegaETH now proxies both — they are functionally identical. Use whichever you prefer; `eth_sendRawTransactionSync` is recommended for cross-chain compatibility.
```bash
# Both work identically:
curl -X POST https://mainnet.megaeth.com/rpc \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "eth_sendRawTransactionSync",
"params": ["0x...signedTx"],
"id": 1
}'
# Or use the original:
curl -X POST https://mainnet.megaeth.com/rpc \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "realtime_sendRawTransaction",
"params": ["0x...signedTx"],
"id": 1
}'
```
**Response:** Full transaction receipt (same schema as `eth_getTransactionReceipt`)
**Corner cases on retry:**
- Tx still in pool: "already known" error
- Tx already executed: "nonce too low" error (future: will return receipt directly)
### eth_getLogsWithCursor
Paginated log queries for large result sets:
```javascript
const response = await client.request({
method: 'eth_getLogsWithCursor',
params: [{
address: '0x...',
topics: ['0x...'],
fromBlock: '0x0',
toBlock: 'latest'
}]
});
// Returns { logs: [...], cursor: "..." }
// Use cursor in next request to continue
```
### Mini-Block Subscription
```javascript
{
"jsonrpc": "2.0",
"method": "eth_subscribe",
"params": ["miniBlocks"],
"id": 1
}
```
**Mini-block schema:**
```json
{
"payload_id": "0x...",
"block_number": 12345,
"index": 0,
"tx_offset": 0,
"log_offset": 0,
"gas_offset": 0,
"timestamp": 1704067200000,
"gas_used": 21000,
"transactions": [...],
"receipts": [...]
}
```
Mini-blocks are ephemeral — cannot be fetched via RPC after assembly into blocks.
## WebSocket Guidelines
### Keepalive Required
Send `eth_chainId` every 30 seconds to prevent disconnection:
```javascript
const ws = new WebSocket('wss://mainnet.megaeth.com/ws');
const keepalive = setInterval(() => {
ws.send(JSON.stringify({
jsonrpc: '2.0',
method: 'eth_chainId',
params: [],
id: Date.now()
}));
}, 30000);
ws.on('close', () => clearInterval(keepalive));
```
### Limits
- 50 WebSocket connections per VIP endpoint
- 10 subscriptions per connection (+1 on subscribe, -1 on unsubscribe)
### Supported Methods on WS
- `eth_sendRawTransaction`
- `eth_sendRawTransactionSync`
- `eth_subscribe` / `eth_unsubscribe`
- `eth_chainId` (for keepalive)
## Batching eth_call Requests (v2.0.14+)
As of v2.0.14, **Multicall is the preferred approach** for batching `eth_call` requests.
### Why Multicall?
With v2.0.14, `eth_call` is 2-10x faster. The EVM execution time is now a small fraction of total CPU time — most overhead is per-RPC framework cost. Multicall amortizes this overhead across multiple calls.
```typescript
// ✅ Preferred: Multicall (v2.0.14+)
import { multicall } from 'viem/actions';
const results = await multicall(client, {
contracts: [
{ address: token1, abi: erc20Abi, functionName: 'balanceOf', args: [user] },
{ address: token2, abi: erc20Abi, functionName: 'balanceOf', args: [user] },
{ address: token3, abi: erc20Abi, functionName: 'balanceOf', args: [user] },
]
});
```
### Historical Context
Earlier MegaETH guidance recommended JSON-RPC batching over Multicall because:
- Multicall made it difficult to cache `eth_call` results effectively
- Certain dApps benefited significantly from this caching
With v2.0.14's performance improvements, the caching mechanism is deprecated and Multicall is now preferred.
### Still Avoid
- **Mixing slow + fast methods** — Don't batch `eth_getLogs` with `eth_call`; logs are always slower
- **Blocking UX on historical queries** — Keep `eth_getLogs` in background
## Rate Limiting
Public endpoints have rate limits based on:
- CPU time consumption
- Network bandwidth (32 MB/s average, 15x burst for VIP)
### Methods Vulnerable to Abuse
These require VIP endpoints for heavy usage:
- `eth_getLogs` (large block ranges)
- `eth_call` (complex contracts)
- `debug_*` / `trace_*` (disabled on public)
### Best Practices
1. **Warm up connections** — Call `eth_chainId` on app init to pre-establish HTTP connection (avoids DNS/TCP/TLS overhead on first real request)
2. **Use Multicall for eth_call batching** — Amortizes per-RPC overhead (v2.0.14+)
3. **Don't batch slow with fast** — `eth_getLogs` blocks entire batch response
4. **Use cursors** — `eth_getLogsWithCursor` instead of huge `eth_getLogs`
5. **Background historical queries** — Never block UX waiting for logs
## eth_getLogs Limits
- Multi-block queries: max 20,000 logs per call
- Single-block queries: no limit
- Workaround: Get headers first to count logs, then build queries accordingly
## Historical Data
Public endpoint supports `eth_call` on blocks from past ~15 days. For older data:
- Use Alchemy/QuickNode
- Run your own archive node
- Use indexers (Envio HyperSync recommended)
## Latency Optimization
MegaETH's real-time capabilities shine when you optimize for low latency. Here's what matters:
### Benchmarks (West Coast US → Public RPC)
| Method | HTTP | WebSocket |
|--------|------|-----------|
| eth_chainId | 40ms | **7ms** |
| eth_getBalance | 140ms | ~50ms |
| eth_sendRawTransactionSync | 200-450ms | **150-300ms** |
WebSocket is **5-6x faster** for simple calls due to persistent connection.
### 1. Use WebSocket Over HTTP
```typescript
// ❌ Slow: HTTP per request (TCP + TLS handshake each time)
const result = await fetch(RPC_URL, { method: 'POST', ... });
// ✅ Fast: Persistent WebSocket connection
const ws = new WebSocket('wss://mainnet.megaeth.com/ws');
ws.send(JSON.stringify({ method: 'eth_sendRawTransactionSync', ... }));
```
### 2. Pre-Sign Transactions
Don't sign in the hot path. Prepare transactions ahead of time:
```typescript
// Pre-sign with sequential nonces
const nonce = await publicClient.getTransactionCount({ address });
const signedTxs = await Promise.all([
wallet.signTransaction({ ...baseTx, nonce: nonce }),
wallet.signTransaction({ ...baseTx, nonce: nonce + 1 }),
wallet.signTransaction({ ...baseTx, nonce: nonce + 2 }),
]);
// Later: fire instantly when needed
const receipt = await rpc('eth_sendRawTransactionSync', [signedTxs[0]]);
```
### 3. Nonce Pipelining
Don't wait for confirmations between transactions:
```typescript
// ❌ Slow: Wait for each confirmation
for (const tx of transactions) {
const receipt = await sendAndWait(tx);
}
// ✅ Fast: Pipeline with sequential nonces
let nonce = await getNonce(address);
const receipts = await Promise.all(
transactions.map((tx, i) =>
rpc('eth_sendRawTransactionSync', [
signTx({ ...tx, nonce: nonce + i })
])
)
);
```
### 4. HTTP Keep-Alive
If using HTTP, ensure connection reuse:
```typescript
import https from 'https';
const agent = new https.Agent({
keepAlive: true,
maxSockets: 10
});
// Reuse for all requests
fetch(RPC_URL, { agent, ... });
```
### 5. Geographic Proximity
| Setup | Latency |
|-------|---------|
| Cross-continent | 150-300ms RTT |
| Same region (cloud) | 20-50ms RTT |
| Local node | **<5ms RTT** |
For ultra-low latency:
- Use Alchemy/QuickNode geo-distributed endpoints
- Run your own node in the same datacenter as your app
### 6. Batch RPC Calls
```typescript
// ❌ Slow: 3 sequential calls = 3x latency
const a = await rpc('eth_call', [params1]);
const b = await rpc('eth_call', [params2]);
const c = await rpc('eth_call', [params3]);
// ✅ Fast: Single batch = 1x latency
const [a, b, c] = await fetch(RPC_URL, {
body: JSON.stringify([
{ method: 'eth_call', params: [params1], id: 1 },
{ method: 'eth_call', params: [params2], id: 2 },
{ method: 'eth_call', params: [params3], id: 3 },
])
});
```
### Theoretical Minimum Latency
With optimal setup (local node + WebSocket + pre-signed):
- Sign: ~1ms (pre-computed)
- Network to local node: ~1ms
- MegaETH processing: ~10ms
- **Total: ~12ms**
## Debugging Commands
```bash
# Estimate gas
cast estimate \
--from 0xYourAddress \
--value 0.001ether \
0xRecipient \
--rpc-url https://mainnet.megaeth.com/rpc
# Get balance at block
cast call --block 12345 0xContract "balanceOf(address)(uint256)" 0xAddress \
--rpc-url https://mainnet.megaeth.com/rpc
# Trace transaction (requires VIP or local node)
cast run <txhash> --rpc-url <vip-endpoint>
```
```
### smart-contracts.md
```markdown
# Smart Contract Patterns (MegaEVM)
## MegaEVM vs Standard EVM
MegaEVM is fully compatible with Ethereum contracts but has different:
- **Gas costs** (especially SSTORE)
- **Block metadata limits** (volatile data access)
- **Contract size limits** (512 KB)
## Contract Limits
| Resource | Limit |
|----------|-------|
| Contract code | 512 KB |
| Calldata | 128 KB |
| eth_call/estimateGas | 10M gas (public), higher on VIP |
## Volatile Data Access Control
After accessing block metadata, transaction is limited to 20M additional compute gas.
**Affected opcodes:**
- `TIMESTAMP` / `block.timestamp`
- `NUMBER` / `block.number`
- `BLOCKHASH` / `blockhash(n)`
```solidity
// ❌ Problematic pattern
function process() external {
uint256 ts = block.timestamp; // Triggers limit
// Complex computation here will hit 20M gas ceiling
for (uint i = 0; i < 10000; i++) {
// Heavy work...
}
}
// ✅ Better: access metadata late
function process() external {
// Do heavy computation first
for (uint i = 0; i < 10000; i++) {
// Heavy work...
}
// Access metadata at the end
emit Processed(block.timestamp);
}
```
**Spec:** https://github.com/megaeth-labs/mega-evm/blob/main/specs/MiniRex.md#28-volatile-data-access-control
## High-Precision Timestamps
For microsecond precision, use the oracle instead of `block.timestamp`:
```solidity
interface ITimestampOracle {
/// @notice Returns timestamp in microseconds
function timestamp() external view returns (uint256);
}
contract MyContract {
ITimestampOracle constant ORACLE =
ITimestampOracle(0x6342000000000000000000000000000000000002);
function getTime() external view returns (uint256) {
return ORACLE.timestamp(); // Microseconds, not seconds
}
}
```
## Storage Patterns
### Avoid Dynamic Mappings
```solidity
// ❌ Expensive: each new key = new storage slot = 2M+ gas
mapping(address => uint256) public balances;
// ✅ Better: fixed-size or use RedBlackTreeLib
uint256[100] public fixedBalances;
```
### Solady RedBlackTreeLib
```solidity
import {RedBlackTreeLib} from "solady/src/utils/RedBlackTreeLib.sol";
contract OptimizedStorage {
using RedBlackTreeLib for RedBlackTreeLib.Tree;
RedBlackTreeLib.Tree private _tree;
// Tree manages contiguous storage slots
// Insert/remove reuses slots instead of allocating new ones
function insert(uint256 key, uint256 value) external {
_tree.insert(key);
// Store value in separate packed array
}
}
```
## Gas Estimation
Always use remote estimation:
```solidity
// foundry.toml
[profile.default]
# Don't rely on local simulation
```
```bash
# Deploy with explicit gas, skip simulation
forge script Deploy.s.sol \
--rpc-url https://mainnet.megaeth.com/rpc \
--gas-limit 5000000 \
--skip-simulation \
--broadcast
```
## Events and Logs
LOG opcodes have quadratic cost above 4KB data:
```solidity
// ❌ Expensive: large event data
event LargeData(bytes data); // If data > 4KB, quadratic cost
// ✅ Better: emit hash, store off-chain
event DataStored(bytes32 indexed hash);
```
## SELFDESTRUCT
EIP-6780 style SELFDESTRUCT is being implemented. Check current status:
- Same-tx destruction works
- Cross-tx destruction behavior may vary
## Deployment Patterns
### Factory Contracts
```solidity
contract Factory {
function deploy(bytes32 salt, bytes memory bytecode)
external
returns (address)
{
address addr;
assembly {
addr := create2(0, add(bytecode, 32), mload(bytecode), salt)
}
require(addr != address(0), "Deploy failed");
return addr;
}
}
```
### Proxy Patterns
Standard proxy patterns (EIP-1967, UUPS, Transparent) work normally. Consider:
- Storage slot allocation costs on first write
- Upgrade authorization patterns
## Testing Contracts
```solidity
// Use Foundry with remote RPC
contract MyTest is Test {
function setUp() public {
// Fork MegaETH testnet for realistic gas costs
vm.createSelectFork("https://carrot.megaeth.com/rpc");
}
function testGasCost() public {
uint256 gasBefore = gasleft();
// Your operation
uint256 gasUsed = gasBefore - gasleft();
console.log("Gas used:", gasUsed);
}
}
```
## SSTORE2: On-Chain Data Storage
For storing large immutable data on-chain (HTML, images, metadata), use the **SSTORE2** pattern — store data as contract bytecode instead of storage slots.
### Why SSTORE2 on MegaETH?
| Approach | Write Cost | Read Cost |
|----------|------------|-----------|
| SSTORE (storage slots) | 2M+ gas per new slot | 100-2100 gas |
| SSTORE2 (bytecode) | ~10K gas per byte | **FREE** (EXTCODECOPY) |
SSTORE2 is ideal for write-once, read-many data — content is immutable once deployed.
### How It Works
1. Deploy a contract with data as bytecode
2. Read data via `EXTCODECOPY` (no gas for view calls)
```solidity
// Writing: Deploy data as contract bytecode
library SSTORE2 {
function write(bytes memory data) internal returns (address) {
// Prepend STOP opcode so contract can't be called
bytes memory bytecode = abi.encodePacked(
hex"00", // STOP opcode
data
);
address pointer;
assembly {
pointer := create(0, add(bytecode, 32), mload(bytecode))
}
require(pointer != address(0), "Deploy failed");
return pointer;
}
function read(address pointer) internal view returns (bytes memory) {
uint256 size;
assembly { size := extcodesize(pointer) }
bytes memory data = new bytes(size - 1); // Skip STOP opcode
assembly {
extcodecopy(pointer, add(data, 32), 1, sub(size, 1))
}
return data;
}
}
```
### MegaETH Gas Estimation for SSTORE2
```javascript
// MegaETH multidimensional gas model for bytecode deployment
const MEGAETH_GAS = {
INTRINSIC_COMPUTE: 21_000n,
INTRINSIC_STORAGE: 39_000n,
CONTRACT_CREATION_COMPUTE: 32_000n,
CODE_DEPOSIT_PER_BYTE: 10_000n,
CALLDATA_NONZERO_PER_BYTE: 160n,
};
function estimateDeployGas(dataSizeBytes) {
const dataSize = BigInt(dataSizeBytes);
const computeGas = MEGAETH_GAS.INTRINSIC_COMPUTE
+ MEGAETH_GAS.CONTRACT_CREATION_COMPUTE;
const storageGas = MEGAETH_GAS.INTRINSIC_STORAGE
+ (dataSize * MEGAETH_GAS.CODE_DEPOSIT_PER_BYTE)
+ (dataSize * MEGAETH_GAS.CALLDATA_NONZERO_PER_BYTE);
return (computeGas + storageGas) * 150n / 100n; // 50% buffer
}
```
### Use Cases
- **On-chain websites/HTML** — permanent, censorship-resistant hosting
- **NFT metadata** — fully on-chain images/JSON
- **Large configs** — immutable protocol parameters
- **Data availability** — store proofs, attestations
### Chunking Large Data
For data > 24KB, chunk into multiple contracts:
```javascript
const CHUNK_SIZE = 15000; // 15KB per chunk
function chunkData(data) {
const chunks = [];
for (let i = 0; i < data.length; i += CHUNK_SIZE) {
chunks.push(data.slice(i, i + CHUNK_SIZE));
}
return chunks;
}
```
### Solady Implementation
Solady provides an optimized SSTORE2:
```solidity
import {SSTORE2} from "solady/src/utils/SSTORE2.sol";
// Write
address pointer = SSTORE2.write(data);
// Read
bytes memory data = SSTORE2.read(pointer);
```
**Reference implementation:** See [warren-deploy](https://clawdhub.ai/planetai87/warren-deploy) for a complete on-chain website deployment system using SSTORE2 on MegaETH.
## EIP-6909: Minimal Multi-Token Standard
For contracts managing multiple token types, prefer [EIP-6909](https://eips.ethereum.org/EIPS/eip-6909) over ERC-1155.
### Why EIP-6909 on MegaETH?
| Feature | MegaETH Benefit |
|---------|-----------------|
| No mandatory callbacks | Less gas, simpler integrations |
| No batching in spec | Allows MegaETH-optimized implementations |
| Single contract | Fewer SSTORE operations (expensive) |
| Granular approvals | Per-token-ID OR full operator access |
| Minimal interface | Smaller bytecode |
### Storage Efficiency
One EIP-6909 contract vs. N separate ERC-20 contracts:
```solidity
// ❌ Deploying many ERC-20s = many new storage slots
// Each contract: new code, new storage initialization
// ✅ Single EIP-6909 = shared storage
// Multiple token IDs in one contract, slot reuse
```
### Basic Implementation
```solidity
// Using Solady's ERC6909 (gas-optimized)
import {ERC6909} from "solady/src/tokens/ERC6909.sol";
contract MultiToken is ERC6909 {
function name(uint256 id) public view override returns (string memory) {
// Return name for token ID
}
function symbol(uint256 id) public view override returns (string memory) {
// Return symbol for token ID
}
function tokenURI(uint256 id) public view override returns (string memory) {
// Return metadata URI for token ID
}
function mint(address to, uint256 id, uint256 amount) external {
_mint(to, id, amount);
}
}
```
### Key Differences from ERC-1155
| | ERC-1155 | EIP-6909 |
|-|----------|----------|
| Callbacks | Required | None |
| Batch transfers | In spec | Implementation choice |
| Approvals | Operator only | Operator + per-ID allowance |
| Complexity | Higher | Minimal |
### Use Cases
- **DEXes**: LP tokens for multiple pairs in one contract
- **Games**: Multiple item/asset types
- **DeFi vaults**: Multiple share classes
- **NFT editions**: Fungible editions of NFTs
### Solady Implementation
Solady provides a gas-optimized EIP-6909:
```bash
forge install vectorized/solady
```
```solidity
import {ERC6909} from "solady/src/tokens/ERC6909.sol";
```
**Docs**: https://github.com/Vectorized/solady/blob/main/src/tokens/ERC6909.sol
## OP Stack Compatibility
MegaETH uses OP Stack. Standard bridge contracts and predeploys are available:
| Contract | Address |
|----------|---------|
| WETH9 | `0x4200000000000000000000000000000000000006` |
| Multicall3 | `0xcA11bde05977b3631167028862bE2a173976CA11` |
| L2CrossDomainMessenger | `0x4200000000000000000000000000000000000007` |
See OP Stack docs for full predeploy list.
## Common Issues
### "Intrinsic gas too low"
Local simulation uses wrong opcode costs. Use `--skip-simulation` or remote estimation.
### "Out of gas" after block.timestamp
Hitting volatile data access limit. Restructure to access metadata late.
### Transaction stuck
Check nonce with `eth_getTransactionCount` using `pending` tag.
```
### storage-optimization.md
```markdown
# Storage Optimization
## The Problem
MegaETH charges high gas for new storage slot creation to prevent state bloat:
```
SSTORE (0 → non-zero): 2,000,000 gas × bucket_multiplier
```
The bucket multiplier scales with usage (1×, 2×, 4×, 8×...). This makes Solidity mappings with dynamic keys expensive.
## Solution 1: Solady RedBlackTreeLib
Replace Solidity mappings with [Solady's RedBlackTreeLib](https://github.com/Vectorized/solady/blob/main/src/utils/RedBlackTreeLib.sol):
```solidity
import {RedBlackTreeLib} from "solady/src/utils/RedBlackTreeLib.sol";
contract StorageOptimized {
using RedBlackTreeLib for RedBlackTreeLib.Tree;
RedBlackTreeLib.Tree private _tree;
// Tree manages contiguous storage slots [from, to)
// Insert: allocates slot at index `to`
// Remove: swap-removes with slot at `to - 1`
// Result: slots are reused, no new allocations
}
```
**Key insight:** Avoid resetting the last slot immediately — reuse it for the next insert.
**Demo available:** MegaETH engineers have a migration demo. Contact team for access.
## Solution 2: Storage Slot Reuse
Design contracts to reuse existing slots:
```solidity
// Bad: constantly allocating new slots
mapping(uint256 => uint256) public data;
function process(uint256 key, uint256 value) {
data[key] = value; // New slot each unique key
delete data[key]; // Slot freed but not reused
}
// Better: fixed-size array with circular buffer
uint256[100] public buffer;
uint256 public head;
function process(uint256 value) {
buffer[head] = value; // Reuses existing slot
head = (head + 1) % 100;
}
```
## Solution 3: ZK Compression
For apps with large state requirements:
1. Store only a hash/commitment on-chain
2. Provide pre-state + proof with each transaction
3. Contract verifies proof, applies state transition, stores new commitment
```solidity
contract ZKCompressed {
bytes32 public stateRoot;
function update(
bytes32 newRoot,
bytes calldata preState,
bytes calldata proof
) external {
require(verify(stateRoot, preState, proof), "Invalid proof");
stateRoot = newRoot; // Only 1 storage slot
}
}
```
**Trade-off:** More compute gas, much less storage gas. Good fit for MegaETH since compute is cheap.
## Solution 4: Off-Chain Storage
For large static data:
- Use IPFS/Arweave for storage
- Store content hash on-chain
- Verify in contract if needed
```solidity
contract HybridStorage {
mapping(bytes32 => bool) public verified;
function verifyData(bytes32 hash, bytes calldata data) external {
require(keccak256(data) == hash, "Hash mismatch");
verified[hash] = true;
}
}
```
## Gas Cost Reference
| Operation | Standard EVM | MegaETH |
|-----------|-------------|---------|
| SSTORE (0→non-zero) | 20,000 | 2,000,000 × multiplier |
| SSTORE (non-zero→non-zero) | 5,000 | ~100-2,100 |
| SLOAD (warm) | 100 | 100 |
| SLOAD (cold) | 2,100 | 2,100 |
## State Size Considerations
MegaETH's state trie scales to 1+ TB but storage remains a scarce resource. At $0.10 per new slot:
- 1 billion slots = 64 GB state = $100M in fees
**Future:** State rent and state expiry mechanisms planned.
## Debugging Storage Costs
Profile gas by opcode:
```bash
# Get trace
mega-evme replay <txhash> --trace --trace.output trace.json
# Profile opcodes
python trace_opcode_gas.py trace.json
```
Look for high SSTORE counts with 0→non-zero transitions.
```
### gas-model.md
```markdown
# Gas Model
## Base Parameters
| Parameter | Value | Notes |
|-----------|-------|-------|
| Base fee | 0.001 gwei (10⁶ wei) | Fixed, no EIP-1559 adjustment |
| Priority fee | 0 | Ignored unless congested |
| Block gas limit | None | Decoupled from tx limit |
| Max tx gas | 5+ ggas | Much higher than other chains |
## Setting Gas Price
### Correct Approach
```javascript
// MegaETH: use base fee directly
const gasPrice = 1000000n; // 0.001 gwei in wei
// Or fetch from RPC (always returns 0.001 gwei)
const baseFee = await client.request({ method: 'eth_gasPrice' });
```
### Common Mistakes
```javascript
// ❌ Wrong: viem adds 20% buffer
const gasPrice = await publicClient.getGasPrice(); // Returns 1.2M wei
// ❌ Wrong: using maxPriorityFeePerGas
const priority = await client.request({
method: 'eth_maxPriorityFeePerGas'
}); // Returns 0 (hardcoded)
```
## Gas Estimation
### MegaEVM Intrinsic Gas
> ⚠️ **Important:** MegaEVM has different intrinsic gas costs than standard EVM. A simple ETH transfer costs **60,000 gas** on MegaETH, not 21,000.
If you hardcode gas limits, use MegaETH-specific values:
```javascript
// Common operations - MegaETH gas limits
const gasLimits = {
transfer: 60000n, // NOT 21000 like standard EVM
erc20Transfer: 100000n, // Higher than standard EVM
erc20Approve: 80000n,
swap: 350000n,
};
// Send with correct gas limit
await wallet.sendTransaction({
to: recipient,
value: amount,
gasLimit: 60000n, // MegaETH intrinsic gas
maxFeePerGas: 1000000n,
});
```
### When to Use Remote Estimation
For any non-trivial operation, use `eth_estimateGas` — MegaEVM opcode costs differ from standard EVM:
```javascript
// ✅ Correct: remote estimation
const gas = await client.request({
method: 'eth_estimateGas',
params: [{ from, to, data }]
});
// ❌ Wrong: local simulation (Hardhat/Foundry)
// These use standard EVM costs, not MegaEVM
```
For Foundry:
```bash
# Skip local simulation, use remote
forge script Deploy.s.sol --gas-limit 5000000 --skip-simulation
```
## Volatile Data Access Limit
After accessing block metadata, tx is limited to 20M additional compute gas:
```solidity
// Operations that trigger the limit:
block.timestamp
block.number
blockhash(n)
// After any of these, only 20M gas remaining for:
// - Complex computations
// - Multiple external calls
// - Large loops
```
**Workaround:** Access block metadata late in execution, or use the high-precision timestamp oracle which has separate accounting.
## Fee History
Get historical gas prices:
```javascript
const history = await client.request({
method: 'eth_feeHistory',
params: ['0x10', 'latest', [25, 50, 75]]
});
// Returns base fees and priority fee percentiles
```
## Priority Fees in Practice
Priority fees only matter during congestion:
```javascript
// During normal operation: any priority fee works
// During congestion: higher priority = faster inclusion
const tx = {
maxFeePerGas: 1000000n, // 0.001 gwei
maxPriorityFeePerGas: 0n, // Usually sufficient
};
```
## Gas Refunds
Standard EVM refunds apply (SSTORE clear, SELFDESTRUCT), but:
- Refund capped at 50% of gas used
- Future: State rent refund mechanism planned
## LOG Opcode Costs
After a DoS attack, LOG opcodes have quadratic cost above 4KB data:
```solidity
// Gas cost for log data:
// < 4KB: linear
// > 4KB: quadratic growth
```
This affects contracts emitting large events.
## Contract Deployment
| Resource | Limit |
|----------|-------|
| Contract code | 512 KB |
| Calldata | 128 KB |
| Deployment gas | Effectively unlimited |
For large contracts, may need VIP endpoint (higher gas limit on `eth_estimateGas`).
```
### testing.md
```markdown
# Debugging Guide
## mega-evme CLI
The official debugging tool for MegaETH transactions.
### Installation
```bash
git clone https://github.com/megaeth-labs/mega-evm
cd mega-evm/bin/mega-evme
cargo build --release
```
### Replay Transactions
```bash
# Basic replay
mega-evme replay <txhash> --rpc https://mainnet.megaeth.com/rpc
# With execution trace
mega-evme replay <txhash> --trace --trace.output trace.json --rpc <endpoint>
# With call tracer
mega-evme replay <txhash> --trace --tracer call --trace.output calls.json
```
**Docs:** https://github.com/megaeth-labs/mega-evm/tree/main/bin/mega-evme
## Gas Profiling
### Opcode-Level Analysis
```bash
# 1. Get debug trace
cast run <txhash> --rpc-url <vip-endpoint> > trace.json
# 2. Profile opcodes
python scripts/trace_opcode_gas.py trace.json
```
**Script:** https://github.com/megaeth-labs/mega-evm/blob/main/scripts/trace_opcode_gas.py
### Example Output
```
op count total avg min max
SSTORE 29 85400 2944.8 100 22100
SLOAD 473 121300 256.4 100 2100
LOG2 25 598601 23944.0 14257 25521
KECCAK256 288 12108 42.0 36 60
```
## Common Issues
### "Intrinsic Gas Too Low"
Local gas estimation uses standard EVM costs. MegaEVM differs.
**Fix:**
```bash
# Foundry: skip local simulation
forge script Deploy.s.sol --gas-limit 5000000 --skip-simulation
# Or use higher hardcoded limit
```
### "Nonce Too Low"
With `eth_sendRawTransactionSync`, this can mean:
1. Tx already executed (check receipt)
2. Race condition with pending tx
**Debug:**
```bash
# Check current nonce
cast call --rpc-url <endpoint> \
--method eth_getTransactionCount \
<address> pending
```
### "Block Pruned" on eth_call
Public endpoint only keeps ~15 days of state.
**Solutions:**
- Use Alchemy/QuickNode for historical calls
- Run archive node
- Use VIP endpoint with longer retention
### WebSocket Disconnections
Connection drops after idle period.
**Fix:** Send keepalive every 30s:
```javascript
setInterval(() => {
ws.send(JSON.stringify({
jsonrpc: '2.0',
method: 'eth_chainId',
params: [],
id: Date.now()
}));
}, 30000);
```
### Volatile Data Access Limit
Error after using `block.timestamp` + heavy computation.
**Cause:** 20M gas limit after accessing block metadata.
**Fix:** Restructure contract to access metadata late, or use oracle.
## Cast Commands
```bash
# Estimate gas
cast estimate --from <addr> --to <addr> --value 0.001ether \
--rpc-url https://mainnet.megaeth.com/rpc
# Call at specific block
cast call --block <number> <contract> "method(args)" \
--rpc-url https://mainnet.megaeth.com/rpc
# Get transaction details
cast tx <txhash> --rpc-url https://mainnet.megaeth.com/rpc
# Decode calldata
cast 4byte-decode <calldata>
```
## HAR Analysis
For debugging frontend RPC patterns:
```bash
# Export HAR from browser devtools, then:
python parse_eth_rpc_har.py export.har > calls.csv
python method_activity_timeline.py calls.csv
```
Identifies:
- Unnecessary RPC calls
- Batching opportunities
- Slow methods blocking UX
## Monitoring Latency
```bash
# Detailed timing breakdown
curl -i -X POST https://mainnet.megaeth.com/rpc \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}' \
-w "dns: %{time_namelookup} | connect: %{time_connect} | total: %{time_total}\n"
```
## Block Explorers
| Network | Explorer |
|---------|----------|
| Mainnet | https://mega.etherscan.io |
| Testnet | https://megaeth-testnet-v2.blockscout.com |
Etherscan may lag a few blocks behind real-time.
## Getting Help
1. Check transaction on explorer
2. Replay with mega-evme locally
3. Profile gas by opcode
4. Contact MegaETH team with:
- Transaction hash
- Error message
- Reproduction steps
```
### security.md
```markdown
# Security Considerations
## MegaETH-Specific Risks
### 1. Storage Cost Attacks
**Risk**: Attacker triggers expensive SSTORE operations to drain gas budgets.
**Attack pattern**:
```solidity
// If contract allows arbitrary key writes:
function store(uint256 key, uint256 value) external {
data[key] = value; // 2M+ gas per new slot
}
// Attacker calls with 1000 unique keys = 2B gas
```
**Prevention**:
- Validate keys against whitelist
- Limit operations per transaction
- Charge users for storage costs
### 2. Volatile Data Timing Attacks
**Risk**: Contract logic depends on block.timestamp precision.
**Attack pattern**:
```solidity
// Auction ends at timestamp
if (block.timestamp >= auctionEnd) {
// MegaETH block.timestamp has 1s granularity
// But mini-blocks happen every 10ms
// Attacker can exploit timing window
}
```
**Prevention**:
- Use high-precision oracle for time-sensitive logic
- Add grace periods for timing-dependent operations
- Consider mini-block timing in design
### 3. Reorg Considerations
MegaETH has fast finality (<10ms) but reorgs are theoretically possible until L1 finalization.
**Prevention**:
- For high-value operations, wait for confirmation count
- Use `eth_sendRawTransactionSync` receipt as soft-finality
- Consider L1 finalization for irreversible actions
## Standard EVM Vulnerabilities
These apply equally to MegaETH:
### Reentrancy
```solidity
// ❌ Vulnerable
function withdraw() external {
uint256 amount = balances[msg.sender];
(bool success, ) = msg.sender.call{value: amount}("");
require(success);
balances[msg.sender] = 0;
}
// ✅ Checks-Effects-Interactions
function withdraw() external {
uint256 amount = balances[msg.sender];
balances[msg.sender] = 0; // Effect before interaction
(bool success, ) = msg.sender.call{value: amount}("");
require(success);
}
```
### Access Control
```solidity
// ✅ Always validate
modifier onlyOwner() {
require(msg.sender == owner, "Not owner");
_;
}
modifier onlyValidSigner(bytes memory signature) {
require(verifySignature(signature), "Invalid signature");
_;
}
```
### Integer Overflow
Solidity 0.8+ has built-in overflow checks. For older code:
```solidity
// Use OpenZeppelin SafeMath or upgrade to 0.8+
```
## Client-Side Security
### RPC Endpoint Trust
```typescript
// ❌ Don't trust random RPCs
const client = createClient({ rpc: userProvidedUrl });
// ✅ Use known endpoints, verify responses
const TRUSTED_RPCS = [
'https://mainnet.megaeth.com/rpc',
'https://rpc.alchemy.com/megaeth'
];
```
### Transaction Simulation
```typescript
// Always simulate before signing
const simulation = await client.simulateTransaction(tx);
if (simulation.error) {
throw new Error(`Simulation failed: ${simulation.error}`);
}
```
### Blockhash Expiry
```typescript
// MegaETH blocks are fast - blockhash expires quickly
// Retry with fresh blockhash on failure
async function submitWithRetry(tx: Transaction, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
const blockhash = await client.getLatestBlockhash();
tx.blockhash = blockhash;
return await client.sendTransaction(tx);
} catch (e) {
if (!e.message.includes('blockhash')) throw e;
}
}
throw new Error('Transaction expired');
}
```
## Audit Recommendations
1. **Use mega-evme** for transaction replay and gas profiling
2. **Test with realistic gas costs** — fork testnet, don't simulate locally
3. **Review SSTORE patterns** — each new slot is expensive
4. **Check volatile data usage** — 20M gas limit after block metadata access
5. **Verify CPI targets** — don't allow arbitrary external calls
## Security Review Questions
1. Can an attacker trigger expensive storage operations?
2. Does the contract rely on block.timestamp precision?
3. Are there timing windows between mini-blocks that can be exploited?
4. Is the contract vulnerable to reorgs before L1 finalization?
5. Are external calls validated and limited?
6. Is gas estimation done remotely (not locally)?
## Monitoring
```typescript
// Set up transaction monitoring
const monitor = new TransactionMonitor({
rpc: 'https://mainnet.megaeth.com/rpc',
contracts: ['0x...'],
onSuspicious: (tx) => {
// Alert on unusual patterns
// - High gas usage
// - Repeated failures
// - Unusual call patterns
}
});
```
## Resources
- **MegaEVM Spec**: https://github.com/megaeth-labs/mega-evm/blob/main/specs/MiniRex.md
- **Security auditors**: Cantina, Spearbit (recommended by MegaETH team)
```
### resources.md
```markdown
# Resources
## Official Documentation
- **MegaETH Docs**: https://docs.megaeth.com
- **Real-time API**: https://docs.megaeth.com/realtime-api
- **Testnet Guide**: https://docs.megaeth.com/testnet
- **Frontier (Mainnet)**: https://docs.megaeth.com/frontier
## Source Code
- **MegaEVM**: https://github.com/megaeth-labs/mega-evm
- **MegaEVM Spec (MiniRex)**: https://github.com/megaeth-labs/mega-evm/blob/main/specs/MiniRex.md
## Token List
**Official:** https://github.com/megaeth-labs/mega-tokenlist
The canonical source for verified token addresses, symbols, decimals, and logos on MegaETH. Use this repo to:
- Look up token contract addresses
- Get token metadata (name, symbol, decimals)
- Access official token logos
- Verify token legitimacy
## Tools
### Warren Deploy (On-Chain Websites)
Deploy websites and files permanently on MegaETH using SSTORE2:
- **Skill**: https://clawdhub.ai/planetai87/warren-deploy
- **Website**: https://megawarren.xyz
- **Install**: `clawdhub install warren-deploy`
Features:
- SSTORE2 bytecode storage (cheap reads)
- Automatic chunking for large files (up to 500KB)
- MegaETH-specific gas estimation
- Stress test workflows
### mega-evme CLI
Transaction replay and debugging:
```bash
git clone https://github.com/megaeth-labs/mega-evm
cd mega-evm/bin/mega-evme
cargo build --release
```
### Gas Profiler
Opcode-level gas analysis:
https://github.com/megaeth-labs/mega-evm/blob/main/scripts/trace_opcode_gas.py
## Block Explorers
| Network | Explorer |
|---------|----------|
| Mainnet | https://mega.etherscan.io |
| Testnet | https://megaeth-testnet-v2.blockscout.com |
| Uptime | https://uptime.megaeth.com |
## RPC Providers
| Provider | Type | Notes |
|----------|------|-------|
| MegaETH | Public | Rate limited |
| Alchemy | Managed | Geo-distributed |
| QuickNode | Managed | Geo-distributed |
**Mainnet**: `https://mainnet.megaeth.com/rpc`
**Testnet**: `https://carrot.megaeth.com/rpc`
## Standards
### EIP-6909 (Minimal Multi-Token)
Simplified alternative to ERC-1155 — no callbacks, minimal interface, granular approvals:
https://eips.ethereum.org/EIPS/eip-6909
**Why use on MegaETH:**
- Single contract for multiple tokens (fewer SSTORE operations)
- No mandatory callbacks (less gas)
- Solady provides gas-optimized implementation
### EIP-7966 (eth_sendRawTransactionSync)
Synchronous transaction submission with immediate receipt:
https://ethereum-magicians.org/t/eip-7966-eth-sendrawtransactionsync-method/24640
**Note:** MegaETH originally created `realtime_sendRawTransaction`. The `eth_sendRawTransactionSync` method was later standardized as EIP-7966. MegaETH proxies both — they are functionally equivalent. Use `eth_sendRawTransactionSync` for cross-chain compatibility.
Supported in:
- viem (native)
- wagmi (native)
- ethers.js (via custom provider)
## Indexers
### Envio HyperSync
High-performance historical data queries:
https://docs.envio.dev/docs/HyperSync/overview
Recommended for:
- Large `eth_getLogs` queries
- Historical trade data
- Event indexing
## Libraries
### Solady
Gas-optimized Solidity utilities:
https://github.com/Vectorized/solady
Key for MegaETH:
- `RedBlackTreeLib` — storage-efficient mappings
- `SafeTransferLib` — optimized token transfers
### viem
TypeScript Ethereum library:
https://viem.sh
MegaETH chain config:
```typescript
import { defineChain } from 'viem';
export const megaeth = defineChain({
id: 4326,
name: 'MegaETH',
nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
rpcUrls: {
default: { http: ['https://mainnet.megaeth.com/rpc'] }
}
});
```
## DEX Aggregator
### Kyber Network
MegaETH uses Kyber Network for token swaps:
- **Aggregator API**: `https://aggregator-api.kyberswap.com/megaeth/api/v1`
- **Docs**: https://docs.kyberswap.com/kyberswap-solutions/kyberswap-aggregator
Features:
- Best-route across multiple DEXs
- MEV protection
- Gas-optimized execution
## Bridges
### Canonical Bridge (OP Stack)
Ethereum ↔ MegaETH:
| Contract | Address (Ethereum) |
|----------|-------------------|
| L1StandardBridgeProxy | `0x0CA3A2FBC3D770b578223FBB6b062fa875a2eE75` |
| OptimismPortalProxy | `0x7f82f57F0Dd546519324392e408b01fcC7D709e8` |
Simple ETH bridge: Send ETH directly to L1StandardBridgeProxy.
## Predeployed Contracts (MegaETH)
| Contract | Address |
|----------|---------|
| WETH9 | `0x4200000000000000000000000000000000000006` |
| Multicall3 | `0xcA11bde05977b3631167028862bE2a173976CA11` |
| High-Precision Timestamp | `0x6342000000000000000000000000000000000002` |
| MEGA Token | `0x28B7E77f82B25B95953825F1E2eA0E36c1c29861` |
See OP Stack docs for full predeploy list.
## Security
### Auditors
Recommended by MegaETH team:
- **Spearbit**: https://spearbit.com
- **Cantina**: https://cantina.xyz
### Monitoring
Consider runtime monitoring for:
- Unusual gas patterns
- Failed transaction spikes
- Storage cost anomalies
## Community
- **Discord**: (contact MegaETH team)
- **Twitter**: @megaeth_labs
## Quick Reference
```bash
# Check balance
cast balance <address> --rpc-url https://mainnet.megaeth.com/rpc
# Send transaction
cast send <to> --value 0.01ether --rpc-url https://mainnet.megaeth.com/rpc
# Call contract
cast call <contract> "method(args)" --rpc-url https://mainnet.megaeth.com/rpc
# Get gas price (always 0.001 gwei)
cast gas-price --rpc-url https://mainnet.megaeth.com/rpc
# Deploy with Foundry
forge script Deploy.s.sol --rpc-url https://mainnet.megaeth.com/rpc --broadcast --skip-simulation
```
```
---
## Skill Companion Files
> Additional files collected from the skill directory layout.
### README.md
```markdown
# MegaETH Developer Skill for AI Agents
A comprehensive skill for AI coding agents (Claude Code, OpenClaw, Codex) to build real-time applications on MegaETH.
## Overview
This skill provides AI agents with deep knowledge of the MegaETH development ecosystem:
- **Transactions**: `eth_sendRawTransactionSync` (EIP-7966) for instant receipts
- **RPC Patterns**: JSON-RPC batching, WebSocket keepalive, mini-block subscriptions
- **Storage**: Optimization patterns to avoid expensive SSTORE costs
- **Gas Model**: MegaEVM-specific costs and estimation strategies
- **Debugging**: mega-evme CLI for transaction replay and gas profiling
- **Security**: MegaETH-specific considerations and audit checklists
## Installation
### Quick Install (skills.sh)
```bash
npx skills add 0xBreadguy/megaeth-ai-developer-skills
```
### Manual Install
```bash
git clone https://github.com/0xBreadguy/megaeth-ai-developer-skills
# Copy to your agent's skills directory
```
### OpenClaw / ClawdHub
```bash
clawdhub install megaeth-developer
```
## Skill Structure
```
├── SKILL.md # Main skill (stack decisions, operating procedure)
├── wallet-operations.md # Wallet setup, balances, transfers, swaps, bridging
├── frontend-patterns.md # React/Next.js, WebSocket, real-time UX
├── rpc-methods.md # RPC reference, rate limits, batching
├── smart-contracts.md # MegaEVM patterns, volatile data, predeploys
├── storage-optimization.md # SSTORE costs, Solady RedBlackTreeLib
├── gas-model.md # Gas costs, estimation, base fee
├── testing.md # mega-evme, Foundry, debugging
├── security.md # Vulnerabilities and prevention
└── resources.md # Links, tools, explorers, bridges, DEX
```
## Usage
Once installed, your AI agent will automatically use this skill when you ask about:
- Building dApps on MegaETH
- Transaction submission and confirmation
- Smart contract development with MegaEVM
- Storage optimization and gas costs
- Real-time WebSocket subscriptions
- Debugging failed transactions
### Example Prompts
```
"Set up a wallet for MegaETH"
"Send 0.1 ETH on MegaETH"
"Swap USDC for ETH on MegaETH"
"Bridge ETH from Ethereum to MegaETH"
"Set up a Next.js app with MegaETH wallet connection"
"Deploy a contract to MegaETH with Foundry"
"Why is my transaction using so much gas?"
"How do I subscribe to real-time mini-blocks?"
"Optimize this contract for MegaETH storage costs"
"Debug this failed transaction on MegaETH"
```
## Key Concepts
### Instant Transaction Receipts
MegaETH supports `eth_sendRawTransactionSync` (EIP-7966) — get your receipt in <10ms instead of polling:
```typescript
const receipt = await client.request({
method: 'eth_sendRawTransactionSync',
params: [signedTx]
});
// Receipt available immediately
```
### Storage Costs
New storage slots are expensive (2M+ gas). The skill teaches agents to:
- Use Solady's RedBlackTreeLib instead of mappings
- Design for slot reuse
- Consider off-chain storage for large data
### Gas Model
MegaETH has a stable 0.001 gwei base fee with no EIP-1559 adjustment. The skill teaches agents to:
- Skip unnecessary gas estimation
- Use remote estimation (MegaEVM costs differ from standard EVM)
- Hardcode gas limits for known operations
## Chain Configuration
| Network | Chain ID | RPC | Explorer |
|---------|----------|-----|----------|
| Mainnet | 4326 | `https://mainnet.megaeth.com/rpc` | `https://mega.etherscan.io` |
| Testnet | 6343 | `https://carrot.megaeth.com/rpc` | `https://megaeth-testnet-v2.blockscout.com` |
## Progressive Disclosure
The skill uses progressive disclosure — the main SKILL.md provides core guidance, and the agent reads specialized files only when needed for specific tasks. This keeps context efficient while providing deep expertise when required.
## Content Sources
This skill incorporates best practices from:
- [MegaETH Official Documentation](https://docs.megaeth.com)
- [MegaEVM Specification](https://github.com/megaeth-labs/mega-evm)
- [EIP-7966 (eth_sendRawTransactionSync)](https://ethereum-magicians.org/t/eip-7966-eth-sendrawtransactionsync-method/24640)
- MegaETH team technical guidance
## Contributing
Contributions welcome! Please ensure updates reflect current MegaETH ecosystem best practices.
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Submit a pull request
## License
MIT
```
### _meta.json
```json
{
"owner": "0xguardbot",
"slug": "megaeth",
"displayName": "MegaETH AI Developer",
"latest": {
"version": "1.0.0",
"publishedAt": 1770297854876,
"commit": "https://github.com/clawdbot/skills/commit/a78d3bfbc0371965cfc468404ae24ad2036f107e"
},
"history": []
}
```