mppx 0.8.15 → 0.8.18

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 (966) hide show
  1. package/CHANGELOG.md +91 -0
  2. package/README.md +15 -0
  3. package/dist/Challenge.js +61 -39
  4. package/dist/Constants.d.ts +17 -17
  5. package/dist/Errors.d.ts +3 -3
  6. package/dist/Method.d.ts +35 -5
  7. package/dist/Method.js +7 -22
  8. package/dist/Store.d.ts +19 -0
  9. package/dist/Store.js +43 -0
  10. package/dist/attestation/Client.d.ts +17 -0
  11. package/dist/attestation/Client.js +28 -0
  12. package/dist/attestation/Constants.d.ts +15 -0
  13. package/dist/attestation/Constants.js +15 -0
  14. package/dist/attestation/Server.d.ts +4 -0
  15. package/dist/attestation/Server.js +8 -0
  16. package/dist/attestation/Types.d.ts +76 -0
  17. package/dist/attestation/Types.js +2 -0
  18. package/dist/attestation/index.d.ts +6 -0
  19. package/dist/attestation/index.js +6 -0
  20. package/dist/attestation/internal/HttpMessageSignature.d.ts +73 -0
  21. package/dist/attestation/internal/HttpMessageSignature.js +320 -0
  22. package/dist/attestation/internal/SigningContext.d.ts +4 -0
  23. package/dist/attestation/internal/SigningContext.js +11 -0
  24. package/dist/bin.js +3 -3
  25. package/dist/cli/THIRD-PARTY-LICENSES.txt +328 -0
  26. package/dist/cli/account.d.ts +14 -14
  27. package/dist/cli/cli.d.ts +6 -6
  28. package/dist/cli/cli.js +253 -1504
  29. package/dist/cli/plugins/index.js +19 -5
  30. package/dist/cli/plugins/tempo.js +7 -3
  31. package/dist/cli/sessions/Manager.js +7 -4
  32. package/dist/cli/sessions/commands.d.ts +4 -4
  33. package/dist/cli/sessions/request.d.ts +2 -0
  34. package/dist/cli/sessions/request.js +18 -0
  35. package/dist/cli/sessions/store.js +28 -14
  36. package/dist/cli/utils.d.ts +1 -1
  37. package/dist/cli/validate/index.d.ts +3 -3
  38. package/dist/client/Mppx.d.ts +3 -0
  39. package/dist/client/Mppx.js +13 -5
  40. package/dist/client/Transport.d.ts +3 -5
  41. package/dist/client/Transport.js +1 -17
  42. package/dist/client/internal/Fetch.js +2 -6
  43. package/dist/discovery/Discovery.js +2 -1
  44. package/dist/discovery/OpenApi.d.ts +3 -5
  45. package/dist/discovery/OpenApi.js +13 -34
  46. package/dist/discovery/internal/Metadata.d.ts +20 -0
  47. package/dist/discovery/internal/Metadata.js +36 -0
  48. package/dist/evm/Methods.d.ts +11 -11
  49. package/dist/evm/Types.d.ts +17 -17
  50. package/dist/evm/client/Charge.d.ts +11 -11
  51. package/dist/evm/client/Charge.js +8 -0
  52. package/dist/evm/client/Methods.d.ts +11 -11
  53. package/dist/evm/server/Charge.d.ts +1 -1
  54. package/dist/evm/server/Charge.js +2 -0
  55. package/dist/evm/server/Methods.d.ts +11 -11
  56. package/dist/internal/HeaderCodec.d.ts +2 -2
  57. package/dist/internal/types.d.ts +6 -0
  58. package/dist/proxy/Proxy.d.ts +2 -0
  59. package/dist/proxy/Proxy.js +117 -9
  60. package/dist/proxy/Service.d.ts +36 -1
  61. package/dist/proxy/Service.js +9 -8
  62. package/dist/proxy/services/anthropic.js +1 -0
  63. package/dist/proxy/services/openai.js +1 -0
  64. package/dist/proxy/services/stripe.js +1 -0
  65. package/dist/server/Mppx.d.ts +75 -13
  66. package/dist/server/Mppx.js +201 -23
  67. package/dist/server/core.d.ts +9 -0
  68. package/dist/server/core.js +9 -0
  69. package/dist/server/internal/html/config.d.ts +9 -9
  70. package/dist/server/internal/html/constants.d.ts +17 -17
  71. package/dist/stripe/Methods.d.ts +10 -10
  72. package/dist/stripe/client/Charge.d.ts +10 -10
  73. package/dist/stripe/client/Methods.d.ts +10 -10
  74. package/dist/stripe/internal/constants.d.ts +1 -1
  75. package/dist/stripe/internal/constants.js +1 -1
  76. package/dist/stripe/internal/types.d.ts +1 -0
  77. package/dist/stripe/server/Charge.d.ts +11 -11
  78. package/dist/stripe/server/Charge.js +51 -5
  79. package/dist/stripe/server/Methods.d.ts +137 -48
  80. package/dist/stripe/server/Methods.js +265 -4
  81. package/dist/stripe/server/internal/deposit-address.d.ts +13 -0
  82. package/dist/stripe/server/internal/deposit-address.js +28 -0
  83. package/dist/stripe/server/internal/html.gen.d.ts +1 -1
  84. package/dist/stripe/server/internal/html.gen.js +1 -1
  85. package/dist/stripe/server/internal/record-payment.d.ts +15 -0
  86. package/dist/stripe/server/internal/record-payment.js +42 -0
  87. package/dist/stripe/server/internal/request.d.ts +25 -0
  88. package/dist/stripe/server/internal/request.js +29 -0
  89. package/dist/stripe/server/spt.d.ts +8 -0
  90. package/dist/stripe/server/spt.js +8 -0
  91. package/dist/tap/Constants.d.ts +28 -0
  92. package/dist/tap/Constants.js +32 -0
  93. package/dist/tap/Types.d.ts +11 -0
  94. package/dist/tap/Types.js +2 -0
  95. package/dist/tap/client/index.d.ts +26 -0
  96. package/dist/tap/client/index.js +33 -0
  97. package/dist/tap/index.d.ts +5 -0
  98. package/dist/tap/index.js +5 -0
  99. package/dist/tap/server/index.d.ts +20 -0
  100. package/dist/tap/server/index.js +36 -0
  101. package/dist/tempo/Attribution.d.ts +1 -1
  102. package/dist/tempo/Methods.d.ts +73 -60
  103. package/dist/tempo/Methods.js +14 -3
  104. package/dist/tempo/Proof.d.ts +16 -16
  105. package/dist/tempo/client/Charge.d.ts +22 -19
  106. package/dist/tempo/client/Charge.js +32 -16
  107. package/dist/tempo/client/Methods.d.ts +51 -38
  108. package/dist/tempo/client/Subscription.d.ts +23 -23
  109. package/dist/tempo/internal/address.d.ts +2 -1
  110. package/dist/tempo/internal/address.js +3 -1
  111. package/dist/tempo/internal/auto-swap.js +4 -19
  112. package/dist/tempo/internal/defaults.d.ts +17 -6
  113. package/dist/tempo/internal/defaults.js +11 -0
  114. package/dist/tempo/internal/fee-payer.d.ts +12 -12
  115. package/dist/tempo/internal/machine-token-charge.d.ts +51 -0
  116. package/dist/tempo/internal/machine-token-charge.js +113 -0
  117. package/dist/tempo/internal/machine-token-session.d.ts +88 -0
  118. package/dist/tempo/internal/machine-token-session.js +173 -0
  119. package/dist/tempo/internal/proof.d.ts +17 -17
  120. package/dist/tempo/internal/signature-envelope.d.ts +14 -0
  121. package/dist/tempo/internal/signature-envelope.js +28 -0
  122. package/dist/tempo/legacy/client/ChannelOps.d.ts +2 -2
  123. package/dist/tempo/legacy/client/ChannelOps.js +11 -5
  124. package/dist/tempo/legacy/client/Session.d.ts +33 -21
  125. package/dist/tempo/legacy/client/Session.js +3 -3
  126. package/dist/tempo/legacy/client/SessionManager.d.ts +3 -1
  127. package/dist/tempo/legacy/client/SessionManager.js +2 -0
  128. package/dist/tempo/legacy/index.d.ts +1 -3
  129. package/dist/tempo/legacy/index.js +1 -3
  130. package/dist/tempo/legacy/session/escrow.abi.d.ts +374 -374
  131. package/dist/tempo/server/Charge.d.ts +28 -11
  132. package/dist/tempo/server/Charge.js +101 -55
  133. package/dist/tempo/server/Methods.d.ts +58 -56
  134. package/dist/tempo/server/Methods.js +8 -18
  135. package/dist/tempo/server/Relay.d.ts +1 -1
  136. package/dist/tempo/server/Relay.js +2 -2
  137. package/dist/tempo/server/Subscription.d.ts +25 -25
  138. package/dist/tempo/server/Subscription.js +2 -0
  139. package/dist/tempo/server/index.d.ts +1 -1
  140. package/dist/tempo/server/index.js +1 -1
  141. package/dist/tempo/server/internal/html.gen.d.ts +1 -1
  142. package/dist/tempo/server/internal/html.gen.js +1 -1
  143. package/dist/tempo/server/internal/transport.d.ts +2 -0
  144. package/dist/tempo/server/internal/transport.js +9 -2
  145. package/dist/tempo/session/client/ChannelOps.d.ts +18 -3
  146. package/dist/tempo/session/client/ChannelOps.js +35 -6
  147. package/dist/tempo/session/client/ChannelStore.d.ts +0 -5
  148. package/dist/tempo/session/client/ChannelStore.js +2 -2
  149. package/dist/tempo/session/client/CredentialState.d.ts +18 -3
  150. package/dist/tempo/session/client/CredentialState.js +77 -76
  151. package/dist/tempo/session/client/Runtime.d.ts +4 -2
  152. package/dist/tempo/session/client/Runtime.js +21 -5
  153. package/dist/tempo/session/client/Session.d.ts +34 -22
  154. package/dist/tempo/session/client/Session.js +186 -63
  155. package/dist/tempo/session/client/SessionManager.d.ts +3 -1
  156. package/dist/tempo/session/client/SessionManager.js +35 -11
  157. package/dist/tempo/session/client/Transports.d.ts +2 -0
  158. package/dist/tempo/session/client/Transports.js +12 -2
  159. package/dist/tempo/session/precompile/Chain.d.ts +37 -2
  160. package/dist/tempo/session/precompile/Chain.js +116 -15
  161. package/dist/tempo/session/precompile/Protocol.d.ts +15 -0
  162. package/dist/tempo/session/precompile/Protocol.js +7 -0
  163. package/dist/tempo/session/precompile/Voucher.d.ts +7 -5
  164. package/dist/tempo/session/precompile/Voucher.js +6 -12
  165. package/dist/tempo/session/precompile/escrow.abi.d.ts +306 -306
  166. package/dist/tempo/session/server/ChannelStore.d.ts +15 -0
  167. package/dist/tempo/session/server/ChannelStore.js +27 -12
  168. package/dist/tempo/session/server/CredentialVerification.d.ts +39 -20
  169. package/dist/tempo/session/server/CredentialVerification.js +359 -89
  170. package/dist/tempo/session/server/MeteredStream.d.ts +4 -1
  171. package/dist/tempo/session/server/MeteredStream.js +8 -5
  172. package/dist/tempo/session/server/RequestState.d.ts +19 -0
  173. package/dist/tempo/session/server/RequestState.js +61 -15
  174. package/dist/tempo/session/server/Session.d.ts +46 -23
  175. package/dist/tempo/session/server/Session.js +150 -56
  176. package/dist/tempo/session/server/Settlement.d.ts +11 -4
  177. package/dist/tempo/session/server/Settlement.js +53 -21
  178. package/dist/tempo/session/server/Sse.d.ts +3 -1
  179. package/dist/tempo/session/server/Sse.js +2 -1
  180. package/dist/tempo/session/server/Transports.d.ts +1 -1
  181. package/dist/tempo/session/server/Transports.js +1 -0
  182. package/dist/tempo/session/server/Ws.d.ts +6 -1
  183. package/dist/tempo/session/server/Ws.js +1 -0
  184. package/dist/tempo/subscription/KeyAuthorization.d.ts +39 -39
  185. package/dist/web-bot-auth/Constants.d.ts +20 -0
  186. package/dist/web-bot-auth/Constants.js +24 -0
  187. package/dist/web-bot-auth/Types.d.ts +10 -0
  188. package/dist/web-bot-auth/Types.js +2 -0
  189. package/dist/web-bot-auth/client/index.d.ts +29 -0
  190. package/dist/web-bot-auth/client/index.js +64 -0
  191. package/dist/web-bot-auth/index.d.ts +7 -0
  192. package/dist/web-bot-auth/index.js +7 -0
  193. package/dist/web-bot-auth/internal/JwkThumbprint.d.ts +5 -0
  194. package/dist/web-bot-auth/internal/JwkThumbprint.js +20 -0
  195. package/dist/web-bot-auth/internal/SignatureAgent.d.ts +3 -0
  196. package/dist/web-bot-auth/internal/SignatureAgent.js +18 -0
  197. package/dist/web-bot-auth/server/index.d.ts +35 -0
  198. package/dist/web-bot-auth/server/index.js +88 -0
  199. package/dist/x402/Types.d.ts +6 -6
  200. package/dist/x402/client/Exact.d.ts +8 -0
  201. package/dist/x402/client/Exact.js +40 -10
  202. package/dist/x402/server/EvmCharge.d.ts +22 -0
  203. package/dist/x402/server/EvmCharge.js +54 -20
  204. package/package.json +28 -34
  205. package/dist/BodyDigest.d.ts.map +0 -1
  206. package/dist/BodyDigest.js.map +0 -1
  207. package/dist/Challenge.d.ts.map +0 -1
  208. package/dist/Challenge.js.map +0 -1
  209. package/dist/Constants.d.ts.map +0 -1
  210. package/dist/Constants.js.map +0 -1
  211. package/dist/Credential.d.ts.map +0 -1
  212. package/dist/Credential.js.map +0 -1
  213. package/dist/Errors.d.ts.map +0 -1
  214. package/dist/Errors.js.map +0 -1
  215. package/dist/Expires.d.ts.map +0 -1
  216. package/dist/Expires.js.map +0 -1
  217. package/dist/Html.d.ts.map +0 -1
  218. package/dist/Html.js.map +0 -1
  219. package/dist/Mcp.d.ts.map +0 -1
  220. package/dist/Mcp.js.map +0 -1
  221. package/dist/Method.d.ts.map +0 -1
  222. package/dist/Method.js.map +0 -1
  223. package/dist/PaymentRequest.d.ts.map +0 -1
  224. package/dist/PaymentRequest.js.map +0 -1
  225. package/dist/Receipt.d.ts.map +0 -1
  226. package/dist/Receipt.js.map +0 -1
  227. package/dist/Store.d.ts.map +0 -1
  228. package/dist/Store.js.map +0 -1
  229. package/dist/bin.d.ts.map +0 -1
  230. package/dist/bin.js.map +0 -1
  231. package/dist/cli/account.d.ts.map +0 -1
  232. package/dist/cli/account.js.map +0 -1
  233. package/dist/cli/cli.d.ts.map +0 -1
  234. package/dist/cli/cli.js.map +0 -1
  235. package/dist/cli/config.d.ts.map +0 -1
  236. package/dist/cli/config.js.map +0 -1
  237. package/dist/cli/internal.d.ts.map +0 -1
  238. package/dist/cli/internal.js.map +0 -1
  239. package/dist/cli/plugins/evm.d.ts.map +0 -1
  240. package/dist/cli/plugins/evm.js.map +0 -1
  241. package/dist/cli/plugins/index.d.ts.map +0 -1
  242. package/dist/cli/plugins/index.js.map +0 -1
  243. package/dist/cli/plugins/plugin.d.ts.map +0 -1
  244. package/dist/cli/plugins/plugin.js.map +0 -1
  245. package/dist/cli/plugins/stripe.d.ts.map +0 -1
  246. package/dist/cli/plugins/stripe.js.map +0 -1
  247. package/dist/cli/plugins/tempo.d.ts.map +0 -1
  248. package/dist/cli/plugins/tempo.js.map +0 -1
  249. package/dist/cli/sessions/Manager.d.ts.map +0 -1
  250. package/dist/cli/sessions/Manager.js.map +0 -1
  251. package/dist/cli/sessions/commands.d.ts.map +0 -1
  252. package/dist/cli/sessions/commands.js.map +0 -1
  253. package/dist/cli/sessions/request.d.ts.map +0 -1
  254. package/dist/cli/sessions/request.js.map +0 -1
  255. package/dist/cli/sessions/store.d.ts.map +0 -1
  256. package/dist/cli/sessions/store.js.map +0 -1
  257. package/dist/cli/utils.d.ts.map +0 -1
  258. package/dist/cli/utils.js.map +0 -1
  259. package/dist/cli/validate/challenge.d.ts.map +0 -1
  260. package/dist/cli/validate/challenge.js.map +0 -1
  261. package/dist/cli/validate/discovery.d.ts.map +0 -1
  262. package/dist/cli/validate/discovery.js.map +0 -1
  263. package/dist/cli/validate/helpers.d.ts.map +0 -1
  264. package/dist/cli/validate/helpers.js.map +0 -1
  265. package/dist/cli/validate/index.d.ts.map +0 -1
  266. package/dist/cli/validate/index.js.map +0 -1
  267. package/dist/cli/validate/messages.d.ts.map +0 -1
  268. package/dist/cli/validate/messages.js.map +0 -1
  269. package/dist/cli/validate/payment.d.ts.map +0 -1
  270. package/dist/cli/validate/payment.js.map +0 -1
  271. package/dist/client/Methods.d.ts.map +0 -1
  272. package/dist/client/Methods.js.map +0 -1
  273. package/dist/client/Mppx.d.ts.map +0 -1
  274. package/dist/client/Mppx.js.map +0 -1
  275. package/dist/client/Transport.d.ts.map +0 -1
  276. package/dist/client/Transport.js.map +0 -1
  277. package/dist/client/index.d.ts.map +0 -1
  278. package/dist/client/index.js.map +0 -1
  279. package/dist/client/internal/Fetch.d.ts.map +0 -1
  280. package/dist/client/internal/Fetch.js.map +0 -1
  281. package/dist/client/internal/MethodChallenge.d.ts.map +0 -1
  282. package/dist/client/internal/MethodChallenge.js.map +0 -1
  283. package/dist/client/internal/MethodResponse.d.ts.map +0 -1
  284. package/dist/client/internal/MethodResponse.js.map +0 -1
  285. package/dist/client/internal/protocols/Mcp.d.ts.map +0 -1
  286. package/dist/client/internal/protocols/Mcp.js.map +0 -1
  287. package/dist/client/internal/protocols/Mpp.d.ts.map +0 -1
  288. package/dist/client/internal/protocols/Mpp.js.map +0 -1
  289. package/dist/client/internal/protocols/Protocol.d.ts.map +0 -1
  290. package/dist/client/internal/protocols/Protocol.js.map +0 -1
  291. package/dist/client/internal/protocols/Shared.d.ts.map +0 -1
  292. package/dist/client/internal/protocols/Shared.js.map +0 -1
  293. package/dist/client/internal/protocols/X402.d.ts.map +0 -1
  294. package/dist/client/internal/protocols/X402.js.map +0 -1
  295. package/dist/client/node.d.ts.map +0 -1
  296. package/dist/client/node.js.map +0 -1
  297. package/dist/discovery/Discovery.d.ts.map +0 -1
  298. package/dist/discovery/Discovery.js.map +0 -1
  299. package/dist/discovery/OpenApi.d.ts.map +0 -1
  300. package/dist/discovery/OpenApi.js.map +0 -1
  301. package/dist/discovery/Validate.d.ts.map +0 -1
  302. package/dist/discovery/Validate.js.map +0 -1
  303. package/dist/discovery/index.d.ts.map +0 -1
  304. package/dist/discovery/index.js.map +0 -1
  305. package/dist/evm/Assets.d.ts.map +0 -1
  306. package/dist/evm/Assets.js.map +0 -1
  307. package/dist/evm/Chains.d.ts.map +0 -1
  308. package/dist/evm/Chains.js.map +0 -1
  309. package/dist/evm/Methods.d.ts.map +0 -1
  310. package/dist/evm/Methods.js.map +0 -1
  311. package/dist/evm/Types.d.ts.map +0 -1
  312. package/dist/evm/Types.js.map +0 -1
  313. package/dist/evm/client/Charge.d.ts.map +0 -1
  314. package/dist/evm/client/Charge.js.map +0 -1
  315. package/dist/evm/client/Methods.d.ts.map +0 -1
  316. package/dist/evm/client/Methods.js.map +0 -1
  317. package/dist/evm/client/index.d.ts.map +0 -1
  318. package/dist/evm/client/index.js.map +0 -1
  319. package/dist/evm/index.d.ts.map +0 -1
  320. package/dist/evm/index.js.map +0 -1
  321. package/dist/evm/server/Charge.d.ts.map +0 -1
  322. package/dist/evm/server/Charge.js.map +0 -1
  323. package/dist/evm/server/Methods.d.ts.map +0 -1
  324. package/dist/evm/server/Methods.js.map +0 -1
  325. package/dist/evm/server/index.d.ts.map +0 -1
  326. package/dist/evm/server/index.js.map +0 -1
  327. package/dist/index.d.ts.map +0 -1
  328. package/dist/index.js.map +0 -1
  329. package/dist/internal/AcceptPayment.d.ts.map +0 -1
  330. package/dist/internal/AcceptPayment.js.map +0 -1
  331. package/dist/internal/HeaderCodec.d.ts.map +0 -1
  332. package/dist/internal/HeaderCodec.js.map +0 -1
  333. package/dist/internal/constantTimeEqual.d.ts.map +0 -1
  334. package/dist/internal/constantTimeEqual.js.map +0 -1
  335. package/dist/internal/env.d.ts.map +0 -1
  336. package/dist/internal/env.js.map +0 -1
  337. package/dist/internal/types.d.ts.map +0 -1
  338. package/dist/internal/types.js.map +0 -1
  339. package/dist/mcp/client/McpClient.d.ts.map +0 -1
  340. package/dist/mcp/client/McpClient.js.map +0 -1
  341. package/dist/mcp/client/index.d.ts.map +0 -1
  342. package/dist/mcp/client/index.js.map +0 -1
  343. package/dist/mcp/server/Transport.d.ts.map +0 -1
  344. package/dist/mcp/server/Transport.js.map +0 -1
  345. package/dist/mcp/server/index.d.ts.map +0 -1
  346. package/dist/mcp/server/index.js.map +0 -1
  347. package/dist/middlewares/elysia.d.ts.map +0 -1
  348. package/dist/middlewares/elysia.js.map +0 -1
  349. package/dist/middlewares/express.d.ts.map +0 -1
  350. package/dist/middlewares/express.js.map +0 -1
  351. package/dist/middlewares/hono.d.ts.map +0 -1
  352. package/dist/middlewares/hono.js.map +0 -1
  353. package/dist/middlewares/internal/mppx.d.ts.map +0 -1
  354. package/dist/middlewares/internal/mppx.js.map +0 -1
  355. package/dist/middlewares/nextjs.d.ts.map +0 -1
  356. package/dist/middlewares/nextjs.js.map +0 -1
  357. package/dist/proxy/Proxy.d.ts.map +0 -1
  358. package/dist/proxy/Proxy.js.map +0 -1
  359. package/dist/proxy/Service.d.ts.map +0 -1
  360. package/dist/proxy/Service.js.map +0 -1
  361. package/dist/proxy/index.d.ts.map +0 -1
  362. package/dist/proxy/index.js.map +0 -1
  363. package/dist/proxy/internal/Headers.d.ts.map +0 -1
  364. package/dist/proxy/internal/Headers.js.map +0 -1
  365. package/dist/proxy/internal/Route.d.ts.map +0 -1
  366. package/dist/proxy/internal/Route.js.map +0 -1
  367. package/dist/proxy/services/anthropic.d.ts.map +0 -1
  368. package/dist/proxy/services/anthropic.js.map +0 -1
  369. package/dist/proxy/services/openai.d.ts.map +0 -1
  370. package/dist/proxy/services/openai.js.map +0 -1
  371. package/dist/proxy/services/stripe.d.ts.map +0 -1
  372. package/dist/proxy/services/stripe.js.map +0 -1
  373. package/dist/server/Methods.d.ts.map +0 -1
  374. package/dist/server/Methods.js.map +0 -1
  375. package/dist/server/Mppx.d.ts.map +0 -1
  376. package/dist/server/Mppx.js.map +0 -1
  377. package/dist/server/NodeListener.d.ts.map +0 -1
  378. package/dist/server/NodeListener.js.map +0 -1
  379. package/dist/server/Request.d.ts.map +0 -1
  380. package/dist/server/Request.js.map +0 -1
  381. package/dist/server/Response.d.ts.map +0 -1
  382. package/dist/server/Response.js.map +0 -1
  383. package/dist/server/Transport.d.ts.map +0 -1
  384. package/dist/server/Transport.js.map +0 -1
  385. package/dist/server/index.d.ts.map +0 -1
  386. package/dist/server/index.js.map +0 -1
  387. package/dist/server/internal/html/compose.main.gen.d.ts.map +0 -1
  388. package/dist/server/internal/html/compose.main.gen.js.map +0 -1
  389. package/dist/server/internal/html/config.d.ts.map +0 -1
  390. package/dist/server/internal/html/config.js.map +0 -1
  391. package/dist/server/internal/html/constants.d.ts.map +0 -1
  392. package/dist/server/internal/html/constants.js.map +0 -1
  393. package/dist/server/internal/html/serviceWorker.client.d.ts.map +0 -1
  394. package/dist/server/internal/html/serviceWorker.client.js.map +0 -1
  395. package/dist/server/internal/html/serviceWorker.gen.d.ts.map +0 -1
  396. package/dist/server/internal/html/serviceWorker.gen.js.map +0 -1
  397. package/dist/server/internal/scope.d.ts.map +0 -1
  398. package/dist/server/internal/scope.js.map +0 -1
  399. package/dist/stripe/Methods.d.ts.map +0 -1
  400. package/dist/stripe/Methods.js.map +0 -1
  401. package/dist/stripe/client/Charge.d.ts.map +0 -1
  402. package/dist/stripe/client/Charge.js.map +0 -1
  403. package/dist/stripe/client/Methods.d.ts.map +0 -1
  404. package/dist/stripe/client/Methods.js.map +0 -1
  405. package/dist/stripe/client/index.d.ts.map +0 -1
  406. package/dist/stripe/client/index.js.map +0 -1
  407. package/dist/stripe/index.d.ts.map +0 -1
  408. package/dist/stripe/index.js.map +0 -1
  409. package/dist/stripe/internal/constants.d.ts.map +0 -1
  410. package/dist/stripe/internal/constants.js.map +0 -1
  411. package/dist/stripe/internal/types.d.ts.map +0 -1
  412. package/dist/stripe/internal/types.js.map +0 -1
  413. package/dist/stripe/server/Charge.d.ts.map +0 -1
  414. package/dist/stripe/server/Charge.js.map +0 -1
  415. package/dist/stripe/server/Methods.d.ts.map +0 -1
  416. package/dist/stripe/server/Methods.js.map +0 -1
  417. package/dist/stripe/server/index.d.ts.map +0 -1
  418. package/dist/stripe/server/index.js.map +0 -1
  419. package/dist/stripe/server/internal/html/types.d.ts.map +0 -1
  420. package/dist/stripe/server/internal/html/types.js.map +0 -1
  421. package/dist/stripe/server/internal/html.gen.d.ts.map +0 -1
  422. package/dist/stripe/server/internal/html.gen.js.map +0 -1
  423. package/dist/tempo/Attribution.d.ts.map +0 -1
  424. package/dist/tempo/Attribution.js.map +0 -1
  425. package/dist/tempo/Methods.d.ts.map +0 -1
  426. package/dist/tempo/Methods.js.map +0 -1
  427. package/dist/tempo/Proof.d.ts.map +0 -1
  428. package/dist/tempo/Proof.js.map +0 -1
  429. package/dist/tempo/client/Charge.d.ts.map +0 -1
  430. package/dist/tempo/client/Charge.js.map +0 -1
  431. package/dist/tempo/client/Methods.d.ts.map +0 -1
  432. package/dist/tempo/client/Methods.js.map +0 -1
  433. package/dist/tempo/client/ResolveAccount.d.ts.map +0 -1
  434. package/dist/tempo/client/ResolveAccount.js.map +0 -1
  435. package/dist/tempo/client/Subscription.d.ts.map +0 -1
  436. package/dist/tempo/client/Subscription.js.map +0 -1
  437. package/dist/tempo/client/index.d.ts.map +0 -1
  438. package/dist/tempo/client/index.js.map +0 -1
  439. package/dist/tempo/index.d.ts.map +0 -1
  440. package/dist/tempo/index.js.map +0 -1
  441. package/dist/tempo/internal/account.d.ts.map +0 -1
  442. package/dist/tempo/internal/account.js.map +0 -1
  443. package/dist/tempo/internal/address.d.ts.map +0 -1
  444. package/dist/tempo/internal/address.js.map +0 -1
  445. package/dist/tempo/internal/auto-swap.d.ts.map +0 -1
  446. package/dist/tempo/internal/auto-swap.js.map +0 -1
  447. package/dist/tempo/internal/charge.d.ts.map +0 -1
  448. package/dist/tempo/internal/charge.js.map +0 -1
  449. package/dist/tempo/internal/defaults.d.ts.map +0 -1
  450. package/dist/tempo/internal/defaults.js.map +0 -1
  451. package/dist/tempo/internal/fee-payer.d.ts.map +0 -1
  452. package/dist/tempo/internal/fee-payer.js.map +0 -1
  453. package/dist/tempo/internal/fee-token.d.ts.map +0 -1
  454. package/dist/tempo/internal/fee-token.js.map +0 -1
  455. package/dist/tempo/internal/proof.d.ts.map +0 -1
  456. package/dist/tempo/internal/proof.js.map +0 -1
  457. package/dist/tempo/internal/selectors.d.ts.map +0 -1
  458. package/dist/tempo/internal/selectors.js.map +0 -1
  459. package/dist/tempo/internal/types.d.ts.map +0 -1
  460. package/dist/tempo/internal/types.js.map +0 -1
  461. package/dist/tempo/legacy/client/ChannelOps.d.ts.map +0 -1
  462. package/dist/tempo/legacy/client/ChannelOps.js.map +0 -1
  463. package/dist/tempo/legacy/client/Session.d.ts.map +0 -1
  464. package/dist/tempo/legacy/client/Session.js.map +0 -1
  465. package/dist/tempo/legacy/client/SessionManager.d.ts.map +0 -1
  466. package/dist/tempo/legacy/client/SessionManager.js.map +0 -1
  467. package/dist/tempo/legacy/client/index.d.ts.map +0 -1
  468. package/dist/tempo/legacy/client/index.js.map +0 -1
  469. package/dist/tempo/legacy/index.d.ts.map +0 -1
  470. package/dist/tempo/legacy/index.js.map +0 -1
  471. package/dist/tempo/legacy/server/Session.d.ts +0 -208
  472. package/dist/tempo/legacy/server/Session.d.ts.map +0 -1
  473. package/dist/tempo/legacy/server/Session.js +0 -698
  474. package/dist/tempo/legacy/server/Session.js.map +0 -1
  475. package/dist/tempo/legacy/server/index.d.ts +0 -5
  476. package/dist/tempo/legacy/server/index.d.ts.map +0 -1
  477. package/dist/tempo/legacy/server/index.js +0 -5
  478. package/dist/tempo/legacy/server/index.js.map +0 -1
  479. package/dist/tempo/legacy/session/Chain.d.ts.map +0 -1
  480. package/dist/tempo/legacy/session/Chain.js.map +0 -1
  481. package/dist/tempo/legacy/session/Channel.d.ts.map +0 -1
  482. package/dist/tempo/legacy/session/Channel.js.map +0 -1
  483. package/dist/tempo/legacy/session/ChannelStore.d.ts +0 -22
  484. package/dist/tempo/legacy/session/ChannelStore.d.ts.map +0 -1
  485. package/dist/tempo/legacy/session/ChannelStore.js +0 -6
  486. package/dist/tempo/legacy/session/ChannelStore.js.map +0 -1
  487. package/dist/tempo/legacy/session/Types.d.ts.map +0 -1
  488. package/dist/tempo/legacy/session/Types.js.map +0 -1
  489. package/dist/tempo/legacy/session/Voucher.d.ts.map +0 -1
  490. package/dist/tempo/legacy/session/Voucher.js.map +0 -1
  491. package/dist/tempo/legacy/session/escrow.abi.d.ts.map +0 -1
  492. package/dist/tempo/legacy/session/escrow.abi.js.map +0 -1
  493. package/dist/tempo/legacy/session/index.d.ts.map +0 -1
  494. package/dist/tempo/legacy/session/index.js.map +0 -1
  495. package/dist/tempo/server/Charge.d.ts.map +0 -1
  496. package/dist/tempo/server/Charge.js.map +0 -1
  497. package/dist/tempo/server/Methods.d.ts.map +0 -1
  498. package/dist/tempo/server/Methods.js.map +0 -1
  499. package/dist/tempo/server/Relay.d.ts.map +0 -1
  500. package/dist/tempo/server/Relay.js.map +0 -1
  501. package/dist/tempo/server/SponsorBudget.d.ts.map +0 -1
  502. package/dist/tempo/server/SponsorBudget.js.map +0 -1
  503. package/dist/tempo/server/Subscription.d.ts.map +0 -1
  504. package/dist/tempo/server/Subscription.js.map +0 -1
  505. package/dist/tempo/server/index.d.ts.map +0 -1
  506. package/dist/tempo/server/index.js.map +0 -1
  507. package/dist/tempo/server/internal/html.gen.d.ts.map +0 -1
  508. package/dist/tempo/server/internal/html.gen.js.map +0 -1
  509. package/dist/tempo/server/internal/request-body.d.ts.map +0 -1
  510. package/dist/tempo/server/internal/request-body.js.map +0 -1
  511. package/dist/tempo/server/internal/transport.d.ts.map +0 -1
  512. package/dist/tempo/server/internal/transport.js.map +0 -1
  513. package/dist/tempo/session/Snapshot.d.ts.map +0 -1
  514. package/dist/tempo/session/Snapshot.js.map +0 -1
  515. package/dist/tempo/session/client/ChannelOps.d.ts.map +0 -1
  516. package/dist/tempo/session/client/ChannelOps.js.map +0 -1
  517. package/dist/tempo/session/client/ChannelStore.d.ts.map +0 -1
  518. package/dist/tempo/session/client/ChannelStore.js.map +0 -1
  519. package/dist/tempo/session/client/CredentialState.d.ts.map +0 -1
  520. package/dist/tempo/session/client/CredentialState.js.map +0 -1
  521. package/dist/tempo/session/client/ReceiptCoordinator.d.ts.map +0 -1
  522. package/dist/tempo/session/client/ReceiptCoordinator.js.map +0 -1
  523. package/dist/tempo/session/client/Runtime.d.ts.map +0 -1
  524. package/dist/tempo/session/client/Runtime.js.map +0 -1
  525. package/dist/tempo/session/client/Session.d.ts.map +0 -1
  526. package/dist/tempo/session/client/Session.js.map +0 -1
  527. package/dist/tempo/session/client/SessionManager.d.ts.map +0 -1
  528. package/dist/tempo/session/client/SessionManager.js.map +0 -1
  529. package/dist/tempo/session/client/Transports.d.ts.map +0 -1
  530. package/dist/tempo/session/client/Transports.js.map +0 -1
  531. package/dist/tempo/session/client/index.d.ts.map +0 -1
  532. package/dist/tempo/session/client/index.js.map +0 -1
  533. package/dist/tempo/session/client/internal/SessionManager.d.ts.map +0 -1
  534. package/dist/tempo/session/client/internal/SessionManager.js.map +0 -1
  535. package/dist/tempo/session/index.d.ts.map +0 -1
  536. package/dist/tempo/session/index.js.map +0 -1
  537. package/dist/tempo/session/precompile/Chain.d.ts.map +0 -1
  538. package/dist/tempo/session/precompile/Chain.js.map +0 -1
  539. package/dist/tempo/session/precompile/Channel.d.ts.map +0 -1
  540. package/dist/tempo/session/precompile/Channel.js.map +0 -1
  541. package/dist/tempo/session/precompile/Protocol.d.ts.map +0 -1
  542. package/dist/tempo/session/precompile/Protocol.js.map +0 -1
  543. package/dist/tempo/session/precompile/Voucher.d.ts.map +0 -1
  544. package/dist/tempo/session/precompile/Voucher.js.map +0 -1
  545. package/dist/tempo/session/precompile/escrow.abi.d.ts.map +0 -1
  546. package/dist/tempo/session/precompile/escrow.abi.js.map +0 -1
  547. package/dist/tempo/session/precompile/index.d.ts.map +0 -1
  548. package/dist/tempo/session/precompile/index.js.map +0 -1
  549. package/dist/tempo/session/server/ChannelOps.d.ts.map +0 -1
  550. package/dist/tempo/session/server/ChannelOps.js.map +0 -1
  551. package/dist/tempo/session/server/ChannelStore.d.ts.map +0 -1
  552. package/dist/tempo/session/server/ChannelStore.js.map +0 -1
  553. package/dist/tempo/session/server/CredentialVerification.d.ts.map +0 -1
  554. package/dist/tempo/session/server/CredentialVerification.js.map +0 -1
  555. package/dist/tempo/session/server/MeteredStream.d.ts.map +0 -1
  556. package/dist/tempo/session/server/MeteredStream.js.map +0 -1
  557. package/dist/tempo/session/server/RequestState.d.ts.map +0 -1
  558. package/dist/tempo/session/server/RequestState.js.map +0 -1
  559. package/dist/tempo/session/server/Session.d.ts.map +0 -1
  560. package/dist/tempo/session/server/Session.js.map +0 -1
  561. package/dist/tempo/session/server/Settlement.d.ts.map +0 -1
  562. package/dist/tempo/session/server/Settlement.js.map +0 -1
  563. package/dist/tempo/session/server/Sse.d.ts.map +0 -1
  564. package/dist/tempo/session/server/Sse.js.map +0 -1
  565. package/dist/tempo/session/server/Transports.d.ts.map +0 -1
  566. package/dist/tempo/session/server/Transports.js.map +0 -1
  567. package/dist/tempo/session/server/Ws.d.ts.map +0 -1
  568. package/dist/tempo/session/server/Ws.js.map +0 -1
  569. package/dist/tempo/session/server/index.d.ts.map +0 -1
  570. package/dist/tempo/session/server/index.js.map +0 -1
  571. package/dist/tempo/subscription/KeyAuthorization.d.ts.map +0 -1
  572. package/dist/tempo/subscription/KeyAuthorization.js.map +0 -1
  573. package/dist/tempo/subscription/Receipt.d.ts.map +0 -1
  574. package/dist/tempo/subscription/Receipt.js.map +0 -1
  575. package/dist/tempo/subscription/Store.d.ts.map +0 -1
  576. package/dist/tempo/subscription/Store.js.map +0 -1
  577. package/dist/tempo/subscription/Types.d.ts.map +0 -1
  578. package/dist/tempo/subscription/Types.js.map +0 -1
  579. package/dist/tempo/subscription/index.d.ts.map +0 -1
  580. package/dist/tempo/subscription/index.js.map +0 -1
  581. package/dist/validation/core.d.ts.map +0 -1
  582. package/dist/validation/core.js.map +0 -1
  583. package/dist/validation/index.d.ts.map +0 -1
  584. package/dist/validation/index.js.map +0 -1
  585. package/dist/viem/Account.d.ts.map +0 -1
  586. package/dist/viem/Account.js.map +0 -1
  587. package/dist/viem/Client.d.ts.map +0 -1
  588. package/dist/viem/Client.js.map +0 -1
  589. package/dist/x402/Assets.d.ts.map +0 -1
  590. package/dist/x402/Assets.js.map +0 -1
  591. package/dist/x402/Header.d.ts.map +0 -1
  592. package/dist/x402/Header.js.map +0 -1
  593. package/dist/x402/Types.d.ts.map +0 -1
  594. package/dist/x402/Types.js.map +0 -1
  595. package/dist/x402/client/Exact.d.ts.map +0 -1
  596. package/dist/x402/client/Exact.js.map +0 -1
  597. package/dist/x402/index.d.ts.map +0 -1
  598. package/dist/x402/index.js.map +0 -1
  599. package/dist/x402/internal/ChallengeBrand.d.ts.map +0 -1
  600. package/dist/x402/internal/ChallengeBrand.js.map +0 -1
  601. package/dist/x402/internal/RouteBinding.d.ts.map +0 -1
  602. package/dist/x402/internal/RouteBinding.js.map +0 -1
  603. package/dist/x402/server/EvmCharge.d.ts.map +0 -1
  604. package/dist/x402/server/EvmCharge.js.map +0 -1
  605. package/dist/x402/server/Facilitator.d.ts.map +0 -1
  606. package/dist/x402/server/Facilitator.js.map +0 -1
  607. package/dist/zod.d.ts.map +0 -1
  608. package/dist/zod.js.map +0 -1
  609. package/src/BodyDigest.test.ts +0 -43
  610. package/src/BodyDigest.ts +0 -55
  611. package/src/Challenge.fuzz.test.ts +0 -121
  612. package/src/Challenge.test-d.ts +0 -82
  613. package/src/Challenge.test.ts +0 -995
  614. package/src/Challenge.ts +0 -683
  615. package/src/Constants.ts +0 -58
  616. package/src/Credential.fuzz.test.ts +0 -62
  617. package/src/Credential.test.ts +0 -378
  618. package/src/Credential.ts +0 -217
  619. package/src/Errors.test.ts +0 -520
  620. package/src/Errors.ts +0 -448
  621. package/src/Expires.test.ts +0 -112
  622. package/src/Expires.ts +0 -59
  623. package/src/Html.ts +0 -67
  624. package/src/Mcp.ts +0 -85
  625. package/src/Method.test.ts +0 -177
  626. package/src/Method.ts +0 -617
  627. package/src/PaymentRequest.test.ts +0 -147
  628. package/src/PaymentRequest.ts +0 -108
  629. package/src/Receipt.test.ts +0 -151
  630. package/src/Receipt.ts +0 -146
  631. package/src/Store.test-d.ts +0 -195
  632. package/src/Store.test.ts +0 -357
  633. package/src/Store.ts +0 -329
  634. package/src/bin.ts +0 -4
  635. package/src/cli/account.ts +0 -269
  636. package/src/cli/cli.test.ts +0 -2221
  637. package/src/cli/cli.ts +0 -1649
  638. package/src/cli/config.test.ts +0 -89
  639. package/src/cli/config.ts +0 -50
  640. package/src/cli/internal.ts +0 -114
  641. package/src/cli/mcp.test.ts +0 -262
  642. package/src/cli/plugins/evm.ts +0 -55
  643. package/src/cli/plugins/index.ts +0 -4
  644. package/src/cli/plugins/plugin.ts +0 -84
  645. package/src/cli/plugins/stripe.ts +0 -174
  646. package/src/cli/plugins/tempo.ts +0 -1102
  647. package/src/cli/sessions/Manager.test.ts +0 -249
  648. package/src/cli/sessions/Manager.ts +0 -93
  649. package/src/cli/sessions/commands.ts +0 -444
  650. package/src/cli/sessions/request.test.ts +0 -51
  651. package/src/cli/sessions/request.ts +0 -353
  652. package/src/cli/sessions/store.test.ts +0 -581
  653. package/src/cli/sessions/store.ts +0 -940
  654. package/src/cli/utils.test.ts +0 -156
  655. package/src/cli/utils.ts +0 -394
  656. package/src/cli/validate/challenge.ts +0 -565
  657. package/src/cli/validate/discovery.test.ts +0 -435
  658. package/src/cli/validate/discovery.ts +0 -221
  659. package/src/cli/validate/helpers.ts +0 -166
  660. package/src/cli/validate/index.ts +0 -229
  661. package/src/cli/validate/messages.ts +0 -7
  662. package/src/cli/validate/payment.ts +0 -774
  663. package/src/cli/validate.test.ts +0 -843
  664. package/src/client/Methods.ts +0 -8
  665. package/src/client/Mppx.test-d.ts +0 -270
  666. package/src/client/Mppx.test.ts +0 -1065
  667. package/src/client/Mppx.ts +0 -466
  668. package/src/client/Transport.test.ts +0 -619
  669. package/src/client/Transport.ts +0 -191
  670. package/src/client/index.ts +0 -29
  671. package/src/client/internal/Fetch.browser.test.ts +0 -197
  672. package/src/client/internal/Fetch.test-d.ts +0 -109
  673. package/src/client/internal/Fetch.test.ts +0 -2336
  674. package/src/client/internal/Fetch.ts +0 -1079
  675. package/src/client/internal/MethodChallenge.ts +0 -35
  676. package/src/client/internal/MethodResponse.ts +0 -67
  677. package/src/client/internal/protocols/Mcp.test.ts +0 -220
  678. package/src/client/internal/protocols/Mcp.ts +0 -186
  679. package/src/client/internal/protocols/Mpp.ts +0 -21
  680. package/src/client/internal/protocols/Protocol.ts +0 -10
  681. package/src/client/internal/protocols/Shared.ts +0 -25
  682. package/src/client/internal/protocols/X402.ts +0 -46
  683. package/src/client/node.test.ts +0 -115
  684. package/src/client/node.ts +0 -247
  685. package/src/discovery/Discovery.test.ts +0 -214
  686. package/src/discovery/Discovery.ts +0 -105
  687. package/src/discovery/OpenApi.test.ts +0 -453
  688. package/src/discovery/OpenApi.ts +0 -224
  689. package/src/discovery/Validate.test.ts +0 -305
  690. package/src/discovery/Validate.ts +0 -77
  691. package/src/discovery/index.ts +0 -3
  692. package/src/env.d.ts +0 -12
  693. package/src/evm/Assets.ts +0 -1
  694. package/src/evm/Chains.ts +0 -11
  695. package/src/evm/Methods.ts +0 -44
  696. package/src/evm/PublicInterface.test-d.ts +0 -134
  697. package/src/evm/Types.ts +0 -140
  698. package/src/evm/client/Charge.test.ts +0 -347
  699. package/src/evm/client/Charge.ts +0 -187
  700. package/src/evm/client/Methods.ts +0 -19
  701. package/src/evm/client/index.ts +0 -6
  702. package/src/evm/index.ts +0 -16
  703. package/src/evm/server/Charge.test.ts +0 -339
  704. package/src/evm/server/Charge.ts +0 -290
  705. package/src/evm/server/Methods.ts +0 -22
  706. package/src/evm/server/index.ts +0 -6
  707. package/src/index.ts +0 -14
  708. package/src/internal/AcceptPayment.test.ts +0 -343
  709. package/src/internal/AcceptPayment.ts +0 -366
  710. package/src/internal/HeaderCodec.ts +0 -36
  711. package/src/internal/changeset.test.ts +0 -106
  712. package/src/internal/constantTimeEqual.test.ts +0 -47
  713. package/src/internal/constantTimeEqual.ts +0 -10
  714. package/src/internal/env.test.ts +0 -42
  715. package/src/internal/env.ts +0 -49
  716. package/src/internal/types.test-d.ts +0 -21
  717. package/src/internal/types.ts +0 -470
  718. package/src/mcp/client/McpClient.integration.test.ts +0 -652
  719. package/src/mcp/client/McpClient.test-d.ts +0 -144
  720. package/src/mcp/client/McpClient.test.ts +0 -463
  721. package/src/mcp/client/McpClient.ts +0 -307
  722. package/src/mcp/client/McpClient.unit.test.ts +0 -135
  723. package/src/mcp/client/index.ts +0 -2
  724. package/src/mcp/server/Transport.test.ts +0 -191
  725. package/src/mcp/server/Transport.ts +0 -111
  726. package/src/mcp/server/index.ts +0 -1
  727. package/src/middlewares/elysia.test.ts +0 -295
  728. package/src/middlewares/elysia.ts +0 -116
  729. package/src/middlewares/express.test.ts +0 -371
  730. package/src/middlewares/express.ts +0 -140
  731. package/src/middlewares/hono.test.ts +0 -476
  732. package/src/middlewares/hono.ts +0 -153
  733. package/src/middlewares/internal/mppx.test.ts +0 -177
  734. package/src/middlewares/internal/mppx.ts +0 -67
  735. package/src/middlewares/nextjs.test.ts +0 -369
  736. package/src/middlewares/nextjs.ts +0 -107
  737. package/src/proxy/Proxy.test.ts +0 -1031
  738. package/src/proxy/Proxy.ts +0 -345
  739. package/src/proxy/Service.test.ts +0 -182
  740. package/src/proxy/Service.ts +0 -253
  741. package/src/proxy/index.ts +0 -6
  742. package/src/proxy/internal/Headers.test.ts +0 -139
  743. package/src/proxy/internal/Headers.ts +0 -66
  744. package/src/proxy/internal/Route.test.ts +0 -217
  745. package/src/proxy/internal/Route.ts +0 -64
  746. package/src/proxy/services/anthropic.test.ts +0 -132
  747. package/src/proxy/services/anthropic.ts +0 -52
  748. package/src/proxy/services/openai.test.ts +0 -157
  749. package/src/proxy/services/openai.ts +0 -59
  750. package/src/proxy/services/stripe.test.ts +0 -175
  751. package/src/proxy/services/stripe.ts +0 -58
  752. package/src/server/Methods.ts +0 -3
  753. package/src/server/Mppx.authorize.test.ts +0 -210
  754. package/src/server/Mppx.test-d.ts +0 -360
  755. package/src/server/Mppx.test.ts +0 -5813
  756. package/src/server/Mppx.ts +0 -2623
  757. package/src/server/NodeListener.test.ts +0 -293
  758. package/src/server/NodeListener.ts +0 -45
  759. package/src/server/Request.test.ts +0 -255
  760. package/src/server/Request.ts +0 -155
  761. package/src/server/Response.test.ts +0 -32
  762. package/src/server/Response.ts +0 -45
  763. package/src/server/Transport.test.ts +0 -598
  764. package/src/server/Transport.ts +0 -320
  765. package/src/server/index.ts +0 -9
  766. package/src/server/internal/html/compose.main.gen.ts +0 -2
  767. package/src/server/internal/html/compose.main.ts +0 -88
  768. package/src/server/internal/html/config.ts +0 -672
  769. package/src/server/internal/html/constants.ts +0 -28
  770. package/src/server/internal/html/serviceWorker.client.ts +0 -28
  771. package/src/server/internal/html/serviceWorker.gen.ts +0 -2
  772. package/src/server/internal/html/serviceWorker.ts +0 -27
  773. package/src/server/internal/html/tsconfig.compose.json +0 -8
  774. package/src/server/internal/html/tsconfig.worker.client.json +0 -8
  775. package/src/server/internal/html/tsconfig.worker.json +0 -8
  776. package/src/server/internal/scope.ts +0 -43
  777. package/src/stripe/Charge.integration.test.ts +0 -329
  778. package/src/stripe/Methods.test.ts +0 -62
  779. package/src/stripe/Methods.ts +0 -44
  780. package/src/stripe/client/Charge.test.ts +0 -205
  781. package/src/stripe/client/Charge.ts +0 -132
  782. package/src/stripe/client/Methods.ts +0 -37
  783. package/src/stripe/client/index.ts +0 -2
  784. package/src/stripe/index.ts +0 -1
  785. package/src/stripe/internal/constants.ts +0 -7
  786. package/src/stripe/internal/types.ts +0 -46
  787. package/src/stripe/server/Charge.test-d.ts +0 -66
  788. package/src/stripe/server/Charge.test.ts +0 -621
  789. package/src/stripe/server/Charge.ts +0 -434
  790. package/src/stripe/server/Methods.ts +0 -24
  791. package/src/stripe/server/index.ts +0 -2
  792. package/src/stripe/server/internal/html/main.ts +0 -165
  793. package/src/stripe/server/internal/html/node_modules/.bin/mppx +0 -22
  794. package/src/stripe/server/internal/html/node_modules/.bin/mppx.src +0 -22
  795. package/src/stripe/server/internal/html/package.json +0 -9
  796. package/src/stripe/server/internal/html/stripe-js-pure.d.ts +0 -7
  797. package/src/stripe/server/internal/html/tsconfig.json +0 -8
  798. package/src/stripe/server/internal/html/types.ts +0 -5
  799. package/src/stripe/server/internal/html.gen.ts +0 -2
  800. package/src/tempo/AccessKeyAuthorization.test.ts +0 -141
  801. package/src/tempo/Attribution.test.ts +0 -294
  802. package/src/tempo/Attribution.ts +0 -185
  803. package/src/tempo/Methods.test.ts +0 -425
  804. package/src/tempo/Methods.ts +0 -367
  805. package/src/tempo/Proof.conformance.test.ts +0 -146
  806. package/src/tempo/Proof.test-d.ts +0 -32
  807. package/src/tempo/Proof.test.ts +0 -40
  808. package/src/tempo/Proof.ts +0 -69
  809. package/src/tempo/PublicExports.test-d.ts +0 -130
  810. package/src/tempo/Subscription.integration.test.ts +0 -591
  811. package/src/tempo/client/Charge.test.ts +0 -501
  812. package/src/tempo/client/Charge.ts +0 -289
  813. package/src/tempo/client/Methods.ts +0 -45
  814. package/src/tempo/client/ResolveAccount.ts +0 -46
  815. package/src/tempo/client/Subscription.test.ts +0 -180
  816. package/src/tempo/client/Subscription.ts +0 -156
  817. package/src/tempo/client/index.ts +0 -17
  818. package/src/tempo/index.ts +0 -5
  819. package/src/tempo/internal/account.ts +0 -56
  820. package/src/tempo/internal/address.ts +0 -6
  821. package/src/tempo/internal/auto-swap.test.ts +0 -198
  822. package/src/tempo/internal/auto-swap.ts +0 -188
  823. package/src/tempo/internal/charge.test.ts +0 -66
  824. package/src/tempo/internal/charge.ts +0 -43
  825. package/src/tempo/internal/defaults.test.ts +0 -95
  826. package/src/tempo/internal/defaults.ts +0 -53
  827. package/src/tempo/internal/fee-payer.test.ts +0 -1177
  828. package/src/tempo/internal/fee-payer.ts +0 -808
  829. package/src/tempo/internal/fee-token.test.ts +0 -165
  830. package/src/tempo/internal/fee-token.ts +0 -72
  831. package/src/tempo/internal/proof.test.ts +0 -97
  832. package/src/tempo/internal/proof.ts +0 -87
  833. package/src/tempo/internal/selectors.ts +0 -10
  834. package/src/tempo/internal/types.ts +0 -19
  835. package/src/tempo/legacy/AccessKeyAuthorization.test.ts +0 -162
  836. package/src/tempo/legacy/README.md +0 -9
  837. package/src/tempo/legacy/client/ChannelOps.test.ts +0 -379
  838. package/src/tempo/legacy/client/ChannelOps.ts +0 -271
  839. package/src/tempo/legacy/client/Session.test.ts +0 -800
  840. package/src/tempo/legacy/client/Session.ts +0 -397
  841. package/src/tempo/legacy/client/SessionManager.test.ts +0 -468
  842. package/src/tempo/legacy/client/SessionManager.ts +0 -909
  843. package/src/tempo/legacy/client/index.ts +0 -6
  844. package/src/tempo/legacy/index.ts +0 -6
  845. package/src/tempo/legacy/server/Defaults.test-d.ts +0 -9
  846. package/src/tempo/legacy/server/Session.test.ts +0 -6370
  847. package/src/tempo/legacy/server/Session.ts +0 -1024
  848. package/src/tempo/legacy/server/index.ts +0 -4
  849. package/src/tempo/legacy/session/Chain.test.ts +0 -1349
  850. package/src/tempo/legacy/session/Chain.ts +0 -830
  851. package/src/tempo/legacy/session/Channel.test.ts +0 -109
  852. package/src/tempo/legacy/session/Channel.ts +0 -51
  853. package/src/tempo/legacy/session/ChannelStore.test.ts +0 -58
  854. package/src/tempo/legacy/session/ChannelStore.ts +0 -39
  855. package/src/tempo/legacy/session/Types.ts +0 -91
  856. package/src/tempo/legacy/session/Voucher.test.ts +0 -410
  857. package/src/tempo/legacy/session/Voucher.ts +0 -183
  858. package/src/tempo/legacy/session/escrow.abi.ts +0 -760
  859. package/src/tempo/legacy/session/index.ts +0 -8
  860. package/src/tempo/server/AtomicStore.test-d.ts +0 -50
  861. package/src/tempo/server/Charge.test.ts +0 -6121
  862. package/src/tempo/server/Charge.ts +0 -1351
  863. package/src/tempo/server/Methods.ts +0 -106
  864. package/src/tempo/server/Relay.test.ts +0 -677
  865. package/src/tempo/server/Relay.ts +0 -297
  866. package/src/tempo/server/SponsorBudget.test.ts +0 -154
  867. package/src/tempo/server/SponsorBudget.ts +0 -219
  868. package/src/tempo/server/Sse.test.ts +0 -321
  869. package/src/tempo/server/Subscription.test.ts +0 -1944
  870. package/src/tempo/server/Subscription.ts +0 -1333
  871. package/src/tempo/server/index.ts +0 -12
  872. package/src/tempo/server/internal/html/main.ts +0 -115
  873. package/src/tempo/server/internal/html/node_modules/.bin/mppx +0 -22
  874. package/src/tempo/server/internal/html/node_modules/.bin/mppx.src +0 -22
  875. package/src/tempo/server/internal/html/package.json +0 -10
  876. package/src/tempo/server/internal/html/tsconfig.json +0 -8
  877. package/src/tempo/server/internal/html.gen.ts +0 -2
  878. package/src/tempo/server/internal/request-body.test.ts +0 -210
  879. package/src/tempo/server/internal/request-body.ts +0 -61
  880. package/src/tempo/server/internal/transport.test.ts +0 -903
  881. package/src/tempo/server/internal/transport.ts +0 -310
  882. package/src/tempo/session/README.md +0 -208
  883. package/src/tempo/session/Snapshot.test.ts +0 -41
  884. package/src/tempo/session/Snapshot.ts +0 -95
  885. package/src/tempo/session/client/ChannelOps.test.ts +0 -218
  886. package/src/tempo/session/client/ChannelOps.ts +0 -348
  887. package/src/tempo/session/client/ChannelStore.ts +0 -111
  888. package/src/tempo/session/client/CredentialState.test.ts +0 -789
  889. package/src/tempo/session/client/CredentialState.ts +0 -942
  890. package/src/tempo/session/client/ReceiptCoordinator.ts +0 -95
  891. package/src/tempo/session/client/Runtime.test.ts +0 -1104
  892. package/src/tempo/session/client/Runtime.ts +0 -1008
  893. package/src/tempo/session/client/Session.test.ts +0 -1355
  894. package/src/tempo/session/client/Session.ts +0 -420
  895. package/src/tempo/session/client/SessionManager.test.ts +0 -1899
  896. package/src/tempo/session/client/SessionManager.ts +0 -996
  897. package/src/tempo/session/client/Transports.test.ts +0 -1141
  898. package/src/tempo/session/client/Transports.ts +0 -1534
  899. package/src/tempo/session/client/index.ts +0 -40
  900. package/src/tempo/session/client/internal/SessionManager.ts +0 -36
  901. package/src/tempo/session/index.ts +0 -7
  902. package/src/tempo/session/precompile/Chain.integration.test.ts +0 -339
  903. package/src/tempo/session/precompile/Chain.test.ts +0 -1641
  904. package/src/tempo/session/precompile/Chain.ts +0 -1149
  905. package/src/tempo/session/precompile/Channel.test.ts +0 -147
  906. package/src/tempo/session/precompile/Channel.ts +0 -108
  907. package/src/tempo/session/precompile/Protocol.test.ts +0 -358
  908. package/src/tempo/session/precompile/Protocol.ts +0 -520
  909. package/src/tempo/session/precompile/Voucher.test.ts +0 -354
  910. package/src/tempo/session/precompile/Voucher.ts +0 -162
  911. package/src/tempo/session/precompile/escrow.abi.ts +0 -226
  912. package/src/tempo/session/precompile/index.ts +0 -33
  913. package/src/tempo/session/server/ChannelOps.test.ts +0 -129
  914. package/src/tempo/session/server/ChannelOps.ts +0 -157
  915. package/src/tempo/session/server/ChannelStore.test.ts +0 -1093
  916. package/src/tempo/session/server/ChannelStore.ts +0 -835
  917. package/src/tempo/session/server/CredentialVerification.test.ts +0 -299
  918. package/src/tempo/session/server/CredentialVerification.ts +0 -775
  919. package/src/tempo/session/server/MeteredStream.ts +0 -95
  920. package/src/tempo/session/server/RequestState.test.ts +0 -574
  921. package/src/tempo/session/server/RequestState.ts +0 -507
  922. package/src/tempo/session/server/Session.integration.test.ts +0 -449
  923. package/src/tempo/session/server/Session.test.ts +0 -3862
  924. package/src/tempo/session/server/Session.ts +0 -570
  925. package/src/tempo/session/server/Settlement.test.ts +0 -345
  926. package/src/tempo/session/server/Settlement.ts +0 -527
  927. package/src/tempo/session/server/Sse.fuzz.test.ts +0 -138
  928. package/src/tempo/session/server/Sse.test.ts +0 -557
  929. package/src/tempo/session/server/Sse.ts +0 -254
  930. package/src/tempo/session/server/Transports.test.ts +0 -346
  931. package/src/tempo/session/server/Transports.ts +0 -255
  932. package/src/tempo/session/server/Ws.test.ts +0 -594
  933. package/src/tempo/session/server/Ws.ts +0 -385
  934. package/src/tempo/session/server/index.ts +0 -12
  935. package/src/tempo/subscription/KeyAuthorization.test.ts +0 -282
  936. package/src/tempo/subscription/KeyAuthorization.ts +0 -396
  937. package/src/tempo/subscription/Receipt.ts +0 -28
  938. package/src/tempo/subscription/Store.test.ts +0 -609
  939. package/src/tempo/subscription/Store.ts +0 -449
  940. package/src/tempo/subscription/Types.ts +0 -68
  941. package/src/tempo/subscription/index.ts +0 -23
  942. package/src/tsconfig.json +0 -10
  943. package/src/validation/core.ts +0 -386
  944. package/src/validation/index.ts +0 -11
  945. package/src/viem/Account.test.ts +0 -72
  946. package/src/viem/Account.ts +0 -30
  947. package/src/viem/Client.test.ts +0 -366
  948. package/src/viem/Client.ts +0 -93
  949. package/src/x402/Assets.test.ts +0 -253
  950. package/src/x402/Assets.ts +0 -221
  951. package/src/x402/Exact.e2e.test.ts +0 -448
  952. package/src/x402/Exact.localnet.test.ts +0 -475
  953. package/src/x402/Header.test.ts +0 -73
  954. package/src/x402/Header.ts +0 -79
  955. package/src/x402/PublicInterface.test-d.ts +0 -39
  956. package/src/x402/Types.ts +0 -248
  957. package/src/x402/client/Exact.test.ts +0 -309
  958. package/src/x402/client/Exact.ts +0 -186
  959. package/src/x402/index.ts +0 -6
  960. package/src/x402/internal/ChallengeBrand.ts +0 -14
  961. package/src/x402/internal/RouteBinding.ts +0 -18
  962. package/src/x402/server/EvmCharge.ts +0 -394
  963. package/src/x402/server/Facilitator.test.ts +0 -111
  964. package/src/x402/server/Facilitator.ts +0 -56
  965. package/src/zod.test.ts +0 -169
  966. package/src/zod.ts +0 -71
