envoy-pay 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (364) hide show
  1. package/CHANGELOG.md +99 -0
  2. package/LICENSE +200 -0
  3. package/README.md +529 -0
  4. package/dist/cjs/adapters/base.js +174 -0
  5. package/dist/cjs/adapters/base.js.map +1 -0
  6. package/dist/cjs/adapters/evm.js +339 -0
  7. package/dist/cjs/adapters/evm.js.map +1 -0
  8. package/dist/cjs/adapters/index.js +15 -0
  9. package/dist/cjs/adapters/index.js.map +1 -0
  10. package/dist/cjs/adapters/ows.js +204 -0
  11. package/dist/cjs/adapters/ows.js.map +1 -0
  12. package/dist/cjs/adapters/solana.js +210 -0
  13. package/dist/cjs/adapters/solana.js.map +1 -0
  14. package/dist/cjs/adapters/stellar.js +173 -0
  15. package/dist/cjs/adapters/stellar.js.map +1 -0
  16. package/dist/cjs/adapters/stripe.js +338 -0
  17. package/dist/cjs/adapters/stripe.js.map +1 -0
  18. package/dist/cjs/adapters/types.js +3 -0
  19. package/dist/cjs/adapters/types.js.map +1 -0
  20. package/dist/cjs/client.js +309 -0
  21. package/dist/cjs/client.js.map +1 -0
  22. package/dist/cjs/contracts/abis/EnvoyFacilitator.js +197 -0
  23. package/dist/cjs/contracts/abis/EnvoyFacilitator.js.map +1 -0
  24. package/dist/cjs/contracts/addresses.js +42 -0
  25. package/dist/cjs/contracts/addresses.js.map +1 -0
  26. package/dist/cjs/contracts/facilitator.js +225 -0
  27. package/dist/cjs/contracts/facilitator.js.map +1 -0
  28. package/dist/cjs/contracts/index.js +21 -0
  29. package/dist/cjs/contracts/index.js.map +1 -0
  30. package/dist/cjs/facilitator/facilitator-service.js +305 -0
  31. package/dist/cjs/facilitator/facilitator-service.js.map +1 -0
  32. package/dist/cjs/facilitator/fee-calculator.js +134 -0
  33. package/dist/cjs/facilitator/fee-calculator.js.map +1 -0
  34. package/dist/cjs/facilitator/index.js +12 -0
  35. package/dist/cjs/facilitator/index.js.map +1 -0
  36. package/dist/cjs/facilitator/types.js +99 -0
  37. package/dist/cjs/facilitator/types.js.map +1 -0
  38. package/dist/cjs/identity/agent-card.js +143 -0
  39. package/dist/cjs/identity/agent-card.js.map +1 -0
  40. package/dist/cjs/identity/agent-identity.js +166 -0
  41. package/dist/cjs/identity/agent-identity.js.map +1 -0
  42. package/dist/cjs/identity/did-resolver.js +149 -0
  43. package/dist/cjs/identity/did-resolver.js.map +1 -0
  44. package/dist/cjs/identity/erc8004/abis.js +218 -0
  45. package/dist/cjs/identity/erc8004/abis.js.map +1 -0
  46. package/dist/cjs/identity/erc8004/identity.js +268 -0
  47. package/dist/cjs/identity/erc8004/identity.js.map +1 -0
  48. package/dist/cjs/identity/erc8004/index.js +36 -0
  49. package/dist/cjs/identity/erc8004/index.js.map +1 -0
  50. package/dist/cjs/identity/erc8004/reputation.js +110 -0
  51. package/dist/cjs/identity/erc8004/reputation.js.map +1 -0
  52. package/dist/cjs/identity/erc8004/types.js +3 -0
  53. package/dist/cjs/identity/erc8004/types.js.map +1 -0
  54. package/dist/cjs/identity/index.js +61 -0
  55. package/dist/cjs/identity/index.js.map +1 -0
  56. package/dist/cjs/identity/owner-registry.js +140 -0
  57. package/dist/cjs/identity/owner-registry.js.map +1 -0
  58. package/dist/cjs/identity/reputation.js +193 -0
  59. package/dist/cjs/identity/reputation.js.map +1 -0
  60. package/dist/cjs/identity/types.js +16 -0
  61. package/dist/cjs/identity/types.js.map +1 -0
  62. package/dist/cjs/index.js +72 -0
  63. package/dist/cjs/index.js.map +1 -0
  64. package/dist/cjs/logger.js +7 -0
  65. package/dist/cjs/logger.js.map +1 -0
  66. package/dist/cjs/monitor/evm-watcher.js +165 -0
  67. package/dist/cjs/monitor/evm-watcher.js.map +1 -0
  68. package/dist/cjs/monitor/index.js +32 -0
  69. package/dist/cjs/monitor/index.js.map +1 -0
  70. package/dist/cjs/monitor/multi-watcher.js +94 -0
  71. package/dist/cjs/monitor/multi-watcher.js.map +1 -0
  72. package/dist/cjs/monitor/solana-watcher.js +172 -0
  73. package/dist/cjs/monitor/solana-watcher.js.map +1 -0
  74. package/dist/cjs/monitor/stellar-watcher.js +125 -0
  75. package/dist/cjs/monitor/stellar-watcher.js.map +1 -0
  76. package/dist/cjs/mpp.js +187 -0
  77. package/dist/cjs/mpp.js.map +1 -0
  78. package/dist/cjs/policy.js +71 -0
  79. package/dist/cjs/policy.js.map +1 -0
  80. package/dist/cjs/providers/bridge.js +323 -0
  81. package/dist/cjs/providers/bridge.js.map +1 -0
  82. package/dist/cjs/providers/onchainos.js +210 -0
  83. package/dist/cjs/providers/onchainos.js.map +1 -0
  84. package/dist/cjs/requests/eip681.js +77 -0
  85. package/dist/cjs/requests/eip681.js.map +1 -0
  86. package/dist/cjs/requests/index.js +18 -0
  87. package/dist/cjs/requests/index.js.map +1 -0
  88. package/dist/cjs/requests/sep7.js +61 -0
  89. package/dist/cjs/requests/sep7.js.map +1 -0
  90. package/dist/cjs/requests/solana-pay.js +51 -0
  91. package/dist/cjs/requests/solana-pay.js.map +1 -0
  92. package/dist/cjs/requests/universal.js +40 -0
  93. package/dist/cjs/requests/universal.js.map +1 -0
  94. package/dist/cjs/server/index.js +35 -0
  95. package/dist/cjs/server/index.js.map +1 -0
  96. package/dist/cjs/server/mpp-gate.js +118 -0
  97. package/dist/cjs/server/mpp-gate.js.map +1 -0
  98. package/dist/cjs/server/payment-gate.js +92 -0
  99. package/dist/cjs/server/payment-gate.js.map +1 -0
  100. package/dist/cjs/server/receipt.js +52 -0
  101. package/dist/cjs/server/receipt.js.map +1 -0
  102. package/dist/cjs/server/webhook.js +122 -0
  103. package/dist/cjs/server/webhook.js.map +1 -0
  104. package/dist/cjs/server/x402-gate.js +103 -0
  105. package/dist/cjs/server/x402-gate.js.map +1 -0
  106. package/dist/cjs/solana.js +14 -0
  107. package/dist/cjs/solana.js.map +1 -0
  108. package/dist/cjs/stellar.js +14 -0
  109. package/dist/cjs/stellar.js.map +1 -0
  110. package/dist/cjs/wallet/balance-aggregator.js +149 -0
  111. package/dist/cjs/wallet/balance-aggregator.js.map +1 -0
  112. package/dist/cjs/wallet/chain-router.js +254 -0
  113. package/dist/cjs/wallet/chain-router.js.map +1 -0
  114. package/dist/cjs/wallet/index.js +15 -0
  115. package/dist/cjs/wallet/index.js.map +1 -0
  116. package/dist/cjs/wallet/intent-resolver.js +145 -0
  117. package/dist/cjs/wallet/intent-resolver.js.map +1 -0
  118. package/dist/cjs/wallet/session-manager.js +170 -0
  119. package/dist/cjs/wallet/session-manager.js.map +1 -0
  120. package/dist/cjs/wallet/types.js +14 -0
  121. package/dist/cjs/wallet/types.js.map +1 -0
  122. package/dist/cjs/wallet/unified-wallet.js +253 -0
  123. package/dist/cjs/wallet/unified-wallet.js.map +1 -0
  124. package/dist/esm/adapters/base.js +170 -0
  125. package/dist/esm/adapters/base.js.map +1 -0
  126. package/dist/esm/adapters/evm.js +334 -0
  127. package/dist/esm/adapters/evm.js.map +1 -0
  128. package/dist/esm/adapters/index.js +6 -0
  129. package/dist/esm/adapters/index.js.map +1 -0
  130. package/dist/esm/adapters/ows.js +194 -0
  131. package/dist/esm/adapters/ows.js.map +1 -0
  132. package/dist/esm/adapters/solana.js +206 -0
  133. package/dist/esm/adapters/solana.js.map +1 -0
  134. package/dist/esm/adapters/stellar.js +136 -0
  135. package/dist/esm/adapters/stellar.js.map +1 -0
  136. package/dist/esm/adapters/stripe.js +334 -0
  137. package/dist/esm/adapters/stripe.js.map +1 -0
  138. package/dist/esm/adapters/types.js +2 -0
  139. package/dist/esm/adapters/types.js.map +1 -0
  140. package/dist/esm/client.js +302 -0
  141. package/dist/esm/client.js.map +1 -0
  142. package/dist/esm/contracts/abis/EnvoyFacilitator.js +194 -0
  143. package/dist/esm/contracts/abis/EnvoyFacilitator.js.map +1 -0
  144. package/dist/esm/contracts/addresses.js +38 -0
  145. package/dist/esm/contracts/addresses.js.map +1 -0
  146. package/dist/esm/contracts/facilitator.js +218 -0
  147. package/dist/esm/contracts/facilitator.js.map +1 -0
  148. package/dist/esm/contracts/index.js +8 -0
  149. package/dist/esm/contracts/index.js.map +1 -0
  150. package/dist/esm/facilitator/facilitator-service.js +301 -0
  151. package/dist/esm/facilitator/facilitator-service.js.map +1 -0
  152. package/dist/esm/facilitator/fee-calculator.js +130 -0
  153. package/dist/esm/facilitator/fee-calculator.js.map +1 -0
  154. package/dist/esm/facilitator/index.js +5 -0
  155. package/dist/esm/facilitator/index.js.map +1 -0
  156. package/dist/esm/facilitator/types.js +96 -0
  157. package/dist/esm/facilitator/types.js.map +1 -0
  158. package/dist/esm/identity/agent-card.js +139 -0
  159. package/dist/esm/identity/agent-card.js.map +1 -0
  160. package/dist/esm/identity/agent-identity.js +162 -0
  161. package/dist/esm/identity/agent-identity.js.map +1 -0
  162. package/dist/esm/identity/did-resolver.js +145 -0
  163. package/dist/esm/identity/did-resolver.js.map +1 -0
  164. package/dist/esm/identity/erc8004/abis.js +215 -0
  165. package/dist/esm/identity/erc8004/abis.js.map +1 -0
  166. package/dist/esm/identity/erc8004/identity.js +250 -0
  167. package/dist/esm/identity/erc8004/identity.js.map +1 -0
  168. package/dist/esm/identity/erc8004/index.js +13 -0
  169. package/dist/esm/identity/erc8004/index.js.map +1 -0
  170. package/dist/esm/identity/erc8004/reputation.js +105 -0
  171. package/dist/esm/identity/erc8004/reputation.js.map +1 -0
  172. package/dist/esm/identity/erc8004/types.js +2 -0
  173. package/dist/esm/identity/erc8004/types.js.map +1 -0
  174. package/dist/esm/identity/index.js +19 -0
  175. package/dist/esm/identity/index.js.map +1 -0
  176. package/dist/esm/identity/owner-registry.js +136 -0
  177. package/dist/esm/identity/owner-registry.js.map +1 -0
  178. package/dist/esm/identity/reputation.js +189 -0
  179. package/dist/esm/identity/reputation.js.map +1 -0
  180. package/dist/esm/identity/types.js +15 -0
  181. package/dist/esm/identity/types.js.map +1 -0
  182. package/dist/esm/index.js +37 -0
  183. package/dist/esm/index.js.map +1 -0
  184. package/dist/esm/logger.js +3 -0
  185. package/dist/esm/logger.js.map +1 -0
  186. package/dist/esm/monitor/evm-watcher.js +162 -0
  187. package/dist/esm/monitor/evm-watcher.js.map +1 -0
  188. package/dist/esm/monitor/index.js +25 -0
  189. package/dist/esm/monitor/index.js.map +1 -0
  190. package/dist/esm/monitor/multi-watcher.js +91 -0
  191. package/dist/esm/monitor/multi-watcher.js.map +1 -0
  192. package/dist/esm/monitor/solana-watcher.js +169 -0
  193. package/dist/esm/monitor/solana-watcher.js.map +1 -0
  194. package/dist/esm/monitor/stellar-watcher.js +122 -0
  195. package/dist/esm/monitor/stellar-watcher.js.map +1 -0
  196. package/dist/esm/mpp.js +175 -0
  197. package/dist/esm/mpp.js.map +1 -0
  198. package/dist/esm/policy.js +67 -0
  199. package/dist/esm/policy.js.map +1 -0
  200. package/dist/esm/providers/bridge.js +319 -0
  201. package/dist/esm/providers/bridge.js.map +1 -0
  202. package/dist/esm/providers/onchainos.js +172 -0
  203. package/dist/esm/providers/onchainos.js.map +1 -0
  204. package/dist/esm/requests/eip681.js +74 -0
  205. package/dist/esm/requests/eip681.js.map +1 -0
  206. package/dist/esm/requests/index.js +11 -0
  207. package/dist/esm/requests/index.js.map +1 -0
  208. package/dist/esm/requests/sep7.js +58 -0
  209. package/dist/esm/requests/sep7.js.map +1 -0
  210. package/dist/esm/requests/solana-pay.js +48 -0
  211. package/dist/esm/requests/solana-pay.js.map +1 -0
  212. package/dist/esm/requests/universal.js +37 -0
  213. package/dist/esm/requests/universal.js.map +1 -0
  214. package/dist/esm/server/index.js +27 -0
  215. package/dist/esm/server/index.js.map +1 -0
  216. package/dist/esm/server/mpp-gate.js +115 -0
  217. package/dist/esm/server/mpp-gate.js.map +1 -0
  218. package/dist/esm/server/payment-gate.js +89 -0
  219. package/dist/esm/server/payment-gate.js.map +1 -0
  220. package/dist/esm/server/receipt.js +48 -0
  221. package/dist/esm/server/receipt.js.map +1 -0
  222. package/dist/esm/server/webhook.js +119 -0
  223. package/dist/esm/server/webhook.js.map +1 -0
  224. package/dist/esm/server/x402-gate.js +100 -0
  225. package/dist/esm/server/x402-gate.js.map +1 -0
  226. package/dist/esm/solana.js +8 -0
  227. package/dist/esm/solana.js.map +1 -0
  228. package/dist/esm/stellar.js +8 -0
  229. package/dist/esm/stellar.js.map +1 -0
  230. package/dist/esm/wallet/balance-aggregator.js +145 -0
  231. package/dist/esm/wallet/balance-aggregator.js.map +1 -0
  232. package/dist/esm/wallet/chain-router.js +250 -0
  233. package/dist/esm/wallet/chain-router.js.map +1 -0
  234. package/dist/esm/wallet/index.js +7 -0
  235. package/dist/esm/wallet/index.js.map +1 -0
  236. package/dist/esm/wallet/intent-resolver.js +141 -0
  237. package/dist/esm/wallet/intent-resolver.js.map +1 -0
  238. package/dist/esm/wallet/session-manager.js +166 -0
  239. package/dist/esm/wallet/session-manager.js.map +1 -0
  240. package/dist/esm/wallet/types.js +13 -0
  241. package/dist/esm/wallet/types.js.map +1 -0
  242. package/dist/esm/wallet/unified-wallet.js +249 -0
  243. package/dist/esm/wallet/unified-wallet.js.map +1 -0
  244. package/dist/types/adapters/base.d.ts +53 -0
  245. package/dist/types/adapters/base.d.ts.map +1 -0
  246. package/dist/types/adapters/evm.d.ts +93 -0
  247. package/dist/types/adapters/evm.d.ts.map +1 -0
  248. package/dist/types/adapters/index.d.ts +7 -0
  249. package/dist/types/adapters/index.d.ts.map +1 -0
  250. package/dist/types/adapters/ows.d.ts +123 -0
  251. package/dist/types/adapters/ows.d.ts.map +1 -0
  252. package/dist/types/adapters/solana.d.ts +77 -0
  253. package/dist/types/adapters/solana.d.ts.map +1 -0
  254. package/dist/types/adapters/stellar.d.ts +67 -0
  255. package/dist/types/adapters/stellar.d.ts.map +1 -0
  256. package/dist/types/adapters/stripe.d.ts +206 -0
  257. package/dist/types/adapters/stripe.d.ts.map +1 -0
  258. package/dist/types/adapters/types.d.ts +110 -0
  259. package/dist/types/adapters/types.d.ts.map +1 -0
  260. package/dist/types/client.d.ts +89 -0
  261. package/dist/types/client.d.ts.map +1 -0
  262. package/dist/types/contracts/abis/EnvoyFacilitator.d.ts +296 -0
  263. package/dist/types/contracts/abis/EnvoyFacilitator.d.ts.map +1 -0
  264. package/dist/types/contracts/addresses.d.ts +24 -0
  265. package/dist/types/contracts/addresses.d.ts.map +1 -0
  266. package/dist/types/contracts/facilitator.d.ts +172 -0
  267. package/dist/types/contracts/facilitator.d.ts.map +1 -0
  268. package/dist/types/contracts/index.d.ts +6 -0
  269. package/dist/types/contracts/index.d.ts.map +1 -0
  270. package/dist/types/facilitator/facilitator-service.d.ts +69 -0
  271. package/dist/types/facilitator/facilitator-service.d.ts.map +1 -0
  272. package/dist/types/facilitator/fee-calculator.d.ts +48 -0
  273. package/dist/types/facilitator/fee-calculator.d.ts.map +1 -0
  274. package/dist/types/facilitator/index.d.ts +5 -0
  275. package/dist/types/facilitator/index.d.ts.map +1 -0
  276. package/dist/types/facilitator/types.d.ts +221 -0
  277. package/dist/types/facilitator/types.d.ts.map +1 -0
  278. package/dist/types/identity/agent-card.d.ts +83 -0
  279. package/dist/types/identity/agent-card.d.ts.map +1 -0
  280. package/dist/types/identity/agent-identity.d.ts +102 -0
  281. package/dist/types/identity/agent-identity.d.ts.map +1 -0
  282. package/dist/types/identity/did-resolver.d.ts +70 -0
  283. package/dist/types/identity/did-resolver.d.ts.map +1 -0
  284. package/dist/types/identity/erc8004/abis.d.ts +336 -0
  285. package/dist/types/identity/erc8004/abis.d.ts.map +1 -0
  286. package/dist/types/identity/erc8004/identity.d.ts +109 -0
  287. package/dist/types/identity/erc8004/identity.d.ts.map +1 -0
  288. package/dist/types/identity/erc8004/index.d.ts +15 -0
  289. package/dist/types/identity/erc8004/index.d.ts.map +1 -0
  290. package/dist/types/identity/erc8004/reputation.d.ts +52 -0
  291. package/dist/types/identity/erc8004/reputation.d.ts.map +1 -0
  292. package/dist/types/identity/erc8004/types.d.ts +31 -0
  293. package/dist/types/identity/erc8004/types.d.ts.map +1 -0
  294. package/dist/types/identity/index.d.ts +10 -0
  295. package/dist/types/identity/index.d.ts.map +1 -0
  296. package/dist/types/identity/owner-registry.d.ts +68 -0
  297. package/dist/types/identity/owner-registry.d.ts.map +1 -0
  298. package/dist/types/identity/reputation.d.ts +66 -0
  299. package/dist/types/identity/reputation.d.ts.map +1 -0
  300. package/dist/types/identity/types.d.ts +182 -0
  301. package/dist/types/identity/types.d.ts.map +1 -0
  302. package/dist/types/index.d.ts +17 -0
  303. package/dist/types/index.d.ts.map +1 -0
  304. package/dist/types/logger.d.ts +10 -0
  305. package/dist/types/logger.d.ts.map +1 -0
  306. package/dist/types/monitor/evm-watcher.d.ts +40 -0
  307. package/dist/types/monitor/evm-watcher.d.ts.map +1 -0
  308. package/dist/types/monitor/index.d.ts +25 -0
  309. package/dist/types/monitor/index.d.ts.map +1 -0
  310. package/dist/types/monitor/multi-watcher.d.ts +48 -0
  311. package/dist/types/monitor/multi-watcher.d.ts.map +1 -0
  312. package/dist/types/monitor/solana-watcher.d.ts +36 -0
  313. package/dist/types/monitor/solana-watcher.d.ts.map +1 -0
  314. package/dist/types/monitor/stellar-watcher.d.ts +34 -0
  315. package/dist/types/monitor/stellar-watcher.d.ts.map +1 -0
  316. package/dist/types/mpp.d.ts +153 -0
  317. package/dist/types/mpp.d.ts.map +1 -0
  318. package/dist/types/policy.d.ts +40 -0
  319. package/dist/types/policy.d.ts.map +1 -0
  320. package/dist/types/providers/bridge.d.ts +162 -0
  321. package/dist/types/providers/bridge.d.ts.map +1 -0
  322. package/dist/types/providers/onchainos.d.ts +128 -0
  323. package/dist/types/providers/onchainos.d.ts.map +1 -0
  324. package/dist/types/requests/eip681.d.ts +51 -0
  325. package/dist/types/requests/eip681.d.ts.map +1 -0
  326. package/dist/types/requests/index.d.ts +11 -0
  327. package/dist/types/requests/index.d.ts.map +1 -0
  328. package/dist/types/requests/sep7.d.ts +56 -0
  329. package/dist/types/requests/sep7.d.ts.map +1 -0
  330. package/dist/types/requests/solana-pay.d.ts +50 -0
  331. package/dist/types/requests/solana-pay.d.ts.map +1 -0
  332. package/dist/types/requests/universal.d.ts +28 -0
  333. package/dist/types/requests/universal.d.ts.map +1 -0
  334. package/dist/types/server/index.d.ts +27 -0
  335. package/dist/types/server/index.d.ts.map +1 -0
  336. package/dist/types/server/mpp-gate.d.ts +66 -0
  337. package/dist/types/server/mpp-gate.d.ts.map +1 -0
  338. package/dist/types/server/payment-gate.d.ts +33 -0
  339. package/dist/types/server/payment-gate.d.ts.map +1 -0
  340. package/dist/types/server/receipt.d.ts +52 -0
  341. package/dist/types/server/receipt.d.ts.map +1 -0
  342. package/dist/types/server/webhook.d.ts +46 -0
  343. package/dist/types/server/webhook.d.ts.map +1 -0
  344. package/dist/types/server/x402-gate.d.ts +70 -0
  345. package/dist/types/server/x402-gate.d.ts.map +1 -0
  346. package/dist/types/solana.d.ts +7 -0
  347. package/dist/types/solana.d.ts.map +1 -0
  348. package/dist/types/stellar.d.ts +7 -0
  349. package/dist/types/stellar.d.ts.map +1 -0
  350. package/dist/types/wallet/balance-aggregator.d.ts +51 -0
  351. package/dist/types/wallet/balance-aggregator.d.ts.map +1 -0
  352. package/dist/types/wallet/chain-router.d.ts +44 -0
  353. package/dist/types/wallet/chain-router.d.ts.map +1 -0
  354. package/dist/types/wallet/index.d.ts +7 -0
  355. package/dist/types/wallet/index.d.ts.map +1 -0
  356. package/dist/types/wallet/intent-resolver.d.ts +39 -0
  357. package/dist/types/wallet/intent-resolver.d.ts.map +1 -0
  358. package/dist/types/wallet/session-manager.d.ts +57 -0
  359. package/dist/types/wallet/session-manager.d.ts.map +1 -0
  360. package/dist/types/wallet/types.d.ts +161 -0
  361. package/dist/types/wallet/types.d.ts.map +1 -0
  362. package/dist/types/wallet/unified-wallet.d.ts +122 -0
  363. package/dist/types/wallet/unified-wallet.d.ts.map +1 -0
  364. package/package.json +194 -0
