Ronin - The Gaming-Optimized EVM Blockchain
Ronin RPC
With Dwellir, you get access to our global Ronin network which always routes your API requests to the nearest available location, ensuring low latency and the fastest speeds.
Why Build on Ronin?
Ronin is an EVM-compatible blockchain built for gaming, powering player-owned economies. Originally developed by Sky Mavis for Axie Infinity, Ronin offers:
🎮 Gaming-First Design
- Sub-3 second block times - Ultra-fast gaming interactions
- Optimized for NFTs - Purpose-built for digital ownership
- Player-owned economies - Enable true ownership of game assets
🚀 Proven Performance
- 250K+ daily active users - Battle-tested at scale
- $4B+ NFT volume processed - Proven ecosystem
- 2M+ wallet downloads - Strong adoption
💰 Low-Cost Operations
- RON gas token - Minimal transaction fees
- DPoS consensus - Energy-efficient validation
- Minimal block finality - ~6 seconds for confirmation
Quick Start with Ronin
Connect to Ronin in seconds with Dwellir's optimized endpoints:
🔗 RPC Endpoints
https://api-ronin-mainnet.n.dwellir.com/YOUR_API_KEY
Quick Connect:
curl -X POST https://api-ronin-mainnet.n.dwellir.com/YOUR_API_KEY \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
Installation & Setup
- Ethers.js v6
- Web3.js
- Viem
import { JsonRpcProvider } from 'ethers';
// Connect to Ronin mainnet
const provider = new JsonRpcProvider(
'https://api-ronin-mainnet.n.dwellir.com/YOUR_API_KEY'
);
// Get the latest block
const block = await provider.getBlock('latest');
console.log('Latest block:', block.number);
// Query account balance
const balance = await provider.getBalance('0x...');
console.log('Balance:', balance.toString());
const Web3 = require('web3');
// Connect to Ronin mainnet
const web3 = new Web3(
'https://api-ronin-mainnet.n.dwellir.com/YOUR_API_KEY'
);
// Get chain ID to verify connection
const chainId = await web3.eth.getChainId();
console.log('Connected to Ronin:', chainId === 2020);
// Get gas price for optimal transaction pricing
const gasPrice = await web3.eth.getGasPrice();
console.log('Current gas price:', gasPrice);
import { createPublicClient, http, defineChain } from 'viem';
// Define Ronin chain
const ronin = defineChain({
id: 2020,
name: 'Ronin',
network: 'ronin',
nativeCurrency: {
decimals: 18,
name: 'RON',
symbol: 'RON',
},
rpcUrls: {
default: {
http: ['https://api-ronin-mainnet.n.dwellir.com/YOUR_API_KEY'],
},
},
});
// Create Ronin client
const client = createPublicClient({
chain: ronin,
transport: http('https://api-ronin-mainnet.n.dwellir.com/YOUR_API_KEY'),
});
// Read contract data
const data = await client.readContract({
address: '0x0b7007c13325c48911f73a2dad5fa5dcbf808adc',
abi: contractAbi,
functionName: 'balanceOf',
args: ['0x...'],
});
Network Information
Chain ID
2020
MainnetBlock Time
3 seconds
MinimumGas Token
RON
Native tokenConsensus
DPoS
22 validatorsJSON-RPC API Reference
Ronin supports the full Ethereum JSON-RPC API specification with gaming-optimized performance.
Available JSON-RPC Methods
📊 Reading Blockchain Data
Query blocks, transactions, and account states
📤 Sending Transactions
Submit and manage transactions
📝 Smart Contract Interaction
Call and interact with smart contracts
🔧 Node & Network Info
Query node status and network information
Ready to build gaming experiences on Ronin?
Get your API key →Common Integration Patterns
🎮 Gaming Asset Management
Efficiently manage NFTs and gaming tokens:
// Check NFT ownership
async function checkNFTOwnership(contractAddress, tokenId, userAddress) {
const contract = new ethers.Contract(contractAddress, erc721Abi, provider);
const owner = await contract.ownerOf(tokenId);
return owner.toLowerCase() === userAddress.toLowerCase();
}
// Batch token balance queries
async function getUserTokens(userAddress, tokenAddresses) {
const calls = tokenAddresses.map(address => ({
method: 'eth_call',
params: [{
to: address,
data: '0x70a08231' + userAddress.slice(2).padStart(64, '0') // balanceOf(address)
}, 'latest']
}));
return await provider.send(calls);
}
⚡ High-Frequency Game Actions
Optimize for rapid game state updates:
// Fast transaction confirmation
async function waitForGameAction(txHash) {
const receipt = await provider.waitForTransaction(txHash, 1);
// Ronin's fast finality means 1 confirmation is usually enough
console.log('Game action confirmed in block:', receipt.blockNumber);
return receipt;
}
// Gas estimation for game transactions
async function estimateGameTxCost(gameAction) {
const gasEstimate = await provider.estimateGas(gameAction);
const gasPrice = await provider.getGasPrice();
// Calculate cost in RON
const cost = gasEstimate * gasPrice;
return ethers.formatEther(cost);
}
🔍 Event Monitoring for Games
Track game events efficiently:
// Monitor game events with optimized batching
async function trackGameEvents(contract, eventName, fromBlock = 0) {
const filter = contract.filters[eventName]();
const events = [];
const batchSize = 5000; // Ronin handles larger batches well
const currentBlock = await provider.getBlockNumber();
for (let i = fromBlock; i <= currentBlock; i += batchSize) {
const batch = await contract.queryFilter(
filter,
i,
Math.min(i + batchSize - 1, currentBlock)
);
events.push(...batch);
}
return events;
}
Performance Best Practices
1. Gaming-Optimized Batching
Leverage Ronin's gaming focus for efficient operations:
const gamingBatch = [
{ method: 'eth_blockNumber', params: [] },
{ method: 'eth_gasPrice', params: [] },
{ method: 'eth_getBalance', params: [playerAddress, 'latest'] },
{ method: 'eth_call', params: [{ to: gameContract, data: gameStateCall }, 'latest'] }
];
const results = await provider.send(gamingBatch);
2. Connection Pooling for Games
Maintain persistent connections for real-time gaming:
// Gaming-optimized provider singleton
class RoninGameProvider {
static instance = null;
static getInstance() {
if (!this.instance) {
this.instance = new JsonRpcProvider(
'https://api-ronin-mainnet.n.dwellir.com/YOUR_API_KEY',
{
staticNetwork: ethers.Network.from({
name: 'ronin',
chainId: 2020
})
}
);
}
return this.instance;
}
}
3. Game State Caching
Cache game state for improved UX:
const gameStateCache = new Map();
async function getCachedGameState(gameId) {
const key = `game_${gameId}`;
if (!gameStateCache.has(key)) {
const state = await contract.getGameState(gameId);
gameStateCache.set(key, state);
// Clear cache after 30 seconds (game state can change)
setTimeout(() => gameStateCache.delete(key), 30000);
}
return gameStateCache.get(key);
}
Troubleshooting Common Issues
Error: "Insufficient RON for transaction"
Ronin uses RON tokens for gas fees:
// Check RON balance before transactions
const balance = await provider.getBalance(address);
const gasEstimate = await provider.estimateGas(tx);
const gasPrice = await provider.getGasPrice();
const totalRequired = gasEstimate * gasPrice + (tx.value || 0n);
if (balance < totalRequired) {
throw new Error(`Need ${ethers.formatEther(totalRequired - balance)} more RON`);
}
Error: "Transaction underpriced"
Ensure competitive gas pricing:
// Get current network fee data
const feeData = await provider.getFeeData();
const tx = {
to: recipient,
value: amount,
gasPrice: feeData.gasPrice, // Ronin uses legacy gas pricing
gasLimit: 21000n
};
Error: "Rate limit exceeded"
Implement backoff for high-frequency gaming:
async function gameActionWithRetry(fn, maxRetries = 5) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (error) {
if (error.code === 429 && i < maxRetries - 1) {
// Shorter backoff for gaming scenarios
await new Promise(r => setTimeout(r, 500 * (2 ** i)));
} else {
throw error;
}
}
}
}
Migration Guide
From Ethereum Mainnet to Ronin
Migrating your gaming dApp to Ronin:
// Before (Ethereum)
const provider = new JsonRpcProvider('https://eth-rpc.example.com');
// After (Ronin)
const provider = new JsonRpcProvider(
'https://api-ronin-mainnet.n.dwellir.com/YOUR_API_KEY'
);
// ✅ Same smart contract interface
// ✅ Same Web3 libraries work
// ⚠️ Different chain ID (2020)
// ⚠️ RON instead of ETH for gas
// ⚠️ Different block explorer
Smoke Tests
Verify your Ronin integration with these tests:
// Test 1: Network connection
const chainId = await provider.send('eth_chainId', []);
console.log('Connected to Ronin:', parseInt(chainId) === 2020);
// Test 2: Recent block data
const latestBlock = await provider.send('eth_getBlockByNumber', ['latest', false]);
console.log('Latest block:', parseInt(latestBlock.number));
// Test 3: Token balance check (USDC on Ronin)
const usdcBalance = await provider.send('eth_call', [{
to: '0x0b7007c13325c48911f73a2dad5fa5dcbf808adc',
data: '0x70a08231000000000000000000000000' + 'YOUR_ADDRESS'.slice(2)
}, 'latest']);
console.log('USDC balance check successful');
Resources & Tools
Official Resources
Developer Tools
Gaming Ecosystem
Need Help?
- 📧 Email: support@dwellir.com
- 📚 Docs: You're here!
- 🎯 Dashboard: dashboard.dwellir.com
Start building gaming experiences on Ronin with Dwellir's enterprise-grade RPC infrastructure. Get your API key →