// Get peer count
const getPeerCount = async () => {
const response = await fetch('https://hyperliquid-mainnet.core.chainstack.com/YOUR_ENDPOINT/evm', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
jsonrpc: '2.0',
method: 'net_peerCount',
params: [],
id: 1
})
});
const data = await response.json();
const peerCount = parseInt(data.result, 16);
return {
hex: data.result,
decimal: peerCount
};
};
// Network health monitor
const monitorNetworkHealth = async () => {
const healthStatus = {
peerCount: 0,
status: 'unknown',
timestamp: new Date(),
history: []
};
try {
const { decimal: peerCount } = await getPeerCount();
healthStatus.peerCount = peerCount;
// Determine network status based on peer count
if (peerCount === 0) {
healthStatus.status = 'disconnected';
} else if (peerCount < 5) {
healthStatus.status = 'poor';
} else if (peerCount < 20) {
healthStatus.status = 'fair';
} else if (peerCount < 50) {
healthStatus.status = 'good';
} else {
healthStatus.status = 'excellent';
}
} catch (error) {
healthStatus.status = 'error';
healthStatus.error = error.message;
}
return healthStatus;
};
// Continuous network monitoring
const startNetworkMonitoring = (callback, intervalMs = 30000) => {
const monitor = {
history: [],
isRunning: false,
intervalId: null
};
const checkNetwork = async () => {
const health = await monitorNetworkHealth();
monitor.history.push(health);
// Keep only last 100 readings
if (monitor.history.length > 100) {
monitor.history = monitor.history.slice(-100);
}
callback(health, monitor.history);
};
monitor.start = () => {
if (!monitor.isRunning) {
monitor.isRunning = true;
checkNetwork(); // Initial check
monitor.intervalId = setInterval(checkNetwork, intervalMs);
}
};
monitor.stop = () => {
if (monitor.isRunning) {
monitor.isRunning = false;
clearInterval(monitor.intervalId);
}
};
monitor.getStats = () => {
if (monitor.history.length === 0) return null;
const peerCounts = monitor.history.map(h => h.peerCount);
return {
current: peerCounts[peerCounts.length - 1],
min: Math.min(...peerCounts),
max: Math.max(...peerCounts),
avg: Math.round(peerCounts.reduce((a, b) => a + b, 0) / peerCounts.length),
samples: monitor.history.length
};
};
return monitor;
};
// Network connectivity dashboard
class NetworkDashboard {
constructor() {
this.data = {
current: null,
history: [],
alerts: []
};
}
async updateStatus() {
try {
const health = await monitorNetworkHealth();
this.data.current = health;
this.data.history.push(health);
// Keep history manageable
if (this.data.history.length > 1000) {
this.data.history = this.data.history.slice(-1000);
}
// Check for alerts
this.checkAlerts(health);
} catch (error) {
console.error('Failed to update network status:', error);
}
}
checkAlerts(health) {
const now = Date.now();
// Low peer count alert
if (health.peerCount < 5 && health.status !== 'error') {
this.data.alerts.push({
type: 'low_peers',
message: `Low peer count detected: ${health.peerCount}`,
timestamp: now,
severity: 'warning'
});
}
// Disconnection alert
if (health.peerCount === 0) {
this.data.alerts.push({
type: 'disconnected',
message: 'Node appears to be disconnected (0 peers)',
timestamp: now,
severity: 'critical'
});
}
// Keep only recent alerts (last hour)
this.data.alerts = this.data.alerts.filter(
alert => now - alert.timestamp < 3600000
);
}
getStatus() {
return this.data.current;
}
getHistory(minutes = 60) {
const cutoff = Date.now() - (minutes * 60 * 1000);
return this.data.history.filter(h => h.timestamp.getTime() > cutoff);
}
getAlerts(minutes = 60) {
const cutoff = Date.now() - (minutes * 60 * 1000);
return this.data.alerts.filter(a => a.timestamp > cutoff);
}
generateReport() {
const recent = this.getHistory(60);
if (recent.length === 0) return null;
const peerCounts = recent.map(h => h.peerCount);
const statusCounts = recent.reduce((acc, h) => {
acc[h.status] = (acc[h.status] || 0) + 1;
return acc;
}, {});
return {
timeRange: '60 minutes',
samples: recent.length,
peerStats: {
current: this.data.current?.peerCount || 0,
min: Math.min(...peerCounts),
max: Math.max(...peerCounts),
avg: Math.round(peerCounts.reduce((a, b) => a + b, 0) / peerCounts.length)
},
statusDistribution: statusCounts,
recentAlerts: this.getAlerts(60).length
};
}
}
// Usage examples
getPeerCount().then(result => {
console.log(`Connected peers: ${result.decimal} (${result.hex})`);
});
// Start network monitoring
const monitor = startNetworkMonitoring((health, history) => {
console.log(`Network Status: ${health.status}, Peers: ${health.peerCount}`);
if (health.status === 'poor' || health.status === 'disconnected') {
console.warn('Network connectivity issues detected!');
}
}, 10000); // Check every 10 seconds
monitor.start();
// Stop monitoring after 5 minutes
setTimeout(() => {
monitor.stop();
console.log('Final stats:', monitor.getStats());
}, 5 * 60 * 1000);
// Use network dashboard
const dashboard = new NetworkDashboard();
// Update dashboard every 30 seconds
setInterval(() => {
dashboard.updateStatus().then(() => {
const report = dashboard.generateReport();
if (report) {
console.log('Network Report:', report);
}
});
}, 30000);