@@ -0,0 +1,91 @@
1
+ import { createEvmWatcher } from './evm-watcher.js';
2
+ import { createStellarWatcher } from './stellar-watcher.js';
3
+ import { createSolanaWatcher } from './solana-watcher.js';
4
+ import { noopLogger } from '../logger.js';
5
+ /**
6
+ * Creates a multi-chain payment watcher.
7
+ *
8
+ * @returns Unsubscribe function that stops ALL chain watchers.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * const unsub = createMultiChainWatcher({
13
+ * evm: [
14
+ * { address: '0x...', rpcUrl: 'https://mainnet.base.org', chainName: 'Base', usdcContractAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' },
15
+ * { address: '0x...', rpcUrl: 'https://arb1.arbitrum.io/rpc', chainName: 'Arbitrum' },
16
+ * ],
17
+ * stellar: { accountId: 'GABCD...' },
18
+ * solana: { address: '7abc...' },
19
+ * onPayment: (event) => console.log(`${event.chain}: ${event.amountFormatted} ${event.asset}`),
20
+ * });
21
+ *
22
+ * // Stop all watchers
23
+ * unsub();
24
+ * ```
25
+ */
26
+ export function createMultiChainWatcher(config) {
27
+ const log = config.logger ?? noopLogger;
28
+ const unsubscribers = [];
29
+ log('[multi-watcher] 🌐 Starting multi-chain payment monitor…');
30
+ // Start EVM watchers
31
+ if (config.evm) {
32
+ for (const evmConfig of config.evm) {
33
+ const unsub = createEvmWatcher({
34
+ ...evmConfig,
35
+ onPayment: (event) => {
36
+ config.onPayment(event);
37
+ evmConfig.onPayment?.(event);
38
+ },
39
+ onError: (err) => {
40
+ config.onError?.(err);
41
+ evmConfig.onError?.(err);
42
+ },
43
+ logger: evmConfig.logger ?? log,
44
+ });
45
+ unsubscribers.push(unsub);
46
+ }
47
+ log(`[multi-watcher] ⛓️ ${config.evm.length} EVM chain(s) active`);
48
+ }
49
+ // Start Stellar watcher
50
+ if (config.stellar) {
51
+ const unsub = createStellarWatcher({
52
+ ...config.stellar,
53
+ onPayment: (event) => {
54
+ config.onPayment(event);
55
+ config.stellar.onPayment?.(event);
56
+ },
57
+ onError: (err) => {
58
+ config.onError?.(err);
59
+ config.stellar.onError?.(err);
60
+ },
61
+ logger: config.stellar.logger ?? log,
62
+ });
63
+ unsubscribers.push(unsub);
64
+ log('[multi-watcher] ⭐ Stellar watcher active');
65
+ }
66
+ // Start Solana watcher
67
+ if (config.solana) {
68
+ const unsub = createSolanaWatcher({
69
+ ...config.solana,
70
+ onPayment: (event) => {
71
+ config.onPayment(event);
72
+ config.solana.onPayment?.(event);
73
+ },
74
+ onError: (err) => {
75
+ config.onError?.(err);
76
+ config.solana.onError?.(err);
77
+ },
78
+ logger: config.solana.logger ?? log,
79
+ });
80
+ unsubscribers.push(unsub);
81
+ log('[multi-watcher] ◎ Solana watcher active');
82
+ }
83
+ log(`[multi-watcher] ✅ ${unsubscribers.length} watcher(s) running`);
84
+ return () => {
85
+ for (const unsub of unsubscribers) {
86
+ unsub();
87
+ }
88
+ log('[multi-watcher] 🛑 All watchers stopped');
89
+ };
90
+ }
91
+ //# sourceMappingURL=multi-watcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multi-watcher.js","sourceRoot":"","sources":["../../../src/monitor/multi-watcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,169 @@
1
+ import { noopLogger } from '../logger.js';
2
+ /** Mainnet USDC mint address. */
3
+ const USDC_MINT = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';
4
+ /**
5
+ * Creates a Solana payment watcher using JSON-RPC polling.
6
+ *
7
+ * Polls `getSignaturesForAddress` for new transactions, then
8
+ * inspects each transaction to detect:
9
+ * 1. Native SOL transfers TO the target address
10
+ * 2. SPL USDC transfers TO the target's Associated Token Account
11
+ *
12
+ * @returns Unsubscribe function to stop watching.
13
+ */
14
+ export function createSolanaWatcher(config) {
15
+ const log = config.logger ?? noopLogger;
16
+ const rpcUrl = config.rpcUrl ?? 'https://api.mainnet-beta.solana.com';
17
+ const pollInterval = config.pollIntervalMs ?? 5000;
18
+ const usdcMint = config.usdcMint ?? USDC_MINT;
19
+ let running = true;
20
+ let lastSignature = null;
21
+ let timer = null;
22
+ async function rpcCall(method, params) {
23
+ const response = await fetch(rpcUrl, {
24
+ method: 'POST',
25
+ headers: { 'Content-Type': 'application/json' },
26
+ body: JSON.stringify({ jsonrpc: '2.0', id: 1, method, params }),
27
+ });
28
+ const json = await response.json();
29
+ if (json.error)
30
+ throw new Error(`Solana RPC error: ${json.error.message}`);
31
+ return json.result;
32
+ }
33
+ async function getNewSignatures() {
34
+ const params = [
35
+ config.address,
36
+ { limit: 20, ...(lastSignature ? { until: lastSignature } : {}) },
37
+ ];
38
+ const result = await rpcCall('getSignaturesForAddress', params);
39
+ if (!Array.isArray(result) || result.length === 0)
40
+ return [];
41
+ // Return newest first
42
+ return result
43
+ .filter((r) => r.confirmationStatus === 'confirmed' || r.confirmationStatus === 'finalized')
44
+ .map((r) => r.signature);
45
+ }
46
+ async function inspectTransaction(signature) {
47
+ try {
48
+ const tx = await rpcCall('getTransaction', [signature, { encoding: 'jsonParsed', maxSupportedTransactionVersion: 0 }]);
49
+ if (!tx?.meta || tx.meta.err)
50
+ return null;
51
+ const targetLower = config.address;
52
+ // Check parsed instructions for SOL transfers and SPL token transfers
53
+ const instructions = tx.transaction?.message?.instructions || [];
54
+ const innerInstructions = tx.meta?.innerInstructions || [];
55
+ const allInstructions = [
56
+ ...instructions,
57
+ ...innerInstructions.flatMap((inner) => inner.instructions || []),
58
+ ];
59
+ for (const ix of allInstructions) {
60
+ const parsed = ix.parsed;
61
+ if (!parsed)
62
+ continue;
63
+ // Native SOL transfer
64
+ if (parsed.type === 'transfer' && ix.program === 'system') {
65
+ if (parsed.info?.destination === targetLower) {
66
+ const lamports = parsed.info.lamports.toString();
67
+ return {
68
+ amount: lamports,
69
+ amountFormatted: formatSol(lamports),
70
+ asset: 'SOL',
71
+ from: parsed.info.source || 'unknown',
72
+ transactionHash: signature,
73
+ chain: 'Solana',
74
+ caip2Id: 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp',
75
+ timestamp: new Date((tx.blockTime || Date.now() / 1000) * 1000),
76
+ confirmations: 1,
77
+ };
78
+ }
79
+ }
80
+ // SPL Token transfer (including USDC)
81
+ if ((parsed.type === 'transfer' || parsed.type === 'transferChecked') &&
82
+ ix.program === 'spl-token') {
83
+ const info = parsed.info;
84
+ // Check if this is USDC (by mint address in transferChecked)
85
+ const isUsdc = info?.mint === usdcMint;
86
+ const amount = info?.amount || info?.tokenAmount?.amount;
87
+ if (amount && info?.destination) {
88
+ // We need to check if the destination ATA belongs to our address
89
+ // For simplicity, we check pre/post token balances
90
+ return {
91
+ amount: amount.toString(),
92
+ amountFormatted: isUsdc ? formatUsdc(amount.toString()) : amount.toString(),
93
+ asset: isUsdc ? 'USDC' : 'SPL',
94
+ from: info.source || info.authority || 'unknown',
95
+ transactionHash: signature,
96
+ chain: 'Solana',
97
+ caip2Id: 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp',
98
+ timestamp: new Date((tx.blockTime || Date.now() / 1000) * 1000),
99
+ confirmations: 1,
100
+ };
101
+ }
102
+ }
103
+ }
104
+ return null;
105
+ }
106
+ catch (err) {
107
+ log(`[solana-watcher] ⚠️ Failed to inspect tx ${signature.slice(0, 16)}…: ${err.message}`);
108
+ return null;
109
+ }
110
+ }
111
+ async function poll() {
112
+ if (!running)
113
+ return;
114
+ try {
115
+ const signatures = await getNewSignatures();
116
+ if (signatures.length > 0 && !lastSignature) {
117
+ // First poll — just record the latest signature
118
+ lastSignature = signatures[0];
119
+ log(`[solana-watcher] 🔍 Started watching from signature ${lastSignature.slice(0, 16)}… on Solana`);
120
+ schedulePoll();
121
+ return;
122
+ }
123
+ if (signatures.length === 0) {
124
+ schedulePoll();
125
+ return;
126
+ }
127
+ log(`[solana-watcher] 📦 Processing ${signatures.length} new transactions`);
128
+ for (const sig of signatures.reverse()) { // Oldest first
129
+ const payment = await inspectTransaction(sig);
130
+ if (payment) {
131
+ log(`[solana-watcher] 💰 Incoming: ${payment.amountFormatted} ${payment.asset} from ${payment.from.slice(0, 10)}…`);
132
+ config.onPayment(payment);
133
+ }
134
+ }
135
+ lastSignature = signatures[0]; // Most recent
136
+ }
137
+ catch (err) {
138
+ log(`[solana-watcher] ❌ Poll error: ${err.message}`);
139
+ config.onError?.(err);
140
+ }
141
+ schedulePoll();
142
+ }
143
+ function schedulePoll() {
144
+ if (running && pollInterval > 0) {
145
+ timer = setTimeout(poll, pollInterval);
146
+ }
147
+ }
148
+ // Start polling
149
+ poll();
150
+ return () => {
151
+ running = false;
152
+ if (timer)
153
+ clearTimeout(timer);
154
+ log(`[solana-watcher] 🛑 Stopped watching on Solana`);
155
+ };
156
+ }
157
+ function formatSol(lamports) {
158
+ const n = BigInt(lamports);
159
+ const whole = n / 1000000000n;
160
+ const frac = ((n % 1000000000n) / 1000n).toString().padStart(6, '0');
161
+ return `${whole}.${frac}`;
162
+ }
163
+ function formatUsdc(atomicAmount) {
164
+ const n = BigInt(atomicAmount);
165
+ const whole = n / 1000000n;
166
+ const frac = (n % 1000000n).toString().padStart(6, '0');
167
+ return `${whole}.${frac}`;
168
+ }
169
+ //# sourceMappingURL=solana-watcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solana-watcher.js","sourceRoot":"","sources":["../../../src/monitor/solana-watcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,122 @@
1
+ import { noopLogger } from '../logger.js';
2
+ /**
3
+ * Creates a Stellar payment watcher using Horizon SSE streaming.
4
+ *
5
+ * Listens for `payment` and `create_account` operations directed
6
+ * to the target account. Supports asset-based filtering.
7
+ *
8
+ * @returns Unsubscribe function to stop watching.
9
+ */
10
+ export function createStellarWatcher(config) {
11
+ const log = config.logger ?? noopLogger;
12
+ const horizonUrl = config.horizonUrl ?? 'https://horizon.stellar.org';
13
+ const assetFilter = config.asset ?? 'all';
14
+ const cursor = config.cursor ?? 'now';
15
+ let abortController = null;
16
+ let running = true;
17
+ let reconnectTimer = null;
18
+ async function startStream() {
19
+ if (!running)
20
+ return;
21
+ const url = `${horizonUrl}/accounts/${config.accountId}/payments?cursor=${cursor}&order=asc`;
22
+ log(`[stellar-watcher] 🔍 Connecting to Horizon SSE: ${config.accountId.slice(0, 10)}…`);
23
+ abortController = new AbortController();
24
+ try {
25
+ const response = await fetch(url, {
26
+ headers: { Accept: 'text/event-stream' },
27
+ signal: abortController.signal,
28
+ });
29
+ if (!response.ok) {
30
+ throw new Error(`Horizon HTTP ${response.status}: ${response.statusText}`);
31
+ }
32
+ if (!response.body) {
33
+ throw new Error('No response body for SSE stream');
34
+ }
35
+ const reader = response.body.getReader();
36
+ const decoder = new TextDecoder();
37
+ let buffer = '';
38
+ log(`[stellar-watcher] ✅ SSE connected, watching for payments…`);
39
+ while (running) {
40
+ const { done, value } = await reader.read();
41
+ if (done)
42
+ break;
43
+ buffer += decoder.decode(value, { stream: true });
44
+ // Parse SSE events
45
+ const lines = buffer.split('\n');
46
+ buffer = lines.pop() || '';
47
+ let currentData = '';
48
+ for (const line of lines) {
49
+ if (line.startsWith('data: ')) {
50
+ currentData += line.slice(6);
51
+ }
52
+ else if (line === '' && currentData) {
53
+ // End of event — process
54
+ if (currentData !== '"hello"' && currentData !== 'hello') {
55
+ processEvent(currentData);
56
+ }
57
+ currentData = '';
58
+ }
59
+ }
60
+ }
61
+ }
62
+ catch (err) {
63
+ if (err.name === 'AbortError') {
64
+ log('[stellar-watcher] 🛑 Stream aborted');
65
+ return;
66
+ }
67
+ log(`[stellar-watcher] ❌ Stream error: ${err.message}`);
68
+ config.onError?.(err);
69
+ // Reconnect after 5s
70
+ if (running) {
71
+ log('[stellar-watcher] 🔄 Reconnecting in 5s…');
72
+ reconnectTimer = setTimeout(startStream, 5000);
73
+ }
74
+ }
75
+ }
76
+ function processEvent(data) {
77
+ try {
78
+ const record = JSON.parse(data);
79
+ // Only process payments TO this account
80
+ if (record.to !== config.accountId)
81
+ return;
82
+ // Only process payment operations
83
+ if (record.type !== 'payment' && record.type !== 'create_account')
84
+ return;
85
+ // Determine asset
86
+ const asset = record.asset_type === 'native'
87
+ ? 'XLM'
88
+ : record.asset_code || 'unknown';
89
+ // Apply asset filter
90
+ if (assetFilter !== 'all' && asset !== assetFilter)
91
+ return;
92
+ // Convert amount to atomic units (stroops = amount * 10^7)
93
+ const atomicAmount = Math.round(parseFloat(record.amount) * 10_000_000).toString();
94
+ const payment = {
95
+ amount: atomicAmount,
96
+ amountFormatted: record.amount,
97
+ asset,
98
+ from: record.from,
99
+ transactionHash: record.transaction_hash,
100
+ chain: 'Stellar',
101
+ caip2Id: 'stellar:pubnet',
102
+ timestamp: new Date(record.created_at),
103
+ };
104
+ log(`[stellar-watcher] 💰 Incoming: ${record.amount} ${asset} from ${record.from.slice(0, 10)}…`);
105
+ config.onPayment(payment);
106
+ }
107
+ catch (err) {
108
+ log(`[stellar-watcher] ⚠️ Failed to parse event: ${err.message}`);
109
+ }
110
+ }
111
+ // Start the stream
112
+ startStream();
113
+ // Return unsubscribe
114
+ return () => {
115
+ running = false;
116
+ abortController?.abort();
117
+ if (reconnectTimer)
118
+ clearTimeout(reconnectTimer);
119
+ log(`[stellar-watcher] 🛑 Stopped watching ${config.accountId.slice(0, 10)}…`);
120
+ };
121
+ }
122
+ //# sourceMappingURL=stellar-watcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stellar-watcher.js","sourceRoot":"","sources":["../../../src/monitor/stellar-watcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,175 @@
1
+ /**
2
+ * MPP — Machine Payments Protocol utilities.
3
+ *
4
+ * Handles parsing/building of MPP-standard headers:
5
+ * - WWW-Authenticate: Payment (Challenge)
6
+ * - Authorization: Payment (Credential)
7
+ * - Payment-Receipt (Receipt)
8
+ *
9
+ * @see https://mpp.dev/protocol/challenges
10
+ * @see https://mpp.dev/protocol/credentials
11
+ * @see https://mpp.dev/protocol/receipts
12
+ * @see https://paymentauth.org — IETF specification
13
+ */
14
+ // ─── Base64url helpers ──────────────────────────────────────────────
15
+ /**
16
+ * Encode string to base64url (RFC 4648 §5).
17
+ * No padding, URL-safe alphabet.
18
+ */
19
+ export function base64urlEncode(str) {
20
+ const b64 = Buffer.from(str, 'utf-8').toString('base64');
21
+ return b64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
22
+ }
23
+ /**
24
+ * Decode base64url string.
25
+ */
26
+ export function base64urlDecode(str) {
27
+ // Restore standard base64
28
+ let b64 = str.replace(/-/g, '+').replace(/_/g, '/');
29
+ // Add padding
30
+ while (b64.length % 4 !== 0)
31
+ b64 += '=';
32
+ return Buffer.from(b64, 'base64').toString('utf-8');
33
+ }
34
+ // ─── Challenge parsing ──────────────────────────────────────────────
35
+ /**
36
+ * Parse a `WWW-Authenticate: Payment` header value into an MppChallenge.
37
+ *
38
+ * Format:
39
+ * ```
40
+ * Payment id="abc", realm="mpp.dev", method="stripe", intent="charge",
41
+ * expires="2025-01-15T12:05:00Z", request="eyJhbW91bnQ..."
42
+ * ```
43
+ *
44
+ * @param header — Raw header value (with or without "Payment " prefix)
45
+ * @returns Parsed challenge object
46
+ * @throws Error if required fields are missing
47
+ */
48
+ export function parseMppChallenge(header) {
49
+ // Strip "Payment " prefix if present
50
+ let raw = header.trim();
51
+ if (raw.startsWith('Payment ')) {
52
+ raw = raw.slice(8);
53
+ }
54
+ // Parse RFC 7235 auth-param format: key="value", key="value"
55
+ const params = parseAuthParams(raw);
56
+ // Validate required fields
57
+ const required = ['id', 'realm', 'method', 'intent', 'request'];
58
+ for (const key of required) {
59
+ if (!params[key]) {
60
+ throw new Error(`MPP Challenge missing required field: ${key}`);
61
+ }
62
+ }
63
+ return {
64
+ id: params.id,
65
+ realm: params.realm,
66
+ method: params.method,
67
+ intent: params.intent,
68
+ request: params.request,
69
+ expires: params.expires,
70
+ description: params.description,
71
+ };
72
+ }
73
+ /**
74
+ * Parse multiple `WWW-Authenticate: Payment` headers.
75
+ * Servers can offer multiple payment options.
76
+ */
77
+ export function parseMppChallenges(headers) {
78
+ return headers.map(parseMppChallenge);
79
+ }
80
+ /**
81
+ * Decode the `request` field of a Challenge into a structured object.
82
+ */
83
+ export function decodeChallengeRequest(challenge) {
84
+ const json = base64urlDecode(challenge.request);
85
+ return JSON.parse(json);
86
+ }
87
+ // ─── Credential building ────────────────────────────────────────────
88
+ /**
89
+ * Build an MPP Credential for the `Authorization: Payment` header.
90
+ *
91
+ * @param challenge — The challenge being responded to
92
+ * @param source — DID or identifier of the payer
93
+ * @param payload — Method-specific proof (SPT for Stripe, tx for Tempo)
94
+ * @returns Base64url-encoded credential string
95
+ */
96
+ export function buildMppCredential(challenge, source, payload) {
97
+ const credential = {
98
+ challenge,
99
+ source,
100
+ payload,
101
+ };
102
+ return base64urlEncode(JSON.stringify(credential));
103
+ }
104
+ /**
105
+ * Build the full `Authorization` header value.
106
+ */
107
+ export function buildAuthorizationHeader(challenge, source, payload) {
108
+ return `Payment ${buildMppCredential(challenge, source, payload)}`;
109
+ }
110
+ // ─── Receipt parsing ────────────────────────────────────────────────
111
+ /**
112
+ * Parse a `Payment-Receipt` header.
113
+ */
114
+ export function parseMppReceipt(header) {
115
+ try {
116
+ const json = base64urlDecode(header.trim());
117
+ return JSON.parse(json);
118
+ }
119
+ catch {
120
+ return { raw: header };
121
+ }
122
+ }
123
+ // ─── Protocol detection ─────────────────────────────────────────────
124
+ /**
125
+ * Detect whether a 402 response uses MPP or x402 protocol.
126
+ *
127
+ * MPP: has `WWW-Authenticate: Payment` header
128
+ * x402: has JSON body with `x402Version` and `accepts[]`
129
+ */
130
+ export function detectProtocol(headers, body) {
131
+ // Check for MPP: WWW-Authenticate header with Payment scheme
132
+ const wwwAuth = headers['www-authenticate'] || headers['WWW-Authenticate'];
133
+ if (wwwAuth) {
134
+ const values = Array.isArray(wwwAuth) ? wwwAuth : [wwwAuth];
135
+ if (values.some((v) => v.trim().startsWith('Payment '))) {
136
+ return 'mpp';
137
+ }
138
+ }
139
+ // Check for x402: JSON body with x402Version
140
+ if (body && typeof body === 'object' && ('x402Version' in body || 'accepts' in body)) {
141
+ return 'x402';
142
+ }
143
+ return 'unknown';
144
+ }
145
+ /**
146
+ * Extract all MPP challenges from response headers.
147
+ * Handles both single and multiple WWW-Authenticate headers.
148
+ */
149
+ export function extractMppChallenges(headers) {
150
+ const wwwAuth = headers['www-authenticate'] || headers['WWW-Authenticate'];
151
+ if (!wwwAuth)
152
+ return [];
153
+ const values = Array.isArray(wwwAuth) ? wwwAuth : [wwwAuth];
154
+ return values
155
+ .filter((v) => v.trim().startsWith('Payment '))
156
+ .map(parseMppChallenge);
157
+ }
158
+ // ─── Internal helpers ───────────────────────────────────────────────
159
+ /**
160
+ * Parse RFC 7235 auth-param format.
161
+ * `key="value", key="value"`
162
+ */
163
+ function parseAuthParams(raw) {
164
+ const params = {};
165
+ // Match key="value" pairs, handling escaped quotes
166
+ const regex = /(\w+)="((?:[^"\\]|\\.)*)"/g;
167
+ let match;
168
+ while ((match = regex.exec(raw)) !== null) {
169
+ const [, key, value] = match;
170
+ // Unescape backslash-escaped characters
171
+ params[key] = value.replace(/\\(.)/g, '$1');
172
+ }
173
+ return params;
174
+ }
175
+ //# sourceMappingURL=mpp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mpp.js","sourceRoot":"","sources":["../../src/mpp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * PolicyEngine — On-device budget controller for autonomous AI agents.
3
+ *
4
+ * Enforces per-transaction caps, monthly rolling budgets, and optional
5
+ * destination whitelists so that an agent can never overspend without
6
+ * explicit human approval.
7
+ *
8
+ * Fail-closed: if any check fails, the payment is rejected.
9
+ */
10
+ import { noopLogger } from './logger.js';
11
+ export class PolicyEngine {
12
+ policy;
13
+ currentMonthSpent = 0;
14
+ log;
15
+ constructor(policy, logger) {
16
+ this.policy = policy;
17
+ this.log = logger ?? noopLogger;
18
+ }
19
+ /**
20
+ * Returns `true` if the proposed spend passes every policy gate.
21
+ * Fail-closed: any unrecognised state returns `false`.
22
+ */
23
+ checkPolicy(amountUsd, destination) {
24
+ if (amountUsd <= 0) {
25
+ this.log(`[Policy] 🚫 Invalid amount: $${amountUsd}`);
26
+ return false;
27
+ }
28
+ if (amountUsd > this.policy.maxAmountPerTransaction) {
29
+ this.log(`[Policy] 🚫 $${amountUsd} exceeds per-tx limit of $${this.policy.maxAmountPerTransaction}`);
30
+ return false;
31
+ }
32
+ if (this.currentMonthSpent + amountUsd > this.policy.monthlyBudget) {
33
+ this.log(`[Policy] 🚫 $${amountUsd} would exceed monthly budget of $${this.policy.monthlyBudget} (spent: $${this.currentMonthSpent})`);
34
+ return false;
35
+ }
36
+ if (this.policy.allowedDestinations &&
37
+ this.policy.allowedDestinations.length > 0 &&
38
+ destination &&
39
+ !this.policy.allowedDestinations.includes(destination)) {
40
+ this.log(`[Policy] 🚫 Destination ${destination} not in whitelist`);
41
+ return false;
42
+ }
43
+ return true;
44
+ }
45
+ /** Record a successful spend against the rolling budget. */
46
+ recordSpend(amountUsd) {
47
+ this.currentMonthSpent += amountUsd;
48
+ this.log(`[Policy] 📊 Spent $${amountUsd} — total: $${this.currentMonthSpent}/$${this.policy.monthlyBudget}`);
49
+ }
50
+ /** Get total USD spent in the current period. */
51
+ getSpent() {
52
+ return this.currentMonthSpent;
53
+ }
54
+ /** Get remaining USD budget. */
55
+ getRemainingBudget() {
56
+ return Math.max(0, this.policy.monthlyBudget - this.currentMonthSpent);
57
+ }
58
+ /** Reset the spend counter (e.g. on month rollover or for testing). */
59
+ resetBudget() {
60
+ this.currentMonthSpent = 0;
61
+ }
62
+ /** Get a snapshot of the current policy configuration. */
63
+ getPolicy() {
64
+ return { ...this.policy };
65
+ }
66
+ }
67
+ //# sourceMappingURL=policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAU,UAAU,EAAE,MAAM,UAAU,CAAC;AAW9C,MAAM,OAAO,YAAY;IAKb;IAJF,iBAAiB,GAAG,CAAC,CAAC;IACtB,GAAG,CAAS;IAEpB,YACU,MAAoB,EAC5B,MAAe;QADP,WAAM,GAAN,MAAM,CAAc;QAG5B,IAAI,CAAC,GAAG,GAAG,MAAM,IAAI,UAAU,CAAC;IAClC,CAAC;IAED;;;OAGG;IACI,WAAW,CAAC,SAAiB,EAAE,WAAoB;QACxD,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;YACnB,IAAI,CAAC,GAAG,CAAC,gCAAgC,SAAS,EAAE,CAAC,CAAC;YACtD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,uBAAuB,EAAE,CAAC;YACpD,IAAI,CAAC,GAAG,CACN,gBAAgB,SAAS,6BAA6B,IAAI,CAAC,MAAM,CAAC,uBAAuB,EAAE,CAC5F,CAAC;YACF,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,IAAI,CAAC,iBAAiB,GAAG,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;YACnE,IAAI,CAAC,GAAG,CACN,gBAAgB,SAAS,oCAAoC,IAAI,CAAC,MAAM,CAAC,aAAa,aAAa,IAAI,CAAC,iBAAiB,GAAG,CAC7H,CAAC;YACF,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IACE,IAAI,CAAC,MAAM,CAAC,mBAAmB;YAC/B,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,MAAM,GAAG,CAAC;YAC1C,WAAW;YACX,CAAC,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,QAAQ,CAAC,WAAW,CAAC,EACtD,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,2BAA2B,WAAW,mBAAmB,CAAC,CAAC;YACpE,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED,4DAA4D;IACrD,WAAW,CAAC,SAAiB;QAClC,IAAI,CAAC,iBAAiB,IAAI,SAAS,CAAC;QACpC,IAAI,CAAC,GAAG,CACN,sBAAsB,SAAS,cAAc,IAAI,CAAC,iBAAiB,KAAK,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CACpG,CAAC;IACJ,CAAC;IAED,iDAAiD;IAC1C,QAAQ;QACb,OAAO,IAAI,CAAC,iBAAiB,CAAC;IAChC,CAAC;IAED,gCAAgC;IACzB,kBAAkB;QACvB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,aAAa,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACzE,CAAC;IAED,uEAAuE;IAChE,WAAW;QAChB,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,0DAA0D;IACnD,SAAS;QACd,OAAO,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;IAC5B,CAAC;CACF"}