@@ -1,2221 +0,0 @@
1
- import { spawnSync } from 'node:child_process'
2
- import * as fs from 'node:fs'
3
- import * as os from 'node:os'
4
- import * as path from 'node:path'
5
- import { pathToFileURL } from 'node:url'
6
-
7
- import { decodeFunctionData, parseUnits, type Address } from 'viem'
8
- import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts'
9
- import { Addresses, Transaction } from 'viem/tempo'
10
- import { afterAll, describe, expect, test } from 'vp/test'
11
- import * as Http from '~test/Http.js'
12
- import { rpcUrl } from '~test/tempo/rpc.js'
13
- import { accounts, asset, chain, client, fundAccount } from '~test/tempo/viem.js'
14
-
15
- import * as Challenge from '../Challenge.js'
16
- import * as Constants from '../Constants.js'
17
- import * as Credential from '../Credential.js'
18
- import * as Method from '../Method.js'
19
- import * as Receipt from '../Receipt.js'
20
- import * as Mppx_server from '../server/Mppx.js'
21
- import { toNodeListener } from '../server/Mppx.js'
22
- import * as Store from '../Store.js'
23
- import { stripePreviewVersion } from '../stripe/internal/constants.js'
24
- import { stripe as stripe_server } from '../stripe/server/Methods.js'
25
- import { tempo } from '../tempo/server/Methods.js'
26
- import { escrowAbi } from '../tempo/session/precompile/escrow.abi.js'
27
- import { tip20ChannelEscrow } from '../tempo/session/precompile/Protocol.js'
28
- import type { SessionCredentialPayload } from '../tempo/session/precompile/Protocol.js'
29
- import * as z from '../zod.js'
30
- import cli from './cli.js'
31
-
32
- const testPrivateKey = generatePrivateKey()
33
- const testAccount = privateKeyToAccount(testPrivateKey)
34
- const cliTestXdgDataHome = fs.mkdtempSync(path.join(os.tmpdir(), 'mppx-cli-xdg-'))
35
- let cliServeInvocation = 0
36
- const unfundedToken = '0x20c0000000000000000000000000000000000002' as Address
37
- const cliSessionFeePayerPolicy = {
38
- maxGas: 2_250_000n,
39
- maxTotalFee: 60_000_000_000_000_000n,
40
- }
41
-
42
- afterAll(() => {
43
- fs.rmSync(cliTestXdgDataHome, { recursive: true, force: true })
44
- })
45
-
46
- async function serve(argv: string[], options?: { env?: Record<string, string | undefined> }) {
47
- const stdoutChunks: Buffer[] = []
48
- let stderr = ''
49
- let exitCode: number | undefined
50
- const saved: Record<string, string | undefined> = {}
51
- const invocationHome = path.join(cliTestXdgDataHome, `serve-${cliServeInvocation++}`)
52
- const env = {
53
- XDG_CONFIG_HOME: path.join(invocationHome, 'config'),
54
- XDG_DATA_HOME: cliTestXdgDataHome,
55
- XDG_STATE_HOME: path.join(invocationHome, 'state'),
56
- ...options?.env,
57
- }
58
- for (const [key, value] of Object.entries(env)) {
59
- saved[key] = process.env[key]
60
- if (value === undefined) delete process.env[key]
61
- else process.env[key] = value
62
- }
63
- const origStdoutWrite = process.stdout.write
64
- const origStderrWrite = process.stderr.write
65
- const origLog = console.log
66
- const origError = console.error
67
- process.stdout.write = ((chunk: unknown) => {
68
- if (typeof chunk === 'string') stdoutChunks.push(Buffer.from(chunk))
69
- else if (chunk instanceof Uint8Array) stdoutChunks.push(Buffer.from(chunk))
70
- else stdoutChunks.push(Buffer.from(String(chunk)))
71
- return true
72
- }) as typeof process.stdout.write
73
- process.stderr.write = ((chunk: unknown) => {
74
- stderr += typeof chunk === 'string' ? chunk : String(chunk)
75
- return true
76
- }) as typeof process.stderr.write
77
- console.log = (...args: unknown[]) => {
78
- stdoutChunks.push(Buffer.from(`${args.map(String).join(' ')}\n`))
79
- }
80
- console.error = (...args: unknown[]) => {
81
- stderr += `${args.map(String).join(' ')}\n`
82
- }
83
- try {
84
- await cli.serve(argv, {
85
- stdout(s: string) {
86
- stdoutChunks.push(Buffer.from(s))
87
- },
88
- exit(code: number) {
89
- exitCode = code
90
- },
91
- })
92
- } finally {
93
- process.stdout.write = origStdoutWrite
94
- process.stderr.write = origStderrWrite
95
- console.log = origLog
96
- console.error = origError
97
- for (const [key, value] of Object.entries(saved)) {
98
- if (value === undefined) delete process.env[key]
99
- else process.env[key] = value
100
- }
101
- }
102
- const stdoutBytes = Buffer.concat(stdoutChunks)
103
- return { output: stdoutBytes.toString(), stderr, exitCode, stdoutBytes }
104
- }
105
-
106
- function createMockChargeMethod(name: string) {
107
- return Method.from({
108
- name,
109
- intent: 'charge',
110
- schema: {
111
- credential: {
112
- payload: z.object({ token: z.string() }),
113
- },
114
- request: z.object({
115
- amount: z.string(),
116
- currency: z.string(),
117
- decimals: z.number(),
118
- recipient: z.string(),
119
- }),
120
- },
121
- })
122
- }
123
-
124
- describe('discover validate', () => {
125
- test('validates a local discovery document', async () => {
126
- const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'mppx-discovery-'))
127
- const file = path.join(dir, 'openapi.json')
128
- fs.writeFileSync(
129
- file,
130
- JSON.stringify({
131
- info: { title: 'Test', version: '1.0.0' },
132
- openapi: '3.1.0',
133
- paths: {
134
- '/search': {
135
- post: {
136
- 'x-payment-info': {
137
- amount: '100',
138
- intent: 'charge',
139
- method: 'tempo',
140
- },
141
- requestBody: {
142
- content: { 'application/json': { schema: { type: 'object' } } },
143
- },
144
- responses: {
145
- '200': { description: 'OK' },
146
- '402': { description: 'Payment Required' },
147
- },
148
- },
149
- },
150
- },
151
- }),
152
- )
153
-
154
- const { output, exitCode } = await serve(['discover', 'validate', file])
155
- expect(exitCode).toBeUndefined()
156
- expect(output).toContain('Discovery document is valid.')
157
- })
158
-
159
- test('returns non-zero for invalid discovery documents', async () => {
160
- const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'mppx-discovery-'))
161
- const file = path.join(dir, 'openapi.json')
162
- fs.writeFileSync(
163
- file,
164
- JSON.stringify({
165
- info: { title: 'Test', version: '1.0.0' },
166
- openapi: '3.1.0',
167
- paths: {
168
- '/search': {
169
- post: {
170
- 'x-payment-info': {
171
- amount: '100',
172
- intent: 'charge',
173
- method: 'tempo',
174
- },
175
- responses: {
176
- '200': { description: 'OK' },
177
- },
178
- },
179
- },
180
- },
181
- }),
182
- )
183
-
184
- const { output, exitCode } = await serve(['discover', 'validate', file])
185
- expect(exitCode).toBe(1)
186
- expect(output).toContain('[error]')
187
- expect(output).toContain('402')
188
- })
189
-
190
- test(
191
- 'validates remote discovery documents and reports warnings',
192
- { timeout: 20_000 },
193
- async () => {
194
- const body = JSON.stringify({
195
- info: { title: 'Test', version: '1.0.0' },
196
- openapi: '3.1.0',
197
- paths: {
198
- '/search': {
199
- post: {
200
- 'x-payment-info': {
201
- amount: '100',
202
- intent: 'charge',
203
- method: 'tempo',
204
- },
205
- responses: {
206
- '200': { description: 'OK' },
207
- '402': { description: 'Payment Required' },
208
- },
209
- },
210
- },
211
- },
212
- })
213
- const server = await Http.createServer((_req, res) => {
214
- res.setHeader('Content-Type', 'application/json')
215
- res.end(body)
216
- })
217
-
218
- try {
219
- const { output, exitCode } = await serve(['discover', 'validate', server.url])
220
- expect(exitCode).toBeUndefined()
221
- expect(output).toContain('[warning]')
222
- expect(output).toContain('requestBody')
223
- expect(output).toContain('valid with 1 warning')
224
- } finally {
225
- server.close()
226
- }
227
- },
228
- )
229
-
230
- test(
231
- 'rejects oversized discovery documents via content-length',
232
- { timeout: 20_000 },
233
- async () => {
234
- const server = await Http.createServer((_req, res) => {
235
- res.setHeader('Content-Type', 'application/json')
236
- res.setHeader('Content-Length', String(11 * 1024 * 1024))
237
- res.end('{}')
238
- })
239
-
240
- try {
241
- const { exitCode, output } = await serve(['discover', 'validate', server.url])
242
- expect(exitCode).toBe(1)
243
- expect(output).toContain('10 MB')
244
- } finally {
245
- server.close()
246
- }
247
- },
248
- )
249
- })
250
-
251
- describe('discover generate', () => {
252
- test('generates from a pre-built OpenAPI document module', async () => {
253
- const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'mppx-generate-'))
254
- const mod = path.join(dir, 'doc.mjs')
255
- fs.writeFileSync(
256
- mod,
257
- `export default ${JSON.stringify({
258
- openapi: '3.1.0',
259
- info: { title: 'Test', version: '1.0.0' },
260
- paths: {
261
- '/pay': {
262
- post: {
263
- 'x-payment-info': { amount: '100', intent: 'charge', method: 'tempo' },
264
- responses: {
265
- '200': { description: 'OK' },
266
- '402': { description: 'Payment Required' },
267
- },
268
- },
269
- },
270
- },
271
- })}`,
272
- )
273
-
274
- const { output, exitCode } = await serve(['discover', 'generate', mod])
275
- expect(exitCode).toBeUndefined()
276
- const doc = JSON.parse(output)
277
- expect(doc.openapi).toBe('3.1.0')
278
- expect(doc.paths['/pay'].post['x-payment-info'].amount).toBe('100')
279
-
280
- fs.rmSync(dir, { recursive: true, force: true })
281
- })
282
-
283
- test('writes to file with --output', async () => {
284
- const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'mppx-generate-'))
285
- const mod = path.join(dir, 'doc.mjs')
286
- const outFile = path.join(dir, 'openapi.json')
287
- fs.writeFileSync(
288
- mod,
289
- `export default ${JSON.stringify({
290
- openapi: '3.1.0',
291
- info: { title: 'Test', version: '1.0.0' },
292
- paths: {},
293
- })}`,
294
- )
295
-
296
- const { output, stderr, exitCode } = await serve([
297
- 'discover',
298
- 'generate',
299
- mod,
300
- '--output',
301
- outFile,
302
- ])
303
- expect(exitCode).toBeUndefined()
304
- expect(output).toBe('')
305
- expect(stderr).toContain(outFile)
306
- const written = JSON.parse(fs.readFileSync(outFile, 'utf-8'))
307
- expect(written.openapi).toBe('3.1.0')
308
-
309
- fs.rmSync(dir, { recursive: true, force: true })
310
- })
311
-
312
- test('errors when module not found', async () => {
313
- const { output, exitCode } = await serve([
314
- 'discover',
315
- 'generate',
316
- '/tmp/nonexistent-mppx-module.mjs',
317
- ])
318
- expect(exitCode).toBe(1)
319
- expect(output).toContain('MODULE_NOT_FOUND')
320
- })
321
-
322
- test('errors when module has no mppx or openapi export', async () => {
323
- const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'mppx-generate-'))
324
- const mod = path.join(dir, 'bad.mjs')
325
- fs.writeFileSync(mod, 'export default { foo: "bar" }')
326
-
327
- const { output, exitCode } = await serve(['discover', 'generate', mod])
328
- expect(exitCode).toBe(1)
329
- expect(output).toContain('INVALID_MODULE')
330
-
331
- fs.rmSync(dir, { recursive: true, force: true })
332
- })
333
- })
334
-
335
- describe('services', () => {
336
- const registry = {
337
- version: 1,
338
- services: [
339
- {
340
- id: 'fal',
341
- name: 'fal',
342
- serviceUrl: 'https://fal.mpp.dev',
343
- description: 'Image generation',
344
- tags: ['image'],
345
- status: 'active',
346
- docs: { homepage: 'https://docs.fal.ai' },
347
- endpoints: [
348
- {
349
- method: 'POST',
350
- path: '/fal-ai/fast-sdxl',
351
- description: 'Generate an image',
352
- payment: {
353
- amount: '3000',
354
- currency: '0x20c000000000000000000000b9537d11c60e8b50',
355
- decimals: 6,
356
- intent: 'charge',
357
- method: 'tempo',
358
- },
359
- },
360
- {
361
- method: 'GET',
362
- path: '/health',
363
- description: 'Health check',
364
- payment: null,
365
- },
366
- ],
367
- },
368
- {
369
- id: 'freebie',
370
- name: 'Freebie',
371
- serviceUrl: 'https://freebie.example',
372
- endpoints: [],
373
- },
374
- ],
375
- }
376
-
377
- async function withRegistry<T>(fn: (url: string) => Promise<T>) {
378
- const server = await Http.createServer((_req, res) => {
379
- res.setHeader('Content-Type', 'application/json')
380
- res.end(JSON.stringify(registry))
381
- })
382
- try {
383
- return await fn(server.url)
384
- } finally {
385
- server.close()
386
- }
387
- }
388
-
389
- test('list: prints registered services', async () => {
390
- await withRegistry(async (url) => {
391
- const { output, exitCode } = await serve(['services', 'list'], {
392
- env: { MPPX_SERVICES_URL: url },
393
- })
394
-
395
- expect(exitCode).toBeUndefined()
396
- expect(output).toContain('fal')
397
- expect(output).toContain('1 paid')
398
- expect(output).toContain('https://fal.mpp.dev')
399
- })
400
- })
401
-
402
- test('list: supports structured output and filtering', async () => {
403
- await withRegistry(async (url) => {
404
- const { output, exitCode } = await serve(['services', 'list', '--query', 'image', '--json'], {
405
- env: { MPPX_SERVICES_URL: url },
406
- })
407
-
408
- expect(exitCode).toBeUndefined()
409
- const parsed = JSON.parse(output)
410
- expect(parsed.services).toHaveLength(1)
411
- expect(parsed.services[0]).toMatchObject({ id: 'fal', paidEndpoints: 1 })
412
- })
413
- })
414
-
415
- test('show: prints service metadata', async () => {
416
- await withRegistry(async (url) => {
417
- const { output, exitCode } = await serve(['services', 'show', 'fal'], {
418
- env: { MPPX_SERVICES_URL: url },
419
- })
420
-
421
- expect(exitCode).toBeUndefined()
422
- expect(output).toContain('Image generation')
423
- expect(output).toContain('https://docs.fal.ai')
424
- expect(output).toContain('2 (1 paid)')
425
- })
426
- })
427
-
428
- test('endpoints: prints paid endpoint details', async () => {
429
- await withRegistry(async (url) => {
430
- const { output, exitCode } = await serve(['services', 'endpoints', 'fal'], {
431
- env: { MPPX_SERVICES_URL: url },
432
- })
433
-
434
- expect(exitCode).toBeUndefined()
435
- expect(output).toContain('POST')
436
- expect(output).toContain('/fal-ai/fast-sdxl')
437
- expect(output).toContain('3000')
438
- expect(output).toContain('tempo/charge')
439
- })
440
- })
441
- })
442
-
443
- describe('request output', () => {
444
- test('writes non-402 response bodies to stdout without text decoding', async () => {
445
- const body = Buffer.from([0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x0a, 0x0a])
446
- const httpServer = await Http.createServer((_req, res) => {
447
- res.writeHead(200, { 'Content-Type': 'application/pdf' })
448
- res.end(body)
449
- })
450
-
451
- try {
452
- const { exitCode, stdoutBytes } = await serve([httpServer.url, '-s'])
453
- expect(exitCode).toBeUndefined()
454
- expect(stdoutBytes).toEqual(body)
455
- } finally {
456
- httpServer.close()
457
- }
458
- })
459
- })
460
-
461
- describe('basic charge (examples/basic)', () => {
462
- test('happy path: makes payment and receives response', { timeout: 120_000 }, async () => {
463
- const { Actions } = await import('viem/tempo')
464
- await Actions.token.transferSync(client, {
465
- account: accounts[0],
466
- chain: client.chain,
467
- token: asset,
468
- to: testAccount.address,
469
- amount: parseUnits('100', 6),
470
- })
471
-
472
- const server = Mppx_server.create({
473
- methods: [tempo.charge({ getClient: () => client })],
474
- realm: 'cli-test-basic',
475
- secretKey: 'cli-test-secret-cli-test-secret-32',
476
- })
477
-
478
- const httpServer = await Http.createServer(async (req, res) => {
479
- const result = await toNodeListener(
480
- server.charge({
481
- amount: '1',
482
- currency: asset,
483
- expires: new Date(Date.now() + 60_000).toISOString(),
484
- recipient: accounts[0].address,
485
- }),
486
- )(req, res)
487
- if (result.status === 402) return
488
- res.end('paid')
489
- })
490
-
491
- try {
492
- const { output } = await serve([httpServer.url, '--rpc-url', rpcUrl, '-s'], {
493
- env: { MPPX_PRIVATE_KEY: testPrivateKey },
494
- })
495
- expect(output).toContain('paid')
496
- } finally {
497
- httpServer.close()
498
- }
499
- })
500
-
501
- test(
502
- 'selects a later Tempo charge challenge when wallet has that token balance',
503
- { timeout: 120_000 },
504
- async () => {
505
- const { Actions } = await import('viem/tempo')
506
- const payerPrivateKey = generatePrivateKey()
507
- const payer = privateKeyToAccount(payerPrivateKey)
508
- await Actions.token.transferSync(client, {
509
- account: accounts[0],
510
- chain: client.chain,
511
- token: asset,
512
- to: payer.address,
513
- amount: parseUnits('100', 6),
514
- })
515
- await Actions.token.transferSync(client, {
516
- account: accounts[0],
517
- chain: client.chain,
518
- token: Addresses.pathUsd,
519
- to: payer.address,
520
- amount: parseUnits('100', 6),
521
- })
522
-
523
- const tempoMethod = tempo.charge({ getClient: () => client })
524
- const server = Mppx_server.create({
525
- methods: [tempoMethod],
526
- realm: 'cli-test-balance-aware-offers',
527
- secretKey: 'cli-test-secret-cli-test-secret-32',
528
- })
529
- let authorization: string | undefined
530
-
531
- const httpServer = await Http.createServer(async (req, res) => {
532
- if (req.headers.authorization) {
533
- authorization = req.headers.authorization
534
- res.end('paid-from-funded-token')
535
- return
536
- }
537
-
538
- const result = await toNodeListener(
539
- server.compose(
540
- [
541
- tempoMethod,
542
- {
543
- amount: '1',
544
- currency: unfundedToken,
545
- decimals: 6,
546
- expires: new Date(Date.now() + 60_000).toISOString(),
547
- recipient: accounts[0].address,
548
- },
549
- ],
550
- [
551
- tempoMethod,
552
- {
553
- amount: '1',
554
- currency: asset,
555
- decimals: 6,
556
- expires: new Date(Date.now() + 60_000).toISOString(),
557
- recipient: accounts[0].address,
558
- },
559
- ],
560
- ),
561
- )(req, res)
562
- if (result.status === 402) return
563
- res.end('unexpected')
564
- })
565
-
566
- try {
567
- const { output, exitCode } = await serve([httpServer.url, '--rpc-url', rpcUrl, '-s'], {
568
- env: { MPPX_PRIVATE_KEY: payerPrivateKey },
569
- })
570
-
571
- expect(exitCode, output).toBeUndefined()
572
- expect(output).toContain('paid-from-funded-token')
573
- expect(Credential.deserialize(authorization!).challenge.request.currency).toBe(asset)
574
- } finally {
575
- httpServer.close()
576
- }
577
- },
578
- )
579
-
580
- test('currency option selects a matching offered challenge', { timeout: 120_000 }, async () => {
581
- const { Actions } = await import('viem/tempo')
582
- const payerPrivateKey = generatePrivateKey()
583
- const payer = privateKeyToAccount(payerPrivateKey)
584
- await Actions.token.transferSync(client, {
585
- account: accounts[0],
586
- chain: client.chain,
587
- token: asset,
588
- to: payer.address,
589
- amount: parseUnits('100', 6),
590
- })
591
- await Actions.token.transferSync(client, {
592
- account: accounts[0],
593
- chain: client.chain,
594
- token: Addresses.pathUsd,
595
- to: payer.address,
596
- amount: parseUnits('100', 6),
597
- })
598
-
599
- const tempoMethod = tempo.charge({ getClient: () => client })
600
- const server = Mppx_server.create({
601
- methods: [tempoMethod],
602
- realm: 'cli-test-currency-option',
603
- secretKey: 'cli-test-secret-cli-test-secret-32',
604
- })
605
- let authorization: string | undefined
606
-
607
- const httpServer = await Http.createServer(async (req, res) => {
608
- if (req.headers.authorization) {
609
- authorization = req.headers.authorization
610
- res.end('paid-from-currency-option')
611
- return
612
- }
613
-
614
- const result = await toNodeListener(
615
- server.compose(
616
- [
617
- tempoMethod,
618
- {
619
- amount: '1',
620
- currency: unfundedToken,
621
- decimals: 6,
622
- expires: new Date(Date.now() + 60_000).toISOString(),
623
- recipient: accounts[0].address,
624
- },
625
- ],
626
- [
627
- tempoMethod,
628
- {
629
- amount: '1',
630
- currency: asset,
631
- decimals: 6,
632
- expires: new Date(Date.now() + 60_000).toISOString(),
633
- recipient: accounts[0].address,
634
- },
635
- ],
636
- ),
637
- )(req, res)
638
- if (result.status === 402) return
639
- res.end('unexpected')
640
- })
641
-
642
- try {
643
- const { output, exitCode } = await serve(
644
- [httpServer.url, '--rpc-url', rpcUrl, '--currency', asset, '-s'],
645
- { env: { MPPX_PRIVATE_KEY: payerPrivateKey } },
646
- )
647
-
648
- expect(exitCode, output).toBeUndefined()
649
- expect(output).toContain('paid-from-currency-option')
650
- expect(Credential.deserialize(authorization!).challenge.request.currency).toBe(asset)
651
- } finally {
652
- httpServer.close()
653
- }
654
- })
655
-
656
- test('currency option rejects currencies the server did not offer', async () => {
657
- const tempoMethod = tempo.charge({ getClient: () => client })
658
- const server = Mppx_server.create({
659
- methods: [tempoMethod],
660
- realm: 'cli-test-currency-unavailable',
661
- secretKey: 'cli-test-secret-cli-test-secret-32',
662
- })
663
-
664
- const httpServer = await Http.createServer(async (req, res) => {
665
- const result = await toNodeListener(
666
- server.charge({
667
- amount: '1',
668
- currency: asset,
669
- expires: new Date(Date.now() + 60_000).toISOString(),
670
- recipient: accounts[0].address,
671
- }),
672
- )(req, res)
673
- if (result.status === 402) return
674
- res.end('unexpected')
675
- })
676
-
677
- try {
678
- const { output, exitCode } = await serve([
679
- httpServer.url,
680
- '--currency',
681
- Addresses.pathUsd,
682
- '-s',
683
- ])
684
-
685
- expect(exitCode).toBe(2)
686
- expect(output).toContain('UNSUPPORTED_CURRENCY')
687
- expect(output).toContain(Addresses.pathUsd)
688
- expect(output).toContain(asset)
689
- } finally {
690
- httpServer.close()
691
- }
692
- })
693
-
694
- test('selects a later supported challenge when the first offer is unsupported', async () => {
695
- const unsupportedMethod = Method.toServer(createMockChargeMethod('unknown'), {
696
- async verify() {
697
- return {
698
- method: 'unknown',
699
- reference: 'unknown-ref',
700
- status: 'success' as const,
701
- timestamp: new Date().toISOString(),
702
- }
703
- },
704
- })
705
- const tempoMethod = tempo.charge({ getClient: () => client })
706
-
707
- const server = Mppx_server.create({
708
- methods: [unsupportedMethod, tempoMethod],
709
- realm: 'cli-test-multi-offer',
710
- secretKey: 'cli-test-secret-cli-test-secret-32',
711
- })
712
-
713
- const httpServer = await Http.createServer(async (req, res) => {
714
- const result = await toNodeListener(
715
- server.compose(
716
- [
717
- unsupportedMethod,
718
- {
719
- amount: '1',
720
- currency: asset,
721
- decimals: 6,
722
- expires: new Date(Date.now() + 60_000).toISOString(),
723
- recipient: accounts[0].address,
724
- },
725
- ],
726
- [
727
- tempoMethod,
728
- {
729
- amount: '1',
730
- currency: asset,
731
- decimals: 6,
732
- expires: new Date(Date.now() + 60_000).toISOString(),
733
- recipient: accounts[0].address,
734
- },
735
- ],
736
- ),
737
- )(req, res)
738
- if (result.status === 402) return
739
- res.end('paid-from-second-offer')
740
- })
741
-
742
- try {
743
- const { output, exitCode } = await serve([httpServer.url, '--rpc-url', rpcUrl, '-s'], {
744
- env: { MPPX_PRIVATE_KEY: testPrivateKey },
745
- })
746
-
747
- expect(exitCode).toBeUndefined()
748
- expect(output).toContain('paid-from-second-offer')
749
- } finally {
750
- httpServer.close()
751
- }
752
- })
753
-
754
- test('config methods emit Accept-Payment and select the preferred challenge', async () => {
755
- const alphaMethod = Method.toServer(createMockChargeMethod('alpha'), {
756
- async verify({ envelope }) {
757
- if (!envelope) throw new Error('expected envelope')
758
- if ((envelope.credential.payload as { token: string }).token !== 'alpha-token') {
759
- throw new Error('expected alpha credential')
760
- }
761
-
762
- return {
763
- method: 'alpha',
764
- reference: 'alpha-ref',
765
- status: 'success' as const,
766
- timestamp: new Date().toISOString(),
767
- }
768
- },
769
- })
770
- const betaMethod = Method.toServer(createMockChargeMethod('beta'), {
771
- async verify({ envelope }) {
772
- if (!envelope) throw new Error('expected envelope')
773
- if ((envelope.credential.payload as { token: string }).token !== 'beta-token') {
774
- throw new Error('expected beta credential')
775
- }
776
-
777
- return {
778
- method: 'beta',
779
- reference: 'beta-ref',
780
- status: 'success' as const,
781
- timestamp: new Date().toISOString(),
782
- }
783
- },
784
- })
785
-
786
- const server = Mppx_server.create({
787
- methods: [betaMethod, alphaMethod],
788
- realm: 'cli-test-config-offers',
789
- secretKey: 'cli-test-secret-cli-test-secret-32',
790
- })
791
-
792
- const configDir = fs.mkdtempSync(path.join(os.tmpdir(), 'mppx-cli-config-'))
793
- const configPath = path.join(configDir, 'mppx.config.mjs')
794
- const mppxModuleUrl = pathToFileURL(path.join(process.cwd(), 'src/index.ts')).href
795
- const cliModuleUrl = pathToFileURL(path.join(process.cwd(), 'src/cli/config.ts')).href
796
- fs.writeFileSync(
797
- configPath,
798
- `
799
- import { Credential, Method, z } from '${mppxModuleUrl}'
800
- import { defineConfig } from '${cliModuleUrl}'
801
-
802
- const alpha = Method.toClient(Method.from({
803
- name: 'alpha',
804
- intent: 'charge',
805
- schema: {
806
- credential: { payload: z.object({ token: z.string() }) },
807
- request: z.object({ amount: z.string(), currency: z.string(), decimals: z.number(), recipient: z.string() }),
808
- },
809
- }), {
810
- async createCredential({ challenge }) {
811
- return Credential.serialize({ challenge, payload: { token: 'alpha-token' } })
812
- },
813
- })
814
-
815
- const beta = Method.toClient(Method.from({
816
- name: 'beta',
817
- intent: 'charge',
818
- schema: {
819
- credential: { payload: z.object({ token: z.string() }) },
820
- request: z.object({ amount: z.string(), currency: z.string(), decimals: z.number(), recipient: z.string() }),
821
- },
822
- }), {
823
- async createCredential({ challenge }) {
824
- return Credential.serialize({ challenge, payload: { token: 'beta-token' } })
825
- },
826
- })
827
-
828
- export default defineConfig({
829
- methods: [beta, alpha],
830
- paymentPreferences: ({ alpha, beta }) => ({
831
- [alpha.charge]: 1,
832
- [beta.charge]: 0.2,
833
- }),
834
- })
835
- `.trim(),
836
- )
837
-
838
- let acceptPaymentHeader: string | undefined
839
- let authorization: string | undefined
840
- const httpServer = await Http.createServer(async (req, res) => {
841
- if (!req.headers.authorization)
842
- acceptPaymentHeader = req.headers['accept-payment'] as string | undefined
843
- else authorization = req.headers.authorization
844
-
845
- const result = await toNodeListener(
846
- server.compose(
847
- [
848
- betaMethod,
849
- {
850
- amount: '1',
851
- currency: asset,
852
- decimals: 6,
853
- expires: new Date(Date.now() + 60_000).toISOString(),
854
- recipient: accounts[0].address,
855
- },
856
- ],
857
- [
858
- alphaMethod,
859
- {
860
- amount: '1',
861
- currency: asset,
862
- decimals: 6,
863
- expires: new Date(Date.now() + 60_000).toISOString(),
864
- recipient: accounts[0].address,
865
- },
866
- ],
867
- ),
868
- )(req, res)
869
- if (result.status === 402) return
870
- res.end('paid-from-config-preference')
871
- })
872
-
873
- try {
874
- const { output, exitCode } = await serve([httpServer.url, '--config', configPath, '-s'])
875
-
876
- expect(exitCode).toBeUndefined()
877
- expect(output).toContain('paid-from-config-preference')
878
- expect(acceptPaymentHeader).toBe('beta/charge;q=0.2, alpha/charge')
879
- expect(Credential.deserialize(authorization!).payload).toEqual({ token: 'alpha-token' })
880
- } finally {
881
- httpServer.close()
882
- fs.rmSync(configDir, { recursive: true, force: true })
883
- }
884
- })
885
-
886
- test(
887
- 'zero-amount charge uses a proof credential and receives response',
888
- { timeout: 120_000 },
889
- async () => {
890
- const server = Mppx_server.create({
891
- methods: [tempo.charge({ getClient: () => client })],
892
- realm: 'localhost',
893
- secretKey: 'cli-test-secret-cli-test-secret-32',
894
- })
895
- let authorization: string | undefined
896
-
897
- const httpServer = await Http.createServer(async (req, res) => {
898
- authorization = req.headers.authorization
899
- const result = await toNodeListener(
900
- server.charge({
901
- amount: '0',
902
- currency: asset,
903
- expires: new Date(Date.now() + 60_000).toISOString(),
904
- recipient: accounts[0].address,
905
- }),
906
- )(req, res)
907
- if (result.status === 402) return
908
- res.end('zero-dollar-paid')
909
- })
910
-
911
- try {
912
- const { output, exitCode } = await serve([httpServer.url, '--rpc-url', rpcUrl, '-s'], {
913
- env: { MPPX_PRIVATE_KEY: testPrivateKey },
914
- })
915
- expect(exitCode).toBeUndefined()
916
- expect(output).toContain('zero-dollar-paid')
917
-
918
- const credential = Credential.deserialize<{ signature: string; type: 'proof' }>(
919
- authorization!,
920
- )
921
- expect(credential.challenge.request.amount).toBe('0')
922
- expect(credential.payload.type).toBe('proof')
923
- expect(credential.payload.signature).toMatch(/^0x/)
924
- expect(credential.source).toBe(`did:pkh:eip155:${chain.id}:${testAccount.address}`)
925
- } finally {
926
- httpServer.close()
927
- }
928
- },
929
- )
930
-
931
- test(
932
- 'zero-amount charge with testnet currency omission uses a proof credential',
933
- { timeout: 120_000 },
934
- async () => {
935
- const isTestnet = true
936
- const mainnetCurrency = '0x20C00000000000000000000b9537d11c60E8b50' as `0x${string}`
937
-
938
- const server = Mppx_server.create({
939
- methods: [
940
- tempo.charge({
941
- getClient: () => client,
942
- ...(isTestnet ? {} : { currency: mainnetCurrency }),
943
- testnet: isTestnet,
944
- }),
945
- ],
946
- realm: 'localhost',
947
- secretKey: 'cli-test-secret-cli-test-secret-32',
948
- })
949
- let authorization: string | undefined
950
-
951
- const httpServer = await Http.createServer(async (req, res) => {
952
- authorization = req.headers.authorization
953
- const result = await toNodeListener(
954
- server.charge({
955
- amount: '0',
956
- chainId: chain.id,
957
- expires: new Date(Date.now() + 60_000).toISOString(),
958
- recipient: accounts[0].address,
959
- }),
960
- )(req, res)
961
- if (result.status === 402) return
962
- res.end('zero-dollar-testnet-paid')
963
- })
964
-
965
- try {
966
- const { output, exitCode } = await serve([httpServer.url, '--rpc-url', rpcUrl, '-s'], {
967
- env: { MPPX_PRIVATE_KEY: testPrivateKey },
968
- })
969
- expect(exitCode).toBeUndefined()
970
- expect(output).toContain('zero-dollar-testnet-paid')
971
-
972
- const credential = Credential.deserialize<{ signature: string; type: 'proof' }>(
973
- authorization!,
974
- )
975
- expect(credential.challenge.request.amount).toBe('0')
976
- expect(credential.challenge.request.currency).toBe(
977
- '0x20c0000000000000000000000000000000000000',
978
- )
979
- expect(credential.payload.type).toBe('proof')
980
- expect(credential.source).toBe(`did:pkh:eip155:${chain.id}:${testAccount.address}`)
981
- } finally {
982
- httpServer.close()
983
- }
984
- },
985
- )
986
-
987
- test('error: no account found', { timeout: 60_000 }, async () => {
988
- const server = Mppx_server.create({
989
- methods: [tempo.charge({ getClient: () => client })],
990
- realm: 'cli-test-no-account',
991
- secretKey: 'cli-test-secret-cli-test-secret-32',
992
- })
993
-
994
- const httpServer = await Http.createServer(async (req, res) => {
995
- const result = await toNodeListener(
996
- server.charge({
997
- amount: '1',
998
- currency: asset,
999
- expires: new Date(Date.now() + 60_000).toISOString(),
1000
- recipient: accounts[0].address,
1001
- }),
1002
- )(req, res)
1003
- if (result.status === 402) return
1004
- res.end('paid')
1005
- })
1006
-
1007
- try {
1008
- const { output, exitCode } = await serve(
1009
- [httpServer.url, '--account', 'nonexistent-account'],
1010
- { env: { MPPX_PRIVATE_KEY: undefined } },
1011
- )
1012
- expect(exitCode).toBe(69)
1013
- expect(output).toContain('nonexistent-account')
1014
- expect(output).toContain('not found')
1015
- } finally {
1016
- httpServer.close()
1017
- }
1018
- })
1019
- })
1020
-
1021
- describe('session multi-fetch (examples/session/multi-fetch)', () => {
1022
- test('happy path: stream payment and receives response', { timeout: 120_000 }, async () => {
1023
- await fundAccount({ address: testAccount.address, token: Addresses.pathUsd })
1024
- await fundAccount({ address: testAccount.address, token: asset })
1025
-
1026
- const escrow = tip20ChannelEscrow
1027
- const store = Store.memory()
1028
- const server = Mppx_server.create({
1029
- methods: [
1030
- tempo.session({
1031
- account: accounts[0],
1032
- store,
1033
- getClient: () => client,
1034
- currency: asset,
1035
- escrowContract: escrow,
1036
- chainId: client.chain.id,
1037
- feePayer: true,
1038
- feePayerPolicy: cliSessionFeePayerPolicy,
1039
- }),
1040
- ],
1041
- realm: 'cli-test-multifetch',
1042
- secretKey: 'cli-test-secret-cli-test-secret-32',
1043
- })
1044
-
1045
- const httpServer = await Http.createServer(async (req, res) => {
1046
- const result = await toNodeListener(
1047
- server.session({
1048
- amount: '0.001',
1049
- recipient: accounts[0].address,
1050
- unitType: 'page',
1051
- }),
1052
- )(req, res)
1053
- if (result.status === 402) return
1054
- res.end('scraped-content')
1055
- })
1056
-
1057
- try {
1058
- const { output } = await serve(
1059
- [httpServer.url, '--rpc-url', rpcUrl, '--include', '-M', 'deposit=10'],
1060
- { env: { MPPX_PRIVATE_KEY: testPrivateKey } },
1061
- )
1062
- expect(output).toBe('scraped-content')
1063
- } finally {
1064
- httpServer.close()
1065
- }
1066
- })
1067
-
1068
- test('uses server suggestedDeposit within CLI max deposit', { timeout: 120_000 }, async () => {
1069
- await fundAccount({ address: testAccount.address, token: Addresses.pathUsd })
1070
- await fundAccount({ address: testAccount.address, token: asset })
1071
-
1072
- const escrow = tip20ChannelEscrow
1073
- let openCredential: SessionCredentialPayload | undefined
1074
-
1075
- const httpServer = await Http.createServer(async (req, res) => {
1076
- const authHeader = req.headers.authorization
1077
- if (!authHeader) {
1078
- res.writeHead(402, {
1079
- 'WWW-Authenticate': Challenge.serialize(
1080
- Challenge.from({
1081
- id: 'cli-deposit-override',
1082
- realm: 'cli-test-deposit-override',
1083
- method: 'tempo',
1084
- intent: 'session',
1085
- request: {
1086
- amount: '1000000',
1087
- currency: asset,
1088
- decimals: 6,
1089
- recipient: accounts[0].address,
1090
- suggestedDeposit: '7000000',
1091
- unitType: 'token',
1092
- methodDetails: {
1093
- chainId: chain.id,
1094
- escrowContract: escrow,
1095
- sessionProtocol: Constants.SessionProtocols.v2,
1096
- },
1097
- },
1098
- }),
1099
- ),
1100
- })
1101
- res.end()
1102
- return
1103
- }
1104
-
1105
- try {
1106
- const cred = Credential.deserialize<SessionCredentialPayload>(authHeader)
1107
- if (cred.payload.action === 'open') openCredential = cred.payload
1108
- } catch {}
1109
-
1110
- res.writeHead(200)
1111
- res.end('scraped-content')
1112
- })
1113
-
1114
- try {
1115
- await serve([httpServer.url, '--rpc-url', rpcUrl, '-s', '-M', 'deposit=10'], {
1116
- env: { MPPX_PRIVATE_KEY: testPrivateKey },
1117
- })
1118
-
1119
- expect(openCredential).toBeDefined()
1120
- expect(openCredential?.action).toBe('open')
1121
- if (!openCredential || openCredential.action !== 'open')
1122
- throw new Error('missing open credential')
1123
-
1124
- const transaction = Transaction.deserialize(openCredential.transaction)
1125
- if (!('calls' in transaction)) throw new Error('unexpected transaction type')
1126
- const [openCall] = transaction.calls as readonly [{ to?: Address; data?: `0x${string}` }]
1127
- const open = decodeFunctionData({ abi: escrowAbi, data: openCall.data ?? '0x' })
1128
- const openArgs = open.args as readonly [Address, Address, Address, bigint, string, Address]
1129
-
1130
- expect(openCall.to?.toLowerCase()).toBe(escrow.toLowerCase())
1131
- expect(open.functionName).toBe('open')
1132
- expect(openArgs[0].toLowerCase()).toBe(accounts[0].address.toLowerCase())
1133
- expect(openArgs[1]).toBe('0x0000000000000000000000000000000000000000')
1134
- expect(openArgs[2].toLowerCase()).toBe(asset.toLowerCase())
1135
- expect(openArgs[3]).toBe(7_000_000n)
1136
- expect(openArgs[4]).toEqual(expect.any(String))
1137
- expect(openArgs[5].toLowerCase()).toBe(testAccount.address.toLowerCase())
1138
- } finally {
1139
- httpServer.close()
1140
- }
1141
- })
1142
-
1143
- test(
1144
- 'selects retained non-SSE channels with auto, explicit, and new modes',
1145
- { timeout: 120_000 },
1146
- async () => {
1147
- await fundAccount({ address: testAccount.address, token: Addresses.pathUsd })
1148
- await fundAccount({ address: testAccount.address, token: asset })
1149
-
1150
- const escrow = tip20ChannelEscrow
1151
- const store = Store.memory()
1152
- const tickAmount = '0.001'
1153
- const server = Mppx_server.create({
1154
- methods: [
1155
- tempo.session({
1156
- account: accounts[0],
1157
- store,
1158
- getClient: () => client,
1159
- currency: asset,
1160
- escrowContract: escrow,
1161
- chainId: client.chain.id,
1162
- feePayer: true,
1163
- feePayerPolicy: cliSessionFeePayerPolicy,
1164
- }),
1165
- ],
1166
- realm: 'cli-test-double-charge',
1167
- secretKey: 'cli-test-secret-cli-test-secret-32',
1168
- })
1169
-
1170
- const voucherAmounts: string[] = []
1171
- const credentials: { action: string; channelId: string }[] = []
1172
-
1173
- const httpServer = await Http.createServer(async (req, res) => {
1174
- const authHeader = req.headers.authorization
1175
- if (authHeader) {
1176
- try {
1177
- const cred = Credential.deserialize<SessionCredentialPayload>(authHeader)
1178
- credentials.push({
1179
- action: cred.payload.action,
1180
- channelId: cred.payload.channelId,
1181
- })
1182
- if (cred.payload.action === 'voucher' && 'cumulativeAmount' in cred.payload) {
1183
- voucherAmounts.push(cred.payload.cumulativeAmount)
1184
- }
1185
- } catch {}
1186
- }
1187
-
1188
- const result = await toNodeListener(
1189
- server.session({
1190
- amount: tickAmount,
1191
- recipient: accounts[0].address,
1192
- unitType: 'page',
1193
- }),
1194
- )(req, res)
1195
- if (result.status === 402) return
1196
- // Non-SSE: plain text response (not text/event-stream)
1197
- res.end('scraped-content')
1198
- })
1199
-
1200
- try {
1201
- const stateHome = fs.mkdtempSync(path.join(cliTestXdgDataHome, 'reuse-state-'))
1202
- const env = { MPPX_PRIVATE_KEY: testPrivateKey, XDG_STATE_HOME: stateHome }
1203
- const runRequest = async (argv: string[]) => {
1204
- const result = await serve(argv, { env })
1205
- expect(result.exitCode, `${result.output}\n${result.stderr}`).toBeUndefined()
1206
- }
1207
- await runRequest([httpServer.url, '--rpc-url', rpcUrl, '-s', '-M', 'deposit=10'])
1208
- const retainedChannelId = credentials.find(({ action }) => action === 'open')!.channelId
1209
- await runRequest([httpServer.url, '--rpc-url', rpcUrl, '-s', '-M', 'deposit=10'])
1210
- await runRequest([
1211
- httpServer.url,
1212
- '--rpc-url',
1213
- rpcUrl,
1214
- '--session',
1215
- retainedChannelId,
1216
- '-s',
1217
- '-M',
1218
- 'deposit=10',
1219
- ])
1220
- await runRequest([
1221
- httpServer.url,
1222
- '--rpc-url',
1223
- rpcUrl,
1224
- '--session',
1225
- 'new',
1226
- '-s',
1227
- '-M',
1228
- 'deposit=10',
1229
- ])
1230
-
1231
- const payments = credentials.filter(({ action }) => ['open', 'voucher'].includes(action))
1232
- expect(voucherAmounts).toEqual(['2000', '3000'])
1233
- expect(payments.map(({ action }) => action)).toEqual(['open', 'voucher', 'voucher', 'open'])
1234
- expect(new Set(payments.slice(0, 3).map(({ channelId }) => channelId))).toEqual(
1235
- new Set([retainedChannelId]),
1236
- )
1237
- expect(payments[3]?.channelId).not.toBe(retainedChannelId)
1238
- } finally {
1239
- httpServer.close()
1240
- }
1241
- },
1242
- )
1243
-
1244
- test('retains a session until `sessions close` is invoked', { timeout: 120_000 }, async () => {
1245
- await fundAccount({ address: testAccount.address, token: Addresses.pathUsd })
1246
- await fundAccount({ address: testAccount.address, token: asset })
1247
-
1248
- const escrow = tip20ChannelEscrow
1249
- const store = Store.memory()
1250
- const server = Mppx_server.create({
1251
- methods: [
1252
- tempo.session({
1253
- account: accounts[0],
1254
- store,
1255
- getClient: () => client,
1256
- currency: asset,
1257
- escrowContract: escrow,
1258
- chainId: client.chain.id,
1259
- feePayer: accounts[1],
1260
- feePayerPolicy: cliSessionFeePayerPolicy,
1261
- }),
1262
- ],
1263
- realm: 'cli-test-close-action',
1264
- secretKey: 'cli-test-secret-cli-test-secret-32',
1265
- })
1266
-
1267
- const credentialActions: string[] = []
1268
- let channelId: string | undefined
1269
-
1270
- const httpServer = await Http.createServer(async (req, res) => {
1271
- // Capture credential action from every request with Authorization header
1272
- const authHeader = req.headers.authorization
1273
- if (authHeader) {
1274
- try {
1275
- const cred = Credential.deserialize<SessionCredentialPayload>(authHeader)
1276
- credentialActions.push(cred.payload.action)
1277
- channelId = cred.payload.channelId
1278
- } catch {}
1279
- }
1280
-
1281
- const result = await toNodeListener(
1282
- server.session({
1283
- amount: '0.001',
1284
- recipient: accounts[0].address,
1285
- unitType: 'page',
1286
- }),
1287
- )(req, res)
1288
- if (result.status === 402) return
1289
- res.end('scraped-content')
1290
- })
1291
-
1292
- try {
1293
- const stateHome = fs.mkdtempSync(path.join(cliTestXdgDataHome, 'close-state-'))
1294
- const env = { MPPX_PRIVATE_KEY: testPrivateKey, XDG_STATE_HOME: stateHome }
1295
- await serve([httpServer.url, '--rpc-url', rpcUrl, '-s', '-M', 'deposit=10'], {
1296
- env,
1297
- })
1298
-
1299
- expect(credentialActions).toEqual(['open'])
1300
- expect(channelId).toMatch(/^0x[0-9a-f]{64}$/)
1301
-
1302
- const listed = await serve(['sessions', 'list', '--json'], { env })
1303
- expect(JSON.parse(listed.output).sessions).toEqual([
1304
- expect.objectContaining({ channelId, status: 'open' }),
1305
- ])
1306
-
1307
- const closed = await serve(['sessions', 'close', channelId!, '--rpc-url', rpcUrl, '--json'], {
1308
- env,
1309
- })
1310
- expect(closed.exitCode, `${closed.output}\n${closed.stderr}`).toBeUndefined()
1311
- expect(JSON.parse(closed.output)).toEqual(
1312
- expect.objectContaining({ channelId, status: 'closed' }),
1313
- )
1314
- expect(credentialActions.at(-1)).toBe('close')
1315
-
1316
- const empty = await serve(['sessions', 'list', '--json'], { env })
1317
- expect(JSON.parse(empty.output)).toEqual({ sessions: [] })
1318
- } finally {
1319
- httpServer.close()
1320
- }
1321
- })
1322
-
1323
- test('error: --fail exits on server error', { timeout: 60_000 }, async () => {
1324
- const httpServer = await Http.createServer(async (_req, res) => {
1325
- res.writeHead(500)
1326
- res.end('Internal Server Error')
1327
- })
1328
-
1329
- try {
1330
- const { exitCode } = await serve([httpServer.url, '--rpc-url', rpcUrl, '--fail'], {
1331
- env: { MPPX_PRIVATE_KEY: testPrivateKey },
1332
- })
1333
- expect(exitCode).toBe(22)
1334
- } finally {
1335
- httpServer.close()
1336
- }
1337
- })
1338
- })
1339
-
1340
- describe('session sse (examples/session/sse)', () => {
1341
- test('streams SSE tokens to stdout', { timeout: 120_000 }, async () => {
1342
- await fundAccount({ address: testAccount.address, token: Addresses.pathUsd })
1343
- await fundAccount({ address: testAccount.address, token: asset })
1344
-
1345
- const escrow = tip20ChannelEscrow
1346
- const store = Store.memory()
1347
- const server = Mppx_server.create({
1348
- methods: [
1349
- tempo.session({
1350
- account: accounts[0],
1351
- store,
1352
- getClient: () => client,
1353
- currency: asset,
1354
- escrowContract: escrow,
1355
- chainId: client.chain.id,
1356
- feePayer: true,
1357
- feePayerPolicy: cliSessionFeePayerPolicy,
1358
- }),
1359
- ],
1360
- realm: 'cli-test-sse',
1361
- secretKey: 'cli-test-secret-cli-test-secret-32',
1362
- })
1363
-
1364
- const paidAcceptHeaders: (string | undefined)[] = []
1365
- const httpServer = await Http.createServer(async (req, res) => {
1366
- if (req.headers.authorization) paidAcceptHeaders.push(req.headers.accept)
1367
- const result = await toNodeListener(
1368
- server.session({
1369
- amount: '0.001',
1370
- recipient: accounts[0].address,
1371
- unitType: 'token',
1372
- }),
1373
- )(req, res)
1374
- if (result.status === 402) return
1375
-
1376
- res.writeHead(200, {
1377
- 'Content-Type': 'text/event-stream',
1378
- 'Cache-Control': 'no-cache',
1379
- Connection: 'keep-alive',
1380
- })
1381
- const tokens = ['Hello', ' world', '!']
1382
- for (const token of tokens) {
1383
- res.write(`data: ${JSON.stringify({ token })}\n\n`)
1384
- }
1385
- res.write('data: [DONE]\n\n')
1386
- res.end()
1387
- })
1388
-
1389
- try {
1390
- const { output } = await serve(
1391
- [httpServer.url, '--rpc-url', rpcUrl, '-H', 'Accept: application/json', '-M', 'deposit=10'],
1392
- { env: { MPPX_PRIVATE_KEY: testPrivateKey } },
1393
- )
1394
- expect(output.trim()).toBe('Hello world!')
1395
- expect(paidAcceptHeaders).toEqual(['application/json'])
1396
- } finally {
1397
- httpServer.close()
1398
- }
1399
- })
1400
-
1401
- test('error: server 500 with --fail exits non-zero', { timeout: 60_000 }, async () => {
1402
- const httpServer = await Http.createServer(async (_req, res) => {
1403
- res.writeHead(500)
1404
- res.end('Internal Server Error')
1405
- })
1406
- try {
1407
- const { exitCode } = await serve([httpServer.url, '--rpc-url', rpcUrl, '--fail'], {
1408
- env: { MPPX_PRIVATE_KEY: testPrivateKey },
1409
- })
1410
- expect(exitCode).toBe(22)
1411
- } finally {
1412
- httpServer.close()
1413
- }
1414
- })
1415
- })
1416
-
1417
- describe('stripe charge', () => {
1418
- test('happy path: makes Stripe payment and receives response', { timeout: 60_000 }, async () => {
1419
- const mockStripeClient = {
1420
- paymentIntents: { create: async () => ({ id: 'pi_mock_cli_123', status: 'succeeded' }) },
1421
- }
1422
-
1423
- const server = Mppx_server.create({
1424
- methods: [
1425
- stripe_server.charge({
1426
- client: mockStripeClient,
1427
- networkId: 'internal',
1428
- paymentMethodTypes: ['card'],
1429
- }),
1430
- ],
1431
- realm: 'cli-test-stripe',
1432
- secretKey: 'cli-test-secret-cli-test-secret-32',
1433
- })
1434
-
1435
- const sptServer = await Http.createServer(async (_req, res) => {
1436
- res.writeHead(200, { 'Content-Type': 'application/json' })
1437
- res.end(JSON.stringify({ id: 'spt_mock_cli_test' }))
1438
- })
1439
-
1440
- const appServer = await Http.createServer(async (req, res) => {
1441
- const result = await Mppx_server.toNodeListener(
1442
- server.charge({ amount: '1', currency: 'usd', decimals: 2 }),
1443
- )(req, res)
1444
- if (result.status === 402) return
1445
- res.end('paid')
1446
- })
1447
-
1448
- try {
1449
- const { output } = await serve([appServer.url, '-s', '-M', 'paymentMethod=pm_card_visa'], {
1450
- env: {
1451
- MPPX_STRIPE_SECRET_KEY: 'sk_test_mock_cli_value',
1452
- MPPX_STRIPE_SPT_URL: sptServer.url,
1453
- },
1454
- })
1455
- expect(output).toContain('paid')
1456
- } finally {
1457
- appServer.close()
1458
- sptServer.close()
1459
- }
1460
- })
1461
-
1462
- test('error: missing MPPX_STRIPE_SECRET_KEY', { timeout: 60_000 }, async () => {
1463
- const server = Mppx_server.create({
1464
- methods: [
1465
- stripe_server.charge({
1466
- secretKey: 'sk_test_mock',
1467
- networkId: 'internal',
1468
- paymentMethodTypes: ['card'],
1469
- }),
1470
- ],
1471
- realm: 'cli-test-stripe-nokey',
1472
- secretKey: 'cli-test-secret-cli-test-secret-32',
1473
- })
1474
-
1475
- const appServer = await Http.createServer(async (req, res) => {
1476
- const result = await Mppx_server.toNodeListener(
1477
- server.charge({ amount: '1', currency: 'usd', decimals: 2 }),
1478
- )(req, res)
1479
- if (result.status === 402) return
1480
- res.end('paid')
1481
- })
1482
-
1483
- try {
1484
- const { output, exitCode } = await serve(
1485
- [appServer.url, '-s', '-M', 'paymentMethod=pm_card_visa'],
1486
- { env: { MPPX_STRIPE_SECRET_KEY: '' } },
1487
- )
1488
- expect(exitCode).toBe(2)
1489
- expect(output).toContain('MPPX_STRIPE_SECRET_KEY')
1490
- } finally {
1491
- appServer.close()
1492
- }
1493
- })
1494
-
1495
- test(
1496
- 'happy path: live key uses production SPT endpoint and seller business profile',
1497
- { timeout: 60_000 },
1498
- async () => {
1499
- const mockStripeClient = {
1500
- paymentIntents: {
1501
- create: async () => ({ id: 'pi_mock_cli_live_123', status: 'succeeded' }),
1502
- },
1503
- }
1504
-
1505
- const server = Mppx_server.create({
1506
- methods: [
1507
- stripe_server.charge({
1508
- client: mockStripeClient,
1509
- networkId: 'profile_live_mock',
1510
- paymentMethodTypes: ['card'],
1511
- }),
1512
- ],
1513
- realm: 'cli-test-stripe-live',
1514
- secretKey: 'cli-test-secret-cli-test-secret-32',
1515
- })
1516
-
1517
- const appServer = await Http.createServer(async (req, res) => {
1518
- const result = await Mppx_server.toNodeListener(
1519
- server.charge({ amount: '1', currency: 'usd', decimals: 2 }),
1520
- )(req, res)
1521
- if (result.status === 402) return
1522
- res.end('paid')
1523
- })
1524
-
1525
- const { restore, stripeRequests } = mockSptFetch(
1526
- 'https://api.stripe.com/v1/shared_payment/issued_tokens',
1527
- )
1528
-
1529
- try {
1530
- const { output } = await serve([appServer.url, '-s', '-M', 'paymentMethod=pm_card_visa'], {
1531
- env: { MPPX_STRIPE_SECRET_KEY: 'sk_live_fake', MPPX_STRIPE_SPT_URL: undefined },
1532
- })
1533
- expect(output).toContain('paid')
1534
- const stripeRequest = stripeRequests[0]
1535
- expect(stripeRequest?.url).toBe('https://api.stripe.com/v1/shared_payment/issued_tokens')
1536
- expect(stripeRequest?.body.get('seller_details[network_business_profile]')).toBe(
1537
- 'profile_live_mock',
1538
- )
1539
- expect(stripeRequest?.body.has('seller_details[network_id]')).toBe(false)
1540
- expect(stripeRequest?.headers['Stripe-Version']).toBe(stripePreviewVersion)
1541
- } finally {
1542
- restore()
1543
- appServer.close()
1544
- }
1545
- },
1546
- )
1547
-
1548
- test(
1549
- 'happy path: test key uses test-helper SPT endpoint and network ID',
1550
- { timeout: 60_000 },
1551
- async () => {
1552
- const mockStripeClient = {
1553
- paymentIntents: {
1554
- create: async () => ({ id: 'pi_mock_cli_test_123', status: 'succeeded' }),
1555
- },
1556
- }
1557
-
1558
- const server = Mppx_server.create({
1559
- methods: [
1560
- stripe_server.charge({
1561
- client: mockStripeClient,
1562
- networkId: 'internal',
1563
- paymentMethodTypes: ['card'],
1564
- }),
1565
- ],
1566
- realm: 'cli-test-stripe-testmode',
1567
- secretKey: 'cli-test-secret-cli-test-secret-32',
1568
- })
1569
-
1570
- const appServer = await Http.createServer(async (req, res) => {
1571
- const result = await Mppx_server.toNodeListener(
1572
- server.charge({ amount: '1', currency: 'usd', decimals: 2 }),
1573
- )(req, res)
1574
- if (result.status === 402) return
1575
- res.end('paid')
1576
- })
1577
-
1578
- const { restore, stripeRequests } = mockSptFetch(
1579
- 'https://api.stripe.com/v1/test_helpers/shared_payment/granted_tokens',
1580
- )
1581
-
1582
- try {
1583
- const { output } = await serve([appServer.url, '-s', '-M', 'paymentMethod=pm_card_visa'], {
1584
- env: { MPPX_STRIPE_SECRET_KEY: 'sk_test_fake', MPPX_STRIPE_SPT_URL: undefined },
1585
- })
1586
- expect(output).toContain('paid')
1587
- const stripeRequest = stripeRequests[0]
1588
- expect(stripeRequest?.url).toBe(
1589
- 'https://api.stripe.com/v1/test_helpers/shared_payment/granted_tokens',
1590
- )
1591
- expect(stripeRequest?.body.get('seller_details[network_id]')).toBe('internal')
1592
- expect(stripeRequest?.body.has('seller_details[network_business_profile]')).toBe(false)
1593
- expect(stripeRequest?.headers['Stripe-Version']).toBe(stripePreviewVersion)
1594
- } finally {
1595
- restore()
1596
- appServer.close()
1597
- }
1598
- },
1599
- )
1600
- })
1601
-
1602
- /**
1603
- * Intercepts `globalThis.fetch` calls to `sptUrl`, recording each request and
1604
- * responding with a mock SPT. Returns the recorded requests and a `restore`
1605
- * function that reinstates the original fetch.
1606
- */
1607
- function mockSptFetch(sptUrl: string) {
1608
- const originalFetch = globalThis.fetch
1609
- const stripeRequests: {
1610
- body: URLSearchParams
1611
- headers: Record<string, string>
1612
- url: string
1613
- }[] = []
1614
- globalThis.fetch = (async (input, init) => {
1615
- const url =
1616
- typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url
1617
- if (url === sptUrl) {
1618
- stripeRequests.push({
1619
- body: new URLSearchParams(init?.body as string),
1620
- headers: (init?.headers ?? {}) as Record<string, string>,
1621
- url,
1622
- })
1623
- return new Response(JSON.stringify({ id: 'spt_mock_cli_test' }), {
1624
- headers: { 'Content-Type': 'application/json' },
1625
- status: 200,
1626
- })
1627
- }
1628
- return originalFetch(input, init)
1629
- }) as typeof fetch
1630
- return { restore: () => (globalThis.fetch = originalFetch), stripeRequests }
1631
- }
1632
-
1633
- // ---------------------------------------------------------------------------
1634
- // account [action]
1635
- // Keychain tests are opt-in because macOS/Linux keychain commands can block on
1636
- // developer machines without an unlocked keychain daemon.
1637
- // ---------------------------------------------------------------------------
1638
- describe.runIf(process.env.MPPX_TEST_KEYCHAIN === 'true')('account', () => {
1639
- const binPath = path.resolve(import.meta.dirname, '../bin.ts')
1640
- const cwd = path.resolve(import.meta.dirname, '../..')
1641
- const accountEnv = {
1642
- ...process.env,
1643
- NODE_NO_WARNINGS: '1',
1644
- XDG_DATA_HOME: cliTestXdgDataHome,
1645
- }
1646
- const prefix = `__mppx_test_${Date.now()}`
1647
- const createdAccounts: string[] = []
1648
-
1649
- function accountRun(args: string[], options?: { input?: string }) {
1650
- const result = spawnSync('node', ['--import', 'tsx', binPath, ...args], {
1651
- encoding: 'utf8',
1652
- cwd,
1653
- timeout: 60_000,
1654
- ...(options?.input !== undefined && { input: options.input }),
1655
- env: accountEnv,
1656
- })
1657
- return { stdout: result.stdout ?? '', stderr: result.stderr ?? '', status: result.status }
1658
- }
1659
-
1660
- function createAccount(name: string) {
1661
- const result = accountRun(['account', 'create', '--account', name], { input: '' })
1662
- if (result.status === 0) createdAccounts.push(name)
1663
- return result
1664
- }
1665
-
1666
- function deleteAccount(name: string) {
1667
- return accountRun(['account', 'delete', '--account', name, '--yes'], { input: '' })
1668
- }
1669
-
1670
- afterAll(() => {
1671
- for (const name of createdAccounts) {
1672
- deleteAccount(name)
1673
- }
1674
- })
1675
-
1676
- // --- account create ---
1677
-
1678
- test('create: creates a new account and prints address', () => {
1679
- const name = `${prefix}_create`
1680
- const result = createAccount(name)
1681
- expect(result.status).toBe(0)
1682
- expect(result.stdout).toContain(`Account "${name}" saved to keychain.`)
1683
- expect(result.stdout).toContain('Address 0x')
1684
- })
1685
-
1686
- test('create: duplicate name exits with message', () => {
1687
- const name = `${prefix}_dup`
1688
- createAccount(name)
1689
- const result = accountRun(['account', 'create', '--account', name], { input: '' })
1690
- expect(result.stdout).not.toContain('saved to keychain')
1691
- })
1692
-
1693
- // --- account view ---
1694
-
1695
- test('view: shows address for existing account', () => {
1696
- const name = `${prefix}_view`
1697
- createAccount(name)
1698
- const result = accountRun(['account', 'view', '--account', name])
1699
- expect(result.status).toBe(0)
1700
- expect(result.stdout).toContain('Address')
1701
- expect(result.stdout).toMatch(/0x[0-9a-fA-F]{40}/)
1702
- })
1703
-
1704
- test('view: missing account exits non-zero', () => {
1705
- const result = accountRun(['account', 'view', '--account', `${prefix}_nonexistent`])
1706
- expect(result.status).not.toBe(0)
1707
- expect(result.stdout).toContain('not found')
1708
- })
1709
-
1710
- // --- account export ---
1711
-
1712
- test('export: prints private key for existing account', () => {
1713
- const name = `${prefix}_export`
1714
- createAccount(name)
1715
- const result = accountRun(['account', 'export', '--account', name])
1716
- expect(result.status).toBe(0)
1717
-
1718
- const privateKey = result.stdout.match(/0x[0-9a-fA-F]{64}/)?.[0]
1719
- expect(privateKey).toBeDefined()
1720
-
1721
- const view = accountRun(['account', 'view', '--account', name])
1722
- expect(view.stdout).toContain(privateKeyToAccount(privateKey as `0x${string}`).address)
1723
- })
1724
-
1725
- test('export: missing account exits non-zero', () => {
1726
- const result = accountRun(['account', 'export', '--account', `${prefix}_missing_export`])
1727
- expect(result.status).not.toBe(0)
1728
- expect(result.stdout).toContain('not found')
1729
- })
1730
-
1731
- // --- account list ---
1732
-
1733
- test('list: includes created accounts', () => {
1734
- const name = `${prefix}_list`
1735
- createAccount(name)
1736
- const result = accountRun(['account', 'list'])
1737
- expect(result.status).toBe(0)
1738
- expect(result.stdout).toContain(name)
1739
- })
1740
-
1741
- // --- account default ---
1742
-
1743
- test('default: sets default account', () => {
1744
- const name = `${prefix}_default`
1745
- createAccount(name)
1746
- const result = accountRun(['account', 'default', '--account', name])
1747
- expect(result.status).toBe(0)
1748
- expect(result.stdout).toContain(`Default account set to "${name}"`)
1749
- })
1750
-
1751
- test('default: missing --account flag exits non-zero', () => {
1752
- const result = accountRun(['account', 'default'])
1753
- expect(result.status).not.toBe(0)
1754
- })
1755
-
1756
- test('default: nonexistent account exits non-zero', () => {
1757
- const result = accountRun(['account', 'default', '--account', `${prefix}_nope`])
1758
- expect(result.status).not.toBe(0)
1759
- expect(result.stdout).toContain('not found')
1760
- })
1761
-
1762
- // --- account delete ---
1763
-
1764
- test('delete: removes an existing account', () => {
1765
- const name = `${prefix}_del`
1766
- createAccount(name)
1767
- const result = deleteAccount(name)
1768
- expect(result.status).toBe(0)
1769
- expect(result.stdout).toContain(`Account "${name}" deleted`)
1770
- const idx = createdAccounts.indexOf(name)
1771
- if (idx !== -1) createdAccounts.splice(idx, 1)
1772
-
1773
- const view = accountRun(['account', 'view', '--account', name])
1774
- expect(view.status).not.toBe(0)
1775
- })
1776
-
1777
- test('delete: missing --account flag exits non-zero', () => {
1778
- const result = accountRun(['account', 'delete', '--yes'])
1779
- expect(result.status).not.toBe(0)
1780
- })
1781
-
1782
- test('delete: nonexistent account exits non-zero', () => {
1783
- const result = accountRun(['account', 'delete', '--account', `${prefix}_ghost`, '--yes'])
1784
- expect(result.status).not.toBe(0)
1785
- expect(result.stdout).toContain('not found')
1786
- })
1787
-
1788
- // --- unknown action ---
1789
-
1790
- test('unknown action exits non-zero', () => {
1791
- const result = accountRun(['account', 'bogus'])
1792
- expect(result.status).not.toBe(0)
1793
- })
1794
-
1795
- // --- no action ---
1796
-
1797
- test('no action prints help', () => {
1798
- const result = accountRun(['account'])
1799
- expect(result.status).toBe(0)
1800
- expect(result.stdout).toContain('account')
1801
- })
1802
- })
1803
-
1804
- // ---------------------------------------------------------------------------
1805
- // init
1806
- // ---------------------------------------------------------------------------
1807
- describe('init', () => {
1808
- let tmpDir: string
1809
-
1810
- function setup(files?: Record<string, string>) {
1811
- tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'mppx-init-'))
1812
- if (files) {
1813
- for (const [name, content] of Object.entries(files))
1814
- fs.writeFileSync(path.join(tmpDir, name), content)
1815
- }
1816
- }
1817
-
1818
- function teardown() {
1819
- fs.rmSync(tmpDir, { recursive: true, force: true })
1820
- }
1821
-
1822
- test('creates mppx.config.ts when tsconfig.json exists', async () => {
1823
- setup({ 'tsconfig.json': '{}' })
1824
- const origCwd = process.cwd()
1825
- process.chdir(tmpDir)
1826
- try {
1827
- const { output, exitCode } = await serve(['init'])
1828
- expect(exitCode).toBeUndefined()
1829
- expect(output).toContain('Created mppx.config.ts')
1830
- const content = fs.readFileSync(path.join(tmpDir, 'mppx.config.ts'), 'utf-8')
1831
- expect(content).toContain("import { defineConfig } from 'mppx/cli'")
1832
- expect(content).toContain('methods:')
1833
- } finally {
1834
- process.chdir(origCwd)
1835
- teardown()
1836
- }
1837
- })
1838
-
1839
- test('creates mppx.config.mjs when package.json has type:module', async () => {
1840
- setup({ 'package.json': '{"type":"module"}' })
1841
- const origCwd = process.cwd()
1842
- process.chdir(tmpDir)
1843
- try {
1844
- const { output, exitCode } = await serve(['init'])
1845
- expect(exitCode).toBeUndefined()
1846
- expect(output).toContain('Created mppx.config.mjs')
1847
- expect(fs.existsSync(path.join(tmpDir, 'mppx.config.mjs'))).toBe(true)
1848
- } finally {
1849
- process.chdir(origCwd)
1850
- teardown()
1851
- }
1852
- })
1853
-
1854
- test('creates mppx.config.js as fallback', async () => {
1855
- setup()
1856
- const origCwd = process.cwd()
1857
- process.chdir(tmpDir)
1858
- try {
1859
- const { output, exitCode } = await serve(['init'])
1860
- expect(exitCode).toBeUndefined()
1861
- expect(output).toContain('Created mppx.config.js')
1862
- expect(fs.existsSync(path.join(tmpDir, 'mppx.config.js'))).toBe(true)
1863
- } finally {
1864
- process.chdir(origCwd)
1865
- teardown()
1866
- }
1867
- })
1868
-
1869
- test('errors when config already exists', async () => {
1870
- setup({ 'tsconfig.json': '{}', 'mppx.config.ts': 'existing' })
1871
- const origCwd = process.cwd()
1872
- process.chdir(tmpDir)
1873
- try {
1874
- const { output, exitCode } = await serve(['init'])
1875
- expect(exitCode).toBe(1)
1876
- expect(output).toContain('already exists')
1877
- expect(fs.readFileSync(path.join(tmpDir, 'mppx.config.ts'), 'utf-8')).toBe('existing')
1878
- } finally {
1879
- process.chdir(origCwd)
1880
- teardown()
1881
- }
1882
- })
1883
-
1884
- test('--force overwrites existing config', async () => {
1885
- setup({ 'tsconfig.json': '{}', 'mppx.config.ts': 'existing' })
1886
- const origCwd = process.cwd()
1887
- process.chdir(tmpDir)
1888
- try {
1889
- const { output, exitCode } = await serve(['init', '--force'])
1890
- expect(exitCode).toBeUndefined()
1891
- expect(output).toContain('Created mppx.config.ts')
1892
- const content = fs.readFileSync(path.join(tmpDir, 'mppx.config.ts'), 'utf-8')
1893
- expect(content).toContain('defineConfig')
1894
- } finally {
1895
- process.chdir(origCwd)
1896
- teardown()
1897
- }
1898
- })
1899
- })
1900
-
1901
- test('mppx --help', async () => {
1902
- const { output } = await serve(['--help'])
1903
- expect(output).toContain('mppx')
1904
- expect(output).toContain('<url>')
1905
- expect(output).toContain('account')
1906
- expect(output).toContain('sessions')
1907
- expect(output).toContain('services')
1908
- expect(output).toContain('sign')
1909
- expect(output).toContain('--session')
1910
- })
1911
-
1912
- test('mppx sessions --help', async () => {
1913
- const { output } = await serve(['sessions', '--help'])
1914
- expect(output).toContain('close Cooperatively close')
1915
- expect(output).toContain('list List persistent')
1916
- expect(output).toContain('view View a persistent')
1917
- })
1918
-
1919
- test('mppx sessions close --help', async () => {
1920
- const { output } = await serve(['sessions', 'close', '--help'])
1921
- expect(output).toContain('--all')
1922
- expect(output).toContain('--yes')
1923
- expect(output).toContain('--url')
1924
- })
1925
-
1926
- test('mppx sessions close --all requires confirmation', async () => {
1927
- const { exitCode, output } = await serve(['sessions', 'close', '--all'])
1928
- expect(exitCode).toBe(2)
1929
- expect(output).toContain('requires --yes')
1930
- })
1931
-
1932
- test('mppx sessions close --all returns an empty structured result', async () => {
1933
- const { exitCode, output } = await serve(['sessions', 'close', '--all', '--yes', '--json'])
1934
- expect(exitCode).toBeUndefined()
1935
- expect(JSON.parse(output)).toEqual({ closed: [], failed: [] })
1936
- })
1937
-
1938
- describe('account fund help', () => {
1939
- test('only advertises testnet network funding', async () => {
1940
- const { output } = await serve(['account', 'fund', '--help'])
1941
- expect(output).toContain('--network <testnet>')
1942
- expect(output).not.toContain('mainnet|testnet')
1943
- })
1944
-
1945
- test('rejects mainnet network funding', async () => {
1946
- const { exitCode, output } = await serve(['account', 'fund', '--network', 'mainnet'])
1947
- expect(exitCode).toBe(1)
1948
- expect(output).toContain('Invalid input')
1949
- expect(output).toContain('testnet')
1950
- })
1951
- })
1952
-
1953
- // ---------------------------------------------------------------------------
1954
- // sign
1955
- // ---------------------------------------------------------------------------
1956
- describe('sign', () => {
1957
- const validChallenge =
1958
- 'Payment id="test", realm="test", method="tempo", intent="charge", request="eyJhbW91bnQiOiIxMDAwIiwiY3VycmVuY3kiOiIweDIwYzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDEiLCJyZWNpcGllbnQiOiIweDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDEiLCJtZXRob2REZXRhaWxzIjp7ImNoYWluSWQiOjEzMzd9fQ"'
1959
-
1960
- test('--dry-run: validates a valid challenge', async () => {
1961
- const { exitCode, stderr } = await serve(['sign', '--dry-run', '--challenge', validChallenge])
1962
- expect(exitCode).toBeUndefined()
1963
- expect(stderr).toContain('Challenge is valid')
1964
- })
1965
-
1966
- test('--dry-run: rejects an invalid challenge', async () => {
1967
- const { exitCode, output } = await serve([
1968
- 'sign',
1969
- '--dry-run',
1970
- '--challenge',
1971
- 'not a valid challenge',
1972
- ])
1973
- expect(exitCode).toBe(2)
1974
- expect(output).toContain('INVALID_CHALLENGE')
1975
- })
1976
-
1977
- test('error: no challenge provided', async () => {
1978
- const { exitCode, output } = await serve(['sign'])
1979
- expect(exitCode).toBe(2)
1980
- expect(output).toContain('No challenge provided')
1981
- })
1982
-
1983
- test('error: unsupported method', async () => {
1984
- const challenge = 'Payment id="x", realm="x", method="unknown", intent="charge", request="e30"'
1985
- const { exitCode, output } = await serve(['sign', '--challenge', challenge])
1986
- expect(exitCode).toBe(2)
1987
- expect(output).toContain('Unsupported payment method')
1988
- })
1989
-
1990
- test('paymentPreferences opt-out is not bypassed by CLI fallback selection', async () => {
1991
- const configDir = fs.mkdtempSync(path.join(os.tmpdir(), 'mppx-sign-config-'))
1992
- const configPath = path.join(configDir, 'mppx.config.mjs')
1993
- const mppxModuleUrl = pathToFileURL(path.join(process.cwd(), 'src/index.ts')).href
1994
- const cliModuleUrl = pathToFileURL(path.join(process.cwd(), 'src/cli/config.ts')).href
1995
- fs.writeFileSync(
1996
- configPath,
1997
- `
1998
- import { Credential, Method, z } from '${mppxModuleUrl}'
1999
- import { defineConfig } from '${cliModuleUrl}'
2000
-
2001
- const alpha = Method.toClient(Method.from({
2002
- name: 'alpha',
2003
- intent: 'charge',
2004
- schema: {
2005
- credential: { payload: z.object({ token: z.string() }) },
2006
- request: z.object({ amount: z.string() }),
2007
- },
2008
- }), {
2009
- async createCredential({ challenge }) {
2010
- return Credential.serialize({ challenge, payload: { token: 'alpha-token' } })
2011
- },
2012
- })
2013
-
2014
- export default defineConfig({
2015
- methods: [alpha],
2016
- paymentPreferences: ({ alpha }) => ({
2017
- [alpha.charge]: 0,
2018
- }),
2019
- })
2020
- `.trim(),
2021
- )
2022
-
2023
- const challenge =
2024
- 'Payment id="x", realm="x", method="alpha", intent="charge", request="eyJhbW91bnQiOiIxIn0"'
2025
-
2026
- try {
2027
- const { exitCode, output } = await serve([
2028
- 'sign',
2029
- '--challenge',
2030
- challenge,
2031
- '--config',
2032
- configPath,
2033
- ])
2034
- expect(exitCode).toBe(2)
2035
- expect(output).toContain('Unsupported payment method')
2036
- } finally {
2037
- fs.rmSync(configDir, { recursive: true, force: true })
2038
- }
2039
- })
2040
-
2041
- test('selects a later supported challenge from a merged challenge value', async () => {
2042
- const merged = [
2043
- 'Payment id="x", realm="x", method="unknown", intent="charge", request="e30"',
2044
- validChallenge,
2045
- ].join(', ')
2046
-
2047
- const { output, exitCode } = await serve(['sign', '--challenge', merged, '--rpc-url', rpcUrl], {
2048
- env: { MPPX_PRIVATE_KEY: testPrivateKey },
2049
- })
2050
-
2051
- expect(exitCode).toBeUndefined()
2052
- expect(output.trim()).toMatch(/^Payment\s+\S+/)
2053
- })
2054
-
2055
- test('error: no account for tempo', async () => {
2056
- const { exitCode, output } = await serve(
2057
- ['sign', '--challenge', validChallenge, '--account', 'nonexistent-sign-test'],
2058
- { env: { MPPX_PRIVATE_KEY: undefined } },
2059
- )
2060
- expect(exitCode).toBe(69)
2061
- expect(output).toContain('not found')
2062
- })
2063
-
2064
- test('happy path: signs a tempo charge challenge', { timeout: 120_000 }, async () => {
2065
- const { output, stderr, exitCode } = await serve(
2066
- ['sign', '--challenge', validChallenge, '--rpc-url', rpcUrl],
2067
- { env: { MPPX_PRIVATE_KEY: testPrivateKey } },
2068
- )
2069
- if (exitCode) console.info('SIGN DEBUG output:', output, 'stderr:', stderr)
2070
- expect(exitCode).toBeUndefined()
2071
- expect(output.trim()).toMatch(/^Payment\s+\S+/)
2072
- })
2073
-
2074
- test('rejects unsupported tempo method options', async () => {
2075
- const { output, exitCode } = await serve(
2076
- ['sign', '--challenge', validChallenge, '--rpc-url', rpcUrl, '-M', 'feeToken=0xabc'],
2077
- { env: { MPPX_PRIVATE_KEY: testPrivateKey } },
2078
- )
2079
-
2080
- expect(exitCode).toBeDefined()
2081
- expect(output).toContain('Unsupported CLI method option')
2082
- expect(output).toContain('feeToken')
2083
- })
2084
-
2085
- test('happy path: --json outputs authorization', { timeout: 120_000 }, async () => {
2086
- const { output, stderr, exitCode } = await serve(
2087
- ['sign', '--challenge', validChallenge, '--rpc-url', rpcUrl, '--json'],
2088
- { env: { MPPX_PRIVATE_KEY: testPrivateKey } },
2089
- )
2090
- if (exitCode) console.info('SIGN JSON DEBUG output:', output, 'stderr:', stderr)
2091
- expect(exitCode).toBeUndefined()
2092
- const parsed = JSON.parse(output.trim())
2093
- expect(parsed.authorization).toMatch(/^Payment\s+\S+/)
2094
- })
2095
-
2096
- test(
2097
- 'happy path: zero-amount challenge returns proof authorization accepted by live server',
2098
- { timeout: 120_000 },
2099
- async () => {
2100
- const server = Mppx_server.create({
2101
- methods: [tempo.charge({ getClient: () => client })],
2102
- realm: 'cli-sign-zero',
2103
- secretKey: 'cli-test-secret-cli-test-secret-32',
2104
- })
2105
-
2106
- const httpServer = await Http.createServer(async (req, res) => {
2107
- const result = await toNodeListener(
2108
- server.charge({
2109
- amount: '0',
2110
- currency: asset,
2111
- expires: new Date(Date.now() + 60_000).toISOString(),
2112
- recipient: accounts[0].address,
2113
- }),
2114
- )(req, res)
2115
- if (result.status === 402) return
2116
- res.end('zero-dollar-live-sign')
2117
- })
2118
-
2119
- try {
2120
- const challengeResponse = await fetch(httpServer.url)
2121
- expect(challengeResponse.status).toBe(402)
2122
- const challenge = Challenge.fromResponse(challengeResponse)
2123
-
2124
- const { output, exitCode } = await serve(
2125
- ['sign', '--challenge', Challenge.serialize(challenge), '--rpc-url', rpcUrl],
2126
- { env: { MPPX_PRIVATE_KEY: testPrivateKey } },
2127
- )
2128
-
2129
- expect(exitCode).toBeUndefined()
2130
-
2131
- const authorization = output.trim()
2132
- const credential = Credential.deserialize<{ signature: string; type: 'proof' }>(
2133
- authorization,
2134
- )
2135
- expect(credential.challenge.request.amount).toBe('0')
2136
- expect(credential.payload.type).toBe('proof')
2137
- expect(credential.source).toBe(`did:pkh:eip155:${chain.id}:${testAccount.address}`)
2138
-
2139
- const response = await fetch(httpServer.url, {
2140
- headers: { Authorization: authorization },
2141
- })
2142
- expect(response.status).toBe(200)
2143
- expect(await response.text()).toBe('zero-dollar-live-sign')
2144
-
2145
- const receipt = Receipt.fromResponse(response)
2146
- expect(receipt.reference).toBe(credential.challenge.id)
2147
- } finally {
2148
- httpServer.close()
2149
- }
2150
- },
2151
- )
2152
-
2153
- test(
2154
- 'happy path: zero-amount testnet challenge without explicit currency is accepted by live server',
2155
- { timeout: 120_000 },
2156
- async () => {
2157
- const isTestnet = true
2158
- const mainnetCurrency = '0x20C00000000000000000000b9537d11c60E8b50' as `0x${string}`
2159
-
2160
- const server = Mppx_server.create({
2161
- methods: [
2162
- tempo.charge({
2163
- getClient: () => client,
2164
- ...(isTestnet ? {} : { currency: mainnetCurrency }),
2165
- testnet: isTestnet,
2166
- }),
2167
- ],
2168
- realm: 'cli-sign-zero-testnet',
2169
- secretKey: 'cli-test-secret-cli-test-secret-32',
2170
- })
2171
-
2172
- const httpServer = await Http.createServer(async (req, res) => {
2173
- const result = await toNodeListener(
2174
- server.charge({
2175
- amount: '0',
2176
- chainId: chain.id,
2177
- expires: new Date(Date.now() + 60_000).toISOString(),
2178
- recipient: accounts[0].address,
2179
- }),
2180
- )(req, res)
2181
- if (result.status === 402) return
2182
- res.end('zero-dollar-live-sign-testnet')
2183
- })
2184
-
2185
- try {
2186
- const challengeResponse = await fetch(httpServer.url)
2187
- expect(challengeResponse.status).toBe(402)
2188
- const challenge = Challenge.fromResponse(challengeResponse)
2189
-
2190
- const { output, exitCode } = await serve(
2191
- ['sign', '--challenge', Challenge.serialize(challenge), '--rpc-url', rpcUrl],
2192
- { env: { MPPX_PRIVATE_KEY: testPrivateKey } },
2193
- )
2194
-
2195
- expect(exitCode).toBeUndefined()
2196
-
2197
- const authorization = output.trim()
2198
- const credential = Credential.deserialize<{ signature: string; type: 'proof' }>(
2199
- authorization,
2200
- )
2201
- expect(credential.challenge.request.amount).toBe('0')
2202
- expect(credential.challenge.request.currency).toBe(
2203
- '0x20c0000000000000000000000000000000000000',
2204
- )
2205
- expect(credential.payload.type).toBe('proof')
2206
- expect(credential.source).toBe(`did:pkh:eip155:${chain.id}:${testAccount.address}`)
2207
-
2208
- const response = await fetch(httpServer.url, {
2209
- headers: { Authorization: authorization },
2210
- })
2211
- expect(response.status).toBe(200)
2212
- expect(await response.text()).toBe('zero-dollar-live-sign-testnet')
2213
-
2214
- const receipt = Receipt.fromResponse(response)
2215
- expect(receipt.reference).toBe(credential.challenge.id)
2216
- } finally {
2217
- httpServer.close()
2218
- }
2219
- },
2220
- )
2221
- })