blue-js-sdk 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (215) hide show
  1. package/CHANGELOG.md +446 -0
  2. package/LICENSE +21 -0
  3. package/README.md +75 -0
  4. package/ai-path/ADMIN-ELEVATION.md +116 -0
  5. package/ai-path/AI-MANIFESTO.md +185 -0
  6. package/ai-path/BREAKING.md +74 -0
  7. package/ai-path/CHECKLIST.md +619 -0
  8. package/ai-path/CONNECTION-STEPS.md +724 -0
  9. package/ai-path/DECISION-TREE.md +378 -0
  10. package/ai-path/DEPENDENCIES.md +459 -0
  11. package/ai-path/E2E-FLOW.md +1555 -0
  12. package/ai-path/FAILURES.md +403 -0
  13. package/ai-path/GUIDE.md +1217 -0
  14. package/ai-path/README.md +558 -0
  15. package/ai-path/SPLIT-TUNNEL.md +266 -0
  16. package/ai-path/cli.js +535 -0
  17. package/ai-path/connect.js +884 -0
  18. package/ai-path/discover.js +178 -0
  19. package/ai-path/environment.js +266 -0
  20. package/ai-path/errors.js +86 -0
  21. package/ai-path/examples/autonomous-agent.mjs +220 -0
  22. package/ai-path/examples/multi-region.mjs +174 -0
  23. package/ai-path/examples/one-shot.mjs +31 -0
  24. package/ai-path/index.js +60 -0
  25. package/ai-path/pricing.js +136 -0
  26. package/ai-path/recommend.js +413 -0
  27. package/ai-path/run-admin.vbs +25 -0
  28. package/ai-path/setup.js +291 -0
  29. package/ai-path/wallet.js +137 -0
  30. package/app-helpers.js +363 -0
  31. package/app-settings.js +95 -0
  32. package/app-types.js +267 -0
  33. package/audit.js +847 -0
  34. package/batch.js +293 -0
  35. package/bin/setup.js +376 -0
  36. package/chain/authz.js +109 -0
  37. package/chain/broadcast.js +472 -0
  38. package/chain/client.js +160 -0
  39. package/chain/fee-grants.js +305 -0
  40. package/chain/index.js +891 -0
  41. package/chain/lcd.js +313 -0
  42. package/chain/queries.js +547 -0
  43. package/chain/rpc.js +408 -0
  44. package/chain/wallet.js +141 -0
  45. package/cli/config.js +143 -0
  46. package/cli/index.js +463 -0
  47. package/cli/output.js +182 -0
  48. package/cli.js +491 -0
  49. package/client/index.js +251 -0
  50. package/client.js +271 -0
  51. package/config/index.js +255 -0
  52. package/connection/connect.js +849 -0
  53. package/connection/disconnect.js +180 -0
  54. package/connection/discovery.js +321 -0
  55. package/connection/index.js +76 -0
  56. package/connection/proxy.js +148 -0
  57. package/connection/resilience.js +428 -0
  58. package/connection/security.js +232 -0
  59. package/connection/state.js +369 -0
  60. package/connection/tunnel.js +691 -0
  61. package/consumer.js +132 -0
  62. package/cosmjs-setup.js +1884 -0
  63. package/defaults.js +366 -0
  64. package/disk-cache.js +107 -0
  65. package/dist/client.d.ts +108 -0
  66. package/dist/client.d.ts.map +1 -0
  67. package/dist/client.js +400 -0
  68. package/dist/client.js.map +1 -0
  69. package/dist/index.d.ts +8 -0
  70. package/dist/index.d.ts.map +1 -0
  71. package/dist/index.js +8 -0
  72. package/dist/index.js.map +1 -0
  73. package/errors/index.js +112 -0
  74. package/errors.js +218 -0
  75. package/examples/README.md +64 -0
  76. package/examples/connect-direct.mjs +106 -0
  77. package/examples/connect-plan.mjs +125 -0
  78. package/examples/error-handling.mjs +109 -0
  79. package/examples/query-nodes.mjs +94 -0
  80. package/examples/wallet-basics.mjs +61 -0
  81. package/generated/amino/amino.ts +9 -0
  82. package/generated/cosmos/base/v1beta1/coin.ts +365 -0
  83. package/generated/cosmos_proto/cosmos.ts +323 -0
  84. package/generated/gogoproto/gogo.ts +9 -0
  85. package/generated/google/protobuf/descriptor.ts +7601 -0
  86. package/generated/google/protobuf/duration.ts +208 -0
  87. package/generated/google/protobuf/timestamp.ts +238 -0
  88. package/generated/sentinel/lease/v1/events.ts +924 -0
  89. package/generated/sentinel/lease/v1/lease.ts +292 -0
  90. package/generated/sentinel/lease/v1/msg.ts +949 -0
  91. package/generated/sentinel/lease/v1/params.ts +164 -0
  92. package/generated/sentinel/node/v3/events.ts +881 -0
  93. package/generated/sentinel/node/v3/msg.ts +1002 -0
  94. package/generated/sentinel/node/v3/node.ts +263 -0
  95. package/generated/sentinel/node/v3/params.ts +183 -0
  96. package/generated/sentinel/plan/v3/events.ts +675 -0
  97. package/generated/sentinel/plan/v3/msg.ts +1191 -0
  98. package/generated/sentinel/plan/v3/plan.ts +283 -0
  99. package/generated/sentinel/provider/v2/events.ts +171 -0
  100. package/generated/sentinel/provider/v2/msg.ts +480 -0
  101. package/generated/sentinel/provider/v2/params.ts +131 -0
  102. package/generated/sentinel/provider/v2/provider.ts +246 -0
  103. package/generated/sentinel/session/v3/events.ts +480 -0
  104. package/generated/sentinel/session/v3/msg.ts +616 -0
  105. package/generated/sentinel/session/v3/params.ts +260 -0
  106. package/generated/sentinel/session/v3/proof.ts +180 -0
  107. package/generated/sentinel/session/v3/session.ts +384 -0
  108. package/generated/sentinel/subscription/v3/events.ts +1181 -0
  109. package/generated/sentinel/subscription/v3/msg.ts +1305 -0
  110. package/generated/sentinel/subscription/v3/params.ts +167 -0
  111. package/generated/sentinel/subscription/v3/subscription.ts +315 -0
  112. package/generated/sentinel/types/v1/bandwidth.ts +124 -0
  113. package/generated/sentinel/types/v1/price.ts +149 -0
  114. package/generated/sentinel/types/v1/renewal.ts +87 -0
  115. package/generated/sentinel/types/v1/status.ts +54 -0
  116. package/generated/typeRegistry.ts +27 -0
  117. package/index.js +486 -0
  118. package/node-connect.js +3015 -0
  119. package/operator.js +134 -0
  120. package/package.json +113 -0
  121. package/plan-operations.js +199 -0
  122. package/preflight.js +352 -0
  123. package/pricing/index.js +262 -0
  124. package/proto/amino/amino.proto +84 -0
  125. package/proto/cosmos/base/v1beta1/coin.proto +61 -0
  126. package/proto/cosmos_proto/cosmos.proto +112 -0
  127. package/proto/gogoproto/gogo.proto +145 -0
  128. package/proto/google/api/annotations.proto +31 -0
  129. package/proto/google/api/http.proto +370 -0
  130. package/proto/google/protobuf/any.proto +106 -0
  131. package/proto/google/protobuf/duration.proto +115 -0
  132. package/proto/google/protobuf/timestamp.proto +145 -0
  133. package/proto/sentinel/lease/v1/events.proto +52 -0
  134. package/proto/sentinel/lease/v1/genesis.proto +15 -0
  135. package/proto/sentinel/lease/v1/lease.proto +25 -0
  136. package/proto/sentinel/lease/v1/msg.proto +62 -0
  137. package/proto/sentinel/lease/v1/params.proto +17 -0
  138. package/proto/sentinel/node/v3/events.proto +50 -0
  139. package/proto/sentinel/node/v3/genesis.proto +15 -0
  140. package/proto/sentinel/node/v3/msg.proto +63 -0
  141. package/proto/sentinel/node/v3/node.proto +27 -0
  142. package/proto/sentinel/node/v3/params.proto +21 -0
  143. package/proto/sentinel/node/v3/querier.proto +63 -0
  144. package/proto/sentinel/plan/v3/events.proto +41 -0
  145. package/proto/sentinel/plan/v3/genesis.proto +21 -0
  146. package/proto/sentinel/plan/v3/msg.proto +83 -0
  147. package/proto/sentinel/plan/v3/plan.proto +32 -0
  148. package/proto/sentinel/plan/v3/querier.proto +53 -0
  149. package/proto/sentinel/provider/v2/events.proto +16 -0
  150. package/proto/sentinel/provider/v2/genesis.proto +15 -0
  151. package/proto/sentinel/provider/v2/msg.proto +35 -0
  152. package/proto/sentinel/provider/v2/params.proto +17 -0
  153. package/proto/sentinel/provider/v2/provider.proto +24 -0
  154. package/proto/sentinel/provider/v3/genesis.proto +15 -0
  155. package/proto/sentinel/provider/v3/params.proto +13 -0
  156. package/proto/sentinel/session/v3/events.proto +30 -0
  157. package/proto/sentinel/session/v3/genesis.proto +15 -0
  158. package/proto/sentinel/session/v3/msg.proto +50 -0
  159. package/proto/sentinel/session/v3/params.proto +25 -0
  160. package/proto/sentinel/session/v3/proof.proto +25 -0
  161. package/proto/sentinel/session/v3/querier.proto +100 -0
  162. package/proto/sentinel/session/v3/session.proto +50 -0
  163. package/proto/sentinel/subscription/v2/allocation.proto +21 -0
  164. package/proto/sentinel/subscription/v2/payout.proto +22 -0
  165. package/proto/sentinel/subscription/v3/events.proto +65 -0
  166. package/proto/sentinel/subscription/v3/genesis.proto +17 -0
  167. package/proto/sentinel/subscription/v3/msg.proto +83 -0
  168. package/proto/sentinel/subscription/v3/params.proto +21 -0
  169. package/proto/sentinel/subscription/v3/subscription.proto +33 -0
  170. package/proto/sentinel/types/v1/bandwidth.proto +19 -0
  171. package/proto/sentinel/types/v1/price.proto +21 -0
  172. package/proto/sentinel/types/v1/renewal.proto +21 -0
  173. package/proto/sentinel/types/v1/status.proto +16 -0
  174. package/protocol/encoding.js +341 -0
  175. package/protocol/events.js +361 -0
  176. package/protocol/handshake.js +297 -0
  177. package/protocol/index.js +15 -0
  178. package/protocol/messages.js +346 -0
  179. package/protocol/plans.js +199 -0
  180. package/protocol/v2ray.js +268 -0
  181. package/protocol/v3.js +723 -0
  182. package/protocol/wireguard.js +125 -0
  183. package/security/index.js +132 -0
  184. package/session-manager.js +329 -0
  185. package/session-tracker.js +80 -0
  186. package/setup.js +376 -0
  187. package/speedtest/index.js +528 -0
  188. package/speedtest.js +567 -0
  189. package/src/client.ts +502 -0
  190. package/src/index.ts +20 -0
  191. package/state/index.js +347 -0
  192. package/state.js +516 -0
  193. package/test-all-chain-ops.js +493 -0
  194. package/test-all-logic.js +199 -0
  195. package/test-all-msg-types.js +292 -0
  196. package/test-every-connection.js +208 -0
  197. package/test-feegrant-connect.js +98 -0
  198. package/test-logic.js +148 -0
  199. package/test-mainnet.js +176 -0
  200. package/test-plan-lifecycle.js +335 -0
  201. package/tls-trust.js +132 -0
  202. package/tsconfig.build.json +20 -0
  203. package/tsconfig.json +34 -0
  204. package/types/chain.d.ts +746 -0
  205. package/types/connection.d.ts +425 -0
  206. package/types/errors.d.ts +174 -0
  207. package/types/index.d.ts +1380 -0
  208. package/types/nodes.d.ts +187 -0
  209. package/types/pricing.d.ts +156 -0
  210. package/types/protocol.d.ts +332 -0
  211. package/types/session.d.ts +236 -0
  212. package/types/settings.d.ts +192 -0
  213. package/v3protocol.js +1053 -0
  214. package/wallet/index.js +153 -0
  215. package/wireguard.js +307 -0
