@antseed/node 0.1.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 (443) hide show
  1. package/README.md +411 -0
  2. package/contracts/AntseedEscrow.sol +310 -0
  3. package/contracts/MockUSDC.sol +64 -0
  4. package/contracts/README.md +102 -0
  5. package/dist/config/encryption.d.ts +17 -0
  6. package/dist/config/encryption.d.ts.map +1 -0
  7. package/dist/config/encryption.js +49 -0
  8. package/dist/config/encryption.js.map +1 -0
  9. package/dist/config/plugin-config-manager.d.ts +31 -0
  10. package/dist/config/plugin-config-manager.d.ts.map +1 -0
  11. package/dist/config/plugin-config-manager.js +135 -0
  12. package/dist/config/plugin-config-manager.js.map +1 -0
  13. package/dist/config/plugin-loader.d.ts +25 -0
  14. package/dist/config/plugin-loader.d.ts.map +1 -0
  15. package/dist/config/plugin-loader.js +64 -0
  16. package/dist/config/plugin-loader.js.map +1 -0
  17. package/dist/discovery/announcer.d.ts +44 -0
  18. package/dist/discovery/announcer.d.ts.map +1 -0
  19. package/dist/discovery/announcer.js +129 -0
  20. package/dist/discovery/announcer.js.map +1 -0
  21. package/dist/discovery/bootstrap.d.ts +13 -0
  22. package/dist/discovery/bootstrap.d.ts.map +1 -0
  23. package/dist/discovery/bootstrap.js +39 -0
  24. package/dist/discovery/bootstrap.js.map +1 -0
  25. package/dist/discovery/default-metadata-resolver.d.ts +16 -0
  26. package/dist/discovery/default-metadata-resolver.d.ts.map +1 -0
  27. package/dist/discovery/default-metadata-resolver.js +16 -0
  28. package/dist/discovery/default-metadata-resolver.js.map +1 -0
  29. package/dist/discovery/dht-health.d.ts +38 -0
  30. package/dist/discovery/dht-health.d.ts.map +1 -0
  31. package/dist/discovery/dht-health.js +101 -0
  32. package/dist/discovery/dht-health.js.map +1 -0
  33. package/dist/discovery/dht-node.d.ts +34 -0
  34. package/dist/discovery/dht-node.d.ts.map +1 -0
  35. package/dist/discovery/dht-node.js +168 -0
  36. package/dist/discovery/dht-node.js.map +1 -0
  37. package/dist/discovery/http-metadata-resolver.d.ts +15 -0
  38. package/dist/discovery/http-metadata-resolver.d.ts.map +1 -0
  39. package/dist/discovery/http-metadata-resolver.js +33 -0
  40. package/dist/discovery/http-metadata-resolver.js.map +1 -0
  41. package/dist/discovery/index.d.ts +16 -0
  42. package/dist/discovery/index.d.ts.map +1 -0
  43. package/dist/discovery/index.js +15 -0
  44. package/dist/discovery/index.js.map +1 -0
  45. package/dist/discovery/metadata-codec.d.ts +22 -0
  46. package/dist/discovery/metadata-codec.d.ts.map +1 -0
  47. package/dist/discovery/metadata-codec.js +390 -0
  48. package/dist/discovery/metadata-codec.js.map +1 -0
  49. package/dist/discovery/metadata-resolver.d.ts +9 -0
  50. package/dist/discovery/metadata-resolver.d.ts.map +1 -0
  51. package/dist/discovery/metadata-resolver.js +2 -0
  52. package/dist/discovery/metadata-resolver.js.map +1 -0
  53. package/dist/discovery/metadata-server.d.ts +16 -0
  54. package/dist/discovery/metadata-server.d.ts.map +1 -0
  55. package/dist/discovery/metadata-server.js +59 -0
  56. package/dist/discovery/metadata-server.js.map +1 -0
  57. package/dist/discovery/metadata-validator.d.ts +12 -0
  58. package/dist/discovery/metadata-validator.d.ts.map +1 -0
  59. package/dist/discovery/metadata-validator.js +153 -0
  60. package/dist/discovery/metadata-validator.js.map +1 -0
  61. package/dist/discovery/peer-lookup.d.ts +26 -0
  62. package/dist/discovery/peer-lookup.d.ts.map +1 -0
  63. package/dist/discovery/peer-lookup.js +86 -0
  64. package/dist/discovery/peer-lookup.js.map +1 -0
  65. package/dist/discovery/peer-metadata.d.ts +31 -0
  66. package/dist/discovery/peer-metadata.d.ts.map +1 -0
  67. package/dist/discovery/peer-metadata.js +2 -0
  68. package/dist/discovery/peer-metadata.js.map +1 -0
  69. package/dist/discovery/peer-selector.d.ts +33 -0
  70. package/dist/discovery/peer-selector.d.ts.map +1 -0
  71. package/dist/discovery/peer-selector.js +80 -0
  72. package/dist/discovery/peer-selector.js.map +1 -0
  73. package/dist/discovery/profile-manager.d.ts +50 -0
  74. package/dist/discovery/profile-manager.d.ts.map +1 -0
  75. package/dist/discovery/profile-manager.js +105 -0
  76. package/dist/discovery/profile-manager.js.map +1 -0
  77. package/dist/discovery/profile-search.d.ts +27 -0
  78. package/dist/discovery/profile-search.d.ts.map +1 -0
  79. package/dist/discovery/profile-search.js +75 -0
  80. package/dist/discovery/profile-search.js.map +1 -0
  81. package/dist/discovery/reputation-verifier.d.ts +25 -0
  82. package/dist/discovery/reputation-verifier.d.ts.map +1 -0
  83. package/dist/discovery/reputation-verifier.js +27 -0
  84. package/dist/discovery/reputation-verifier.js.map +1 -0
  85. package/dist/index.d.ts +37 -0
  86. package/dist/index.d.ts.map +1 -0
  87. package/dist/index.js +32 -0
  88. package/dist/index.js.map +1 -0
  89. package/dist/interfaces/buyer-router.d.ts +21 -0
  90. package/dist/interfaces/buyer-router.d.ts.map +1 -0
  91. package/dist/interfaces/buyer-router.js +2 -0
  92. package/dist/interfaces/buyer-router.js.map +1 -0
  93. package/dist/interfaces/plugin.d.ts +31 -0
  94. package/dist/interfaces/plugin.d.ts.map +1 -0
  95. package/dist/interfaces/plugin.js +2 -0
  96. package/dist/interfaces/plugin.js.map +1 -0
  97. package/dist/interfaces/seller-provider.d.ts +69 -0
  98. package/dist/interfaces/seller-provider.d.ts.map +1 -0
  99. package/dist/interfaces/seller-provider.js +2 -0
  100. package/dist/interfaces/seller-provider.js.map +1 -0
  101. package/dist/metering/index.d.ts +7 -0
  102. package/dist/metering/index.d.ts.map +1 -0
  103. package/dist/metering/index.js +7 -0
  104. package/dist/metering/index.js.map +1 -0
  105. package/dist/metering/receipt-generator.d.ts +49 -0
  106. package/dist/metering/receipt-generator.d.ts.map +1 -0
  107. package/dist/metering/receipt-generator.js +74 -0
  108. package/dist/metering/receipt-generator.js.map +1 -0
  109. package/dist/metering/receipt-verifier.d.ts +52 -0
  110. package/dist/metering/receipt-verifier.d.ts.map +1 -0
  111. package/dist/metering/receipt-verifier.js +63 -0
  112. package/dist/metering/receipt-verifier.js.map +1 -0
  113. package/dist/metering/session-tracker.d.ts +59 -0
  114. package/dist/metering/session-tracker.d.ts.map +1 -0
  115. package/dist/metering/session-tracker.js +119 -0
  116. package/dist/metering/session-tracker.js.map +1 -0
  117. package/dist/metering/storage.d.ts +72 -0
  118. package/dist/metering/storage.d.ts.map +1 -0
  119. package/dist/metering/storage.js +446 -0
  120. package/dist/metering/storage.js.map +1 -0
  121. package/dist/metering/token-counter.d.ts +50 -0
  122. package/dist/metering/token-counter.d.ts.map +1 -0
  123. package/dist/metering/token-counter.js +96 -0
  124. package/dist/metering/token-counter.js.map +1 -0
  125. package/dist/metering/usage-aggregator.d.ts +46 -0
  126. package/dist/metering/usage-aggregator.d.ts.map +1 -0
  127. package/dist/metering/usage-aggregator.js +170 -0
  128. package/dist/metering/usage-aggregator.js.map +1 -0
  129. package/dist/node.d.ts +179 -0
  130. package/dist/node.d.ts.map +1 -0
  131. package/dist/node.js +1328 -0
  132. package/dist/node.js.map +1 -0
  133. package/dist/p2p/connection-auth.d.ts +35 -0
  134. package/dist/p2p/connection-auth.d.ts.map +1 -0
  135. package/dist/p2p/connection-auth.js +102 -0
  136. package/dist/p2p/connection-auth.js.map +1 -0
  137. package/dist/p2p/connection-manager.d.ts +101 -0
  138. package/dist/p2p/connection-manager.d.ts.map +1 -0
  139. package/dist/p2p/connection-manager.js +726 -0
  140. package/dist/p2p/connection-manager.js.map +1 -0
  141. package/dist/p2p/handshake.d.ts +47 -0
  142. package/dist/p2p/handshake.d.ts.map +1 -0
  143. package/dist/p2p/handshake.js +107 -0
  144. package/dist/p2p/handshake.js.map +1 -0
  145. package/dist/p2p/ice-config.d.ts +27 -0
  146. package/dist/p2p/ice-config.d.ts.map +1 -0
  147. package/dist/p2p/ice-config.js +43 -0
  148. package/dist/p2p/ice-config.js.map +1 -0
  149. package/dist/p2p/identity.d.ts +27 -0
  150. package/dist/p2p/identity.d.ts.map +1 -0
  151. package/dist/p2p/identity.js +76 -0
  152. package/dist/p2p/identity.js.map +1 -0
  153. package/dist/p2p/index.d.ts +12 -0
  154. package/dist/p2p/index.d.ts.map +1 -0
  155. package/dist/p2p/index.js +11 -0
  156. package/dist/p2p/index.js.map +1 -0
  157. package/dist/p2p/keepalive.d.ts +49 -0
  158. package/dist/p2p/keepalive.d.ts.map +1 -0
  159. package/dist/p2p/keepalive.js +93 -0
  160. package/dist/p2p/keepalive.js.map +1 -0
  161. package/dist/p2p/message-protocol.d.ts +50 -0
  162. package/dist/p2p/message-protocol.d.ts.map +1 -0
  163. package/dist/p2p/message-protocol.js +134 -0
  164. package/dist/p2p/message-protocol.js.map +1 -0
  165. package/dist/p2p/nat-traversal.d.ts +51 -0
  166. package/dist/p2p/nat-traversal.d.ts.map +1 -0
  167. package/dist/p2p/nat-traversal.js +135 -0
  168. package/dist/p2p/nat-traversal.js.map +1 -0
  169. package/dist/p2p/payment-codec.d.ts +20 -0
  170. package/dist/p2p/payment-codec.d.ts.map +1 -0
  171. package/dist/p2p/payment-codec.js +130 -0
  172. package/dist/p2p/payment-codec.js.map +1 -0
  173. package/dist/p2p/payment-mux.d.ts +49 -0
  174. package/dist/p2p/payment-mux.d.ts.map +1 -0
  175. package/dist/p2p/payment-mux.js +131 -0
  176. package/dist/p2p/payment-mux.js.map +1 -0
  177. package/dist/p2p/reconnect.d.ts +48 -0
  178. package/dist/p2p/reconnect.d.ts.map +1 -0
  179. package/dist/p2p/reconnect.js +89 -0
  180. package/dist/p2p/reconnect.js.map +1 -0
  181. package/dist/payments/balance-manager.d.ts +17 -0
  182. package/dist/payments/balance-manager.d.ts.map +1 -0
  183. package/dist/payments/balance-manager.js +54 -0
  184. package/dist/payments/balance-manager.js.map +1 -0
  185. package/dist/payments/buyer-payment-manager.d.ts +122 -0
  186. package/dist/payments/buyer-payment-manager.d.ts.map +1 -0
  187. package/dist/payments/buyer-payment-manager.js +280 -0
  188. package/dist/payments/buyer-payment-manager.js.map +1 -0
  189. package/dist/payments/disputes.d.ts +18 -0
  190. package/dist/payments/disputes.d.ts.map +1 -0
  191. package/dist/payments/disputes.js +47 -0
  192. package/dist/payments/disputes.js.map +1 -0
  193. package/dist/payments/evm/escrow-client.d.ts +61 -0
  194. package/dist/payments/evm/escrow-client.d.ts.map +1 -0
  195. package/dist/payments/evm/escrow-client.js +170 -0
  196. package/dist/payments/evm/escrow-client.js.map +1 -0
  197. package/dist/payments/evm/keypair.d.ts +21 -0
  198. package/dist/payments/evm/keypair.d.ts.map +1 -0
  199. package/dist/payments/evm/keypair.js +29 -0
  200. package/dist/payments/evm/keypair.js.map +1 -0
  201. package/dist/payments/evm/signatures.d.ts +11 -0
  202. package/dist/payments/evm/signatures.d.ts.map +1 -0
  203. package/dist/payments/evm/signatures.js +56 -0
  204. package/dist/payments/evm/signatures.js.map +1 -0
  205. package/dist/payments/evm/wallet.d.ts +5 -0
  206. package/dist/payments/evm/wallet.d.ts.map +1 -0
  207. package/dist/payments/evm/wallet.js +31 -0
  208. package/dist/payments/evm/wallet.js.map +1 -0
  209. package/dist/payments/index.d.ts +13 -0
  210. package/dist/payments/index.d.ts.map +1 -0
  211. package/dist/payments/index.js +14 -0
  212. package/dist/payments/index.js.map +1 -0
  213. package/dist/payments/settlement.d.ts +6 -0
  214. package/dist/payments/settlement.d.ts.map +1 -0
  215. package/dist/payments/settlement.js +25 -0
  216. package/dist/payments/settlement.js.map +1 -0
  217. package/dist/payments/types.d.ts +66 -0
  218. package/dist/payments/types.d.ts.map +1 -0
  219. package/dist/payments/types.js +2 -0
  220. package/dist/payments/types.js.map +1 -0
  221. package/dist/proxy/index.d.ts +4 -0
  222. package/dist/proxy/index.d.ts.map +1 -0
  223. package/dist/proxy/index.js +4 -0
  224. package/dist/proxy/index.js.map +1 -0
  225. package/dist/proxy/provider-detection.d.ts +20 -0
  226. package/dist/proxy/provider-detection.d.ts.map +1 -0
  227. package/dist/proxy/provider-detection.js +61 -0
  228. package/dist/proxy/provider-detection.js.map +1 -0
  229. package/dist/proxy/proxy-mux.d.ts +35 -0
  230. package/dist/proxy/proxy-mux.d.ts.map +1 -0
  231. package/dist/proxy/proxy-mux.js +137 -0
  232. package/dist/proxy/proxy-mux.js.map +1 -0
  233. package/dist/proxy/request-codec.d.ts +33 -0
  234. package/dist/proxy/request-codec.d.ts.map +1 -0
  235. package/dist/proxy/request-codec.js +238 -0
  236. package/dist/proxy/request-codec.js.map +1 -0
  237. package/dist/reputation/index.d.ts +7 -0
  238. package/dist/reputation/index.d.ts.map +1 -0
  239. package/dist/reputation/index.js +6 -0
  240. package/dist/reputation/index.js.map +1 -0
  241. package/dist/reputation/rating-manager.d.ts +20 -0
  242. package/dist/reputation/rating-manager.d.ts.map +1 -0
  243. package/dist/reputation/rating-manager.js +91 -0
  244. package/dist/reputation/rating-manager.js.map +1 -0
  245. package/dist/reputation/report-manager.d.ts +21 -0
  246. package/dist/reputation/report-manager.d.ts.map +1 -0
  247. package/dist/reputation/report-manager.js +70 -0
  248. package/dist/reputation/report-manager.js.map +1 -0
  249. package/dist/reputation/trust-engine.d.ts +36 -0
  250. package/dist/reputation/trust-engine.d.ts.map +1 -0
  251. package/dist/reputation/trust-engine.js +95 -0
  252. package/dist/reputation/trust-engine.js.map +1 -0
  253. package/dist/reputation/trust-score.d.ts +43 -0
  254. package/dist/reputation/trust-score.d.ts.map +1 -0
  255. package/dist/reputation/trust-score.js +34 -0
  256. package/dist/reputation/trust-score.js.map +1 -0
  257. package/dist/reputation/uptime-tracker.d.ts +51 -0
  258. package/dist/reputation/uptime-tracker.d.ts.map +1 -0
  259. package/dist/reputation/uptime-tracker.js +123 -0
  260. package/dist/reputation/uptime-tracker.js.map +1 -0
  261. package/dist/routing/default-router.d.ts +21 -0
  262. package/dist/routing/default-router.d.ts.map +1 -0
  263. package/dist/routing/default-router.js +60 -0
  264. package/dist/routing/default-router.js.map +1 -0
  265. package/dist/types/buyer.d.ts +36 -0
  266. package/dist/types/buyer.d.ts.map +1 -0
  267. package/dist/types/buyer.js +2 -0
  268. package/dist/types/buyer.js.map +1 -0
  269. package/dist/types/capability.d.ts +25 -0
  270. package/dist/types/capability.d.ts.map +1 -0
  271. package/dist/types/capability.js +2 -0
  272. package/dist/types/capability.js.map +1 -0
  273. package/dist/types/connection.d.ts +27 -0
  274. package/dist/types/connection.d.ts.map +1 -0
  275. package/dist/types/connection.js +11 -0
  276. package/dist/types/connection.js.map +1 -0
  277. package/dist/types/http.d.ts +19 -0
  278. package/dist/types/http.d.ts.map +1 -0
  279. package/dist/types/http.js +2 -0
  280. package/dist/types/http.js.map +1 -0
  281. package/dist/types/index.d.ts +15 -0
  282. package/dist/types/index.d.ts.map +1 -0
  283. package/dist/types/index.js +15 -0
  284. package/dist/types/index.js.map +1 -0
  285. package/dist/types/metering.d.ts +170 -0
  286. package/dist/types/metering.d.ts.map +1 -0
  287. package/dist/types/metering.js +2 -0
  288. package/dist/types/metering.js.map +1 -0
  289. package/dist/types/peer-profile.d.ts +24 -0
  290. package/dist/types/peer-profile.d.ts.map +1 -0
  291. package/dist/types/peer-profile.js +2 -0
  292. package/dist/types/peer-profile.js.map +1 -0
  293. package/dist/types/peer.d.ts +56 -0
  294. package/dist/types/peer.d.ts.map +1 -0
  295. package/dist/types/peer.js +11 -0
  296. package/dist/types/peer.js.map +1 -0
  297. package/dist/types/plugin-config.d.ts +31 -0
  298. package/dist/types/plugin-config.d.ts.map +1 -0
  299. package/dist/types/plugin-config.js +2 -0
  300. package/dist/types/plugin-config.js.map +1 -0
  301. package/dist/types/protocol.d.ts +141 -0
  302. package/dist/types/protocol.d.ts.map +1 -0
  303. package/dist/types/protocol.js +42 -0
  304. package/dist/types/protocol.js.map +1 -0
  305. package/dist/types/provider.d.ts +38 -0
  306. package/dist/types/provider.d.ts.map +1 -0
  307. package/dist/types/provider.js +11 -0
  308. package/dist/types/provider.js.map +1 -0
  309. package/dist/types/rating.d.ts +21 -0
  310. package/dist/types/rating.d.ts.map +1 -0
  311. package/dist/types/rating.js +2 -0
  312. package/dist/types/rating.js.map +1 -0
  313. package/dist/types/report.d.ts +20 -0
  314. package/dist/types/report.d.ts.map +1 -0
  315. package/dist/types/report.js +2 -0
  316. package/dist/types/report.js.map +1 -0
  317. package/dist/types/seller.d.ts +36 -0
  318. package/dist/types/seller.d.ts.map +1 -0
  319. package/dist/types/seller.js +2 -0
  320. package/dist/types/seller.js.map +1 -0
  321. package/dist/types/staking.d.ts +16 -0
  322. package/dist/types/staking.d.ts.map +1 -0
  323. package/dist/types/staking.js +6 -0
  324. package/dist/types/staking.js.map +1 -0
  325. package/dist/utils/debug.d.ts +4 -0
  326. package/dist/utils/debug.d.ts.map +1 -0
  327. package/dist/utils/debug.js +25 -0
  328. package/dist/utils/debug.js.map +1 -0
  329. package/dist/utils/hex.d.ts +3 -0
  330. package/dist/utils/hex.d.ts.map +1 -0
  331. package/dist/utils/hex.js +15 -0
  332. package/dist/utils/hex.js.map +1 -0
  333. package/package.json +62 -0
  334. package/scripts/ensure-node-native-modules.mjs +153 -0
  335. package/scripts/patch-ethers.js +44 -0
  336. package/src/config/encryption.test.ts +49 -0
  337. package/src/config/encryption.ts +53 -0
  338. package/src/config/plugin-config-manager.test.ts +92 -0
  339. package/src/config/plugin-config-manager.ts +153 -0
  340. package/src/config/plugin-loader.ts +90 -0
  341. package/src/discovery/announcer.ts +169 -0
  342. package/src/discovery/bootstrap.ts +57 -0
  343. package/src/discovery/default-metadata-resolver.ts +18 -0
  344. package/src/discovery/dht-health.ts +136 -0
  345. package/src/discovery/dht-node.ts +191 -0
  346. package/src/discovery/http-metadata-resolver.ts +47 -0
  347. package/src/discovery/index.ts +15 -0
  348. package/src/discovery/metadata-codec.ts +453 -0
  349. package/src/discovery/metadata-resolver.ts +7 -0
  350. package/src/discovery/metadata-server.ts +73 -0
  351. package/src/discovery/metadata-validator.ts +172 -0
  352. package/src/discovery/peer-lookup.ts +122 -0
  353. package/src/discovery/peer-metadata.ts +34 -0
  354. package/src/discovery/peer-selector.ts +134 -0
  355. package/src/discovery/profile-manager.ts +131 -0
  356. package/src/discovery/profile-search.ts +100 -0
  357. package/src/discovery/reputation-verifier.ts +54 -0
  358. package/src/index.ts +61 -0
  359. package/src/interfaces/buyer-router.ts +21 -0
  360. package/src/interfaces/plugin.ts +36 -0
  361. package/src/interfaces/seller-provider.ts +81 -0
  362. package/src/metering/index.ts +6 -0
  363. package/src/metering/receipt-generator.ts +105 -0
  364. package/src/metering/receipt-verifier.ts +102 -0
  365. package/src/metering/session-tracker.ts +145 -0
  366. package/src/metering/storage.ts +600 -0
  367. package/src/metering/token-counter.ts +127 -0
  368. package/src/metering/usage-aggregator.ts +236 -0
  369. package/src/node.ts +1698 -0
  370. package/src/p2p/connection-auth.ts +152 -0
  371. package/src/p2p/connection-manager.ts +916 -0
  372. package/src/p2p/handshake.ts +162 -0
  373. package/src/p2p/ice-config.ts +59 -0
  374. package/src/p2p/identity.ts +110 -0
  375. package/src/p2p/index.ts +11 -0
  376. package/src/p2p/keepalive.ts +118 -0
  377. package/src/p2p/message-protocol.ts +171 -0
  378. package/src/p2p/nat-traversal.ts +169 -0
  379. package/src/p2p/payment-codec.ts +165 -0
  380. package/src/p2p/payment-mux.ts +153 -0
  381. package/src/p2p/reconnect.ts +117 -0
  382. package/src/payments/balance-manager.ts +77 -0
  383. package/src/payments/buyer-payment-manager.ts +414 -0
  384. package/src/payments/disputes.ts +72 -0
  385. package/src/payments/evm/escrow-client.ts +263 -0
  386. package/src/payments/evm/keypair.ts +31 -0
  387. package/src/payments/evm/signatures.ts +103 -0
  388. package/src/payments/evm/wallet.ts +42 -0
  389. package/src/payments/index.ts +50 -0
  390. package/src/payments/settlement.ts +40 -0
  391. package/src/payments/types.ts +79 -0
  392. package/src/proxy/index.ts +3 -0
  393. package/src/proxy/provider-detection.ts +78 -0
  394. package/src/proxy/proxy-mux.ts +173 -0
  395. package/src/proxy/request-codec.ts +294 -0
  396. package/src/reputation/index.ts +6 -0
  397. package/src/reputation/rating-manager.ts +118 -0
  398. package/src/reputation/report-manager.ts +91 -0
  399. package/src/reputation/trust-engine.ts +120 -0
  400. package/src/reputation/trust-score.ts +74 -0
  401. package/src/reputation/uptime-tracker.ts +155 -0
  402. package/src/routing/default-router.ts +75 -0
  403. package/src/types/bittorrent-dht.d.ts +19 -0
  404. package/src/types/buyer.ts +37 -0
  405. package/src/types/capability.ts +34 -0
  406. package/src/types/connection.ts +29 -0
  407. package/src/types/http.ts +20 -0
  408. package/src/types/index.ts +14 -0
  409. package/src/types/metering.ts +175 -0
  410. package/src/types/nat-api.d.ts +29 -0
  411. package/src/types/peer-profile.ts +25 -0
  412. package/src/types/peer.ts +62 -0
  413. package/src/types/plugin-config.ts +31 -0
  414. package/src/types/protocol.ts +162 -0
  415. package/src/types/provider.ts +40 -0
  416. package/src/types/rating.ts +23 -0
  417. package/src/types/report.ts +30 -0
  418. package/src/types/seller.ts +38 -0
  419. package/src/types/staking.ts +23 -0
  420. package/src/utils/debug.ts +30 -0
  421. package/src/utils/hex.ts +14 -0
  422. package/tests/balance-manager.test.ts +156 -0
  423. package/tests/bootstrap.test.ts +108 -0
  424. package/tests/buyer-payment-manager.test.ts +358 -0
  425. package/tests/connection-auth.test.ts +87 -0
  426. package/tests/default-router.test.ts +148 -0
  427. package/tests/evm-keypair.test.ts +173 -0
  428. package/tests/identity.test.ts +133 -0
  429. package/tests/message-protocol.test.ts +212 -0
  430. package/tests/metadata-codec.test.ts +165 -0
  431. package/tests/metadata-validator.test.ts +261 -0
  432. package/tests/metering-storage.test.ts +244 -0
  433. package/tests/payment-codec.test.ts +95 -0
  434. package/tests/payment-mux.test.ts +191 -0
  435. package/tests/peer-selector.test.ts +184 -0
  436. package/tests/provider-detection.test.ts +107 -0
  437. package/tests/proxy-mux-security.test.ts +38 -0
  438. package/tests/receipt.test.ts +215 -0
  439. package/tests/reputation-integration.test.ts +195 -0
  440. package/tests/request-codec.test.ts +144 -0
  441. package/tests/token-counter.test.ts +122 -0
  442. package/tsconfig.json +9 -0
  443. package/vitest.config.ts +7 -0
