Docs

Ronin - Gaming-Focused Blockchain Documentation

Complete guide to Ronin blockchain integration with Dwellir RPC. Learn how to build on Ronin, access JSON-RPC methods, and optimize your gaming dApp performance.

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.

Get your API key

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:

Ronin RPC Endpoints
HTTPS
curl -sS -X POST https://api-ronin-mainnet.n.dwellir.com/<API_Keys_Are_Not_Made_for_Bots> \  -H 'Content-Type: application/json' \  -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
import { JsonRpcProvider } from 'ethers';const provider = new JsonRpcProvider(  'https://api-ronin-mainnet.n.dwellir.com/<API_Keys_Are_Not_Made_for_Bots>');const latest = await provider.getBlockNumber();console.log('block', latest);
import requestsurl = 'https://api-ronin-mainnet.n.dwellir.com/<API_Keys_Are_Not_Made_for_Bots>'payload = {  'jsonrpc': '2.0', 'id': 1,  'method': 'eth_blockNumber', 'params': []}resp = requests.post(url, json=payload)print(resp.json())
package mainimport (  "bytes"  "fmt"  "io"  "net/http")func main() {  url := "https://api-ronin-mainnet.n.dwellir.com/<API_Keys_Are_Not_Made_for_Bots>"  payload := []byte(`{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}`)  resp, err := http.Post(url, "application/json",    bytes.NewBuffer(payload))  if err != nil { panic(err) }  defer resp.Body.Close()  body, _ := io.ReadAll(resp.Body)  fmt.Println(string(body))}

Installation & Setup

Network Information

ParameterValueDetails
Chain ID2020Mainnet
Block Time3 secondsMinimum
Gas TokenRONNative token
ConsensusDPoS22 validators

API Reference

Ronin supports the full Ethereum JSON-RPC API specification with gaming-optimized performance.

Common Integration Patterns

Gaming Asset Management

Efficiently manage NFTs and gaming tokens:

JavaScript
// 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:

JavaScript
// 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:

JavaScript
// 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:

JavaScript
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:

JavaScript
// 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:

JavaScript
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:

JavaScript
// 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:

JavaScript
// 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:

JavaScript
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:

JavaScript
// 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
// Note: Different chain ID (2020)
// Note: RON instead of ETH for gas
// Note: Different block explorer

Smoke Tests

Verify your Ronin integration with these tests:

JavaScript
// 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?


Start building gaming experiences on Ronin with Dwellir's enterprise-grade RPC infrastructure. Get your API key