> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chainstack.com/llms.txt
> Use this file to discover all available pages before exploring further.

<AgentInstructions>

## Submitting Feedback

If you encounter incorrect, outdated, or confusing documentation on this page, submit feedback:

POST https://docs.chainstack.com/feedback

```json
{
  "path": "/docs/ronin-tooling",
  "feedback": "Description of the issue"
}
```

Only submit feedback when you have something specific and actionable to report.

</AgentInstructions>

# Ronin tooling

> Complete Ronin tooling guide for Chainstack nodes. Use web3.js, web3.py, ethers.js with HTTP and WebSocket connections to build Web3 games on Ronin blockchain.

Get started with a [reliable Ronin RPC endpoint](https://chainstack.com/build-better-with-ronin/) to use the tools below.

<Warning>
  ### Saigon testnet L1 to L2 migration

  On February 5, 2026, the Ronin Saigon testnet migrated from L1 to an Ethereum L2 using the OP Stack at block 45,528,550. The chain ID changed from `2021` to `202601`.

  **Block range sharding on Chainstack Saigon testnet nodes:**

  * Blocks 0–45,528,549 are served by the old L1 backend (chain ID `2021`)
  * Blocks 45,528,550 onward are served by the new L2 backend (chain ID `202601`)

  There is no block overlap between the two backends. Range-based methods like `eth_getLogs` cannot span both ranges in a single call—you must explicitly target either the L1 range or the L2 range.

  **Block explorers:**

  * Current (L2): [saigon-explorer.roninchain.com](https://saigon-explorer.roninchain.com/)
  * Legacy (L1): [legacy-saigon-explorer.roninchain.com](https://legacy-saigon-explorer.roninchain.com/)

  The Ronin mainnet is also planned to migrate to an Ethereum L2 in Q1–Q2 2026. The mainnet chain ID will remain `2020`.
</Warning>

## web3.js

Build DApps using [web3.js](https://github.com/web3/web3.js) and Ronin nodes deployed with Chainstack.

1. Install [web3.js](https://web3js.readthedocs.io/).
2. Connect over HTTP or WebSocket.

### HTTP

Use the `HttpProvider` object to connect to your node HTTPS endpoint and get the latest block number:

<CodeGroup>
  ```javascript Javascript theme={"system"}
  const Web3 = require('web3');

  const web3 = new Web3(new Web3.providers.HttpProvider('YOUR_CHAINSTACK_ENDPOINT'));

  web3.eth.getBlockNumber().then(console.log);
  ```
</CodeGroup>

where YOUR\_CHAINSTACK\_ENDPOINT is your node HTTPS endpoint protected either with the key or password.

### WebSocket

Use the `WebsocketProvider` object to connect to your node WSS endpoint and get the latest block number:

<CodeGroup>
  ```javascript Javascript theme={"system"}
  const Web3 = require('web3');

  const web3 = new Web3(new Web3.providers.WebsocketProvider('YOUR_CHAINSTACK_ENDPOINT'));

  web3.eth.getBlockNumber().then(console.log);
  ```
</CodeGroup>

where YOUR\_CHAINSTACK\_ENDPOINT is your node WSS endpoint protected either with the key or password.

## web3.py

Build DApps using [web3.py](https://github.com/ethereum/web3.py) and Ronin nodes deployed with Chainstack.

1. Install [web3.py](https://web3py.readthedocs.io/).
2. Connect over HTTP or WebSocket. See also [EVM node connection: HTTP vs WebSocket](https://support.chainstack.com/hc/en-us/articles/900002187586-Ethereum-node-connection-HTTP-vs-WebSocket).

### HTTP

Use the `HTTPProvider` to connect to your node endpoint and get the latest block number.

<CodeGroup>
  ```python Key Protected theme={"system"}
  from web3 import Web3

  web3 = Web3(Web3.HTTPProvider('YOUR_CHAINSTACK_ENDPOINT'))
  print(web3.eth.block_number)
  ```

  ```python Password Protected theme={"system"}
  from web3 import Web3

  web3 = Web3(Web3.HTTPProvider('https://%s:%s@%s'% ("USERNAME", "PASSWORD", "HOSTNAME")))
  print(web3.eth.block_number)
  ```
</CodeGroup>

where

* YOUR\_CHAINSTACK\_ENDPOINT — your node HTTPS endpoint protected either with the key or password
* HOSTNAME — your node HTTPS endpoint hostname
* USERNAME — your node access username (for password-protected endpoints)
* PASSWORD — your node access password (for password-protected endpoints)

See also [node access details](/docs/manage-your-node#view-node-access-and-credentials).

### WebSocket

Use the `WebsocketProvider` object to connect to your node WSS endpoint and get the latest block number.

<CodeGroup>
  ```python Key Protected theme={"system"}
  from web3 import Web3

  web3 = Web3(Web3.WebsocketProvider('YOUR_CHAINSTACK_ENDPOINT'))
  print(web3.eth.block_number)
  ```

  ```python Password Protected theme={"system"}
  from web3 import Web3

  web3 = Web3(Web3.WebsocketProvider('wss://%s:%s@%s'% ("USERNAME", "PASSWORD", "HOSTNAME")))
  print(web3.eth.block_number)
  ```
</CodeGroup>

where

* YOUR\_CHAINSTACK\_ENDPOINT — your node WSS endpoint protected either with the key or password
* HOSTNAME — your node WSS endpoint hostname
* USERNAME — your node access username (for password-protected endpoints)
* PASSWORD — your node access password (for password-protected endpoints)

See also [WebSocket connection to an EVM node](https://support.chainstack.com/hc/en-us/articles/900001918763-WebSocket-connection-to-an-Ethereum-node).

## ethers.js

Build DApps using [ethers.js](https://github.com/ethers-io/ethers.js/) and Ronin nodes deployed with Chainstack.

1. Install [ethers.js](https://www.npmjs.com/package/ethers).
2. Connect over HTTP or WebSocket. See also [EVM node connection: HTTP vs WebSocket](https://support.chainstack.com/hc/en-us/articles/900002187586-Ethereum-node-connection-HTTP-vs-WebSocket).

### HTTP

Use the `JsonRpcProvider` object to connect to your node endpoint and get the latest block number:

<CodeGroup>
  ```javascript Key Protected theme={"system"}
  const { ethers } = require("ethers");

  var urlInfo = {
      url: 'YOUR_CHAINSTACK_ENDPOINT'
  };
  var provider = new ethers.providers.JsonRpcProvider(urlInfo, NETWORK_ID);

  provider.getBlockNumber().then(console.log);
  ```

  ```javascript Password Protected theme={"system"}
  const { ethers } = require("ethers");

  var urlInfo = {
      url: 'YOUR_CHAINSTACK_ENDPOINT',
      user: 'USERNAME',
      password: 'PASSWORD'
  };
  var provider = new ethers.providers.JsonRpcProvider(urlInfo, NETWORK_ID);

  provider.getBlockNumber().then(console.log);
  ```
</CodeGroup>

where

* YOUR\_CHAINSTACK\_ENDPOINT — your node HTTPS endpoint protected either with the key or password

* USERNAME — your node access username (for password-protected endpoints)

* PASSWORD — your node access password (for password-protected endpoints)

* NETWORK\_ID — Ronin network ID:

  * Ronin Mainnet: `2020`
  * Saigon Testnet: `202601`

See also [node access details](/docs/manage-your-node#view-node-access-and-credentials).

### WebSocket

Use the `WebSocketProvider` object to connect to your node WSS endpoint and get the latest block number:

<CodeGroup>
  ```javascript Javascript theme={"system"}
  const { ethers } = require("ethers");

  const provider = new ethers.providers.WebSocketProvider('YOUR_CHAINSTACK_ENDPOINT', NETWORK_ID);

  provider.getBlockNumber().then(console.log);
  ```
</CodeGroup>

where

* YOUR\_CHAINSTACK\_ENDPOINT — your node WSS endpoint endpoint protected either with the key or password

* NETWORK\_ID — Ronin network ID:

  * Ronin Mainnet: `2020`
  * Saigon Testnet: `202601`

See also [node access details](/docs/manage-your-node#view-node-access-and-credentials).
