@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
@@ -0,0 +1,276 @@
1
+ /**
2
+ * Semaphore - Concurrency limiter for ACTP SDK
3
+ *
4
+ * SECURITY FIX (MEDIUM-4): Prevents unbounded concurrent execution
5
+ * which could lead to resource exhaustion (memory/CPU DoS).
6
+ *
7
+ * @module utils/Semaphore
8
+ */
9
+
10
+ /**
11
+ * Simple semaphore for limiting concurrent operations
12
+ *
13
+ * Uses a FIFO queue to ensure fair scheduling of waiting tasks.
14
+ */
15
+ export class Semaphore {
16
+ private permits: number;
17
+ private readonly maxPermits: number;
18
+ private readonly waitQueue: Array<{
19
+ resolve: () => void;
20
+ reject: (error: Error) => void;
21
+ }> = [];
22
+
23
+ /**
24
+ * Create a semaphore with specified concurrency limit
25
+ *
26
+ * @param maxPermits - Maximum concurrent permits (default: 10)
27
+ * @throws Error if maxPermits is not positive
28
+ */
29
+ constructor(maxPermits: number = 10) {
30
+ if (maxPermits <= 0 || !Number.isInteger(maxPermits)) {
31
+ throw new Error(`maxPermits must be a positive integer, got: ${maxPermits}`);
32
+ }
33
+ this.maxPermits = maxPermits;
34
+ this.permits = maxPermits;
35
+ }
36
+
37
+ /**
38
+ * Acquire a permit, waiting if necessary
39
+ *
40
+ * @param timeoutMs - Optional timeout in milliseconds (0 = no timeout)
41
+ * @returns Promise that resolves when permit is acquired
42
+ * @throws Error if timeout is exceeded
43
+ */
44
+ async acquire(timeoutMs: number = 0): Promise<void> {
45
+ if (this.permits > 0) {
46
+ this.permits--;
47
+ return;
48
+ }
49
+
50
+ // No permits available, queue the request
51
+ return new Promise<void>((resolve, reject) => {
52
+ const waiter = { resolve, reject };
53
+ this.waitQueue.push(waiter);
54
+
55
+ // Set up timeout if specified
56
+ if (timeoutMs > 0) {
57
+ const timeoutId = setTimeout(() => {
58
+ const index = this.waitQueue.indexOf(waiter);
59
+ if (index >= 0) {
60
+ this.waitQueue.splice(index, 1);
61
+ reject(new Error(`Semaphore acquire timeout after ${timeoutMs}ms`));
62
+ }
63
+ }, timeoutMs);
64
+
65
+ // Clear timeout when resolved
66
+ const originalResolve = waiter.resolve;
67
+ waiter.resolve = () => {
68
+ clearTimeout(timeoutId);
69
+ originalResolve();
70
+ };
71
+ }
72
+ });
73
+ }
74
+
75
+ /**
76
+ * Try to acquire a permit without waiting
77
+ *
78
+ * @returns true if permit was acquired, false if none available
79
+ */
80
+ tryAcquire(): boolean {
81
+ if (this.permits > 0) {
82
+ this.permits--;
83
+ return true;
84
+ }
85
+ return false;
86
+ }
87
+
88
+ /**
89
+ * Release a permit
90
+ *
91
+ * @throws Error if releasing more permits than acquired
92
+ */
93
+ release(): void {
94
+ if (this.permits >= this.maxPermits) {
95
+ throw new Error('Cannot release: no permits held');
96
+ }
97
+
98
+ // If there are waiters, give permit to first in queue (FIFO)
99
+ if (this.waitQueue.length > 0) {
100
+ const waiter = this.waitQueue.shift()!;
101
+ waiter.resolve();
102
+ } else {
103
+ this.permits++;
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Execute a function with semaphore protection
109
+ *
110
+ * Automatically acquires before execution and releases after,
111
+ * even if the function throws.
112
+ *
113
+ * @param fn - Function to execute
114
+ * @param timeoutMs - Optional timeout for acquiring permit
115
+ * @returns Result of the function
116
+ */
117
+ async run<T>(fn: () => Promise<T> | T, timeoutMs: number = 0): Promise<T> {
118
+ await this.acquire(timeoutMs);
119
+ try {
120
+ return await fn();
121
+ } finally {
122
+ this.release();
123
+ }
124
+ }
125
+
126
+ /**
127
+ * Get current available permits
128
+ */
129
+ get availablePermits(): number {
130
+ return this.permits;
131
+ }
132
+
133
+ /**
134
+ * Get number of waiters in queue
135
+ */
136
+ get queueLength(): number {
137
+ return this.waitQueue.length;
138
+ }
139
+
140
+ /**
141
+ * Get maximum permits
142
+ */
143
+ get limit(): number {
144
+ return this.maxPermits;
145
+ }
146
+
147
+ /**
148
+ * Check if semaphore is fully utilized
149
+ */
150
+ get isFull(): boolean {
151
+ return this.permits === 0;
152
+ }
153
+
154
+ /**
155
+ * Cancel all waiting tasks
156
+ *
157
+ * @param reason - Error message for rejected promises
158
+ */
159
+ cancelAll(reason: string = 'Semaphore cancelled'): void {
160
+ while (this.waitQueue.length > 0) {
161
+ const waiter = this.waitQueue.shift()!;
162
+ waiter.reject(new Error(reason));
163
+ }
164
+ }
165
+ }
166
+
167
+ /**
168
+ * Rate limiter using sliding window algorithm
169
+ *
170
+ * SECURITY FIX (MEDIUM-4): Complements semaphore for rate-based limiting
171
+ */
172
+ export class RateLimiter {
173
+ private readonly timestamps: number[] = [];
174
+ private readonly windowMs: number;
175
+ private readonly maxRequests: number;
176
+
177
+ /**
178
+ * Create a rate limiter
179
+ *
180
+ * @param maxRequests - Maximum requests per window
181
+ * @param windowMs - Time window in milliseconds
182
+ */
183
+ constructor(maxRequests: number, windowMs: number) {
184
+ if (maxRequests <= 0) {
185
+ throw new Error('maxRequests must be positive');
186
+ }
187
+ if (windowMs <= 0) {
188
+ throw new Error('windowMs must be positive');
189
+ }
190
+ this.maxRequests = maxRequests;
191
+ this.windowMs = windowMs;
192
+ }
193
+
194
+ /**
195
+ * Check if a request is allowed and record it
196
+ *
197
+ * @returns true if request is allowed, false if rate limited
198
+ */
199
+ tryAcquire(): boolean {
200
+ const now = Date.now();
201
+ const windowStart = now - this.windowMs;
202
+
203
+ // Remove timestamps outside the window
204
+ while (this.timestamps.length > 0 && this.timestamps[0] < windowStart) {
205
+ this.timestamps.shift();
206
+ }
207
+
208
+ // Check if we're at the limit
209
+ if (this.timestamps.length >= this.maxRequests) {
210
+ return false;
211
+ }
212
+
213
+ // Record this request
214
+ this.timestamps.push(now);
215
+ return true;
216
+ }
217
+
218
+ /**
219
+ * Wait until a request is allowed
220
+ *
221
+ * @param timeoutMs - Optional timeout
222
+ * @returns Promise that resolves when request is allowed
223
+ */
224
+ async acquire(timeoutMs: number = 0): Promise<void> {
225
+ const startTime = Date.now();
226
+
227
+ while (!this.tryAcquire()) {
228
+ if (timeoutMs > 0 && Date.now() - startTime >= timeoutMs) {
229
+ throw new Error(`Rate limiter timeout after ${timeoutMs}ms`);
230
+ }
231
+
232
+ // Wait a short time before retrying
233
+ const waitTime = Math.min(100, this.timeUntilNextSlot());
234
+ await new Promise((resolve) => setTimeout(resolve, waitTime));
235
+ }
236
+ }
237
+
238
+ /**
239
+ * Get time until next slot is available
240
+ *
241
+ * @returns Milliseconds until next slot, or 0 if slot available
242
+ */
243
+ timeUntilNextSlot(): number {
244
+ if (this.timestamps.length < this.maxRequests) {
245
+ return 0;
246
+ }
247
+
248
+ const now = Date.now();
249
+ const windowStart = now - this.windowMs;
250
+ const oldestTimestamp = this.timestamps[0];
251
+
252
+ if (oldestTimestamp <= windowStart) {
253
+ return 0;
254
+ }
255
+
256
+ return oldestTimestamp - windowStart;
257
+ }
258
+
259
+ /**
260
+ * Get current usage stats
261
+ */
262
+ get stats(): { current: number; max: number; windowMs: number } {
263
+ // Clean up old timestamps
264
+ const now = Date.now();
265
+ const windowStart = now - this.windowMs;
266
+ while (this.timestamps.length > 0 && this.timestamps[0] < windowStart) {
267
+ this.timestamps.shift();
268
+ }
269
+
270
+ return {
271
+ current: this.timestamps.length,
272
+ max: this.maxRequests,
273
+ windowMs: this.windowMs,
274
+ };
275
+ }
276
+ }
@@ -0,0 +1,387 @@
1
+ /**
2
+ * UsedAttestationTracker - Prevents EAS Attestation Replay Attacks (C-1)
3
+ *
4
+ * Tracks which attestation UIDs have been used for which transaction IDs.
5
+ * This prevents a malicious provider from reusing an attestation from
6
+ * Transaction A to settle Transaction B.
7
+ *
8
+ * SECURITY: ACTPKernel V1 contract accepts any attestationUID without validation.
9
+ * This tracker provides SDK-side protection until contract is upgraded.
10
+ *
11
+ * @module utils/UsedAttestationTracker
12
+ */
13
+
14
+ import { assertSafeFileForRead, ensureSafeDir, ensureSafeFile } from './fsSafe';
15
+
16
+ /**
17
+ * Interface for tracking used attestations
18
+ */
19
+ export interface IUsedAttestationTracker {
20
+ /**
21
+ * Record that an attestation was used for a transaction
22
+ * @param attestationUID - EAS attestation UID (bytes32)
23
+ * @param txId - Transaction ID (bytes32)
24
+ * @returns true if recorded, false if already used for different transaction
25
+ *
26
+ * SECURITY FIX (HIGH-1): This method is now async to ensure persistence completes
27
+ * before returning. Use recordUsageSync() for fire-and-forget behavior.
28
+ */
29
+ recordUsage(attestationUID: string, txId: string): Promise<boolean>;
30
+
31
+ /**
32
+ * Check if attestation has been used
33
+ * @param attestationUID - EAS attestation UID (bytes32)
34
+ * @returns Transaction ID if used, null if not used
35
+ */
36
+ getUsageForAttestation(attestationUID: string): string | null;
37
+
38
+ /**
39
+ * Check if attestation is valid for transaction
40
+ * @param attestationUID - EAS attestation UID
41
+ * @param txId - Transaction ID
42
+ * @returns true if attestation is unused or already used for this txId
43
+ */
44
+ isValidForTransaction(attestationUID: string, txId: string): boolean;
45
+
46
+ /**
47
+ * Clear all tracked attestations
48
+ */
49
+ clear(): void;
50
+ }
51
+
52
+ /**
53
+ * In-Memory Used Attestation Tracker
54
+ *
55
+ * SECURITY FIX (C-1): Prevents attestation replay attacks by tracking
56
+ * which attestation UIDs have been used for which transactions.
57
+ *
58
+ * SECURITY FIX (NEW-H-2): LRU-style cache with max size to prevent DoS
59
+ *
60
+ * WARNING: In-memory only. For production:
61
+ * - Use persistent storage (Redis, PostgreSQL, etc.)
62
+ * - Implement recovery from blockchain events
63
+ */
64
+ export class InMemoryUsedAttestationTracker implements IUsedAttestationTracker {
65
+ // Map: attestationUID -> txId
66
+ private usedAttestations: Map<string, string> = new Map();
67
+
68
+ // SECURITY FIX (NEW-H-2): Maximum size to prevent memory exhaustion DoS
69
+ private readonly maxSize: number;
70
+
71
+ /**
72
+ * Create in-memory tracker with optional max size
73
+ * @param maxSize - Maximum entries to store (default: 100,000)
74
+ */
75
+ constructor(maxSize: number = 100000) {
76
+ if (maxSize <= 0) {
77
+ throw new Error('maxSize must be positive');
78
+ }
79
+ this.maxSize = maxSize;
80
+ }
81
+
82
+ /**
83
+ * Record that an attestation was used for a transaction
84
+ * @param attestationUID - EAS attestation UID (bytes32)
85
+ * @param txId - Transaction ID (bytes32)
86
+ * @returns true if recorded, false if already used for different transaction
87
+ *
88
+ * SECURITY FIX (NEW-H-2): LRU eviction when max size reached
89
+ * SECURITY FIX (HIGH-1): Now async for interface consistency
90
+ */
91
+ async recordUsage(attestationUID: string, txId: string): Promise<boolean> {
92
+ return this.recordUsageSync(attestationUID, txId);
93
+ }
94
+
95
+ /**
96
+ * Synchronous version of recordUsage (for backward compatibility)
97
+ * @param attestationUID - EAS attestation UID (bytes32)
98
+ * @param txId - Transaction ID (bytes32)
99
+ * @returns true if recorded, false if already used for different transaction
100
+ */
101
+ recordUsageSync(attestationUID: string, txId: string): boolean {
102
+ const normalizedUID = attestationUID.toLowerCase();
103
+ const normalizedTxId = txId.toLowerCase();
104
+
105
+ const existingTxId = this.usedAttestations.get(normalizedUID);
106
+
107
+ // If attestation was already used for a different transaction, reject
108
+ if (existingTxId && existingTxId !== normalizedTxId) {
109
+ return false;
110
+ }
111
+
112
+ // SECURITY FIX (NEW-H-2): Enforce max size limit with true LRU behavior
113
+ if (this.usedAttestations.size >= this.maxSize && !existingTxId) {
114
+ // Remove oldest entry (first entry in Map)
115
+ const firstKey = this.usedAttestations.keys().next().value;
116
+ if (firstKey) {
117
+ this.usedAttestations.delete(firstKey);
118
+ }
119
+ } else if (existingTxId) {
120
+ // SECURITY FIX (M-3): True LRU - delete and re-add to move to end
121
+ this.usedAttestations.delete(normalizedUID);
122
+ }
123
+
124
+ // Record the usage (at end for LRU)
125
+ this.usedAttestations.set(normalizedUID, normalizedTxId);
126
+ return true;
127
+ }
128
+
129
+ /**
130
+ * Check if attestation has been used
131
+ * @param attestationUID - EAS attestation UID (bytes32)
132
+ * @returns Transaction ID if used, null if not used
133
+ *
134
+ * SECURITY FIX (MEDIUM-4): Updates access order for true LRU behavior
135
+ * Accessed items are moved to end of Map (most recently used)
136
+ */
137
+ getUsageForAttestation(attestationUID: string): string | null {
138
+ const normalizedUID = attestationUID.toLowerCase();
139
+ const txId = this.usedAttestations.get(normalizedUID);
140
+
141
+ // SECURITY FIX (MEDIUM-4): True LRU - move accessed item to end
142
+ // Without this, eviction uses insertion order, not access order
143
+ if (txId !== undefined) {
144
+ this.usedAttestations.delete(normalizedUID);
145
+ this.usedAttestations.set(normalizedUID, txId);
146
+ }
147
+
148
+ return txId || null;
149
+ }
150
+
151
+ /**
152
+ * Check if attestation is valid for transaction
153
+ * @param attestationUID - EAS attestation UID
154
+ * @param txId - Transaction ID
155
+ * @returns true if attestation is unused or already used for this txId
156
+ *
157
+ * SECURITY FIX (MEDIUM-4): Updates access order for true LRU behavior
158
+ */
159
+ isValidForTransaction(attestationUID: string, txId: string): boolean {
160
+ const normalizedUID = attestationUID.toLowerCase();
161
+ const normalizedTxId = txId.toLowerCase();
162
+
163
+ const existingTxId = this.usedAttestations.get(normalizedUID);
164
+
165
+ // SECURITY FIX (MEDIUM-4): True LRU - move accessed item to end
166
+ if (existingTxId !== undefined) {
167
+ this.usedAttestations.delete(normalizedUID);
168
+ this.usedAttestations.set(normalizedUID, existingTxId);
169
+ }
170
+
171
+ // Valid if: not used OR used for same transaction
172
+ return !existingTxId || existingTxId === normalizedTxId;
173
+ }
174
+
175
+ /**
176
+ * Clear all tracked attestations
177
+ */
178
+ clear(): void {
179
+ this.usedAttestations.clear();
180
+ }
181
+
182
+ /**
183
+ * Get all tracked attestations (for debugging/persistence)
184
+ */
185
+ getAllUsages(): Record<string, string> {
186
+ return Object.fromEntries(this.usedAttestations.entries());
187
+ }
188
+
189
+ /**
190
+ * Get count of tracked attestations
191
+ */
192
+ getCount(): number {
193
+ return this.usedAttestations.size;
194
+ }
195
+
196
+ /**
197
+ * Cleanup old entries based on timestamp (optional)
198
+ *
199
+ * SECURITY FIX (NEW-H-2): Manual cleanup for old entries
200
+ * Note: This requires external timestamp tracking. For automatic cleanup,
201
+ * use FileBasedUsedAttestationTracker with periodic cleanup.
202
+ *
203
+ * @param maxAgeHours - Remove entries older than this many hours
204
+ */
205
+ cleanupOldEntries(maxAgeHours: number): number {
206
+ // In-memory tracker doesn't track timestamps
207
+ // This is a placeholder for future enhancement
208
+ console.warn(
209
+ 'cleanupOldEntries not implemented for InMemoryUsedAttestationTracker. ' +
210
+ 'Consider using FileBasedUsedAttestationTracker for time-based cleanup.'
211
+ );
212
+ return 0;
213
+ }
214
+ }
215
+
216
+ /**
217
+ * File-based Used Attestation Tracker for persistence
218
+ *
219
+ * SECURITY FIX (C-1): Persistent storage for attestation tracking
220
+ * SECURITY FIX (NEW-H-4): File locking to prevent concurrent write corruption
221
+ *
222
+ * Survives process restarts.
223
+ */
224
+ export class FileBasedUsedAttestationTracker implements IUsedAttestationTracker {
225
+ private inMemory: InMemoryUsedAttestationTracker;
226
+ private filePath: string;
227
+ private fs: typeof import('fs');
228
+ private path: typeof import('path');
229
+ private lockfile: typeof import('proper-lockfile');
230
+
231
+ constructor(stateDirectory: string) {
232
+ this.inMemory = new InMemoryUsedAttestationTracker();
233
+ this.fs = require('fs');
234
+ this.path = require('path');
235
+ // SECURITY FIX (NEW-H-4): File locking to prevent race conditions
236
+ this.lockfile = require('proper-lockfile');
237
+
238
+ // Ensure directory exists
239
+ const actpDir = this.path.join(stateDirectory, '.actp');
240
+ ensureSafeDir(actpDir, 0o755);
241
+
242
+ this.filePath = this.path.join(actpDir, 'used-attestations.json');
243
+
244
+ // Load existing data
245
+ this.loadFromFile();
246
+ }
247
+
248
+ private loadFromFile(): void {
249
+ if (!this.fs.existsSync(this.filePath)) return;
250
+
251
+ // SECURITY: Refuse to read from symlinked tracker files
252
+ assertSafeFileForRead(this.filePath);
253
+
254
+ // Basic size limit to avoid memory DoS on parse
255
+ const MAX_TRACKER_FILE_SIZE = 10 * 1024 * 1024; // 10MB
256
+ const st = this.fs.statSync(this.filePath);
257
+ if (st.size > MAX_TRACKER_FILE_SIZE) {
258
+ throw new Error(
259
+ `used-attestations.json exceeds ${MAX_TRACKER_FILE_SIZE / 1024 / 1024}MB limit: ${this.filePath}`
260
+ );
261
+ }
262
+
263
+ try {
264
+ const data = JSON.parse(this.fs.readFileSync(this.filePath, 'utf-8'));
265
+ for (const [uid, txId] of Object.entries(data)) {
266
+ this.inMemory.recordUsageSync(uid, txId as string);
267
+ }
268
+ } catch (e: any) {
269
+ // Fail closed: losing replay-protection state is a security issue.
270
+ throw new Error(
271
+ `Failed to parse used-attestations.json (replay protection would be disabled). ` +
272
+ `Fix/delete the file: ${this.filePath}. Error: ${e?.message || String(e)}`
273
+ );
274
+ }
275
+ }
276
+
277
+ /**
278
+ * Save data to file with file locking
279
+ *
280
+ * SECURITY FIX (NEW-H-4): File locking prevents concurrent write corruption
281
+ * SECURITY FIX (NEW-HIGH-1): Create file before locking if it doesn't exist
282
+ */
283
+ private async saveToFile(): Promise<void> {
284
+ const data = this.inMemory.getAllUsages();
285
+ const tempPath = `${this.filePath}.tmp`;
286
+
287
+ // SECURITY FIX (NEW-HIGH-1): Ensure file exists before locking
288
+ // proper-lockfile.lock() fails on non-existent files
289
+ ensureSafeFile(this.filePath, '{}', 0o644);
290
+
291
+ // SECURITY FIX (NEW-H-4): Acquire file lock before writing
292
+ let release: (() => Promise<void>) | null = null;
293
+ try {
294
+ release = await this.lockfile.lock(this.filePath, {
295
+ stale: 10000, // Lock expires after 10 seconds if process crashes
296
+ retries: {
297
+ retries: 5,
298
+ minTimeout: 100,
299
+ maxTimeout: 500
300
+ }
301
+ });
302
+
303
+ // Atomic write: temp file + rename
304
+ if (this.fs.existsSync(tempPath)) {
305
+ this.fs.unlinkSync(tempPath);
306
+ }
307
+ this.fs.writeFileSync(tempPath, JSON.stringify(data, null, 2), {
308
+ encoding: 'utf-8',
309
+ mode: 0o644,
310
+ flag: 'wx'
311
+ });
312
+ this.fs.renameSync(tempPath, this.filePath);
313
+ } catch (error) {
314
+ // Clean up temp file on error
315
+ if (this.fs.existsSync(tempPath)) {
316
+ try {
317
+ this.fs.unlinkSync(tempPath);
318
+ } catch {
319
+ // Ignore cleanup errors
320
+ }
321
+ }
322
+ throw error;
323
+ } finally {
324
+ // Always release lock if acquired
325
+ if (release) {
326
+ await release();
327
+ }
328
+ }
329
+ }
330
+
331
+ /**
332
+ * Record attestation usage with guaranteed persistence
333
+ *
334
+ * SECURITY FIX (HIGH-1): Now properly awaits persistence to prevent data loss
335
+ */
336
+ async recordUsage(attestationUID: string, txId: string): Promise<boolean> {
337
+ const result = this.inMemory.recordUsageSync(attestationUID, txId);
338
+ if (result) {
339
+ // SECURITY FIX (HIGH-1): Await persistence to ensure data is saved
340
+ await this.saveToFile();
341
+ }
342
+ return result;
343
+ }
344
+
345
+ /**
346
+ * Fire-and-forget version for backward compatibility
347
+ * WARNING: May lose data if process crashes before save completes
348
+ */
349
+ recordUsageSync(attestationUID: string, txId: string): boolean {
350
+ const result = this.inMemory.recordUsageSync(attestationUID, txId);
351
+ if (result) {
352
+ this.saveToFile().catch((err) => {
353
+ console.error('Failed to save attestation tracker state:', err);
354
+ });
355
+ }
356
+ return result;
357
+ }
358
+
359
+ getUsageForAttestation(attestationUID: string): string | null {
360
+ return this.inMemory.getUsageForAttestation(attestationUID);
361
+ }
362
+
363
+ isValidForTransaction(attestationUID: string, txId: string): boolean {
364
+ return this.inMemory.isValidForTransaction(attestationUID, txId);
365
+ }
366
+
367
+ clear(): void {
368
+ this.inMemory.clear();
369
+ if (this.fs.existsSync(this.filePath)) {
370
+ this.fs.unlinkSync(this.filePath);
371
+ }
372
+ }
373
+ }
374
+
375
+ /**
376
+ * Factory to create attestation tracker
377
+ * @param stateDirectory - Optional directory for persistent storage
378
+ * @returns IUsedAttestationTracker instance
379
+ */
380
+ export function createUsedAttestationTracker(
381
+ stateDirectory?: string
382
+ ): IUsedAttestationTracker {
383
+ if (stateDirectory) {
384
+ return new FileBasedUsedAttestationTracker(stateDirectory);
385
+ }
386
+ return new InMemoryUsedAttestationTracker();
387
+ }