Ensure you have the following installed:
Execute the script using Node:
node ./main.js| const https = require("https"); | |
| const http = require("http"); | |
| const fs = require("fs/promises"); | |
| const MAINNET = "https://api.mainnet-beta.solana.com"; | |
| const CSV_FILE_NAME = "rpc-nodes.csv"; | |
| // Helper function for making POST requests | |
| function postRequest(url, data) { | |
| return new Promise((resolve, reject) => { | |
| const urlObj = new URL(url); | |
| const module = urlObj.protocol === "https:" ? https : http; | |
| const options = { | |
| method: "POST", | |
| headers: { | |
| "Content-Type": "application/json", | |
| "Content-Length": Buffer.byteLength(data), | |
| }, | |
| hostname: urlObj.hostname, | |
| port: urlObj.port || (urlObj.protocol === "https:" ? 443 : 80), | |
| path: urlObj.pathname, | |
| }; | |
| const req = module.request(options, (res) => { | |
| let body = ""; | |
| res.on("data", (chunk) => { | |
| body += chunk; | |
| }); | |
| res.on("end", () => { | |
| try { | |
| const json = JSON.parse(body); | |
| resolve(json); | |
| } catch (error) { | |
| reject(error); | |
| } | |
| }); | |
| }); | |
| req.on("error", (error) => { | |
| reject(error); | |
| }); | |
| req.write(data); | |
| req.end(); | |
| }); | |
| } | |
| // Function to get the list of cluster nodes | |
| async function getClusterNodes() { | |
| const data = JSON.stringify({ | |
| jsonrpc: "2.0", | |
| id: 1, | |
| method: "getClusterNodes", | |
| }); | |
| const response = await postRequest(MAINNET, data); | |
| return response.result; | |
| } | |
| // Function to check the health of a node | |
| async function checkHealth(rpcUrl) { | |
| try { | |
| const data = JSON.stringify({ | |
| jsonrpc: "2.0", | |
| id: 1, | |
| method: "getHealth", | |
| }); | |
| const response = await postRequest(rpcUrl, data); | |
| return response.result || response.error?.message || "unknown"; | |
| } catch (e) { | |
| console.error("> Error:", e.message, "|", rpcUrl); | |
| return undefined; | |
| } | |
| } | |
| // Main program logic | |
| (async () => { | |
| // Get the list of cluster nodes | |
| const clusterNodes = await getClusterNodes(); | |
| // Filter nodes with RPC and add the main node | |
| const nodesWithRpc = clusterNodes.filter((node) => !!node.rpc); | |
| nodesWithRpc.push({ rpc: MAINNET }); | |
| console.log("> Total nodes:", clusterNodes.length); | |
| console.log("> Found", nodesWithRpc.length, "nodes with RPC"); | |
| // Check the health of each node | |
| const data = []; | |
| await Promise.all( | |
| nodesWithRpc.map(async (node, i) => { | |
| console.log(`> Connecting to node ${i + 1}/${nodesWithRpc.length}`); | |
| let rpcUrl = node.rpc; | |
| if (!rpcUrl.startsWith("http")) { | |
| rpcUrl = `http://${rpcUrl}`; | |
| } | |
| const healthStatus = await checkHealth(rpcUrl); | |
| if (healthStatus) { | |
| data.push([rpcUrl, healthStatus]); | |
| } | |
| }) | |
| ); | |
| console.log("> Active nodes with RPC:", data.length); | |
| // Prepare data for CSV | |
| const CSV_HEADERS = ["rpc_url", "health_status"]; | |
| const CSV_DATA = [ | |
| CSV_HEADERS.join(","), | |
| ...data | |
| .sort((a, b) => b[1].localeCompare(a[1])) | |
| .map((row) => row.join(",")), | |
| ]; | |
| // Write data to CSV file | |
| await fs.writeFile(CSV_FILE_NAME, CSV_DATA.join("\n")); | |
| console.log(`> Saved to ${CSV_FILE_NAME}`); | |
| })(); |
| rpc_url | health_status | |
|---|---|---|
| http://149.255.37.130:8899 | Node is behind by 109287 slots | |
| http://147.28.133.107:8899 | Node is behind by 432094 slots | |
| http://147.28.175.189:8899 | Node is behind by 59589 slots | |
| http://208.91.110.134:8899 | Node is behind by 6017 slots | |
| http://213.163.64.146:8900 | Node is behind by 9001 slots | |
| https://api.mainnet-beta.solana.com | ok | |
| http://72.46.84.195:8899 | ok | |
| http://162.19.222.23:8899 | ok | |
| http://185.177.74.241:8899 | ok | |
| http://64.176.65.109:8899 | ok | |
| http://212.7.207.1:8899 | ok | |
| http://88.198.54.74:8899 | ok | |
| http://149.255.37.174:8899 | ok | |
| http://141.95.97.47:8899 | ok | |
| http://3.120.147.22:8899 | ok | |
| http://149.255.37.154:8899 | ok | |
| http://70.34.245.172:8899 | ok | |
| http://67.213.119.41:8899 | ok | |
| http://3.79.229.25:8899 | ok | |
| http://45.76.3.216:8899 | ok | |
| http://149.255.37.170:8899 | ok | |
| http://147.75.193.169:8899 | ok | |
| http://104.238.189.205:8899 | ok | |
| http://185.221.164.118:8899 | ok | |
| http://185.189.44.239:8899 | ok | |
| http://185.86.135.78:8899 | ok | |
| http://208.85.17.92:8899 | ok | |
| http://80.77.161.201:8899 | ok | |
| http://145.40.64.255:8899 | ok | |
| http://192.158.239.143:8899 | ok | |
| http://66.45.229.34:8899 | ok | |
| http://155.138.205.169:8899 | ok | |
| http://145.40.88.77:8899 | ok | |
| http://91.242.214.213:8899 | ok | |
| http://162.19.102.192:8899 | ok | |
| http://64.130.32.60:8899 | ok | |
| http://147.28.173.31:8899 | ok | |
| http://204.13.239.42:8899 | ok | |
| http://147.28.134.99:8899 | ok | |
| http://3.76.48.117:8899 | ok | |
| http://107.182.162.210:8899 | ok | |
| http://145.40.95.83:8899 | ok | |
| http://139.178.73.255:8899 | ok | |
| http://149.248.62.208:8899 | ok | |
| http://147.28.171.53:8899 | ok | |
| http://207.148.14.220:8899 | ok | |
| http://88.216.198.210:8899 | ok | |
| http://65.20.105.6:8899 | ok | |
| http://38.58.176.230:8899 | ok | |
| http://84.32.186.110:8899 | ok | |
| http://185.189.44.139:8899 | ok | |
| http://84.32.186.43:8899 | ok | |
| http://18.195.65.66:8899 | ok | |
| http://149.28.232.189:8899 | ok | |
| http://50.115.47.106:8899 | ok | |
| http://104.37.190.98:8899 | ok | |
| http://216.18.208.18:8899 | ok | |
| http://185.26.9.215:8899 | ok | |
| http://205.209.107.186:8899 | ok | |
| http://185.86.135.71:8899 | ok | |
| http://173.231.22.242:8899 | ok | |
| http://80.77.175.93:8899 | ok | |
| http://70.34.212.218:8899 | ok | |
| http://173.231.14.98:8899 | ok | |
| http://147.28.173.107:8899 | ok | |
| http://147.28.180.247:8899 | ok | |
| http://149.248.8.41:8899 | ok | |
| http://38.29.227.126:8899 | ok | |
| http://69.67.150.141:8899 | ok | |
| http://88.216.198.205:8899 | ok | |
| http://177.54.154.27:8899 | ok | |
| http://147.28.169.155:8899 | ok | |
| http://69.67.150.19:8899 | ok | |
| http://147.124.195.78:8899 | ok | |
| http://45.63.111.115:8899 | ok | |
| http://107.182.163.194:8899 | ok | |
| http://195.162.83.18:8899 | ok | |
| http://74.50.77.122:8899 | ok | |
| http://216.238.102.89:8899 | ok | |
| http://45.250.254.191:8899 | ok | |
| http://147.75.198.191:8899 | ok | |
| http://108.171.216.114:8899 | ok | |
| http://144.202.50.238:8899 | ok | |
| http://147.75.92.227:8899 | ok | |
| http://185.26.9.5:8899 | ok | |
| http://67.213.115.17:8899 | ok | |
| http://108.171.216.194:8899 | ok | |
| http://192.64.85.242:8899 | ok | |
| http://139.84.238.57:8899 | ok | |
| http://64.176.11.113:8899 | ok | |
| http://145.40.91.45:8899 | ok | |
| http://207.246.119.26:8899 | ok | |
| http://137.220.59.111:8899 | ok | |
| http://172.96.172.242:8899 | ok | |
| http://38.97.61.158:8899 | ok | |
| http://147.28.173.35:8899 | ok | |
| http://103.88.233.29:8899 | ok | |
| http://86.109.14.143:8899 | ok | |
| http://145.40.117.251:8899 | ok | |
| http://103.106.58.75:8899 | ok | |
| http://147.28.169.105:8899 | ok | |
| http://145.40.91.41:8899 | ok | |
| http://38.29.227.125:8899 | ok | |
| http://147.28.169.15:8899 | ok |