@@ -0,0 +1,169 @@
1
+ import NatAPI from "@silentbot1/nat-api";
2
+ import { debugLog, debugWarn } from "../utils/debug.js";
3
+
4
+ export interface NatMapping {
5
+ /** The internal port that was mapped. */
6
+ internalPort: number;
7
+ /** The external port on the router (usually same as internal). */
8
+ externalPort: number;
9
+ /** The external/public IP address. */
10
+ externalIp: string;
11
+ /** Protocol that was mapped. */
12
+ protocol: "TCP" | "UDP";
13
+ }
14
+
15
+ export interface NatTraversalResult {
16
+ /** Whether UPnP/NAT-PMP mapping succeeded. */
17
+ success: boolean;
18
+ /** External IP if discovered. */
19
+ externalIp: string | null;
20
+ /** Successfully created mappings. */
21
+ mappings: NatMapping[];
22
+ }
23
+
24
+ /**
25
+ * Automatic NAT traversal via UPnP and NAT-PMP.
26
+ *
27
+ * Requests port forwarding from the router so that inbound connections
28
+ * from the internet can reach the seller's signaling port. This is
29
+ * transparent to the caller — just call `mapPorts()` after binding
30
+ * and `cleanup()` on shutdown.
31
+ */
32
+ export class NatTraversal {
33
+ private _nat: NatAPI | null = null;
34
+ private _mappings: NatMapping[] = [];
35
+ private _externalIp: string | null = null;
36
+ private _destroyed = false;
37
+
38
+ /**
39
+ * Attempt to map the given ports via UPnP/NAT-PMP.
40
+ *
41
+ * @param ports - Array of { port, protocol } to map.
42
+ * @param timeoutMs - How long to wait before giving up (default 10s).
43
+ * @returns Result indicating success and discovered external IP.
44
+ */
45
+ async mapPorts(
46
+ ports: Array<{ port: number; protocol: "TCP" | "UDP" }>,
47
+ timeoutMs = 10_000,
48
+ ): Promise<NatTraversalResult> {
49
+ this._nat = new NatAPI({
50
+ enablePMP: true,
51
+ enableUPNP: true,
52
+ description: "Antseed P2P",
53
+ ttl: 7200,
54
+ });
55
+
56
+ const result: NatTraversalResult = {
57
+ success: false,
58
+ externalIp: null,
59
+ mappings: [],
60
+ };
61
+
62
+ // Race against timeout
63
+ try {
64
+ await Promise.race([
65
+ this._doMapping(ports, result),
66
+ rejectAfter(timeoutMs, "NAT traversal timed out"),
67
+ ]);
68
+ } catch (err) {
69
+ // Timeout or error — return partial result
70
+ const msg = err instanceof Error ? err.message : String(err);
71
+ debugWarn(`[NAT] ${msg}`);
72
+ }
73
+
74
+ this._mappings = result.mappings;
75
+ this._externalIp = result.externalIp;
76
+ result.success = result.mappings.length > 0;
77
+
78
+ return result;
79
+ }
80
+
81
+ private async _doMapping(
82
+ ports: Array<{ port: number; protocol: "TCP" | "UDP" }>,
83
+ result: NatTraversalResult,
84
+ ): Promise<void> {
85
+ if (!this._nat) return;
86
+
87
+ // Try to get external IP first
88
+ try {
89
+ const ip = await this._nat.externalIp();
90
+ if (ip) {
91
+ result.externalIp = ip;
92
+ debugLog(`[NAT] External IP: ${ip}`);
93
+ }
94
+ } catch {
95
+ debugWarn("[NAT] Could not determine external IP");
96
+ }
97
+
98
+ // Map each port
99
+ for (const { port, protocol } of ports) {
100
+ try {
101
+ const mapped = await this._nat.map({
102
+ publicPort: port,
103
+ privatePort: port,
104
+ protocol,
105
+ description: `Antseed ${protocol}`,
106
+ });
107
+
108
+ if (mapped) {
109
+ const mapping: NatMapping = {
110
+ internalPort: port,
111
+ externalPort: port,
112
+ externalIp: result.externalIp ?? "",
113
+ protocol,
114
+ };
115
+ result.mappings.push(mapping);
116
+ debugLog(`[NAT] Mapped ${protocol} port ${port}`);
117
+ } else {
118
+ debugWarn(`[NAT] Failed to map ${protocol} port ${port}`);
119
+ }
120
+ } catch (err) {
121
+ const msg = err instanceof Error ? err.message : String(err);
122
+ debugWarn(`[NAT] Error mapping ${protocol} port ${port}: ${msg}`);
123
+ }
124
+ }
125
+ }
126
+
127
+ /** The external IP discovered during mapping, if any. */
128
+ get externalIp(): string | null {
129
+ return this._externalIp;
130
+ }
131
+
132
+ /** All active port mappings. */
133
+ get mappings(): readonly NatMapping[] {
134
+ return this._mappings;
135
+ }
136
+
137
+ /** Remove all port mappings and clean up. */
138
+ async cleanup(): Promise<void> {
139
+ if (this._destroyed || !this._nat) return;
140
+ this._destroyed = true;
141
+
142
+ for (const m of this._mappings) {
143
+ try {
144
+ await this._nat.unmap({
145
+ publicPort: m.externalPort,
146
+ privatePort: m.internalPort,
147
+ protocol: m.protocol,
148
+ });
149
+ } catch {
150
+ // Best-effort cleanup
151
+ }
152
+ }
153
+
154
+ try {
155
+ await this._nat.destroy();
156
+ } catch {
157
+ // Best-effort cleanup
158
+ }
159
+
160
+ this._mappings = [];
161
+ this._nat = null;
162
+ }
163
+ }
164
+
165
+ function rejectAfter(ms: number, message: string): Promise<never> {
166
+ return new Promise((_, reject) => {
167
+ setTimeout(() => reject(new Error(message)), ms);
168
+ });
169
+ }
@@ -0,0 +1,165 @@
1
+ import type {
2
+ SessionLockAuthPayload,
3
+ SessionLockConfirmPayload,
4
+ SessionLockRejectPayload,
5
+ SellerReceiptPayload,
6
+ BuyerAckPayload,
7
+ SessionEndPayload,
8
+ TopUpRequestPayload,
9
+ TopUpAuthPayload,
10
+ DisputeNotifyPayload,
11
+ } from '../types/protocol.js';
12
+
13
+ const encoder = new TextEncoder();
14
+ const decoder = new TextDecoder();
15
+
16
+ // --- Validation helpers ---
17
+
18
+ function parseJson(data: Uint8Array): Record<string, unknown> {
19
+ const raw: unknown = JSON.parse(decoder.decode(data));
20
+ if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {
21
+ throw new Error('Expected JSON object');
22
+ }
23
+ return raw as Record<string, unknown>;
24
+ }
25
+
26
+ function requireString(obj: Record<string, unknown>, field: string): string {
27
+ const val = obj[field];
28
+ if (typeof val !== 'string' || val.length === 0) {
29
+ throw new Error(`Missing or invalid string field: ${field}`);
30
+ }
31
+ return val;
32
+ }
33
+
34
+ function requireNumber(obj: Record<string, unknown>, field: string): number {
35
+ const val = obj[field];
36
+ if (typeof val !== 'number' || !Number.isFinite(val)) {
37
+ throw new Error(`Missing or invalid number field: ${field}`);
38
+ }
39
+ return val;
40
+ }
41
+
42
+ // --- Encoders ---
43
+
44
+ export function encodeSessionLockAuth(payload: SessionLockAuthPayload): Uint8Array {
45
+ return encoder.encode(JSON.stringify(payload));
46
+ }
47
+
48
+ export function encodeSessionLockConfirm(payload: SessionLockConfirmPayload): Uint8Array {
49
+ return encoder.encode(JSON.stringify(payload));
50
+ }
51
+
52
+ export function encodeSessionLockReject(payload: SessionLockRejectPayload): Uint8Array {
53
+ return encoder.encode(JSON.stringify(payload));
54
+ }
55
+
56
+ export function encodeSellerReceipt(payload: SellerReceiptPayload): Uint8Array {
57
+ return encoder.encode(JSON.stringify(payload));
58
+ }
59
+
60
+ export function encodeBuyerAck(payload: BuyerAckPayload): Uint8Array {
61
+ return encoder.encode(JSON.stringify(payload));
62
+ }
63
+
64
+ export function encodeSessionEnd(payload: SessionEndPayload): Uint8Array {
65
+ return encoder.encode(JSON.stringify(payload));
66
+ }
67
+
68
+ export function encodeTopUpRequest(payload: TopUpRequestPayload): Uint8Array {
69
+ return encoder.encode(JSON.stringify(payload));
70
+ }
71
+
72
+ export function encodeTopUpAuth(payload: TopUpAuthPayload): Uint8Array {
73
+ return encoder.encode(JSON.stringify(payload));
74
+ }
75
+
76
+ export function encodeDisputeNotify(payload: DisputeNotifyPayload): Uint8Array {
77
+ return encoder.encode(JSON.stringify(payload));
78
+ }
79
+
80
+ // --- Decoders (with runtime validation) ---
81
+
82
+ export function decodeSessionLockAuth(data: Uint8Array): SessionLockAuthPayload {
83
+ const obj = parseJson(data);
84
+ return {
85
+ sessionId: requireString(obj, 'sessionId'),
86
+ lockedAmount: requireString(obj, 'lockedAmount'),
87
+ buyerSig: requireString(obj, 'buyerSig'),
88
+ };
89
+ }
90
+
91
+ export function decodeSessionLockConfirm(data: Uint8Array): SessionLockConfirmPayload {
92
+ const obj = parseJson(data);
93
+ return {
94
+ sessionId: requireString(obj, 'sessionId'),
95
+ txSignature: requireString(obj, 'txSignature'),
96
+ };
97
+ }
98
+
99
+ export function decodeSessionLockReject(data: Uint8Array): SessionLockRejectPayload {
100
+ const obj = parseJson(data);
101
+ return {
102
+ sessionId: requireString(obj, 'sessionId'),
103
+ reason: requireString(obj, 'reason'),
104
+ };
105
+ }
106
+
107
+ export function decodeSellerReceipt(data: Uint8Array): SellerReceiptPayload {
108
+ const obj = parseJson(data);
109
+ return {
110
+ sessionId: requireString(obj, 'sessionId'),
111
+ runningTotal: requireString(obj, 'runningTotal'),
112
+ requestCount: requireNumber(obj, 'requestCount'),
113
+ responseHash: requireString(obj, 'responseHash'),
114
+ sellerSig: requireString(obj, 'sellerSig'),
115
+ };
116
+ }
117
+
118
+ export function decodeBuyerAck(data: Uint8Array): BuyerAckPayload {
119
+ const obj = parseJson(data);
120
+ return {
121
+ sessionId: requireString(obj, 'sessionId'),
122
+ runningTotal: requireString(obj, 'runningTotal'),
123
+ requestCount: requireNumber(obj, 'requestCount'),
124
+ buyerSig: requireString(obj, 'buyerSig'),
125
+ };
126
+ }
127
+
128
+ export function decodeSessionEnd(data: Uint8Array): SessionEndPayload {
129
+ const obj = parseJson(data);
130
+ return {
131
+ sessionId: requireString(obj, 'sessionId'),
132
+ runningTotal: requireString(obj, 'runningTotal'),
133
+ requestCount: requireNumber(obj, 'requestCount'),
134
+ score: requireNumber(obj, 'score'),
135
+ buyerSig: requireString(obj, 'buyerSig'),
136
+ };
137
+ }
138
+
139
+ export function decodeTopUpRequest(data: Uint8Array): TopUpRequestPayload {
140
+ const obj = parseJson(data);
141
+ return {
142
+ sessionId: requireString(obj, 'sessionId'),
143
+ additionalAmount: requireString(obj, 'additionalAmount'),
144
+ currentRunningTotal: requireString(obj, 'currentRunningTotal'),
145
+ currentLockedAmount: requireString(obj, 'currentLockedAmount'),
146
+ };
147
+ }
148
+
149
+ export function decodeTopUpAuth(data: Uint8Array): TopUpAuthPayload {
150
+ const obj = parseJson(data);
151
+ return {
152
+ sessionId: requireString(obj, 'sessionId'),
153
+ additionalAmount: requireString(obj, 'additionalAmount'),
154
+ buyerSig: requireString(obj, 'buyerSig'),
155
+ };
156
+ }
157
+
158
+ export function decodeDisputeNotify(data: Uint8Array): DisputeNotifyPayload {
159
+ const obj = parseJson(data);
160
+ return {
161
+ sessionId: requireString(obj, 'sessionId'),
162
+ reason: requireString(obj, 'reason'),
163
+ txSignature: requireString(obj, 'txSignature'),
164
+ };
165
+ }
@@ -0,0 +1,153 @@
1
+ import type { PeerConnection } from './connection-manager.js';
2
+ import { MessageType } from '../types/protocol.js';
3
+ import type {
4
+ SessionLockAuthPayload,
5
+ SessionLockConfirmPayload,
6
+ SessionLockRejectPayload,
7
+ SellerReceiptPayload,
8
+ BuyerAckPayload,
9
+ SessionEndPayload,
10
+ TopUpRequestPayload,
11
+ TopUpAuthPayload,
12
+ DisputeNotifyPayload,
13
+ } from '../types/protocol.js';
14
+ import { encodeFrame } from './message-protocol.js';
15
+ import type { FramedMessage } from '../types/protocol.js';
16
+ import * as codec from './payment-codec.js';
17
+
18
+ export type PaymentMessageHandler<T> = (payload: T) => void | Promise<void>;
19
+
20
+ /**
21
+ * Multiplexes bilateral payment messages over a PeerConnection.
22
+ * Register handlers for each message type, then call handleFrame()
23
+ * when a payment-range frame arrives.
24
+ */
25
+ export class PaymentMux {
26
+ private _connection: PeerConnection;
27
+ private _messageIdCounter = 0;
28
+
29
+ // Handler registrations
30
+ private _onSessionLockAuth?: PaymentMessageHandler<SessionLockAuthPayload>;
31
+ private _onSessionLockConfirm?: PaymentMessageHandler<SessionLockConfirmPayload>;
32
+ private _onSessionLockReject?: PaymentMessageHandler<SessionLockRejectPayload>;
33
+ private _onSellerReceipt?: PaymentMessageHandler<SellerReceiptPayload>;
34
+ private _onBuyerAck?: PaymentMessageHandler<BuyerAckPayload>;
35
+ private _onSessionEnd?: PaymentMessageHandler<SessionEndPayload>;
36
+ private _onTopUpRequest?: PaymentMessageHandler<TopUpRequestPayload>;
37
+ private _onTopUpAuth?: PaymentMessageHandler<TopUpAuthPayload>;
38
+ private _onDisputeNotify?: PaymentMessageHandler<DisputeNotifyPayload>;
39
+
40
+ constructor(connection: PeerConnection) {
41
+ this._connection = connection;
42
+ }
43
+
44
+ // --- Handler registration ---
45
+ onSessionLockAuth(handler: PaymentMessageHandler<SessionLockAuthPayload>): void {
46
+ this._onSessionLockAuth = handler;
47
+ }
48
+ onSessionLockConfirm(handler: PaymentMessageHandler<SessionLockConfirmPayload>): void {
49
+ this._onSessionLockConfirm = handler;
50
+ }
51
+ onSessionLockReject(handler: PaymentMessageHandler<SessionLockRejectPayload>): void {
52
+ this._onSessionLockReject = handler;
53
+ }
54
+ onSellerReceipt(handler: PaymentMessageHandler<SellerReceiptPayload>): void {
55
+ this._onSellerReceipt = handler;
56
+ }
57
+ onBuyerAck(handler: PaymentMessageHandler<BuyerAckPayload>): void {
58
+ this._onBuyerAck = handler;
59
+ }
60
+ onSessionEnd(handler: PaymentMessageHandler<SessionEndPayload>): void {
61
+ this._onSessionEnd = handler;
62
+ }
63
+ onTopUpRequest(handler: PaymentMessageHandler<TopUpRequestPayload>): void {
64
+ this._onTopUpRequest = handler;
65
+ }
66
+ onTopUpAuth(handler: PaymentMessageHandler<TopUpAuthPayload>): void {
67
+ this._onTopUpAuth = handler;
68
+ }
69
+ onDisputeNotify(handler: PaymentMessageHandler<DisputeNotifyPayload>): void {
70
+ this._onDisputeNotify = handler;
71
+ }
72
+
73
+ // --- Sending ---
74
+ sendSessionLockAuth(payload: SessionLockAuthPayload): void {
75
+ this._send(MessageType.SessionLockAuth, codec.encodeSessionLockAuth(payload));
76
+ }
77
+ sendSessionLockConfirm(payload: SessionLockConfirmPayload): void {
78
+ this._send(MessageType.SessionLockConfirm, codec.encodeSessionLockConfirm(payload));
79
+ }
80
+ sendSessionLockReject(payload: SessionLockRejectPayload): void {
81
+ this._send(MessageType.SessionLockReject, codec.encodeSessionLockReject(payload));
82
+ }
83
+ sendSellerReceipt(payload: SellerReceiptPayload): void {
84
+ this._send(MessageType.SellerReceipt, codec.encodeSellerReceipt(payload));
85
+ }
86
+ sendBuyerAck(payload: BuyerAckPayload): void {
87
+ this._send(MessageType.BuyerAck, codec.encodeBuyerAck(payload));
88
+ }
89
+ sendSessionEnd(payload: SessionEndPayload): void {
90
+ this._send(MessageType.SessionEnd, codec.encodeSessionEnd(payload));
91
+ }
92
+ sendTopUpRequest(payload: TopUpRequestPayload): void {
93
+ this._send(MessageType.TopUpRequest, codec.encodeTopUpRequest(payload));
94
+ }
95
+ sendTopUpAuth(payload: TopUpAuthPayload): void {
96
+ this._send(MessageType.TopUpAuth, codec.encodeTopUpAuth(payload));
97
+ }
98
+ sendDisputeNotify(payload: DisputeNotifyPayload): void {
99
+ this._send(MessageType.DisputeNotify, codec.encodeDisputeNotify(payload));
100
+ }
101
+
102
+ // --- Receiving ---
103
+ /**
104
+ * Returns true if this frame is a payment message and was handled.
105
+ */
106
+ async handleFrame(frame: FramedMessage): Promise<boolean> {
107
+ switch (frame.type) {
108
+ case MessageType.SessionLockAuth:
109
+ await this._onSessionLockAuth?.(codec.decodeSessionLockAuth(frame.payload));
110
+ return true;
111
+ case MessageType.SessionLockConfirm:
112
+ await this._onSessionLockConfirm?.(codec.decodeSessionLockConfirm(frame.payload));
113
+ return true;
114
+ case MessageType.SessionLockReject:
115
+ await this._onSessionLockReject?.(codec.decodeSessionLockReject(frame.payload));
116
+ return true;
117
+ case MessageType.SellerReceipt:
118
+ await this._onSellerReceipt?.(codec.decodeSellerReceipt(frame.payload));
119
+ return true;
120
+ case MessageType.BuyerAck:
121
+ await this._onBuyerAck?.(codec.decodeBuyerAck(frame.payload));
122
+ return true;
123
+ case MessageType.SessionEnd:
124
+ await this._onSessionEnd?.(codec.decodeSessionEnd(frame.payload));
125
+ return true;
126
+ case MessageType.TopUpRequest:
127
+ await this._onTopUpRequest?.(codec.decodeTopUpRequest(frame.payload));
128
+ return true;
129
+ case MessageType.TopUpAuth:
130
+ await this._onTopUpAuth?.(codec.decodeTopUpAuth(frame.payload));
131
+ return true;
132
+ case MessageType.DisputeNotify:
133
+ await this._onDisputeNotify?.(codec.decodeDisputeNotify(frame.payload));
134
+ return true;
135
+ default:
136
+ return false;
137
+ }
138
+ }
139
+
140
+ /** Check if a message type is in the payment range (0x50-0x5F). */
141
+ static isPaymentMessage(type: number): boolean {
142
+ return type >= 0x50 && type <= 0x5f;
143
+ }
144
+
145
+ private _send(type: MessageType, payload: Uint8Array): void {
146
+ const frame = encodeFrame({
147
+ type,
148
+ messageId: this._messageIdCounter++ & 0xffffffff,
149
+ payload,
150
+ });
151
+ this._connection.send(frame);
152
+ }
153
+ }
@@ -0,0 +1,117 @@
1
+ /** Configuration for the reconnection strategy. */
2
+ export interface ReconnectConfig {
3
+ /** Base delay in milliseconds before the first reconnect attempt. */
4
+ baseDelayMs?: number;
5
+ /** Maximum delay in milliseconds between reconnect attempts. */
6
+ maxDelayMs?: number;
7
+ /** Maximum number of reconnect attempts before giving up. */
8
+ maxAttempts?: number;
9
+ /** Jitter factor (0-1) to randomize the delay. */
10
+ jitterFactor?: number;
11
+ }
12
+
13
+ const DEFAULT_BASE_DELAY_MS = 1_000;
14
+ const DEFAULT_MAX_DELAY_MS = 30_000;
15
+ const DEFAULT_MAX_ATTEMPTS = 5;
16
+ const DEFAULT_JITTER_FACTOR = 0.3;
17
+
18
+ export interface ReconnectCallbacks {
19
+ /** Called when a reconnect attempt should be made. */
20
+ onReconnect: (attempt: number) => Promise<boolean>;
21
+ /** Called when all attempts are exhausted. */
22
+ onGiveUp: (totalAttempts: number) => void;
23
+ /** Called when reconnection succeeds. */
24
+ onSuccess: (attempt: number) => void;
25
+ }
26
+
27
+ /**
28
+ * Manages reconnection with exponential backoff and jitter.
29
+ *
30
+ * Delay formula: min(baseDelay * 2^attempt + jitter, maxDelay)
31
+ */
32
+ export class ReconnectManager {
33
+ private _baseDelay: number;
34
+ private _maxDelay: number;
35
+ private _maxAttempts: number;
36
+ private _jitterFactor: number;
37
+ private _attempt = 0;
38
+ private _callbacks: ReconnectCallbacks;
39
+ private _timeoutHandle: ReturnType<typeof setTimeout> | null = null;
40
+ private _active = false;
41
+
42
+ constructor(callbacks: ReconnectCallbacks, config?: ReconnectConfig) {
43
+ this._callbacks = callbacks;
44
+ this._baseDelay = config?.baseDelayMs ?? DEFAULT_BASE_DELAY_MS;
45
+ this._maxDelay = config?.maxDelayMs ?? DEFAULT_MAX_DELAY_MS;
46
+ this._maxAttempts = config?.maxAttempts ?? DEFAULT_MAX_ATTEMPTS;
47
+ this._jitterFactor = config?.jitterFactor ?? DEFAULT_JITTER_FACTOR;
48
+ }
49
+
50
+ get attempt(): number {
51
+ return this._attempt;
52
+ }
53
+
54
+ get isActive(): boolean {
55
+ return this._active;
56
+ }
57
+
58
+ /** Calculate delay for the current attempt with exponential backoff + jitter. */
59
+ calculateDelay(attempt: number): number {
60
+ const exponentialDelay = this._baseDelay * Math.pow(2, attempt);
61
+ const jitter = exponentialDelay * this._jitterFactor * Math.random();
62
+ return Math.min(exponentialDelay + jitter, this._maxDelay);
63
+ }
64
+
65
+ /** Start the reconnection process. */
66
+ start(): void {
67
+ if (this._active) return;
68
+ this._active = true;
69
+ this._attempt = 0;
70
+ this._scheduleAttempt();
71
+ }
72
+
73
+ /** Stop the reconnection process. */
74
+ stop(): void {
75
+ this._active = false;
76
+ if (this._timeoutHandle) {
77
+ clearTimeout(this._timeoutHandle);
78
+ this._timeoutHandle = null;
79
+ }
80
+ }
81
+
82
+ /** Reset the attempt counter (e.g., after a successful connection). */
83
+ reset(): void {
84
+ this._attempt = 0;
85
+ this.stop();
86
+ }
87
+
88
+ /** Schedule the next reconnect attempt. */
89
+ private _scheduleAttempt(): void {
90
+ if (!this._active) return;
91
+
92
+ if (this._attempt >= this._maxAttempts) {
93
+ this._active = false;
94
+ this._callbacks.onGiveUp(this._attempt);
95
+ return;
96
+ }
97
+
98
+ const delay = this.calculateDelay(this._attempt);
99
+
100
+ this._timeoutHandle = setTimeout(async () => {
101
+ if (!this._active) return;
102
+
103
+ this._attempt++;
104
+ try {
105
+ const success = await this._callbacks.onReconnect(this._attempt);
106
+ if (success) {
107
+ this._active = false;
108
+ this._callbacks.onSuccess(this._attempt);
109
+ } else {
110
+ this._scheduleAttempt();
111
+ }
112
+ } catch {
113
+ this._scheduleAttempt();
114
+ }
115
+ }, delay);
116
+ }
117
+ }
@@ -0,0 +1,77 @@
1
+ import { readFile, writeFile, mkdir } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import type { WalletInfo, Transaction, TransactionType } from './types.js';
4
+
5
+ export interface UnifiedBalance {
6
+ cryptoUSDC: number;
7
+ inEscrowUSDC: number;
8
+ totalUSD: number;
9
+ }
10
+
11
+ export class BalanceManager {
12
+ private transactions: Transaction[] = [];
13
+
14
+ getBalance(
15
+ walletInfo: WalletInfo | null,
16
+ inEscrowUSDC: number,
17
+ ): UnifiedBalance {
18
+ const cryptoUSDC = walletInfo ? parseFloat(walletInfo.balanceUSDC) : 0;
19
+ const totalUSD = cryptoUSDC + inEscrowUSDC;
20
+
21
+ return {
22
+ cryptoUSDC,
23
+ inEscrowUSDC,
24
+ totalUSD,
25
+ };
26
+ }
27
+
28
+ recordTransaction(tx: Transaction): void {
29
+ this.transactions.push(tx);
30
+ }
31
+
32
+ getTransactionHistory(
33
+ filter?: TransactionType,
34
+ limit?: number,
35
+ offset?: number,
36
+ ): Transaction[] {
37
+ let result = this.transactions;
38
+
39
+ if (filter) {
40
+ result = result.filter((tx) => tx.type === filter);
41
+ }
42
+
43
+ const start = offset ?? 0;
44
+ const end = limit !== undefined ? start + limit : undefined;
45
+ return result.slice(start, end);
46
+ }
47
+
48
+ getTotalEarnings(since?: number): number {
49
+ return this.transactions
50
+ .filter((tx) => tx.type === 'escrow_release')
51
+ .filter((tx) => (since !== undefined ? tx.timestamp >= since : true))
52
+ .reduce((sum, tx) => sum + tx.amountUSD, 0);
53
+ }
54
+
55
+ getTotalSpending(since?: number): number {
56
+ return this.transactions
57
+ .filter((tx) => tx.type === 'escrow_lock')
58
+ .filter((tx) => (since !== undefined ? tx.timestamp >= since : true))
59
+ .reduce((sum, tx) => sum + tx.amountUSD, 0);
60
+ }
61
+
62
+ async save(configDir: string): Promise<void> {
63
+ await mkdir(configDir, { recursive: true });
64
+ const filePath = join(configDir, 'transactions.json');
65
+ await writeFile(filePath, JSON.stringify(this.transactions, null, 2), 'utf-8');
66
+ }
67
+
68
+ async load(configDir: string): Promise<void> {
69
+ const filePath = join(configDir, 'transactions.json');
70
+ try {
71
+ const data = await readFile(filePath, 'utf-8');
72
+ this.transactions = JSON.parse(data) as Transaction[];
73
+ } catch {
74
+ this.transactions = [];
75
+ }
76
+ }
77
+ }