Network audit dashboard for the Sentinel dVPN blockchain. Tests every active node for real VPN throughput, protocol compliance, speed, and accessibility.
Built on the Sentinel dVPN SDK — the same protocol stack that powers consumer VPN applications.
Connects to the Sentinel blockchain, discovers every active dVPN node, pays for bandwidth sessions, establishes real VPN tunnels (WireGuard + V2Ray), and measures actual throughput. Every node gets a PASS or FAIL with full diagnostics.
- 987+ nodes tested in a single audit run
- WireGuard + V2Ray dual-protocol coverage
- Batch payments (5 nodes per transaction — 5x gas savings)
- Zero-skip system — every node ends as PASS or FAIL
- Real-time dashboard with SSE streaming, speed charts, and failure analysis
- Test run history — save, compare, and load past audits
Test any dVPN node for actual bandwidth. Measures download speed through a real VPN tunnel against Cloudflare CDN with adaptive fallback.
Toggle between three SDK implementations from the dashboard:
| SDK | Label | Package | Code Path |
|---|---|---|---|
| Blue JS | Our JavaScript SDK | sentinel-dvpn-sdk |
Status + handshake + config |
| Blue C# | Our C# SDK | SentinelBridge.exe |
Status + handshake via CLI bridge |
| TKD JS | Official Sentinel SDK by TKD Alex | @sentinel-official/sentinel-js-sdk |
Status (nodeInfo) + handshake + V2Ray/WG classes |
Same nodes, same protocol, different code paths. Every difference reveals an SDK bug.
Exercises the full Sentinel v3 pipeline end-to-end:
LCD Discovery -> Session Creation -> Handshake -> Tunnel Setup -> Bandwidth Test -> Disconnect
Configure different DNS resolvers per audit run. Compare results across:
- Handshake DNS (103.196.38.38) — decentralized naming
- Google DNS (8.8.8.8)
- Cloudflare DNS (1.1.1.1)
- Custom resolvers
WireGuard and V2Ray behave differently across Windows, macOS, and Linux. Run the same audit on different machines to find OS-specific failures.
Every node is tested for Google.com reachability through the VPN tunnel. Maps which countries and nodes provide uncensored internet access.
V2Ray supports multiple transports: TCP, WebSocket, HTTP, gRPC, gun. The tester tries every variant and builds an intelligence cache that learns which transports work best per node and geography.
Run audits from different devices — laptops, desktops, VPS, ARM boards — to identify device-specific networking issues, MTU problems, and driver compatibility.
Every failure produces a structured diagnostic:
- Connection timeouts with port scan data
- Clock drift detection for VMess AEAD failures
- Address mismatch analysis across
remote_addrs - Chain propagation lag measurement
- Database corruption detection on nodes
- Node.js 20+
- WireGuard installed (optional — V2Ray works without)
- Administrator/root for WireGuard tunnel management
- Sentinel wallet with P2P tokens (~1 P2P per 25 node tests)
git clone https://github.com/nicxd531/sentinel-node-tester.git
cd sentinel-node-tester
npm install
# Configure wallet
cp .env.example .env
# Edit .env — add your mnemonic
# Launch (as Administrator for WireGuard)
node server.js
# Open dashboard
# http://localhost:3001cscript //nologo SentinelAudit.vbsThe VBS script handles admin elevation automatically.
The easy API gives you 3 functions — no server, no dashboard, just results.
npm install sentinel-node-testerimport { getNodes } from 'sentinel-node-tester/easy';
const nodes = await getNodes();
console.log(`${nodes.length} nodes online`);
// With filters
const usNodes = await getNodes({ country: 'United States', type: 'wireguard', withStatus: true });import { testOne } from 'sentinel-node-tester/easy';
const result = await testOne({
mnemonic: 'your twelve words...',
node: 'sentnode1qx2p7kyep6m44ae47yh9zf3cfxrzrv5zt9vdnj',
});
if (result.pass) {
console.log(`${result.speed} Mbps via ${result.type} in ${result.country}`);
} else {
console.log(`Failed: ${result.error}`);
}import { audit } from 'sentinel-node-tester/easy';
const { results, summary } = await audit({
mnemonic: 'your twelve words...',
maxNodes: 50, // 0 = all ~1000 nodes
onProgress: ({ tested, total, passed }) =>
console.log(`${tested}/${total} — ${passed} passed`),
});
console.log(`${summary.passRate} pass rate, avg ${summary.avgSpeed} Mbps`);import express from 'express';
import { middleware } from 'sentinel-node-tester/easy';
const app = express();
app.use(express.json());
app.use(middleware({ mnemonic: process.env.MNEMONIC }));
// Now available:
// GET /sentinel/nodes — list online nodes
// POST /sentinel/test — test node(s): { node: 'sentnode1...' } or { maxNodes: 10 }
// GET /sentinel/health — readiness check
app.listen(3000);| Operation | Cost |
|---|---|
| List nodes | Free |
| Test 1 node | |
| Test 50 nodes | |
| Full audit (~1000 nodes) |
Get P2P tokens: Osmosis DEX
Web dashboard at http://localhost:3001:
- Live progress — SSE streaming as each node is tested
- Speed charts — baseline vs node speed history
- Failure analysis — categorized breakdown with retest recommendations
- Test history — browse and compare past runs
- DNS config — switch resolvers mid-audit
- SDK toggle — JS or C#
- Economy mode — cap tests to balance
| Button | Action |
|---|---|
| Start | New full audit (auto-saves previous) |
| Resume | Continue from where last audit stopped |
| Stop | Graceful stop after current node |
| Retest Failed | Re-test only failed nodes |
| Auto Retest | Smart retest based on failure categories |
All functionality is available programmatically:
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/stats |
Quick counters (no results) |
GET |
/api/state |
Full state + all results |
GET |
/api/results?page=1&limit=100 |
Paginated results |
GET |
/api/events |
SSE real-time stream |
POST |
/api/start |
Start new audit |
POST |
/api/resume |
Resume current audit |
POST |
/api/stop |
Stop audit |
POST |
/api/retest-fails |
Retest failed nodes |
POST |
/api/auto-retest |
Smart retest (analysis-based) |
GET |
/api/failure-analysis |
Categorized failure breakdown |
GET |
/api/runs |
List all saved test runs |
GET |
/api/runs/:num |
Get specific run results |
POST |
/api/runs/load/:num |
Load historical run |
GET/POST |
/api/dns |
DNS resolver config |
GET/POST |
/api/sdk |
SDK toggle (js/csharp/tkd) |
GET |
/api/transport-cache |
Transport intelligence stats |
GET |
/api/health |
Prelaunch readiness check |
GET |
/api/cross-sdk |
Cross-SDK comparison data |
POST |
/api/test-plan |
WIP — Plan-specific testing (not ready) |
Import as a library:
import { testNode } from 'sentinel-node-tester/audit/node-test.js';
import { runAudit, createState } from 'sentinel-node-tester/audit/pipeline.js';
import { nodeStatusV3, buildV2RayClientConfig } from 'sentinel-node-tester/protocol/v3protocol.js';
import { speedtestDirect, speedtestViaSocks5 } from 'sentinel-node-tester/protocol/speedtest.js';See docs/BUILD-ON-ME.md for the complete integration guide.
sentinel-node-tester/
├── server.js — Express server: routes + SSE (thin, ~300 lines)
├── index.js — Library entry point
├── index.html — Dashboard UI
│
├── core/ — Shared infrastructure
│ ├── constants.js — Config, env vars, endpoints
│ ├── errors.js — Typed errors (SDK SentinelError + .diag)
│ ├── wallet.js — Wallet derivation + signing (SDK adapter)
│ ├── chain.js — LCD queries + node discovery (SDK adapter)
│ ├── session.js — Session map, credentials, batch payment
│ └── transport-cache.js — V2Ray transport intelligence
│
├── audit/ — Audit orchestration
│ ├── pipeline.js — runAudit, runRetest, state management
│ ├── node-test.js — Single node test (~450 lines)
│ └── retry.js — Zero-skip retry with classification
│
├── protocol/ — Network protocol
│ ├── v3protocol.js — Sentinel v3 handshake (SDK re-exports)
│ ├── speedtest.js — Bandwidth + Google checks (SDK + local)
│ └── diagnostics.js — Interference detection, failure classification
│
├── platforms/ — OS-specific
│ └── windows/
│ ├── wireguard.js — WireGuard service management
│ ├── v2ray.js — V2Ray process management
│ └── network.js — VPN adapter detection
│
├── docs/ — Technical documentation
└── results/ — Runtime data (gitignored)
{
timestamp: '2026-03-28T07:34:24Z',
address: 'sentnode1...',
type: 'WireGuard', // or 'V2Ray'
moniker: 'Node Name',
country: 'Germany',
city: 'Frankfurt',
actualMbps: 45.2, // null = FAILED
baselineAtTest: 85.0,
pass15mbps: true,
pass10mbps: true,
peers: 3,
googleAccessible: true,
googleLatencyMs: 142,
sdk: 'js',
os: 'Windows',
error: null, // Error message if failed
diag: {}, // Structured diagnostic payload
}The critical field: actualMbps — if null, the node failed. If a number, it passed.
| Item | Cost |
|---|---|
| Per node (1 GB session) | ~40 P2P (varies by node) |
| Gas per batch (5 nodes) | ~1 P2P |
| Full 987-node audit | ~700-800 P2P |
-
Peers > 0 = our fault. Any node with active users that fails to connect is a bug in our code, not the node.
-
Zero-skip. Every node ends as PASS or FAIL. No "skipped" category.
-
Never lose data. Auto-save before every new test. Immutable run archives.
-
Same code + same node = same result. Never retest without a fix.
| Document | Description |
|---|---|
docs/BUILD-ON-ME.md |
One-shot integration guide with working code |
docs/COMPLETE-INTEGRATION-SPEC.md |
Every button, stat, and platform gotcha |
docs/EMBEDDING-GUIDE.md |
JS vs C# vs Swift comparison |
docs/FUNCTION-REFERENCE.md |
Every function in execution order |
docs/TECHNICAL-BLUEPRINT.md |
Files, data flows, edge cases |
docs/UX-FEATURE-PARITY.md |
Features apps must replicate |
CONTEXT.md |
Project conventions and rules |
ARCH.md |
Module graph and request flow |
MANIFESTO.md |
Mission and principles |
MIT