@@ -0,0 +1,619 @@
1
+ # Sentinel AI Path — Operational Checklists
2
+
3
+ > **For AI agents.** Run these checklists programmatically before, during, and after VPN operations. Every check includes the exact code, expected result, and failure response. Assume the wallet has sufficient P2P for bandwidth consumption.
4
+
5
+ ---
6
+
7
+ ## How to Use
8
+
9
+ ```javascript
10
+ import {
11
+ setup, getEnvironment, createWallet, importWallet, getBalance,
12
+ discoverNodes, getNodeInfo, getNetworkStats,
13
+ estimateCost, PRICING, recommend,
14
+ connect, disconnect, status, isVpnActive, verify, onEvent,
15
+ } from './index.js'; // or 'sentinel-ai-connect' when published to npm
16
+ ```
17
+
18
+ Each checklist item has:
19
+ - **Check**: what to verify
20
+ - **Code**: exact call
21
+ - **Pass**: expected result
22
+ - **Fail**: what the failure means and what to do
23
+
24
+ Run all checks in order. Stop at the first `CRITICAL` failure. `WARNING` items can be bypassed with degraded capability.
25
+
26
+ ---
27
+
28
+ ## Checklist 1: Pre-Flight (Before Any Connection)
29
+
30
+ Run once per session. Verifies the machine can operate.
31
+
32
+ ### 1.1 Node.js Version
33
+
34
+ ```javascript
35
+ const [major] = process.versions.node.split('.').map(Number);
36
+ ```
37
+
38
+ | | |
39
+ |---|---|
40
+ | **Pass** | `major >= 20` |
41
+ | **Fail** | CRITICAL. Node.js 20+ required for stable ESM, `crypto.randomUUID`, and `AbortSignal.timeout`. Upgrade Node.js. |
42
+
43
+ ### 1.2 Environment Detection
44
+
45
+ ```javascript
46
+ const env = getEnvironment();
47
+ ```
48
+
49
+ | Check | Pass | Fail |
50
+ |-------|------|------|
51
+ | `env.v2ray.available` | `true` | WARNING. Run `setup()` to download V2Ray 5.2.1. Without V2Ray, only WireGuard nodes work. |
52
+ | `env.v2ray.version` | Starts with `'5.2'` | WARNING. V2Ray 5.44.1+ has observatory bugs that break VMess. Delete and redownload 5.2.1. |
53
+ | `env.wireguard.available` | `true` | WARNING. WireGuard not installed. Limited to V2Ray nodes (~70% of network). |
54
+ | `env.admin` | `true` | WARNING. Not admin. WireGuard tunnel installation will be blocked. V2Ray still works. |
55
+ | `env.capabilities.length` | `> 0` | CRITICAL. No tunnel protocol available. Install V2Ray or WireGuard before proceeding. |
56
+
57
+ ### 1.3 Full System Check
58
+
59
+ ```javascript
60
+ const check = await setup();
61
+ ```
62
+
63
+ | Check | Pass | Fail |
64
+ |-------|------|------|
65
+ | `check.ready` | `true` | See `check.issues` array for specific problems. |
66
+ | `check.issues.length` | `0` | Review each issue: `issue.severity`, `issue.message`, `issue.action`. Fix `error` severity items. `warning` items are non-blocking. |
67
+ | `check.preflight.ok` | `true` | Preflight found blockers. Check `check.preflight.issues` for details. |
68
+ | `check.preflight.ready.anyProtocol` | `true` | CRITICAL. Neither WireGuard nor V2Ray is operational. |
69
+
70
+ ### 1.4 Orphan Detection
71
+
72
+ ```javascript
73
+ const pf = check.preflight;
74
+ const orphans = pf.issues.filter(i => i.component === 'wireguard' && i.message.includes('orphan'));
75
+ const conflicts = pf.issues.filter(i => i.component === 'system');
76
+ ```
77
+
78
+ | Check | Pass | Fail |
79
+ |-------|------|------|
80
+ | `orphans.length` | `0` | WARNING. Leftover WireGuard tunnels from a previous crash. Run `setup()` with autoClean or manually uninstall: `wireguard.exe /uninstalltunnelservice wgsent0` |
81
+ | `conflicts.length` | `0` | WARNING. Conflicting VPN software detected (NordVPN, ExpressVPN, etc.). May interfere with tunnel routing. |
82
+
83
+ ### 1.5 Axios Adapter
84
+
85
+ ```javascript
86
+ const axios = (await import('axios')).default;
87
+ const adapterOk = axios.defaults.adapter === 'http';
88
+ if (!adapterOk) axios.defaults.adapter = 'http';
89
+ ```
90
+
91
+ | Check | Pass | Fail |
92
+ |-------|------|------|
93
+ | Adapter is `'http'` | `true` | Auto-fixed above. Without this, Node.js 20+ uses fetch adapter which silently fails on self-signed node certificates. The `connect()` function handles this automatically, but verify if making direct SDK calls. |
94
+
95
+ ---
96
+
97
+ ## Checklist 2: Wallet & Funding
98
+
99
+ Run before every connection attempt.
100
+
101
+ ### 2.1 Wallet Valid
102
+
103
+ ```javascript
104
+ const bal = await getBalance(process.env.MNEMONIC);
105
+ ```
106
+
107
+ | Check | Pass | Fail |
108
+ |-------|------|------|
109
+ | No exception thrown | Call succeeds | CRITICAL. If `INVALID_MNEMONIC`: check word count (must be 12 or 24), check for typos, verify BIP39 English wordlist. If network error: LCD endpoints may be down — retry in 30s. |
110
+ | `bal.address` starts with `'sent1'` | `true` | CRITICAL. Wrong address prefix means wrong chain derivation. |
111
+ | `bal.address.length >= 43 && bal.address.length <= 46` | `true` | CRITICAL. Malformed address — expected 43-46 characters. |
112
+
113
+ ### 2.2 Balance Sufficient
114
+
115
+ ```javascript
116
+ const { funded, udvpn, p2p } = bal;
117
+ ```
118
+
119
+ | Check | Pass | Fail |
120
+ |-------|------|------|
121
+ | `funded` | `true` | CRITICAL. Balance below 1.0 P2P. Fund wallet at `bal.address`. Prices vary — use `estimateCost()` to check if current balance covers at least one session. |
122
+ | `udvpn > 0` | `true` | CRITICAL. Wallet is empty. Send P2P tokens to `bal.address`. |
123
+
124
+ ### 2.3 Cost Estimation
125
+
126
+ ```javascript
127
+ const cost = await estimateCost({ gigabytes: 1 });
128
+ const canAfford = bal.udvpn >= cost.grandTotal.udvpn;
129
+ ```
130
+
131
+ | Check | Pass | Fail |
132
+ |-------|------|------|
133
+ | `canAfford` | `true` | CRITICAL. Balance `${bal.p2p}` insufficient for 1 GB session costing ~`${cost.grandTotal.p2p}`. Fund wallet with at least `${cost.grandTotal.p2p}`. |
134
+ | `cost.mode` | Any value returned | If exception: network issue querying node prices. Proceed with `funded: true` as a fallback estimate. |
135
+
136
+ ---
137
+
138
+ ## Checklist 3: Network Reachability
139
+
140
+ Run before connection to verify chain infrastructure is accessible.
141
+
142
+ ### 3.1 LCD Endpoint
143
+
144
+ ```javascript
145
+ const res = await fetch('https://lcd.sentinel.co/cosmos/bank/v1beta1/balances/' + bal.address, {
146
+ signal: AbortSignal.timeout(10000),
147
+ });
148
+ ```
149
+
150
+ | Check | Pass | Fail |
151
+ |-------|------|------|
152
+ | `res.ok` | `true` | WARNING. Primary LCD down. The SDK has 4 failover endpoints and handles this automatically. If all 4 fail, check your internet connection. |
153
+
154
+ ### 3.2 Node Discovery
155
+
156
+ ```javascript
157
+ const nodes = await discoverNodes({ quick: true });
158
+ ```
159
+
160
+ | Check | Pass | Fail |
161
+ |-------|------|------|
162
+ | `nodes.length > 0` | `true` | CRITICAL. Zero nodes returned. Chain may be down or LCD endpoints unreachable. Retry in 60s. |
163
+ | `nodes.length > 100` | `true` | WARNING. Unusually few nodes. Possible pagination issue or chain maintenance. Connection may still work. |
164
+
165
+ ### 3.3 Network Health
166
+
167
+ ```javascript
168
+ const stats = await getNetworkStats();
169
+ ```
170
+
171
+ | Check | Pass | Fail |
172
+ |-------|------|------|
173
+ | `stats.totalNodes > 0` | `true` | CRITICAL. Network appears empty. |
174
+ | `stats.byProtocol.v2ray > 0` or `stats.byProtocol.wireguard > 0` | At least one `> 0` | CRITICAL. No nodes available for any protocol. |
175
+
176
+ ---
177
+
178
+ ## Checklist 4: Connection
179
+
180
+ Run during the `connect()` call. Use `onProgress` to track each phase.
181
+
182
+ ### 4.1 Progress Monitoring
183
+
184
+ ```javascript
185
+ const phases = new Set();
186
+ let lastPhase = null;
187
+ let lastError = null;
188
+
189
+ const vpn = await connect({
190
+ mnemonic: process.env.MNEMONIC,
191
+ // fullTunnel: true (default) for privacy, or protocol: 'v2ray' for per-app split tunnel
192
+ onProgress: (step, detail) => {
193
+ phases.add(step);
194
+ lastPhase = step;
195
+ // Log for diagnostics: console.log(`[${step}] ${detail}`);
196
+ },
197
+ });
198
+ ```
199
+
200
+ ### 4.2 Phase Completion Verification
201
+
202
+ After `connect()` returns successfully, verify all critical phases were reached:
203
+
204
+ | Phase | Expected in `phases` | If Missing |
205
+ |-------|---------------------|------------|
206
+ | `'wallet'` | Yes | CRITICAL. Wallet derivation never started. Check mnemonic. |
207
+ | `'session'` | Yes | CRITICAL. Node selection or payment never started. Check balance, check node availability. |
208
+ | `'handshake'` | Yes | CRITICAL. Handshake phase never reached. Payment may have failed — check `lastError`. Session may exist on-chain (tokens spent). |
209
+ | `'tunnel'` | Yes | CRITICAL. Tunnel installation never started. Handshake may have failed. |
210
+ | `'verify'` | Yes | WARNING. Verification phase was skipped. Tunnel may still work — proceed to manual verification (Checklist 5). |
211
+
212
+ ### 4.3 Connect Result Validation
213
+
214
+ ```javascript
215
+ const { sessionId, protocol, nodeAddress, socksPort, ip } = vpn;
216
+ ```
217
+
218
+ | Check | Pass | Fail |
219
+ |-------|------|------|
220
+ | `sessionId` defined and non-empty | `true` | CRITICAL. No session ID means the blockchain TX may have failed. Check wallet balance — if it decreased, the session exists but ID extraction failed. |
221
+ | `protocol` is `'wireguard'` or `'v2ray'` | `true` | WARNING. Unknown protocol `'${protocol}'`. Connection may still work. |
222
+ | `nodeAddress` starts with `'sentnode1'` | `true` | WARNING. Node address missing or malformed. Connection may still work if sessionId is valid. |
223
+ | If V2Ray: `socksPort` is a number > 0 | `true` | WARNING. No SOCKS5 port. V2Ray may not be routing traffic. Verify manually. |
224
+ | `ip !== null` | `true` | WARNING. IP verification failed (ipify.org may be unreachable through this node). Tunnel may still work. Run Checklist 5 to confirm. |
225
+ | `ip !== yourOriginalIp` | `true` | WARNING. IP didn't change. Possible split tunnel mode or full tunnel not installed. May be expected if `fullTunnel: false`. |
226
+
227
+ ---
228
+
229
+ ## Checklist 5: Post-Connection Verification
230
+
231
+ Run immediately after `connect()` succeeds. Confirms the tunnel is actually working.
232
+
233
+ ### 5.1 Connection State
234
+
235
+ ```javascript
236
+ const active = isVpnActive();
237
+ const st = status();
238
+ ```
239
+
240
+ | Check | Pass | Fail |
241
+ |-------|------|------|
242
+ | `active` | `true` | CRITICAL. `isVpnActive()` returns false immediately after connect. Tunnel may have collapsed. Disconnect and retry with a different node. |
243
+ | `st.connected` | `true` | CRITICAL. Same as above — status shows disconnected. |
244
+ | `st.sessionId` matches `vpn.sessionId` | `true` | WARNING. Session ID mismatch. State may be stale. |
245
+ | `st.protocol` matches `vpn.protocol` | `true` | WARNING. Protocol mismatch. Likely a state tracking issue — tunnel may still work. |
246
+
247
+ ### 5.2 Traffic Verification
248
+
249
+ ```javascript
250
+ const v = await verify();
251
+ ```
252
+
253
+ | Check | Pass | Fail |
254
+ |-------|------|------|
255
+ | `v.connected` | `true` | CRITICAL. Tunnel down during verification. |
256
+ | `v.verified` | `true` | CRITICAL. Cannot confirm traffic flows through the tunnel. The tunnel may be installed but not routing. Disconnect and try a different node. |
257
+ | `v.ip !== null` | `true` | WARNING. IP check failed but `verified` may still be true from SDK verification. If both `ip === null` and `verified === false`, the tunnel is dead. |
258
+
259
+ ### 5.3 Data Transfer Test
260
+
261
+ ```javascript
262
+ let testRes;
263
+ if (vpn.socksPort) {
264
+ // V2Ray: test through SOCKS5 proxy
265
+ const axios = (await import('axios')).default;
266
+ const { SocksProxyAgent } = await import('socks-proxy-agent');
267
+ const agent = new SocksProxyAgent(`socks5h://127.0.0.1:${vpn.socksPort}`);
268
+ testRes = await axios.get('https://api.ipify.org?format=json', {
269
+ httpAgent: agent, httpsAgent: agent, timeout: 15000, adapter: 'http',
270
+ });
271
+ } else {
272
+ // WireGuard: traffic routes automatically through the tunnel
273
+ const axios = (await import('axios')).default;
274
+ testRes = await axios.get('https://api.ipify.org?format=json', {
275
+ timeout: 15000, adapter: 'http',
276
+ });
277
+ }
278
+ ```
279
+
280
+ | Check | Pass | Fail |
281
+ |-------|------|------|
282
+ | Response received within timeout | `true` | WARNING. Tunnel may be slow or congested. Increase timeout to 30s and retry once. If still fails, try a different node. |
283
+ | `testRes.data.ip` is not your real IP | `true` | CRITICAL (WireGuard full tunnel). Traffic is not routing through the VPN. NORMAL (V2Ray split tunnel) — only SOCKS5-proxied traffic routes through the tunnel. |
284
+ | `testRes.status === 200` | `true` | WARNING. Non-200 response. The test endpoint may be down. Try `https://ifconfig.me` as fallback. |
285
+
286
+ ### 5.4 DNS Leak Check
287
+
288
+ ```javascript
289
+ // Verify DNS resolves through the tunnel, not your ISP
290
+ const dnsRes = await axios.get('https://1.1.1.1/cdn-cgi/trace', {
291
+ httpAgent: agent, httpsAgent: agent, timeout: 10000, adapter: 'http', // V2Ray
292
+ // For WireGuard: omit agents, DNS is enforced by tunnel config
293
+ });
294
+ ```
295
+
296
+ | Check | Pass | Fail |
297
+ |-------|------|------|
298
+ | Response received | `true` | WARNING. Cloudflare trace endpoint unreachable. DNS may still be correct — this is a secondary check. |
299
+ | Response does not contain your real ISP IP | `true` | WARNING. Possible DNS leak. If using WireGuard, check that `DNS = 10.8.0.1` is in the config. If using V2Ray, verify SOCKS5 proxy is routing DNS queries. |
300
+
301
+ ---
302
+
303
+ ## Checklist 6: Runtime Health Monitoring
304
+
305
+ Run periodically while connected (every 30-60 seconds).
306
+
307
+ ### 6.1 Connection Still Active
308
+
309
+ ```javascript
310
+ const alive = isVpnActive();
311
+ const st = status();
312
+ ```
313
+
314
+ | Check | Pass | Fail |
315
+ |-------|------|------|
316
+ | `alive` | `true` | CRITICAL. Connection lost. Begin reconnection (Checklist 8). |
317
+ | `st.connected` | `true` | CRITICAL. Same — status shows disconnected. |
318
+ | `st.uptimeMs > previousUptimeMs` | `true` | WARNING. Uptime not advancing. State may be stale. Verify with `verify()`. |
319
+
320
+ ### 6.2 Traffic Still Flows
321
+
322
+ ```javascript
323
+ const v = await verify();
324
+ ```
325
+
326
+ | Check | Pass | Fail |
327
+ |-------|------|------|
328
+ | `v.verified` | `true` | CRITICAL. Tunnel is up but traffic has stopped flowing. Disconnect and reconnect. |
329
+ | Time since last successful verify < 120s | `true` | WARNING. Verification hasn't succeeded in 2+ minutes. Network may be degrading. |
330
+
331
+ ### 6.3 Balance Monitor (Every 5 Minutes)
332
+
333
+ ```javascript
334
+ const bal = await getBalance(process.env.MNEMONIC);
335
+ ```
336
+
337
+ | Check | Pass | Fail |
338
+ |-------|------|------|
339
+ | `bal.funded` | `true` | WARNING. Balance dropping below threshold. Plan for disconnection or top-up. Session continues until data allocation is consumed, but new sessions cannot be created. |
340
+ | `bal.udvpn > previousBalance - expectedConsumption` | `true` | INFO. Track spend rate. If balance is dropping faster than expected, session may have an issue. |
341
+
342
+ ---
343
+
344
+ ## Checklist 7: Disconnection
345
+
346
+ Run when work is complete or on shutdown.
347
+
348
+ ### 7.1 Graceful Disconnect
349
+
350
+ ```javascript
351
+ const result = await disconnect();
352
+ ```
353
+
354
+ | Check | Pass | Fail |
355
+ |-------|------|------|
356
+ | `result.disconnected` | `true` | WARNING. Disconnect reported failure, but tunnel is likely down. Proceed to verification. |
357
+ | No exception thrown | `true` | WARNING. Best-effort — the tunnel was probably torn down. Continue to post-disconnect verification. |
358
+
359
+ ### 7.2 Post-Disconnect Verification
360
+
361
+ ```javascript
362
+ const active = isVpnActive();
363
+ const st = status();
364
+ ```
365
+
366
+ | Check | Pass | Fail |
367
+ |-------|------|------|
368
+ | `active` | `false` | CRITICAL. Tunnel still active after disconnect. Orphaned tunnel. Attempt: `await disconnect()` again. If still active, escalate to manual cleanup (7.3). |
369
+ | `st.connected` | `false` | CRITICAL. Same — state still shows connected. |
370
+
371
+ ### 7.3 Orphan Cleanup (If 7.2 Fails)
372
+
373
+ ```javascript
374
+ import { emergencyCleanupSync } from 'sentinel-dvpn-sdk';
375
+ emergencyCleanupSync();
376
+ ```
377
+
378
+ | Check | Pass | Fail |
379
+ |-------|------|------|
380
+ | After cleanup: `isVpnActive() === false` | `true` | CRITICAL. Orphaned tunnel survived emergency cleanup. Manual intervention required: `wireguard.exe /uninstalltunnelservice wgsent0` (WireGuard) or kill V2Ray process by PID (NOT `taskkill /F /IM node.exe` — that kills your own process). |
381
+
382
+ ### 7.4 System State Clean
383
+
384
+ ```javascript
385
+ // Verify no system proxy left behind (V2Ray)
386
+ // On Windows, check registry or run:
387
+ // netsh winhttp show proxy
388
+ ```
389
+
390
+ | Check | Pass | Fail |
391
+ |-------|------|------|
392
+ | No system proxy pointing to dead SOCKS5 port | `true` | WARNING. Orphaned system proxy will break system HTTP traffic. Clear it: `netsh winhttp reset proxy` |
393
+
394
+ ---
395
+
396
+ ## Checklist 8: Error Recovery
397
+
398
+ Run when any connection attempt fails or when runtime health check fails.
399
+
400
+ ### 8.1 Classify the Error
401
+
402
+ ```javascript
403
+ try {
404
+ await connect(opts);
405
+ } catch (err) {
406
+ const code = err.code || 'UNKNOWN';
407
+ const msg = err.message;
408
+ }
409
+ ```
410
+
411
+ | Error Code | Severity | Recovery Action |
412
+ |------------|----------|----------------|
413
+ | `INVALID_MNEMONIC` | Fatal | Fix mnemonic. Do not retry. |
414
+ | `INSUFFICIENT_BALANCE` | Fatal | Fund wallet. Do not retry until funded. |
415
+ | `ALREADY_CONNECTED` | Fatal | Call `disconnect()` first, then retry. |
416
+ | `ABORTED` | Fatal | Timeout or cancellation. Increase `timeout` or check network. |
417
+ | `SESSION_POISONED` | Fatal | Previous session is corrupted. Do not reuse. Fresh connection needed. |
418
+ | `NODE_OFFLINE` | Retryable | Try a different node. |
419
+ | `NODE_CLOCK_DRIFT` | Retryable | Skip this node. Try another. |
420
+ | `V2RAY_ALL_FAILED` | Retryable | All transports failed. Try a WireGuard node or different V2Ray node. |
421
+ | `WG_NO_CONNECTIVITY` | Retryable | Tunnel installed but dead. Try a different node. |
422
+ | `BROADCAST_FAILED` | Retryable | Chain TX failed. Wait 30s, retry. |
423
+ | `ALL_NODES_FAILED` | Retryable | Every candidate failed. Wait 60s, retry with different country or protocol. |
424
+ | `ALL_ENDPOINTS_FAILED` | Retryable | LCD/RPC all down. Check internet. Wait 60s, retry. |
425
+ | `V2RAY_NOT_FOUND` | Setup | Run `setup()` to install V2Ray binary. |
426
+ | `WG_NOT_AVAILABLE` | Setup | Install WireGuard or retry with `protocol: 'v2ray'`. |
427
+ | `SESSION_EXISTS` | Recoverable | Active session found. SDK reuses it automatically. If it keeps failing, wait for session expiry. |
428
+ | `PARTIAL_CONNECTION_FAILED` | Recoverable | Payment succeeded but tunnel failed. Session exists on-chain. Retry connection to same node — session will be reused (no double payment). |
429
+
430
+ ### 8.2 Retry Strategy
431
+
432
+ ```javascript
433
+ const MAX_RETRIES = 3;
434
+ const BACKOFF = [5000, 10000, 20000]; // ms
435
+
436
+ for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
437
+ try {
438
+ const vpn = await connect(opts);
439
+ // Run Checklist 4 + 5
440
+ break; // Success
441
+ } catch (err) {
442
+ if (['INVALID_MNEMONIC', 'INSUFFICIENT_BALANCE', 'ABORTED'].includes(err.code)) {
443
+ throw err; // Fatal — do not retry
444
+ }
445
+ if (attempt < MAX_RETRIES - 1) {
446
+ await new Promise(r => setTimeout(r, BACKOFF[attempt]));
447
+ } else {
448
+ throw err; // Exhausted retries
449
+ }
450
+ }
451
+ }
452
+ ```
453
+
454
+ ### 8.3 Post-Failure Cleanup
455
+
456
+ After any failed connection attempt:
457
+
458
+ ```javascript
459
+ // Always verify no orphaned state
460
+ try { await disconnect(); } catch { /* best effort */ }
461
+ const stillActive = isVpnActive();
462
+ if (stillActive) {
463
+ const { emergencyCleanupSync } = await import('sentinel-dvpn-sdk');
464
+ emergencyCleanupSync();
465
+ }
466
+ ```
467
+
468
+ | Check | Pass | Fail |
469
+ |-------|------|------|
470
+ | `isVpnActive() === false` after cleanup | `true` | Orphaned tunnel exists. See Checklist 7.3. |
471
+
472
+ ---
473
+
474
+ ## Checklist 9: Full End-to-End Validation
475
+
476
+ Run this as a single script to verify the entire pipeline works. This is the definitive test.
477
+
478
+ ```javascript
479
+ // Load mnemonic from .env (use dotenv or manual parsing)
480
+ // import 'dotenv/config'; // Requires: npm install dotenv
481
+ import {
482
+ setup, getEnvironment, getBalance, estimateCost, recommend,
483
+ connect, disconnect, status, isVpnActive, verify,
484
+ } from './index.js'; // or 'sentinel-ai-connect' when published to npm
485
+
486
+ const results = {
487
+ preflight: false,
488
+ wallet: false,
489
+ balance: false,
490
+ costEstimate: false,
491
+ recommendation: false,
492
+ connection: false,
493
+ stateConsistent: false,
494
+ trafficVerified: false,
495
+ disconnection: false,
496
+ cleanState: false,
497
+ };
498
+
499
+ try {
500
+ // ── Preflight ──
501
+ const env = getEnvironment();
502
+ if (env.capabilities.length === 0) throw new Error('No tunnel protocol available');
503
+ const check = await setup();
504
+ if (!check.ready) throw new Error(`Setup issues: ${check.issues.join(', ')}`);
505
+ results.preflight = true;
506
+
507
+ // ── Wallet ──
508
+ const bal = await getBalance(process.env.MNEMONIC);
509
+ if (!bal.address.startsWith('sent1')) throw new Error('Bad address');
510
+ results.wallet = true;
511
+
512
+ // ── Balance ──
513
+ if (!bal.funded) throw new Error(`Underfunded: ${bal.p2p}`);
514
+ results.balance = true;
515
+
516
+ // ── Cost Estimate ──
517
+ const cost = await estimateCost({ gigabytes: 1 });
518
+ if (bal.udvpn < cost.grandTotal.udvpn) throw new Error(`Need ${cost.grandTotal.p2p}, have ${bal.p2p}`);
519
+ results.costEstimate = true;
520
+
521
+ // ── Recommendation ──
522
+ const rec = await recommend({ priority: 'reliability' });
523
+ if (rec.action === 'cannot-connect') throw new Error('No nodes available');
524
+ results.recommendation = true;
525
+
526
+ // ── Connection ──
527
+ const phases = new Set();
528
+ const vpn = await connect({
529
+ mnemonic: process.env.MNEMONIC,
530
+ fullTunnel: false,
531
+ onProgress: (step) => phases.add(step),
532
+ timeout: 120000,
533
+ });
534
+ if (!vpn.sessionId) throw new Error('No session ID');
535
+ if (!phases.has('wallet')) throw new Error('Wallet phase missing');
536
+ if (!phases.has('session')) throw new Error('Session phase missing');
537
+ if (!phases.has('handshake')) throw new Error('Handshake phase missing');
538
+ if (!phases.has('tunnel')) throw new Error('Tunnel phase missing');
539
+ results.connection = true;
540
+
541
+ // ── State Consistency ──
542
+ const st = status();
543
+ if (!st.connected) throw new Error('Status says disconnected after connect');
544
+ if (!isVpnActive()) throw new Error('isVpnActive false after connect');
545
+ if (st.sessionId !== vpn.sessionId) throw new Error('Session ID mismatch');
546
+ results.stateConsistent = true;
547
+
548
+ // ── Traffic Verification ──
549
+ const v = await verify();
550
+ if (!v.verified) throw new Error('Traffic verification failed');
551
+ results.trafficVerified = true;
552
+
553
+ // ── Disconnection ──
554
+ await disconnect();
555
+ results.disconnection = true;
556
+
557
+ // ── Clean State ──
558
+ if (isVpnActive()) throw new Error('Still active after disconnect');
559
+ if (status().connected) throw new Error('Status still connected after disconnect');
560
+ results.cleanState = true;
561
+
562
+ } catch (err) {
563
+ console.error(`FAILED: ${err.message} (code: ${err.code || 'none'})`);
564
+ } finally {
565
+ // Ensure cleanup even on failure
566
+ try { await disconnect(); } catch {}
567
+ }
568
+
569
+ // ── Report ──
570
+ console.log('\n═══ End-to-End Checklist Results ═══');
571
+ const entries = Object.entries(results);
572
+ const passed = entries.filter(([, v]) => v).length;
573
+ const total = entries.length;
574
+
575
+ for (const [name, ok] of entries) {
576
+ console.log(` ${ok ? 'PASS' : 'FAIL'} ${name}`);
577
+ }
578
+
579
+ console.log(`\n ${passed}/${total} checks passed.`);
580
+ if (passed === total) {
581
+ console.log(' All systems operational. AI Path is fully functional.');
582
+ } else {
583
+ const firstFail = entries.find(([, v]) => !v)?.[0];
584
+ console.log(` First failure: ${firstFail}. Fix this before retrying.`);
585
+ }
586
+ ```
587
+
588
+ ### Expected Output (All Pass)
589
+
590
+ ```
591
+ ═══ End-to-End Checklist Results ═══
592
+ PASS preflight
593
+ PASS wallet
594
+ PASS balance
595
+ PASS costEstimate
596
+ PASS recommendation
597
+ PASS connection
598
+ PASS stateConsistent
599
+ PASS trafficVerified
600
+ PASS disconnection
601
+ PASS cleanState
602
+
603
+ 10/10 checks passed.
604
+ All systems operational. AI Path is fully functional.
605
+ ```
606
+
607
+ ---
608
+
609
+ ## Quick Reference: Which Checklist When
610
+
611
+ | Situation | Run |
612
+ |-----------|-----|
613
+ | First time using AI Path | Checklist 1 (preflight) → 2 (wallet) → 3 (network) → 9 (full E2E) |
614
+ | Before each connection | Checklist 2.2 (balance) → 4 (connection) → 5 (post-connect) |
615
+ | While connected (every 30-60s) | Checklist 6 (health) |
616
+ | Connection fails | Checklist 8 (error recovery) |
617
+ | Shutting down | Checklist 7 (disconnection) |
618
+ | After crash or unexpected restart | Checklist 1.4 (orphan detection) → 7.3 (orphan cleanup) |
619
+ | Validating a new environment | Checklist 9 (full E2E) |