@agirails/sdk 2.0.1-beta → 2.0.2

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 (405) hide show
  1. package/LICENSE +190 -0
  2. package/README.md +116 -108
  3. package/bin/actp +10 -0
  4. package/dist/ACTPClient.d.ts +456 -33
  5. package/dist/ACTPClient.d.ts.map +1 -1
  6. package/dist/ACTPClient.js +477 -93
  7. package/dist/ACTPClient.js.map +1 -1
  8. package/dist/abi/AgentRegistry.json +782 -0
  9. package/dist/abi/EscrowVault.json +106 -38
  10. package/dist/abi/IdentityRegistry.json +316 -0
  11. package/dist/adapters/BaseAdapter.d.ts +231 -0
  12. package/dist/adapters/BaseAdapter.d.ts.map +1 -0
  13. package/dist/adapters/BaseAdapter.js +393 -0
  14. package/dist/adapters/BaseAdapter.js.map +1 -0
  15. package/dist/adapters/BeginnerAdapter.d.ts +152 -0
  16. package/dist/adapters/BeginnerAdapter.d.ts.map +1 -0
  17. package/dist/adapters/BeginnerAdapter.js +168 -0
  18. package/dist/adapters/BeginnerAdapter.js.map +1 -0
  19. package/dist/adapters/IntermediateAdapter.d.ts +211 -0
  20. package/dist/adapters/IntermediateAdapter.d.ts.map +1 -0
  21. package/dist/adapters/IntermediateAdapter.js +260 -0
  22. package/dist/adapters/IntermediateAdapter.js.map +1 -0
  23. package/dist/adapters/index.d.ts +15 -0
  24. package/dist/adapters/index.d.ts.map +1 -0
  25. package/dist/adapters/index.js +26 -0
  26. package/dist/adapters/index.js.map +1 -0
  27. package/dist/builders/DeliveryProofBuilder.d.ts +60 -1
  28. package/dist/builders/DeliveryProofBuilder.d.ts.map +1 -1
  29. package/dist/builders/DeliveryProofBuilder.js +81 -5
  30. package/dist/builders/DeliveryProofBuilder.js.map +1 -1
  31. package/dist/builders/QuoteBuilder.d.ts +101 -0
  32. package/dist/builders/QuoteBuilder.d.ts.map +1 -1
  33. package/dist/builders/QuoteBuilder.js +120 -3
  34. package/dist/builders/QuoteBuilder.js.map +1 -1
  35. package/dist/builders/index.d.ts +4 -0
  36. package/dist/builders/index.d.ts.map +1 -1
  37. package/dist/builders/index.js +4 -0
  38. package/dist/builders/index.js.map +1 -1
  39. package/dist/cli/commands/balance.d.ts +13 -0
  40. package/dist/cli/commands/balance.d.ts.map +1 -0
  41. package/dist/cli/commands/balance.js +89 -0
  42. package/dist/cli/commands/balance.js.map +1 -0
  43. package/dist/cli/commands/batch.d.ts +24 -0
  44. package/dist/cli/commands/batch.d.ts.map +1 -0
  45. package/dist/cli/commands/batch.js +424 -0
  46. package/dist/cli/commands/batch.js.map +1 -0
  47. package/dist/cli/commands/config.d.ts +13 -0
  48. package/dist/cli/commands/config.d.ts.map +1 -0
  49. package/dist/cli/commands/config.js +192 -0
  50. package/dist/cli/commands/config.js.map +1 -0
  51. package/dist/cli/commands/init.d.ts +19 -0
  52. package/dist/cli/commands/init.d.ts.map +1 -0
  53. package/dist/cli/commands/init.js +143 -0
  54. package/dist/cli/commands/init.js.map +1 -0
  55. package/dist/cli/commands/mint.d.ts +13 -0
  56. package/dist/cli/commands/mint.d.ts.map +1 -0
  57. package/dist/cli/commands/mint.js +91 -0
  58. package/dist/cli/commands/mint.js.map +1 -0
  59. package/dist/cli/commands/pay.d.ts +18 -0
  60. package/dist/cli/commands/pay.d.ts.map +1 -0
  61. package/dist/cli/commands/pay.js +87 -0
  62. package/dist/cli/commands/pay.js.map +1 -0
  63. package/dist/cli/commands/simulate.d.ts +32 -0
  64. package/dist/cli/commands/simulate.d.ts.map +1 -0
  65. package/dist/cli/commands/simulate.js +290 -0
  66. package/dist/cli/commands/simulate.js.map +1 -0
  67. package/dist/cli/commands/time.d.ts +29 -0
  68. package/dist/cli/commands/time.d.ts.map +1 -0
  69. package/dist/cli/commands/time.js +252 -0
  70. package/dist/cli/commands/time.js.map +1 -0
  71. package/dist/cli/commands/tx.d.ts +16 -0
  72. package/dist/cli/commands/tx.d.ts.map +1 -0
  73. package/dist/cli/commands/tx.js +379 -0
  74. package/dist/cli/commands/tx.js.map +1 -0
  75. package/dist/cli/commands/watch.d.ts +20 -0
  76. package/dist/cli/commands/watch.d.ts.map +1 -0
  77. package/dist/cli/commands/watch.js +160 -0
  78. package/dist/cli/commands/watch.js.map +1 -0
  79. package/dist/cli/index.d.ts +17 -0
  80. package/dist/cli/index.d.ts.map +1 -0
  81. package/dist/cli/index.js +104 -0
  82. package/dist/cli/index.js.map +1 -0
  83. package/dist/cli/utils/client.d.ts +70 -0
  84. package/dist/cli/utils/client.d.ts.map +1 -0
  85. package/dist/cli/utils/client.js +240 -0
  86. package/dist/cli/utils/client.js.map +1 -0
  87. package/dist/cli/utils/config.d.ts +91 -0
  88. package/dist/cli/utils/config.d.ts.map +1 -0
  89. package/dist/cli/utils/config.js +240 -0
  90. package/dist/cli/utils/config.js.map +1 -0
  91. package/dist/cli/utils/output.d.ts +174 -0
  92. package/dist/cli/utils/output.d.ts.map +1 -0
  93. package/dist/cli/utils/output.js +380 -0
  94. package/dist/cli/utils/output.js.map +1 -0
  95. package/dist/config/networks.d.ts +28 -0
  96. package/dist/config/networks.d.ts.map +1 -1
  97. package/dist/config/networks.js +60 -12
  98. package/dist/config/networks.js.map +1 -1
  99. package/dist/errors/index.d.ts +165 -2
  100. package/dist/errors/index.d.ts.map +1 -1
  101. package/dist/errors/index.js +260 -2
  102. package/dist/errors/index.js.map +1 -1
  103. package/dist/index.d.ts +61 -13
  104. package/dist/index.d.ts.map +1 -1
  105. package/dist/index.js +141 -36
  106. package/dist/index.js.map +1 -1
  107. package/dist/level0/Provider.d.ts +106 -0
  108. package/dist/level0/Provider.d.ts.map +1 -0
  109. package/dist/level0/Provider.js +10 -0
  110. package/dist/level0/Provider.js.map +1 -0
  111. package/dist/level0/ServiceDirectory.d.ts +74 -0
  112. package/dist/level0/ServiceDirectory.d.ts.map +1 -0
  113. package/dist/level0/ServiceDirectory.js +122 -0
  114. package/dist/level0/ServiceDirectory.js.map +1 -0
  115. package/dist/level0/index.d.ts +10 -0
  116. package/dist/level0/index.d.ts.map +1 -0
  117. package/dist/level0/index.js +15 -0
  118. package/dist/level0/index.js.map +1 -0
  119. package/dist/level0/provide.d.ts +51 -0
  120. package/dist/level0/provide.d.ts.map +1 -0
  121. package/dist/level0/provide.js +113 -0
  122. package/dist/level0/provide.js.map +1 -0
  123. package/dist/level0/request.d.ts +53 -0
  124. package/dist/level0/request.d.ts.map +1 -0
  125. package/dist/level0/request.js +462 -0
  126. package/dist/level0/request.js.map +1 -0
  127. package/dist/level1/Agent.d.ts +472 -0
  128. package/dist/level1/Agent.d.ts.map +1 -0
  129. package/dist/level1/Agent.js +1091 -0
  130. package/dist/level1/Agent.js.map +1 -0
  131. package/dist/level1/index.d.ts +10 -0
  132. package/dist/level1/index.d.ts.map +1 -0
  133. package/dist/level1/index.js +30 -0
  134. package/dist/level1/index.js.map +1 -0
  135. package/dist/level1/pricing/PriceCalculator.d.ts +62 -0
  136. package/dist/level1/pricing/PriceCalculator.d.ts.map +1 -0
  137. package/dist/level1/pricing/PriceCalculator.js +237 -0
  138. package/dist/level1/pricing/PriceCalculator.js.map +1 -0
  139. package/dist/level1/pricing/PricingStrategy.d.ts +179 -0
  140. package/dist/level1/pricing/PricingStrategy.d.ts.map +1 -0
  141. package/dist/level1/pricing/PricingStrategy.js +11 -0
  142. package/dist/level1/pricing/PricingStrategy.js.map +1 -0
  143. package/dist/level1/types/Job.d.ts +166 -0
  144. package/dist/level1/types/Job.d.ts.map +1 -0
  145. package/dist/level1/types/Job.js +11 -0
  146. package/dist/level1/types/Job.js.map +1 -0
  147. package/dist/level1/types/Options.d.ts +258 -0
  148. package/dist/level1/types/Options.d.ts.map +1 -0
  149. package/dist/level1/types/Options.js +8 -0
  150. package/dist/level1/types/Options.js.map +1 -0
  151. package/dist/level1/types/index.d.ts +8 -0
  152. package/dist/level1/types/index.d.ts.map +1 -0
  153. package/dist/level1/types/index.js +8 -0
  154. package/dist/level1/types/index.js.map +1 -0
  155. package/dist/protocol/ACTPKernel.d.ts +229 -2
  156. package/dist/protocol/ACTPKernel.d.ts.map +1 -1
  157. package/dist/protocol/ACTPKernel.js +367 -33
  158. package/dist/protocol/ACTPKernel.js.map +1 -1
  159. package/dist/protocol/AgentRegistry.d.ts +177 -0
  160. package/dist/protocol/AgentRegistry.d.ts.map +1 -0
  161. package/dist/protocol/AgentRegistry.js +449 -0
  162. package/dist/protocol/AgentRegistry.js.map +1 -0
  163. package/dist/protocol/DIDManager.d.ts +289 -0
  164. package/dist/protocol/DIDManager.d.ts.map +1 -0
  165. package/dist/protocol/DIDManager.js +481 -0
  166. package/dist/protocol/DIDManager.js.map +1 -0
  167. package/dist/protocol/DIDResolver.d.ts +236 -0
  168. package/dist/protocol/DIDResolver.d.ts.map +1 -0
  169. package/dist/protocol/DIDResolver.js +495 -0
  170. package/dist/protocol/DIDResolver.js.map +1 -0
  171. package/dist/protocol/EASHelper.d.ts +57 -2
  172. package/dist/protocol/EASHelper.d.ts.map +1 -1
  173. package/dist/protocol/EASHelper.js +230 -37
  174. package/dist/protocol/EASHelper.js.map +1 -1
  175. package/dist/protocol/EscrowVault.d.ts +93 -2
  176. package/dist/protocol/EscrowVault.d.ts.map +1 -1
  177. package/dist/protocol/EscrowVault.js +122 -33
  178. package/dist/protocol/EscrowVault.js.map +1 -1
  179. package/dist/protocol/EventMonitor.d.ts +45 -1
  180. package/dist/protocol/EventMonitor.d.ts.map +1 -1
  181. package/dist/protocol/EventMonitor.js +64 -8
  182. package/dist/protocol/EventMonitor.js.map +1 -1
  183. package/dist/protocol/MessageSigner.d.ts +116 -2
  184. package/dist/protocol/MessageSigner.d.ts.map +1 -1
  185. package/dist/protocol/MessageSigner.js +215 -9
  186. package/dist/protocol/MessageSigner.js.map +1 -1
  187. package/dist/protocol/ProofGenerator.d.ts +93 -0
  188. package/dist/protocol/ProofGenerator.d.ts.map +1 -1
  189. package/dist/protocol/ProofGenerator.js +194 -9
  190. package/dist/protocol/ProofGenerator.js.map +1 -1
  191. package/dist/protocol/QuoteBuilder.d.ts +8 -0
  192. package/dist/protocol/QuoteBuilder.d.ts.map +1 -1
  193. package/dist/protocol/QuoteBuilder.js +8 -0
  194. package/dist/protocol/QuoteBuilder.js.map +1 -1
  195. package/dist/runtime/BlockchainRuntime.d.ts +360 -0
  196. package/dist/runtime/BlockchainRuntime.d.ts.map +1 -0
  197. package/dist/runtime/BlockchainRuntime.js +767 -0
  198. package/dist/runtime/BlockchainRuntime.js.map +1 -0
  199. package/dist/runtime/IACTPRuntime.d.ts +271 -0
  200. package/dist/runtime/IACTPRuntime.d.ts.map +1 -0
  201. package/dist/runtime/IACTPRuntime.js +15 -0
  202. package/dist/runtime/IACTPRuntime.js.map +1 -0
  203. package/dist/runtime/MockRuntime.d.ts +445 -0
  204. package/dist/runtime/MockRuntime.d.ts.map +1 -0
  205. package/dist/runtime/MockRuntime.js +1065 -0
  206. package/dist/runtime/MockRuntime.js.map +1 -0
  207. package/dist/runtime/MockStateManager.d.ts +233 -0
  208. package/dist/runtime/MockStateManager.d.ts.map +1 -0
  209. package/dist/runtime/MockStateManager.js +533 -0
  210. package/dist/runtime/MockStateManager.js.map +1 -0
  211. package/dist/runtime/index.d.ts +14 -0
  212. package/dist/runtime/index.d.ts.map +1 -0
  213. package/dist/runtime/index.js +42 -0
  214. package/dist/runtime/index.js.map +1 -0
  215. package/dist/runtime/types/MockState.d.ts +167 -0
  216. package/dist/runtime/types/MockState.d.ts.map +1 -0
  217. package/dist/runtime/types/MockState.js +43 -0
  218. package/dist/runtime/types/MockState.js.map +1 -0
  219. package/dist/types/agent.d.ts +76 -0
  220. package/dist/types/agent.d.ts.map +1 -0
  221. package/dist/types/agent.js +8 -0
  222. package/dist/types/agent.js.map +1 -0
  223. package/dist/types/did.d.ts +192 -0
  224. package/dist/types/did.d.ts.map +1 -0
  225. package/dist/types/did.js +38 -0
  226. package/dist/types/did.js.map +1 -0
  227. package/dist/types/eip712.d.ts +34 -0
  228. package/dist/types/eip712.d.ts.map +1 -1
  229. package/dist/types/eip712.js +31 -5
  230. package/dist/types/eip712.js.map +1 -1
  231. package/dist/types/escrow.d.ts +17 -10
  232. package/dist/types/escrow.d.ts.map +1 -1
  233. package/dist/types/index.d.ts +5 -0
  234. package/dist/types/index.d.ts.map +1 -1
  235. package/dist/types/index.js +8 -0
  236. package/dist/types/index.js.map +1 -1
  237. package/dist/types/message.d.ts +32 -0
  238. package/dist/types/message.d.ts.map +1 -1
  239. package/dist/types/message.js +4 -0
  240. package/dist/types/message.js.map +1 -1
  241. package/dist/types/state.d.ts +28 -0
  242. package/dist/types/state.d.ts.map +1 -1
  243. package/dist/types/state.js +37 -6
  244. package/dist/types/state.js.map +1 -1
  245. package/dist/types/transaction.d.ts +17 -0
  246. package/dist/types/transaction.d.ts.map +1 -1
  247. package/dist/utils/ErrorRecoveryGuide.d.ts +125 -0
  248. package/dist/utils/ErrorRecoveryGuide.d.ts.map +1 -0
  249. package/dist/utils/ErrorRecoveryGuide.js +579 -0
  250. package/dist/utils/ErrorRecoveryGuide.js.map +1 -0
  251. package/dist/utils/Helpers.d.ts +453 -0
  252. package/dist/utils/Helpers.d.ts.map +1 -0
  253. package/dist/utils/Helpers.js +623 -0
  254. package/dist/utils/Helpers.js.map +1 -0
  255. package/dist/utils/IPFSClient.d.ts +113 -0
  256. package/dist/utils/IPFSClient.d.ts.map +1 -1
  257. package/dist/utils/IPFSClient.js +128 -7
  258. package/dist/utils/IPFSClient.js.map +1 -1
  259. package/dist/utils/Logger.d.ts +195 -0
  260. package/dist/utils/Logger.d.ts.map +1 -0
  261. package/dist/utils/Logger.js +382 -0
  262. package/dist/utils/Logger.js.map +1 -0
  263. package/dist/utils/NonceManager.d.ts +234 -1
  264. package/dist/utils/NonceManager.d.ts.map +1 -1
  265. package/dist/utils/NonceManager.js +372 -7
  266. package/dist/utils/NonceManager.js.map +1 -1
  267. package/dist/utils/RateLimiter.d.ts +253 -0
  268. package/dist/utils/RateLimiter.d.ts.map +1 -0
  269. package/dist/utils/RateLimiter.js +424 -0
  270. package/dist/utils/RateLimiter.js.map +1 -0
  271. package/dist/utils/ReceivedNonceTracker.d.ts +175 -0
  272. package/dist/utils/ReceivedNonceTracker.d.ts.map +1 -1
  273. package/dist/utils/ReceivedNonceTracker.js +261 -5
  274. package/dist/utils/ReceivedNonceTracker.js.map +1 -1
  275. package/dist/utils/SDKLifecycle.d.ts +156 -0
  276. package/dist/utils/SDKLifecycle.d.ts.map +1 -0
  277. package/dist/utils/SDKLifecycle.js +347 -0
  278. package/dist/utils/SDKLifecycle.js.map +1 -0
  279. package/dist/utils/SecureNonce.d.ts +57 -0
  280. package/dist/utils/SecureNonce.d.ts.map +1 -0
  281. package/dist/utils/SecureNonce.js +80 -0
  282. package/dist/utils/SecureNonce.js.map +1 -0
  283. package/dist/utils/Semaphore.d.ts +123 -0
  284. package/dist/utils/Semaphore.d.ts.map +1 -0
  285. package/dist/utils/Semaphore.js +247 -0
  286. package/dist/utils/Semaphore.js.map +1 -0
  287. package/dist/utils/UsedAttestationTracker.d.ts +167 -0
  288. package/dist/utils/UsedAttestationTracker.d.ts.map +1 -0
  289. package/dist/utils/UsedAttestationTracker.js +309 -0
  290. package/dist/utils/UsedAttestationTracker.js.map +1 -0
  291. package/dist/utils/canonicalJson.d.ts +22 -0
  292. package/dist/utils/canonicalJson.d.ts.map +1 -1
  293. package/dist/utils/canonicalJson.js +26 -3
  294. package/dist/utils/canonicalJson.js.map +1 -1
  295. package/dist/utils/computeTypeHash.d.ts +14 -0
  296. package/dist/utils/computeTypeHash.d.ts.map +1 -1
  297. package/dist/utils/computeTypeHash.js +19 -2
  298. package/dist/utils/computeTypeHash.js.map +1 -1
  299. package/dist/utils/fsSafe.d.ts +14 -0
  300. package/dist/utils/fsSafe.d.ts.map +1 -0
  301. package/dist/utils/fsSafe.js +89 -0
  302. package/dist/utils/fsSafe.js.map +1 -0
  303. package/dist/utils/index.d.ts +15 -0
  304. package/dist/utils/index.d.ts.map +1 -0
  305. package/dist/utils/index.js +51 -0
  306. package/dist/utils/index.js.map +1 -0
  307. package/dist/utils/security.d.ts +147 -0
  308. package/dist/utils/security.d.ts.map +1 -0
  309. package/dist/utils/security.js +391 -0
  310. package/dist/utils/security.js.map +1 -0
  311. package/dist/utils/validation.d.ts +40 -0
  312. package/dist/utils/validation.d.ts.map +1 -1
  313. package/dist/utils/validation.js +184 -7
  314. package/dist/utils/validation.js.map +1 -1
  315. package/package.json +54 -37
  316. package/src/ACTPClient.ts +692 -178
  317. package/src/abi/AgentRegistry.json +782 -0
  318. package/src/abi/EscrowVault.json +106 -38
  319. package/src/abi/IdentityRegistry.json +316 -0
  320. package/src/adapters/BaseAdapter.ts +473 -0
  321. package/src/adapters/BeginnerAdapter.ts +232 -0
  322. package/src/adapters/IntermediateAdapter.ts +316 -0
  323. package/src/adapters/index.ts +25 -0
  324. package/src/builders/DeliveryProofBuilder.ts +3 -2
  325. package/src/cli/commands/balance.ts +110 -0
  326. package/src/cli/commands/batch.ts +487 -0
  327. package/src/cli/commands/config.ts +231 -0
  328. package/src/cli/commands/init.ts +161 -0
  329. package/src/cli/commands/mint.ts +116 -0
  330. package/src/cli/commands/pay.ts +113 -0
  331. package/src/cli/commands/simulate.ts +345 -0
  332. package/src/cli/commands/time.ts +303 -0
  333. package/src/cli/commands/tx.ts +448 -0
  334. package/src/cli/commands/watch.ts +211 -0
  335. package/src/cli/index.ts +116 -0
  336. package/src/cli/utils/client.ts +249 -0
  337. package/src/cli/utils/config.ts +282 -0
  338. package/src/cli/utils/output.ts +465 -0
  339. package/src/config/networks.ts +32 -9
  340. package/src/errors/index.ts +298 -1
  341. package/src/index.ts +207 -71
  342. package/src/level0/Provider.ts +117 -0
  343. package/src/level0/ServiceDirectory.ts +131 -0
  344. package/src/level0/index.ts +10 -0
  345. package/src/level0/provide.ts +131 -0
  346. package/src/level0/request.ts +494 -0
  347. package/src/level1/Agent.ts +1432 -0
  348. package/src/level1/index.ts +10 -0
  349. package/src/level1/pricing/PriceCalculator.ts +255 -0
  350. package/src/level1/pricing/PricingStrategy.ts +198 -0
  351. package/src/level1/types/Job.ts +179 -0
  352. package/src/level1/types/Options.ts +291 -0
  353. package/src/level1/types/index.ts +8 -0
  354. package/src/protocol/ACTPKernel.ts +175 -23
  355. package/src/protocol/AgentRegistry.ts +559 -0
  356. package/src/protocol/DIDManager.ts +629 -0
  357. package/src/protocol/DIDResolver.ts +554 -0
  358. package/src/protocol/EASHelper.ts +230 -46
  359. package/src/protocol/EscrowVault.ts +68 -50
  360. package/src/protocol/EventMonitor.ts +44 -15
  361. package/src/protocol/MessageSigner.ts +193 -13
  362. package/src/protocol/ProofGenerator.ts +223 -4
  363. package/src/runtime/BlockchainRuntime.ts +993 -0
  364. package/src/runtime/IACTPRuntime.ts +284 -0
  365. package/src/runtime/MockRuntime.ts +1244 -0
  366. package/src/runtime/MockStateManager.ts +576 -0
  367. package/src/runtime/index.ts +25 -0
  368. package/src/runtime/types/MockState.ts +227 -0
  369. package/src/types/agent.ts +79 -0
  370. package/src/types/did.ts +223 -0
  371. package/src/types/escrow.ts +12 -11
  372. package/src/types/index.ts +5 -1
  373. package/src/types/state.ts +12 -3
  374. package/src/types/transaction.ts +4 -1
  375. package/src/utils/ErrorRecoveryGuide.ts +675 -0
  376. package/src/utils/Helpers.ts +688 -0
  377. package/src/utils/IPFSClient.ts +122 -5
  378. package/src/utils/Logger.ts +484 -0
  379. package/src/utils/NonceManager.ts +305 -8
  380. package/src/utils/RateLimiter.ts +534 -0
  381. package/src/utils/ReceivedNonceTracker.ts +170 -0
  382. package/src/utils/SDKLifecycle.ts +416 -0
  383. package/src/utils/SecureNonce.ts +78 -0
  384. package/src/utils/Semaphore.ts +276 -0
  385. package/src/utils/UsedAttestationTracker.ts +387 -0
  386. package/src/utils/fsSafe.ts +75 -0
  387. package/src/utils/index.ts +80 -0
  388. package/src/utils/security.ts +418 -0
  389. package/src/utils/validation.ts +164 -0
  390. package/src/__tests__/ProofGenerator.test.ts +0 -124
  391. package/src/__tests__/QuoteBuilder.test.ts +0 -516
  392. package/src/__tests__/StateMachine.test.ts +0 -82
  393. package/src/__tests__/builders/DeliveryProofBuilder.test.ts +0 -581
  394. package/src/__tests__/integration/ACTPClient.test.ts +0 -263
  395. package/src/__tests__/integration.test.ts +0 -289
  396. package/src/__tests__/protocol/EASHelper.test.ts +0 -472
  397. package/src/__tests__/protocol/EventMonitor.test.ts +0 -382
  398. package/src/__tests__/security/ACTPKernel.security.test.ts +0 -1167
  399. package/src/__tests__/security/EscrowVault.security.test.ts +0 -570
  400. package/src/__tests__/security/MessageSigner.security.test.ts +0 -286
  401. package/src/__tests__/security/NonceReplay.security.test.ts +0 -501
  402. package/src/__tests__/security/validation.security.test.ts +0 -376
  403. package/src/__tests__/utils/IPFSClient.test.ts +0 -262
  404. package/src/__tests__/utils/NonceManager.test.ts +0 -205
  405. package/src/__tests__/utils/canonicalJson.test.ts +0 -153
