@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,473 @@
1
+ /**
2
+ * BaseAdapter - Abstract base class for all adapter implementations
3
+ *
4
+ * Provides shared utility methods for parsing user-friendly inputs into
5
+ * protocol-level types. All adapters extend this class to ensure consistent
6
+ * behavior across the Three-Level API.
7
+ *
8
+ * Key Responsibilities:
9
+ * - Amount parsing (string → bigint with 6 decimals for USDC)
10
+ * - Address validation (0x-prefixed hex)
11
+ * - Deadline parsing ("+24h" → Unix timestamp)
12
+ * - User-friendly error messages
13
+ *
14
+ * @module adapters/BaseAdapter
15
+ */
16
+
17
+ // ============================================================================
18
+ // Constants
19
+ // ============================================================================
20
+
21
+ /**
22
+ * Default dispute window in seconds (2 days).
23
+ * Used when no dispute window is specified in transaction parameters.
24
+ */
25
+ export const DEFAULT_DISPUTE_WINDOW_SECONDS = 172800;
26
+
27
+ /**
28
+ * Minimum dispute window in seconds (1 hour).
29
+ * Ensures requesters have reasonable time to dispute.
30
+ *
31
+ * SECURITY: Prevents providers from setting windows too short
32
+ * to avoid dispute detection.
33
+ */
34
+ export const MIN_DISPUTE_WINDOW_SECONDS = 3600; // 1 hour
35
+
36
+ /**
37
+ * Maximum dispute window in seconds (30 days).
38
+ * Prevents excessively long fund locks.
39
+ *
40
+ * SECURITY: Prevents DoS via indefinite fund locking.
41
+ */
42
+ export const MAX_DISPUTE_WINDOW_SECONDS = 30 * 24 * 3600; // 30 days
43
+
44
+ /**
45
+ * Default deadline offset in seconds (24 hours).
46
+ * Used when no deadline is specified in transaction parameters.
47
+ */
48
+ export const DEFAULT_DEADLINE_SECONDS = 86400;
49
+
50
+ /**
51
+ * Minimum transaction amount in USDC wei (6 decimals).
52
+ * $0.05 minimum per AGIRAILS protocol specification.
53
+ */
54
+ export const MIN_AMOUNT_WEI = 50_000n; // $0.05 USDC
55
+
56
+ /**
57
+ * Maximum deadline in hours (10 years).
58
+ * Prevents integer overflow in deadline calculations.
59
+ */
60
+ export const MAX_DEADLINE_HOURS = 87600; // 10 years
61
+
62
+ /**
63
+ * Maximum deadline in days (10 years).
64
+ * Prevents integer overflow in deadline calculations.
65
+ */
66
+ export const MAX_DEADLINE_DAYS = 3650; // 10 years
67
+
68
+ /**
69
+ * Custom error for validation failures.
70
+ *
71
+ * Thrown when user input is invalid (e.g., malformed address, negative amount).
72
+ * Provides descriptive error messages for end-user debugging.
73
+ *
74
+ * @example
75
+ * ```typescript
76
+ * throw new ValidationError('Invalid amount format: "abc". Expected number like "100" or "100.50"');
77
+ * ```
78
+ */
79
+ export class ValidationError extends Error {
80
+ constructor(message: string) {
81
+ super(message);
82
+ this.name = 'ValidationError';
83
+ }
84
+ }
85
+
86
+ /**
87
+ * Abstract base adapter with shared parsing utilities.
88
+ *
89
+ * Provides common functionality for all adapter implementations:
90
+ * - Amount parsing (USDC has 6 decimals)
91
+ * - Address validation
92
+ * - Deadline parsing (relative time or Unix timestamp)
93
+ * - Amount formatting
94
+ *
95
+ * @abstract
96
+ */
97
+ export abstract class BaseAdapter {
98
+ /**
99
+ * Creates a new BaseAdapter instance.
100
+ *
101
+ * @param requesterAddress - The requester's Ethereum address
102
+ */
103
+ constructor(protected requesterAddress: string) {}
104
+
105
+ /**
106
+ * Parse user-friendly amount string to bigint (USDC has 6 decimals).
107
+ *
108
+ * Accepts multiple input formats:
109
+ * - "100" → 100_000_000n (100.00 USDC)
110
+ * - "100.50" → 100_500_000n (100.50 USDC)
111
+ * - "100 USDC" → 100_000_000n (strips currency suffix)
112
+ * - "$100" → 100_000_000n (strips $ prefix)
113
+ * - 100 (number) → 100_000_000n
114
+ *
115
+ * Rejects:
116
+ * - "abc" → throws ValidationError
117
+ * - "" → throws ValidationError
118
+ * - "-100" → throws ValidationError (negative amounts)
119
+ * - "100.1234567" → throws ValidationError (too many decimals)
120
+ *
121
+ * @param amount - Amount as string or number
122
+ * @returns Amount as bigint with 6 decimals
123
+ * @throws {ValidationError} If amount format is invalid
124
+ *
125
+ * @example
126
+ * ```typescript
127
+ * const amount = this.parseAmount("100.50"); // 100_500_000n
128
+ * const amount = this.parseAmount("100 USDC"); // 100_000_000n
129
+ * ```
130
+ */
131
+ protected parseAmount(amount: string | number): bigint {
132
+ // Issue #3 Fix: Normalize input - handle all Unicode whitespace
133
+ // Converts all Unicode whitespace to regular spaces, then strip currency symbols
134
+ let normalized = String(amount)
135
+ .replace(/[\s\u00A0\u2000-\u200B\uFEFF]/g, ' ') // Replace all Unicode whitespace with regular space
136
+ .replace(/^[\$]/, '') // Strip leading $
137
+ .replace(/\s*(USDC|usdc)$/, '') // Strip trailing USDC
138
+ .replace(/,/g, '') // Strip thousands separators
139
+ .replace(/\s+/g, '') // Remove ALL whitespace (including normalized Unicode spaces)
140
+ .trim(); // Final trim for edge cases
141
+
142
+ // Check for negative
143
+ if (normalized.startsWith('-')) {
144
+ throw new ValidationError('Amount cannot be negative');
145
+ }
146
+
147
+ // Validate format (integer or decimal with up to 6 decimal places)
148
+ if (!/^\d+(\.\d{1,6})?$/.test(normalized)) {
149
+ throw new ValidationError(
150
+ `Invalid amount format: "${amount}". Expected number like "100" or "100.50"`
151
+ );
152
+ }
153
+
154
+ // Parse to bigint with 6 decimals
155
+ try {
156
+ const parts = normalized.split('.');
157
+ const wholePart = parts[0];
158
+ const decimalPart = (parts[1] || '').padEnd(6, '0'); // Pad to 6 decimals
159
+
160
+ const wholeAmount = BigInt(wholePart) * 1_000_000n;
161
+ const decimalAmount = BigInt(decimalPart);
162
+
163
+ const totalAmount = wholeAmount + decimalAmount;
164
+
165
+ // M1 Fix: Enforce minimum amount ($0.05 USDC = 50,000 wei)
166
+ if (totalAmount < MIN_AMOUNT_WEI) {
167
+ throw new ValidationError(
168
+ `Amount too small: "${amount}". Minimum transaction is $0.05 USDC`
169
+ );
170
+ }
171
+
172
+ return totalAmount;
173
+ } catch (error) {
174
+ // Re-throw ValidationError as-is
175
+ if (error instanceof ValidationError) {
176
+ throw error;
177
+ }
178
+ throw new ValidationError(
179
+ `Failed to parse amount: "${amount}". Please use format like "100" or "100.50"`
180
+ );
181
+ }
182
+ }
183
+
184
+ /**
185
+ * Validate Ethereum address format.
186
+ *
187
+ * Checks that address:
188
+ * - Is a string
189
+ * - Starts with "0x"
190
+ * - Is exactly 42 characters (0x + 40 hex chars)
191
+ * - Contains only valid hex characters
192
+ *
193
+ * Note: Does not validate checksum (EIP-55) in mock mode.
194
+ *
195
+ * @param address - Address to validate
196
+ * @param paramName - Parameter name for error message
197
+ * @returns Validated address (unchanged)
198
+ * @throws {ValidationError} If address format is invalid
199
+ *
200
+ * @example
201
+ * ```typescript
202
+ * const provider = this.validateAddress(params.to, 'to');
203
+ * ```
204
+ */
205
+ protected validateAddress(address: string, paramName: string): string {
206
+ if (typeof address !== 'string') {
207
+ throw new ValidationError(
208
+ `Invalid ${paramName} address: expected string, got ${typeof address}`
209
+ );
210
+ }
211
+
212
+ // Check 0x prefix
213
+ if (!address.startsWith('0x')) {
214
+ throw new ValidationError(
215
+ `Invalid ${paramName} address: "${address}". Expected 0x-prefixed hex string.`
216
+ );
217
+ }
218
+
219
+ // Check length (0x + 40 hex chars = 42 total)
220
+ if (address.length !== 42) {
221
+ throw new ValidationError(
222
+ `Invalid ${paramName} address: "${address}". Expected 42 characters (0x + 40 hex).`
223
+ );
224
+ }
225
+
226
+ // Check hex format
227
+ if (!/^0x[0-9a-fA-F]{40}$/.test(address)) {
228
+ throw new ValidationError(
229
+ `Invalid ${paramName} address: "${address}". Contains invalid hex characters.`
230
+ );
231
+ }
232
+
233
+ // Issue #2 Fix: Normalize to lowercase for consistency
234
+ // This prevents case-sensitivity issues when comparing addresses
235
+ return address.toLowerCase();
236
+ }
237
+
238
+ /**
239
+ * Parse deadline from relative time expression or Unix timestamp.
240
+ *
241
+ * Accepts multiple formats:
242
+ * - undefined → now + 24 hours (default)
243
+ * - 1734076400 (number) → passed through as Unix timestamp
244
+ * - "+1h" → now + 1 hour
245
+ * - "+24h" → now + 24 hours
246
+ * - "+7d" → now + 7 days
247
+ *
248
+ * Rejects:
249
+ * - "invalid" → throws ValidationError
250
+ * - "-24h" → throws ValidationError (negative time)
251
+ *
252
+ * @param deadline - Deadline as relative time string, Unix timestamp, or undefined
253
+ * @param currentTime - Current time in seconds (defaults to Date.now() / 1000)
254
+ * @returns Unix timestamp in seconds
255
+ * @throws {ValidationError} If deadline format is invalid
256
+ *
257
+ * @example
258
+ * ```typescript
259
+ * const deadline = this.parseDeadline("+24h"); // now + 86400
260
+ * const deadline = this.parseDeadline(1734076400); // 1734076400
261
+ * const deadline = this.parseDeadline(); // now + 86400 (default)
262
+ * ```
263
+ */
264
+ protected parseDeadline(deadline?: string | number, currentTime?: number): number {
265
+ const now = currentTime ?? Math.floor(Date.now() / 1000);
266
+
267
+ if (deadline === undefined) {
268
+ // Default: 24 hours from now
269
+ return now + DEFAULT_DEADLINE_SECONDS;
270
+ }
271
+
272
+ if (typeof deadline === 'number') {
273
+ return deadline;
274
+ }
275
+
276
+ // Parse relative time
277
+ const match = deadline.match(/^\+(\d+)(h|d)$/);
278
+ if (!match) {
279
+ throw new ValidationError(
280
+ `Invalid deadline format: "${deadline}". Expected Unix timestamp or relative time (e.g., "+24h", "+7d")`
281
+ );
282
+ }
283
+
284
+ const [, amountStr, unit] = match;
285
+ const amount = parseInt(amountStr, 10);
286
+
287
+ // H1 Fix: Add bounds check to prevent integer overflow
288
+ if (unit === 'h' && amount > MAX_DEADLINE_HOURS) {
289
+ throw new ValidationError(
290
+ `Deadline too far in future: "${deadline}". Maximum is 10 years (${MAX_DEADLINE_HOURS}h)`
291
+ );
292
+ }
293
+ if (unit === 'd' && amount > MAX_DEADLINE_DAYS) {
294
+ throw new ValidationError(
295
+ `Deadline too far in future: "${deadline}". Maximum is 10 years (${MAX_DEADLINE_DAYS}d)`
296
+ );
297
+ }
298
+
299
+ const multiplier = unit === 'h' ? 3600 : 86400;
300
+
301
+ return now + amount * multiplier;
302
+ }
303
+
304
+ /**
305
+ * Validate and normalize dispute window.
306
+ *
307
+ * SECURITY FIX (L-1): Enforces bounds on dispute window:
308
+ * - Minimum: 1 hour (prevents skipping disputes)
309
+ * - Maximum: 30 days (prevents indefinite fund locking)
310
+ *
311
+ * @param disputeWindow - Dispute window in seconds (undefined uses default)
312
+ * @returns Validated dispute window in seconds
313
+ * @throws {ValidationError} If window is outside allowed bounds
314
+ *
315
+ * @example
316
+ * ```typescript
317
+ * this.validateDisputeWindow(3600); // 1 hour - OK
318
+ * this.validateDisputeWindow(86400); // 1 day - OK
319
+ * this.validateDisputeWindow(100); // Too short - throws
320
+ * this.validateDisputeWindow(31 * 86400); // Too long - throws
321
+ * ```
322
+ */
323
+ protected validateDisputeWindow(disputeWindow?: number): number {
324
+ if (disputeWindow === undefined) {
325
+ return DEFAULT_DISPUTE_WINDOW_SECONDS;
326
+ }
327
+
328
+ if (disputeWindow < MIN_DISPUTE_WINDOW_SECONDS) {
329
+ throw new ValidationError(
330
+ `Dispute window too short: ${disputeWindow} seconds. ` +
331
+ `Minimum is ${MIN_DISPUTE_WINDOW_SECONDS} seconds (1 hour).`
332
+ );
333
+ }
334
+
335
+ if (disputeWindow > MAX_DISPUTE_WINDOW_SECONDS) {
336
+ throw new ValidationError(
337
+ `Dispute window too long: ${disputeWindow} seconds. ` +
338
+ `Maximum is ${MAX_DISPUTE_WINDOW_SECONDS} seconds (30 days).`
339
+ );
340
+ }
341
+
342
+ return disputeWindow;
343
+ }
344
+
345
+ /**
346
+ * Validate bytes32 hex string format.
347
+ *
348
+ * SECURITY FIX (L-2): Validates that a string is a valid bytes32 hex.
349
+ * Used for transaction IDs, escrow IDs, attestation UIDs, etc.
350
+ *
351
+ * @param value - Value to validate
352
+ * @param paramName - Parameter name for error message
353
+ * @returns Validated bytes32 string (normalized to lowercase)
354
+ * @throws {ValidationError} If format is invalid
355
+ *
356
+ * @example
357
+ * ```typescript
358
+ * const txId = this.validateBytes32(id, 'transactionId');
359
+ * ```
360
+ */
361
+ protected validateBytes32(value: string, paramName: string): string {
362
+ if (typeof value !== 'string') {
363
+ throw new ValidationError(
364
+ `Invalid ${paramName}: expected string, got ${typeof value}`
365
+ );
366
+ }
367
+
368
+ // Check 0x prefix
369
+ if (!value.startsWith('0x')) {
370
+ throw new ValidationError(
371
+ `Invalid ${paramName}: "${value}". Expected 0x-prefixed bytes32 (66 characters total).`
372
+ );
373
+ }
374
+
375
+ // Check length (0x + 64 hex chars = 66 total)
376
+ if (value.length !== 66) {
377
+ throw new ValidationError(
378
+ `Invalid ${paramName}: "${value}". Expected 66 characters (0x + 64 hex), got ${value.length}.`
379
+ );
380
+ }
381
+
382
+ // Check hex format
383
+ if (!/^0x[0-9a-fA-F]{64}$/.test(value)) {
384
+ throw new ValidationError(
385
+ `Invalid ${paramName}: "${value}". Contains invalid hex characters.`
386
+ );
387
+ }
388
+
389
+ // Normalize to lowercase
390
+ return value.toLowerCase();
391
+ }
392
+
393
+ /**
394
+ * Validate Unix timestamp is reasonable.
395
+ *
396
+ * SECURITY FIX (L-6): Validates timestamps to prevent overflow/underflow.
397
+ *
398
+ * @param timestamp - Unix timestamp in seconds
399
+ * @param paramName - Parameter name for error message
400
+ * @returns Validated timestamp
401
+ * @throws {ValidationError} If timestamp is invalid
402
+ */
403
+ protected validateTimestamp(timestamp: number, paramName: string): number {
404
+ // Check it's a number
405
+ if (typeof timestamp !== 'number' || isNaN(timestamp)) {
406
+ throw new ValidationError(
407
+ `Invalid ${paramName}: expected number, got ${typeof timestamp}`
408
+ );
409
+ }
410
+
411
+ // Check it's positive
412
+ if (timestamp <= 0) {
413
+ throw new ValidationError(
414
+ `Invalid ${paramName}: timestamp must be positive`
415
+ );
416
+ }
417
+
418
+ // Check it's not in the past (with 1 minute buffer)
419
+ const now = Math.floor(Date.now() / 1000);
420
+ const oneMinuteAgo = now - 60;
421
+
422
+ // Only apply this check if it looks like a deadline/future timestamp
423
+ // (e.g., createdAt can be in the past)
424
+ // For now, just validate it's reasonable
425
+
426
+ // Check for overflow (year 3000 = ~32503680000)
427
+ const year3000 = 32503680000;
428
+ if (timestamp > year3000) {
429
+ throw new ValidationError(
430
+ `Invalid ${paramName}: timestamp ${timestamp} is too far in the future (overflow prevention)`
431
+ );
432
+ }
433
+
434
+ return timestamp;
435
+ }
436
+
437
+ /**
438
+ * Format bigint amount to human-readable string.
439
+ *
440
+ * Converts USDC wei (6 decimals) to formatted string with 2 decimal places.
441
+ * Uses proper rounding (round half up) for display purposes.
442
+ *
443
+ * @param amount - Amount as bigint (6 decimals) or string
444
+ * @returns Formatted string like "100.00 USDC"
445
+ *
446
+ * @example
447
+ * ```typescript
448
+ * this.formatAmount(100_000_000n); // "100.00 USDC"
449
+ * this.formatAmount(100_500_000n); // "100.50 USDC"
450
+ * this.formatAmount(100_126_000n); // "100.13 USDC" (rounded)
451
+ * ```
452
+ */
453
+ protected formatAmount(amount: bigint | string): string {
454
+ const amountBigInt = typeof amount === 'string' ? BigInt(amount) : amount;
455
+
456
+ // Convert from 6 decimals to decimal string
457
+ const wholePart = amountBigInt / 1_000_000n;
458
+ const decimalPart = amountBigInt % 1_000_000n;
459
+
460
+ // M3 Fix: Proper rounding to 2 decimal places (round half up)
461
+ // decimalPart is 0-999999, we need to round to nearest 10000 (cents)
462
+ const decimalNum = Number(decimalPart);
463
+ const roundedCents = Math.round(decimalNum / 10000); // 6 decimals → 2 decimals
464
+
465
+ // Handle case where rounding causes overflow (e.g., 99.999999 → 100.00)
466
+ if (roundedCents >= 100) {
467
+ return `${wholePart + 1n}.00 USDC`;
468
+ }
469
+
470
+ const formattedDecimal = roundedCents.toString().padStart(2, '0');
471
+ return `${wholePart}.${formattedDecimal} USDC`;
472
+ }
473
+ }
@@ -0,0 +1,232 @@
1
+ /**
2
+ * BeginnerAdapter - High-level, opinionated API for simple use cases
3
+ *
4
+ * Provides the simplest possible interface for creating and checking transactions.
5
+ * Designed for developers who want to "just make it work" without deep protocol knowledge.
6
+ *
7
+ * Key Features:
8
+ * - Smart defaults (24h deadline, 2-day dispute window)
9
+ * - Inferred requester (from constructor)
10
+ * - User-friendly input (strings, no BigInt)
11
+ * - User-friendly output (formatted amounts, ISO dates)
12
+ *
13
+ * @module adapters/BeginnerAdapter
14
+ */
15
+
16
+ import { BaseAdapter, ValidationError, DEFAULT_DISPUTE_WINDOW_SECONDS } from './BaseAdapter';
17
+ import { IACTPRuntime } from '../runtime/IACTPRuntime';
18
+ import { TransactionState } from '../runtime/types/MockState';
19
+ import { EASHelper } from '../protocol/EASHelper';
20
+
21
+ /**
22
+ * Parameters for creating a simple payment.
23
+ *
24
+ * This is the most beginner-friendly interface - minimal required fields.
25
+ */
26
+ export interface BeginnerPayParams {
27
+ /** Recipient address (provider) */
28
+ to: string;
29
+
30
+ /** Amount in user-friendly format ("100", "100.50", "100 USDC", "$100") */
31
+ amount: string | number;
32
+
33
+ /** Optional: Deadline as relative time ("+24h") or Unix timestamp. Defaults to +24h */
34
+ deadline?: string | number;
35
+
36
+ /** Optional: Dispute window in seconds. Defaults to 172800 (2 days) */
37
+ disputeWindow?: number;
38
+ }
39
+
40
+ /**
41
+ * Result of creating a payment.
42
+ *
43
+ * Provides user-friendly formatted data (not raw protocol types).
44
+ */
45
+ export interface BeginnerPayResult {
46
+ /** Transaction ID (bytes32 hex string) */
47
+ txId: string;
48
+
49
+ /** Provider address */
50
+ provider: string;
51
+
52
+ /** Requester address (caller) */
53
+ requester: string;
54
+
55
+ /** Amount in USDC (human-readable, e.g., "100.00 USDC") */
56
+ amount: string;
57
+
58
+ /** Deadline as ISO 8601 timestamp */
59
+ deadline: string;
60
+
61
+ /** Transaction state */
62
+ state: string;
63
+ }
64
+
65
+ /**
66
+ * BeginnerAdapter - High-level API for simple payment flows.
67
+ *
68
+ * This adapter provides the simplest possible interface:
69
+ * - `pay()` - Create and fund a transaction in one call
70
+ * - `checkStatus()` - Get transaction status with action hints
71
+ *
72
+ * All complexity is hidden behind smart defaults.
73
+ *
74
+ * @example
75
+ * ```typescript
76
+ * const client = await ACTPClient.create({ mode: 'mock' });
77
+ *
78
+ * // Simple payment (all defaults)
79
+ * const result = await client.beginner.pay({
80
+ * to: '0xProvider123',
81
+ * amount: '100',
82
+ * });
83
+ * console.log('Transaction ID:', result.txId);
84
+ * console.log('Amount:', result.amount); // "100.00 USDC"
85
+ *
86
+ * // Check status
87
+ * const status = await client.beginner.checkStatus(result.txId);
88
+ * if (status.canAccept) {
89
+ * console.log('Provider can accept this transaction');
90
+ * }
91
+ * ```
92
+ */
93
+ export class BeginnerAdapter extends BaseAdapter {
94
+ /**
95
+ * Creates a new BeginnerAdapter instance.
96
+ *
97
+ * @param runtime - ACTP runtime implementation (MockRuntime or BlockchainRuntime)
98
+ * @param requesterAddress - The requester's Ethereum address
99
+ * @param easHelper - Optional EAS helper for attestation verification (SECURITY FIX C-4)
100
+ */
101
+ constructor(
102
+ private runtime: IACTPRuntime,
103
+ requesterAddress: string,
104
+ private easHelper?: EASHelper
105
+ ) {
106
+ super(requesterAddress);
107
+ }
108
+
109
+ /**
110
+ * Create a payment transaction with smart defaults.
111
+ *
112
+ * This is the simplest way to create a transaction - just specify
113
+ * recipient and amount. All other parameters use sensible defaults.
114
+ *
115
+ * Smart defaults:
116
+ * - Requester: Inferred from constructor
117
+ * - Deadline: 24 hours from now
118
+ * - Dispute window: 2 days (172800 seconds)
119
+ *
120
+ * Validations performed:
121
+ * - Address format (0x-prefixed hex)
122
+ * - Amount format (positive number)
123
+ * - Deadline in future
124
+ * - Cannot pay yourself
125
+ *
126
+ * @param params - Payment parameters
127
+ * @returns User-friendly payment result
128
+ * @throws {ValidationError} If inputs are invalid
129
+ *
130
+ * @example
131
+ * ```typescript
132
+ * const result = await adapter.pay({
133
+ * to: '0xProvider123',
134
+ * amount: '100.50',
135
+ * deadline: '+7d', // Optional: 7 days from now
136
+ * });
137
+ * ```
138
+ */
139
+ async pay(params: BeginnerPayParams): Promise<BeginnerPayResult> {
140
+ // Validate and parse inputs
141
+ const provider = this.validateAddress(params.to, 'to');
142
+ const amount = this.parseAmount(params.amount);
143
+ const currentTime = this.runtime.time.now();
144
+ const deadline = this.parseDeadline(params.deadline, currentTime);
145
+ // SECURITY FIX (L-1): Validate dispute window bounds
146
+ const disputeWindow = this.validateDisputeWindow(params.disputeWindow);
147
+
148
+ const requester = this.requesterAddress;
149
+
150
+ // Additional validations
151
+ if (requester.toLowerCase() === provider.toLowerCase()) {
152
+ throw new ValidationError('Cannot pay yourself (requester equals provider)');
153
+ }
154
+
155
+ if (deadline <= currentTime) {
156
+ throw new ValidationError('Deadline must be in the future');
157
+ }
158
+
159
+ // Create transaction
160
+ const txId = await this.runtime.createTransaction({
161
+ provider,
162
+ requester,
163
+ amount: amount.toString(),
164
+ deadline,
165
+ disputeWindow,
166
+ });
167
+
168
+ // Link escrow (auto-transitions to COMMITTED)
169
+ await this.runtime.linkEscrow(txId, amount.toString());
170
+
171
+ // Fetch transaction details for user-friendly response
172
+ const tx = await this.runtime.getTransaction(txId);
173
+
174
+ if (!tx) {
175
+ throw new Error(`Transaction ${txId} not found after creation`);
176
+ }
177
+
178
+ return {
179
+ txId,
180
+ provider,
181
+ requester,
182
+ amount: this.formatAmount(amount),
183
+ deadline: new Date(deadline * 1000).toISOString(),
184
+ state: tx.state,
185
+ };
186
+ }
187
+
188
+ /**
189
+ * Check payment status by transaction ID.
190
+ *
191
+ * Returns current state plus action hints (what can be done next).
192
+ *
193
+ * Action hints:
194
+ * - `canAccept`: Provider can accept (INITIATED state, before deadline)
195
+ * - `canComplete`: Provider can mark as delivered (COMMITTED state)
196
+ * - `canDispute`: Requester can dispute (DELIVERED state, within dispute window)
197
+ *
198
+ * @param txId - Transaction ID to check
199
+ * @returns Status with action hints
200
+ * @throws {Error} If transaction not found
201
+ *
202
+ * @example
203
+ * ```typescript
204
+ * const status = await adapter.checkStatus(txId);
205
+ * console.log('State:', status.state); // "COMMITTED"
206
+ * if (status.canComplete) {
207
+ * // Provider can deliver now
208
+ * }
209
+ * ```
210
+ */
211
+ async checkStatus(txId: string): Promise<{
212
+ state: string;
213
+ canAccept: boolean;
214
+ canComplete: boolean;
215
+ canDispute: boolean;
216
+ }> {
217
+ const tx = await this.runtime.getTransaction(txId);
218
+
219
+ if (!tx) {
220
+ throw new Error(`Transaction ${txId} not found`);
221
+ }
222
+
223
+ const now = this.runtime.time.now();
224
+
225
+ return {
226
+ state: tx.state,
227
+ canAccept: tx.state === 'INITIATED' && tx.deadline > now,
228
+ canComplete: tx.state === 'COMMITTED' || tx.state === 'IN_PROGRESS',
229
+ canDispute: tx.state === 'DELIVERED' && tx.completedAt !== null && tx.completedAt + tx.disputeWindow > now,
230
+ };
231
+ }
232
+ }