@@ -228,6 +228,10 @@ export class InMemoryReceivedNonceTracker implements IReceivedNonceTracker {
228
228
  * - Reject duplicate nonces (replay attack)
229
229
  * - Allows non-sequential nonces (nonce gaps are OK)
230
230
  *
231
+ * SECURITY FIX (NEW-H-2): Max size enforcement to prevent memory exhaustion
232
+ * SECURITY FIX (HIGH-2): Global total entries limit to prevent DoS via many sender combinations
233
+ * SECURITY FIX (H-2): Rate limiting per sender to prevent flood attacks
234
+ *
231
235
  * Trade-off:
232
236
  * - Higher memory usage (stores every nonce)
233
237
  * - More flexible (allows out-of-order delivery)
@@ -237,8 +241,94 @@ export class SetBasedReceivedNonceTracker implements IReceivedNonceTracker {
237
241
  // Map: sender -> messageType -> Set of used nonces
238
242
  private usedNonces: Map<string, Map<string, Set<string>>> = new Map();
239
243
 
244
+ // SECURITY FIX (NEW-H-2): Maximum entries per sender+messageType
245
+ private readonly maxSizePerType: number;
246
+
247
+ // SECURITY FIX (HIGH-2): Global limit across ALL sender+messageType combinations
248
+ private readonly maxTotalEntries: number;
249
+ private totalEntries: number = 0;
250
+
251
+ // SECURITY FIX (H-2): Rate limiting per sender
252
+ // Map: sender -> { count: number, windowStart: number }
253
+ private rateLimitState: Map<string, { count: number; windowStart: number }> = new Map();
254
+ private readonly maxNoncesPerMinute: number;
255
+ private readonly rateLimitWindowMs: number = 60000; // 1 minute window
256
+
257
+ /**
258
+ * Create set-based tracker with optional max size
259
+ * @param maxSizePerType - Maximum nonces per sender+messageType (default: 10,000)
260
+ * @param maxTotalEntries - Maximum total nonces across all combinations (default: 100,000)
261
+ * @param maxNoncesPerMinute - Maximum nonces per sender per minute (default: 100)
262
+ */
263
+ constructor(
264
+ maxSizePerType: number = 10000,
265
+ maxTotalEntries: number = 100000,
266
+ maxNoncesPerMinute: number = 100
267
+ ) {
268
+ if (maxSizePerType <= 0) {
269
+ throw new Error('maxSizePerType must be positive');
270
+ }
271
+ if (maxTotalEntries <= 0) {
272
+ throw new Error('maxTotalEntries must be positive');
273
+ }
274
+ if (maxNoncesPerMinute <= 0) {
275
+ throw new Error('maxNoncesPerMinute must be positive');
276
+ }
277
+ this.maxSizePerType = maxSizePerType;
278
+ this.maxTotalEntries = maxTotalEntries;
279
+ this.maxNoncesPerMinute = maxNoncesPerMinute;
280
+ }
281
+
282
+ /**
283
+ * SECURITY FIX (H-2): Check rate limit for sender
284
+ * @param sender - Sender DID
285
+ * @returns true if rate limit exceeded
286
+ */
287
+ private checkRateLimit(sender: string): boolean {
288
+ const now = Date.now();
289
+ const state = this.rateLimitState.get(sender);
290
+
291
+ if (!state) {
292
+ // First nonce from this sender
293
+ this.rateLimitState.set(sender, { count: 1, windowStart: now });
294
+ return false; // Not rate limited
295
+ }
296
+
297
+ // Check if window expired (reset counter)
298
+ if (now - state.windowStart >= this.rateLimitWindowMs) {
299
+ state.count = 1;
300
+ state.windowStart = now;
301
+ return false; // Not rate limited
302
+ }
303
+
304
+ // Increment counter
305
+ state.count++;
306
+
307
+ // Check if rate limit exceeded
308
+ return state.count > this.maxNoncesPerMinute;
309
+ }
310
+
311
+ /**
312
+ * SECURITY FIX (H-2): Periodic cleanup of rate limit state
313
+ * Removes expired rate limit entries (older than 5 minutes)
314
+ */
315
+ private cleanupRateLimitState(): void {
316
+ const now = Date.now();
317
+ const expiryThreshold = 5 * 60 * 1000; // 5 minutes
318
+
319
+ for (const [sender, state] of this.rateLimitState.entries()) {
320
+ if (now - state.windowStart > expiryThreshold) {
321
+ this.rateLimitState.delete(sender);
322
+ }
323
+ }
324
+ }
325
+
240
326
  /**
241
327
  * Validate and record a received nonce
328
+ *
329
+ * SECURITY FIX (NEW-H-2): Automatic cleanup when max size reached
330
+ * SECURITY FIX (HIGH-2): Global limit check to prevent DoS
331
+ * SECURITY FIX (H-2): Rate limiting per sender (max 100 nonces/minute)
242
332
  */
243
333
  validateAndRecord(sender: string, messageType: string, nonce: string): NonceValidationResult {
244
334
  // Validate nonce format
@@ -250,6 +340,34 @@ export class SetBasedReceivedNonceTracker implements IReceivedNonceTracker {
250
340
  };
251
341
  }
252
342
 
343
+ // SECURITY FIX (H-2): Rate limit check (BEFORE global limit to avoid unnecessary work)
344
+ if (this.checkRateLimit(sender)) {
345
+ return {
346
+ valid: false,
347
+ reason: `Rate limit exceeded for sender ${sender}: ` +
348
+ `Maximum ${this.maxNoncesPerMinute} nonces per minute allowed. ` +
349
+ `This may indicate a flood attack or misconfigured client. ` +
350
+ `Wait 1 minute before retrying.`,
351
+ receivedNonce: nonce
352
+ };
353
+ }
354
+
355
+ // SECURITY FIX (H-2): Periodic cleanup every 100 validations (amortized cost)
356
+ if (this.totalEntries % 100 === 0) {
357
+ this.cleanupRateLimitState();
358
+ }
359
+
360
+ // SECURITY FIX (HIGH-2): Check global limit BEFORE adding
361
+ if (this.totalEntries >= this.maxTotalEntries) {
362
+ return {
363
+ valid: false,
364
+ reason: `Global nonce tracker limit reached (${this.maxTotalEntries} entries). ` +
365
+ `This may indicate a DoS attack or need for cleanup. ` +
366
+ `Current usage: ${this.totalEntries} entries across ${this.getCombinationCount()} sender+type combinations.`,
367
+ receivedNonce: nonce
368
+ };
369
+ }
370
+
253
371
  // Get sender's nonce map
254
372
  let senderNonces = this.usedNonces.get(sender);
255
373
  if (!senderNonces) {
@@ -273,11 +391,53 @@ export class SetBasedReceivedNonceTracker implements IReceivedNonceTracker {
273
391
  };
274
392
  }
275
393
 
394
+ // SECURITY FIX (NEW-H-2): Auto-cleanup if max size per type reached
395
+ if (usedSet.size >= this.maxSizePerType) {
396
+ // Keep only last 80% of entries (sorted by nonce value)
397
+ const keepCount = Math.floor(this.maxSizePerType * 0.8);
398
+ const sortedNonces = Array.from(usedSet).sort((a, b) => {
399
+ const aVal = BigInt(a);
400
+ const bVal = BigInt(b);
401
+ return aVal < bVal ? -1 : aVal > bVal ? 1 : 0;
402
+ });
403
+ const removedCount = usedSet.size - keepCount;
404
+ usedSet = new Set(sortedNonces.slice(-keepCount));
405
+ senderNonces.set(messageType, usedSet);
406
+ // SECURITY FIX (HIGH-2): Update global counter
407
+ this.totalEntries -= removedCount;
408
+ }
409
+
276
410
  // Valid nonce - record it
277
411
  usedSet.add(nonce);
412
+ // SECURITY FIX (HIGH-2): Update global counter
413
+ this.totalEntries++;
278
414
  return { valid: true };
279
415
  }
280
416
 
417
+ /**
418
+ * Get number of sender+messageType combinations (for monitoring)
419
+ * SECURITY FIX (HIGH-2): Monitoring method
420
+ */
421
+ private getCombinationCount(): number {
422
+ let count = 0;
423
+ this.usedNonces.forEach(senderMap => {
424
+ count += senderMap.size;
425
+ });
426
+ return count;
427
+ }
428
+
429
+ /**
430
+ * Get memory usage statistics
431
+ * SECURITY FIX (HIGH-2): Monitoring method for DoS detection
432
+ */
433
+ getMemoryUsage(): { totalEntries: number; combinations: number; maxTotalEntries: number } {
434
+ return {
435
+ totalEntries: this.totalEntries,
436
+ combinations: this.getCombinationCount(),
437
+ maxTotalEntries: this.maxTotalEntries
438
+ };
439
+ }
440
+
281
441
  /**
282
442
  * Check if a nonce has been used
283
443
  */
@@ -327,6 +487,11 @@ export class SetBasedReceivedNonceTracker implements IReceivedNonceTracker {
327
487
  reset(sender: string, messageType: string): void {
328
488
  const senderNonces = this.usedNonces.get(sender);
329
489
  if (senderNonces) {
490
+ const usedSet = senderNonces.get(messageType);
491
+ if (usedSet) {
492
+ // SECURITY FIX (HIGH-2): Update global counter
493
+ this.totalEntries -= usedSet.size;
494
+ }
330
495
  senderNonces.delete(messageType);
331
496
  if (senderNonces.size === 0) {
332
497
  this.usedNonces.delete(sender);
@@ -339,6 +504,8 @@ export class SetBasedReceivedNonceTracker implements IReceivedNonceTracker {
339
504
  */
340
505
  clearAll(): void {
341
506
  this.usedNonces.clear();
507
+ // SECURITY FIX (HIGH-2): Reset global counter
508
+ this.totalEntries = 0;
342
509
  }
343
510
 
344
511
  /**
@@ -377,8 +544,11 @@ export class SetBasedReceivedNonceTracker implements IReceivedNonceTracker {
377
544
  });
378
545
 
379
546
  // Keep only the last N nonces
547
+ const removedCount = usedSet.size - keepLast;
380
548
  const toKeep = new Set(sortedNonces.slice(-keepLast));
381
549
  senderNonces.set(messageType, toKeep);
550
+ // SECURITY FIX (HIGH-2): Update global counter
551
+ this.totalEntries -= removedCount;
382
552
  }
383
553
  }
384
554
 
@@ -0,0 +1,416 @@
1
+ /**
2
+ * SDKLifecycle - Proper cleanup and resource management
3
+ *
4
+ * SECURITY FIX (M-8): Ensures proper cleanup on SDK shutdown:
5
+ * - Connection cleanup
6
+ * - Pending request handling
7
+ * - Memory release
8
+ * - Graceful shutdown
9
+ *
10
+ * @module utils/SDKLifecycle
11
+ */
12
+
13
+ import { sdkLogger, Logger } from './Logger';
14
+
15
+ /**
16
+ * Disposable resource interface
17
+ */
18
+ export interface Disposable {
19
+ /** Cleanup method */
20
+ dispose(): Promise<void> | void;
21
+ }
22
+
23
+ /**
24
+ * Shutdown handler function
25
+ */
26
+ export type ShutdownHandler = () => Promise<void> | void;
27
+
28
+ /**
29
+ * Lifecycle event types
30
+ */
31
+ export type LifecycleEvent =
32
+ | 'initializing'
33
+ | 'ready'
34
+ | 'shutting-down'
35
+ | 'shutdown'
36
+ | 'error';
37
+
38
+ /**
39
+ * Lifecycle event listener
40
+ */
41
+ export type LifecycleListener = (event: LifecycleEvent, data?: unknown) => void;
42
+
43
+ /**
44
+ * SDK Lifecycle Manager
45
+ *
46
+ * Manages SDK initialization, shutdown, and resource cleanup.
47
+ *
48
+ * @example
49
+ * ```typescript
50
+ * const lifecycle = new SDKLifecycle();
51
+ *
52
+ * // Register cleanup handlers
53
+ * lifecycle.onShutdown(async () => {
54
+ * await closeConnections();
55
+ * });
56
+ *
57
+ * // Register disposable resources
58
+ * lifecycle.registerDisposable(myResource);
59
+ *
60
+ * // Later, initiate shutdown
61
+ * await lifecycle.shutdown();
62
+ * ```
63
+ */
64
+ export class SDKLifecycle {
65
+ private state: LifecycleEvent = 'initializing';
66
+ private shutdownHandlers: ShutdownHandler[] = [];
67
+ private disposables: Disposable[] = [];
68
+ private listeners: LifecycleListener[] = [];
69
+ private shutdownPromise: Promise<void> | null = null;
70
+ private readonly logger: Logger;
71
+ private isShuttingDown = false;
72
+
73
+ // SECURITY FIX (NEW-HIGH-2): Store handler references for cleanup
74
+ private processHandlers: {
75
+ sigint?: () => void;
76
+ sigterm?: () => void;
77
+ uncaughtException?: (error: Error) => void;
78
+ unhandledRejection?: (reason: unknown) => void;
79
+ } = {};
80
+ private processHandlersRegistered = false;
81
+
82
+ constructor(logger?: Logger) {
83
+ this.logger = logger ?? sdkLogger.child('Lifecycle');
84
+
85
+ // Register process shutdown handlers
86
+ this.registerProcessHandlers();
87
+ }
88
+
89
+ /**
90
+ * Get current lifecycle state
91
+ */
92
+ getState(): LifecycleEvent {
93
+ return this.state;
94
+ }
95
+
96
+ /**
97
+ * Check if SDK is ready for operations
98
+ */
99
+ isReady(): boolean {
100
+ return this.state === 'ready';
101
+ }
102
+
103
+ /**
104
+ * Mark SDK as ready
105
+ */
106
+ markReady(): void {
107
+ this.state = 'ready';
108
+ this.emit('ready');
109
+ this.logger.info('SDK ready');
110
+ }
111
+
112
+ /**
113
+ * Register a shutdown handler
114
+ *
115
+ * @param handler - Function to call during shutdown
116
+ * @returns Unregister function
117
+ */
118
+ onShutdown(handler: ShutdownHandler): () => void {
119
+ this.shutdownHandlers.push(handler);
120
+
121
+ return () => {
122
+ const index = this.shutdownHandlers.indexOf(handler);
123
+ if (index > -1) {
124
+ this.shutdownHandlers.splice(index, 1);
125
+ }
126
+ };
127
+ }
128
+
129
+ /**
130
+ * Register a disposable resource
131
+ *
132
+ * @param disposable - Resource with dispose() method
133
+ * @returns Unregister function
134
+ */
135
+ registerDisposable(disposable: Disposable): () => void {
136
+ this.disposables.push(disposable);
137
+
138
+ return () => {
139
+ const index = this.disposables.indexOf(disposable);
140
+ if (index > -1) {
141
+ this.disposables.splice(index, 1);
142
+ }
143
+ };
144
+ }
145
+
146
+ /**
147
+ * Add lifecycle event listener
148
+ *
149
+ * @param listener - Event listener function
150
+ * @returns Unregister function
151
+ */
152
+ addListener(listener: LifecycleListener): () => void {
153
+ this.listeners.push(listener);
154
+
155
+ return () => {
156
+ const index = this.listeners.indexOf(listener);
157
+ if (index > -1) {
158
+ this.listeners.splice(index, 1);
159
+ }
160
+ };
161
+ }
162
+
163
+ /**
164
+ * Emit lifecycle event
165
+ */
166
+ private emit(event: LifecycleEvent, data?: unknown): void {
167
+ for (const listener of this.listeners) {
168
+ try {
169
+ listener(event, data);
170
+ } catch (error) {
171
+ this.logger.error('Lifecycle listener error', { event }, error as Error);
172
+ }
173
+ }
174
+ }
175
+
176
+ /**
177
+ * Initiate graceful shutdown
178
+ *
179
+ * @param timeout - Maximum time to wait for cleanup (ms)
180
+ * @returns Promise that resolves when shutdown is complete
181
+ */
182
+ async shutdown(timeout = 30000): Promise<void> {
183
+ // Prevent multiple shutdown calls
184
+ if (this.shutdownPromise) {
185
+ return this.shutdownPromise;
186
+ }
187
+
188
+ if (this.isShuttingDown) {
189
+ return;
190
+ }
191
+
192
+ this.isShuttingDown = true;
193
+ this.state = 'shutting-down';
194
+ this.emit('shutting-down');
195
+ this.logger.info('SDK shutting down...');
196
+
197
+ this.shutdownPromise = this.executeShutdown(timeout);
198
+ return this.shutdownPromise;
199
+ }
200
+
201
+ /**
202
+ * Execute shutdown sequence
203
+ */
204
+ private async executeShutdown(timeout: number): Promise<void> {
205
+ const startTime = Date.now();
206
+ const errors: Error[] = [];
207
+
208
+ // Create timeout promise
209
+ const timeoutPromise = new Promise<void>((_, reject) => {
210
+ setTimeout(() => {
211
+ reject(new Error(`Shutdown timed out after ${timeout}ms`));
212
+ }, timeout);
213
+ });
214
+
215
+ try {
216
+ // Run shutdown handlers first (in reverse order - LIFO)
217
+ const handlersPromise = (async () => {
218
+ for (let i = this.shutdownHandlers.length - 1; i >= 0; i--) {
219
+ try {
220
+ const elapsed = Date.now() - startTime;
221
+ if (elapsed >= timeout) {
222
+ this.logger.warn('Shutdown timeout reached, skipping remaining handlers');
223
+ break;
224
+ }
225
+
226
+ const handler = this.shutdownHandlers[i];
227
+ await handler();
228
+ } catch (error) {
229
+ this.logger.error('Shutdown handler error', {}, error as Error);
230
+ errors.push(error as Error);
231
+ }
232
+ }
233
+
234
+ // Dispose resources (in reverse order)
235
+ for (let i = this.disposables.length - 1; i >= 0; i--) {
236
+ try {
237
+ const elapsed = Date.now() - startTime;
238
+ if (elapsed >= timeout) {
239
+ this.logger.warn('Shutdown timeout reached, skipping remaining disposables');
240
+ break;
241
+ }
242
+
243
+ const disposable = this.disposables[i];
244
+ await disposable.dispose();
245
+ } catch (error) {
246
+ this.logger.error('Disposable cleanup error', {}, error as Error);
247
+ errors.push(error as Error);
248
+ }
249
+ }
250
+ })();
251
+
252
+ // Race against timeout
253
+ await Promise.race([handlersPromise, timeoutPromise]);
254
+
255
+ } catch (error) {
256
+ if ((error as Error).message.includes('timed out')) {
257
+ this.logger.warn('Shutdown timed out, forcing cleanup');
258
+ } else {
259
+ errors.push(error as Error);
260
+ }
261
+ }
262
+
263
+ // SECURITY FIX (NEW-HIGH-2): Remove process handlers to prevent memory leaks
264
+ this.unregisterProcessHandlers();
265
+
266
+ // Clear registrations
267
+ this.shutdownHandlers = [];
268
+ this.disposables = [];
269
+
270
+ this.state = 'shutdown';
271
+ this.emit('shutdown');
272
+ this.logger.info('SDK shutdown complete', { errors: errors.length });
273
+
274
+ if (errors.length > 0) {
275
+ this.logger.error('Shutdown completed with errors', {
276
+ errorCount: errors.length,
277
+ errors: errors.map((e) => e.message),
278
+ });
279
+ }
280
+ }
281
+
282
+ /**
283
+ * Register process-level shutdown handlers
284
+ *
285
+ * SECURITY FIX (NEW-HIGH-2): Store handler references for cleanup
286
+ * to prevent memory leaks when multiple SDKLifecycle instances are created.
287
+ */
288
+ private registerProcessHandlers(): void {
289
+ // Only register in Node.js environment
290
+ if (typeof process === 'undefined') {
291
+ return;
292
+ }
293
+
294
+ // SECURITY FIX (NEW-HIGH-2): Prevent duplicate registrations
295
+ if (this.processHandlersRegistered) {
296
+ return;
297
+ }
298
+
299
+ // SECURITY FIX (NEW-HIGH-2): Create named handlers we can remove later
300
+ this.processHandlers.sigint = () => {
301
+ this.logger.info('Received SIGINT, initiating shutdown');
302
+ this.shutdown().then(() => {
303
+ process.exit(0);
304
+ }).catch((error) => {
305
+ this.logger.error('Shutdown error', {}, error);
306
+ process.exit(1);
307
+ });
308
+ };
309
+
310
+ this.processHandlers.sigterm = () => {
311
+ this.logger.info('Received SIGTERM, initiating shutdown');
312
+ this.shutdown().then(() => {
313
+ process.exit(0);
314
+ }).catch((error) => {
315
+ this.logger.error('Shutdown error', {}, error);
316
+ process.exit(1);
317
+ });
318
+ };
319
+
320
+ this.processHandlers.uncaughtException = (error: Error) => {
321
+ this.logger.error('Uncaught exception', {}, error);
322
+ this.emit('error', error);
323
+ this.shutdown().finally(() => {
324
+ process.exit(1);
325
+ });
326
+ };
327
+
328
+ this.processHandlers.unhandledRejection = (reason: unknown) => {
329
+ const error = reason instanceof Error ? reason : new Error(String(reason));
330
+ this.logger.error('Unhandled rejection', {}, error);
331
+ this.emit('error', error);
332
+ };
333
+
334
+ // Handle termination signals
335
+ process.on('SIGINT', this.processHandlers.sigint);
336
+ process.on('SIGTERM', this.processHandlers.sigterm);
337
+
338
+ // Handle uncaught errors
339
+ process.on('uncaughtException', this.processHandlers.uncaughtException);
340
+ process.on('unhandledRejection', this.processHandlers.unhandledRejection);
341
+
342
+ this.processHandlersRegistered = true;
343
+ }
344
+
345
+ /**
346
+ * Unregister process-level shutdown handlers
347
+ *
348
+ * SECURITY FIX (NEW-HIGH-2): Remove handlers to prevent memory leaks
349
+ */
350
+ private unregisterProcessHandlers(): void {
351
+ if (typeof process === 'undefined' || !this.processHandlersRegistered) {
352
+ return;
353
+ }
354
+
355
+ if (this.processHandlers.sigint) {
356
+ process.removeListener('SIGINT', this.processHandlers.sigint);
357
+ }
358
+ if (this.processHandlers.sigterm) {
359
+ process.removeListener('SIGTERM', this.processHandlers.sigterm);
360
+ }
361
+ if (this.processHandlers.uncaughtException) {
362
+ process.removeListener('uncaughtException', this.processHandlers.uncaughtException);
363
+ }
364
+ if (this.processHandlers.unhandledRejection) {
365
+ process.removeListener('unhandledRejection', this.processHandlers.unhandledRejection);
366
+ }
367
+
368
+ this.processHandlers = {};
369
+ this.processHandlersRegistered = false;
370
+ }
371
+
372
+ /**
373
+ * Create a disposable wrapper for any cleanup function
374
+ */
375
+ static createDisposable(cleanup: () => Promise<void> | void): Disposable {
376
+ return {
377
+ dispose: cleanup,
378
+ };
379
+ }
380
+ }
381
+
382
+ /**
383
+ * Global SDK lifecycle manager instance
384
+ */
385
+ export const sdkLifecycle = new SDKLifecycle();
386
+
387
+ /**
388
+ * Convenience function to run cleanup on shutdown
389
+ *
390
+ * @example
391
+ * ```typescript
392
+ * const cleanup = onShutdown(async () => {
393
+ * await closeDatabase();
394
+ * });
395
+ *
396
+ * // Later, to remove the handler:
397
+ * cleanup();
398
+ * ```
399
+ */
400
+ export function onShutdown(handler: ShutdownHandler): () => void {
401
+ return sdkLifecycle.onShutdown(handler);
402
+ }
403
+
404
+ /**
405
+ * Convenience function to register disposable
406
+ */
407
+ export function registerDisposable(disposable: Disposable): () => void {
408
+ return sdkLifecycle.registerDisposable(disposable);
409
+ }
410
+
411
+ /**
412
+ * Convenience function to shutdown SDK
413
+ */
414
+ export function shutdownSDK(timeout?: number): Promise<void> {
415
+ return sdkLifecycle.shutdown(timeout);
416
+ }
@@ -0,0 +1,78 @@
1
+ /**
2
+ * SecureNonce - Cryptographically secure nonce generation
3
+ *
4
+ * SECURITY FIX (NEW-H-3): Provides secure random nonce generation
5
+ * to prevent weak randomness vulnerabilities in EIP-712 message signing.
6
+ *
7
+ * Reference: V7 Re-Audit NEW-H-3 (Weak Random Nonce Generation)
8
+ *
9
+ * @module utils/SecureNonce
10
+ */
11
+
12
+ import { ethers } from 'ethers';
13
+
14
+ /**
15
+ * Generate a cryptographically secure random nonce (bytes32)
16
+ *
17
+ * Uses ethers.js randomBytes() which:
18
+ * - Uses Node.js crypto.randomBytes() (CSPRNG)
19
+ * - Uses Web Crypto API in browsers (window.crypto.getRandomValues)
20
+ * - Guaranteed to be cryptographically secure
21
+ *
22
+ * @returns 32-byte hex string (0x...)
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * import { generateSecureNonce } from '@agirails/sdk';
27
+ *
28
+ * const nonce = generateSecureNonce();
29
+ * console.log(nonce); // 0x1234...abcd (64 hex chars)
30
+ * ```
31
+ */
32
+ export function generateSecureNonce(): string {
33
+ return ethers.hexlify(ethers.randomBytes(32));
34
+ }
35
+
36
+ /**
37
+ * Validate nonce format (must be bytes32)
38
+ *
39
+ * @param nonce - Nonce to validate
40
+ * @returns true if valid bytes32 format
41
+ *
42
+ * @example
43
+ * ```typescript
44
+ * isValidNonce('0x' + '00'.repeat(32)); // true
45
+ * isValidNonce('0x1234'); // false (too short)
46
+ * isValidNonce('not-hex'); // false (invalid format)
47
+ * ```
48
+ */
49
+ export function isValidNonce(nonce: string): boolean {
50
+ return /^0x[a-fA-F0-9]{64}$/.test(nonce);
51
+ }
52
+
53
+ /**
54
+ * Generate an array of secure nonces
55
+ *
56
+ * @param count - Number of nonces to generate
57
+ * @returns Array of bytes32 hex strings
58
+ *
59
+ * @example
60
+ * ```typescript
61
+ * const nonces = generateSecureNonces(10);
62
+ * console.log(nonces.length); // 10
63
+ * ```
64
+ */
65
+ export function generateSecureNonces(count: number): string[] {
66
+ if (count <= 0) {
67
+ throw new Error('Count must be positive');
68
+ }
69
+ if (count > 10000) {
70
+ throw new Error('Count exceeds maximum allowed (10000)');
71
+ }
72
+
73
+ const nonces: string[] = [];
74
+ for (let i = 0; i < count; i++) {
75
+ nonces.push(generateSecureNonce());
76
+ }
77
+ return nonces;
78
+ }