mppx 0.8.14 → 0.8.17

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 (507) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/dist/Challenge.d.ts.map +1 -1
  3. package/dist/Challenge.js +40 -35
  4. package/dist/Challenge.js.map +1 -1
  5. package/dist/Constants.d.ts +17 -17
  6. package/dist/Constants.d.ts.map +1 -1
  7. package/dist/Credential.d.ts.map +1 -1
  8. package/dist/Errors.d.ts +3 -3
  9. package/dist/Errors.d.ts.map +1 -1
  10. package/dist/Errors.js.map +1 -1
  11. package/dist/Method.d.ts +35 -5
  12. package/dist/Method.d.ts.map +1 -1
  13. package/dist/Method.js +7 -22
  14. package/dist/Method.js.map +1 -1
  15. package/dist/Store.d.ts +19 -0
  16. package/dist/Store.d.ts.map +1 -1
  17. package/dist/Store.js +43 -0
  18. package/dist/Store.js.map +1 -1
  19. package/dist/attestation/Client.d.ts +17 -0
  20. package/dist/attestation/Client.d.ts.map +1 -0
  21. package/dist/attestation/Client.js +28 -0
  22. package/dist/attestation/Client.js.map +1 -0
  23. package/dist/attestation/Constants.d.ts +15 -0
  24. package/dist/attestation/Constants.d.ts.map +1 -0
  25. package/dist/attestation/Constants.js +15 -0
  26. package/dist/attestation/Constants.js.map +1 -0
  27. package/dist/attestation/Server.d.ts +4 -0
  28. package/dist/attestation/Server.d.ts.map +1 -0
  29. package/dist/attestation/Server.js +8 -0
  30. package/dist/attestation/Server.js.map +1 -0
  31. package/dist/attestation/Types.d.ts +76 -0
  32. package/dist/attestation/Types.d.ts.map +1 -0
  33. package/dist/attestation/Types.js +2 -0
  34. package/dist/attestation/Types.js.map +1 -0
  35. package/dist/attestation/index.d.ts +6 -0
  36. package/dist/attestation/index.d.ts.map +1 -0
  37. package/dist/attestation/index.js +6 -0
  38. package/dist/attestation/index.js.map +1 -0
  39. package/dist/attestation/internal/HttpMessageSignature.d.ts +73 -0
  40. package/dist/attestation/internal/HttpMessageSignature.d.ts.map +1 -0
  41. package/dist/attestation/internal/HttpMessageSignature.js +320 -0
  42. package/dist/attestation/internal/HttpMessageSignature.js.map +1 -0
  43. package/dist/attestation/internal/SigningContext.d.ts +4 -0
  44. package/dist/attestation/internal/SigningContext.d.ts.map +1 -0
  45. package/dist/attestation/internal/SigningContext.js +11 -0
  46. package/dist/attestation/internal/SigningContext.js.map +1 -0
  47. package/dist/cli/account.d.ts +14 -14
  48. package/dist/cli/account.d.ts.map +1 -1
  49. package/dist/cli/cli.d.ts +6 -6
  50. package/dist/cli/cli.d.ts.map +1 -1
  51. package/dist/cli/cli.js +1 -0
  52. package/dist/cli/cli.js.map +1 -1
  53. package/dist/cli/plugins/tempo.js.map +1 -1
  54. package/dist/cli/sessions/commands.d.ts +4 -4
  55. package/dist/cli/sessions/commands.d.ts.map +1 -1
  56. package/dist/cli/sessions/commands.js.map +1 -1
  57. package/dist/cli/sessions/store.d.ts.map +1 -1
  58. package/dist/cli/sessions/store.js.map +1 -1
  59. package/dist/cli/utils.d.ts +1 -1
  60. package/dist/cli/utils.d.ts.map +1 -1
  61. package/dist/cli/utils.js.map +1 -1
  62. package/dist/cli/validate/discovery.js.map +1 -1
  63. package/dist/cli/validate/index.d.ts +3 -3
  64. package/dist/cli/validate/index.d.ts.map +1 -1
  65. package/dist/cli/validate/payment.d.ts.map +1 -1
  66. package/dist/cli/validate/payment.js +18 -4
  67. package/dist/cli/validate/payment.js.map +1 -1
  68. package/dist/client/Mppx.d.ts +3 -0
  69. package/dist/client/Mppx.d.ts.map +1 -1
  70. package/dist/client/Mppx.js +13 -5
  71. package/dist/client/Mppx.js.map +1 -1
  72. package/dist/client/Transport.d.ts +3 -5
  73. package/dist/client/Transport.d.ts.map +1 -1
  74. package/dist/client/Transport.js +1 -17
  75. package/dist/client/Transport.js.map +1 -1
  76. package/dist/client/internal/Fetch.d.ts.map +1 -1
  77. package/dist/client/internal/Fetch.js +92 -13
  78. package/dist/client/internal/Fetch.js.map +1 -1
  79. package/dist/client/internal/MethodChallenge.d.ts +2 -0
  80. package/dist/client/internal/MethodChallenge.d.ts.map +1 -1
  81. package/dist/client/internal/MethodChallenge.js +4 -0
  82. package/dist/client/internal/MethodChallenge.js.map +1 -1
  83. package/dist/client/internal/MethodResponse.d.ts +15 -0
  84. package/dist/client/internal/MethodResponse.d.ts.map +1 -1
  85. package/dist/client/internal/MethodResponse.js +10 -0
  86. package/dist/client/internal/MethodResponse.js.map +1 -1
  87. package/dist/client/node.js.map +1 -1
  88. package/dist/discovery/OpenApi.d.ts +3 -5
  89. package/dist/discovery/OpenApi.d.ts.map +1 -1
  90. package/dist/discovery/OpenApi.js +13 -34
  91. package/dist/discovery/OpenApi.js.map +1 -1
  92. package/dist/discovery/internal/Metadata.d.ts +20 -0
  93. package/dist/discovery/internal/Metadata.d.ts.map +1 -0
  94. package/dist/discovery/internal/Metadata.js +36 -0
  95. package/dist/discovery/internal/Metadata.js.map +1 -0
  96. package/dist/evm/Methods.d.ts +11 -11
  97. package/dist/evm/Methods.d.ts.map +1 -1
  98. package/dist/evm/Types.d.ts +17 -17
  99. package/dist/evm/Types.d.ts.map +1 -1
  100. package/dist/evm/client/Charge.d.ts +11 -11
  101. package/dist/evm/client/Methods.d.ts +11 -11
  102. package/dist/evm/server/Charge.d.ts +1 -1
  103. package/dist/evm/server/Charge.d.ts.map +1 -1
  104. package/dist/evm/server/Charge.js +2 -0
  105. package/dist/evm/server/Charge.js.map +1 -1
  106. package/dist/evm/server/Methods.d.ts +11 -11
  107. package/dist/internal/HeaderCodec.d.ts +2 -2
  108. package/dist/internal/HeaderCodec.d.ts.map +1 -1
  109. package/dist/internal/types.d.ts +6 -0
  110. package/dist/internal/types.d.ts.map +1 -1
  111. package/dist/middlewares/elysia.js.map +1 -1
  112. package/dist/middlewares/express.js.map +1 -1
  113. package/dist/middlewares/hono.js.map +1 -1
  114. package/dist/middlewares/nextjs.js.map +1 -1
  115. package/dist/proxy/Proxy.d.ts +2 -0
  116. package/dist/proxy/Proxy.d.ts.map +1 -1
  117. package/dist/proxy/Proxy.js +117 -9
  118. package/dist/proxy/Proxy.js.map +1 -1
  119. package/dist/proxy/Service.d.ts +36 -1
  120. package/dist/proxy/Service.d.ts.map +1 -1
  121. package/dist/proxy/Service.js +9 -8
  122. package/dist/proxy/Service.js.map +1 -1
  123. package/dist/proxy/services/anthropic.d.ts.map +1 -1
  124. package/dist/proxy/services/anthropic.js +1 -0
  125. package/dist/proxy/services/anthropic.js.map +1 -1
  126. package/dist/proxy/services/openai.d.ts.map +1 -1
  127. package/dist/proxy/services/openai.js +1 -0
  128. package/dist/proxy/services/openai.js.map +1 -1
  129. package/dist/proxy/services/stripe.d.ts.map +1 -1
  130. package/dist/proxy/services/stripe.js +1 -0
  131. package/dist/proxy/services/stripe.js.map +1 -1
  132. package/dist/server/Mppx.d.ts +75 -13
  133. package/dist/server/Mppx.d.ts.map +1 -1
  134. package/dist/server/Mppx.js +201 -23
  135. package/dist/server/Mppx.js.map +1 -1
  136. package/dist/server/internal/html/config.d.ts +9 -9
  137. package/dist/server/internal/html/config.d.ts.map +1 -1
  138. package/dist/server/internal/html/constants.d.ts +17 -17
  139. package/dist/server/internal/html/constants.d.ts.map +1 -1
  140. package/dist/stripe/Methods.d.ts +10 -10
  141. package/dist/stripe/Methods.d.ts.map +1 -1
  142. package/dist/stripe/client/Charge.d.ts +10 -10
  143. package/dist/stripe/client/Methods.d.ts +10 -10
  144. package/dist/stripe/internal/constants.d.ts +1 -1
  145. package/dist/stripe/internal/constants.js +1 -1
  146. package/dist/stripe/internal/types.d.ts +1 -0
  147. package/dist/stripe/internal/types.d.ts.map +1 -1
  148. package/dist/stripe/server/Charge.d.ts +11 -11
  149. package/dist/stripe/server/Charge.d.ts.map +1 -1
  150. package/dist/stripe/server/Charge.js +49 -1
  151. package/dist/stripe/server/Charge.js.map +1 -1
  152. package/dist/stripe/server/Methods.d.ts +137 -48
  153. package/dist/stripe/server/Methods.d.ts.map +1 -1
  154. package/dist/stripe/server/Methods.js +259 -4
  155. package/dist/stripe/server/Methods.js.map +1 -1
  156. package/dist/stripe/server/internal/deposit-address.d.ts +13 -0
  157. package/dist/stripe/server/internal/deposit-address.d.ts.map +1 -0
  158. package/dist/stripe/server/internal/deposit-address.js +28 -0
  159. package/dist/stripe/server/internal/deposit-address.js.map +1 -0
  160. package/dist/stripe/server/internal/html.gen.d.ts +1 -1
  161. package/dist/stripe/server/internal/html.gen.d.ts.map +1 -1
  162. package/dist/stripe/server/internal/html.gen.js +1 -1
  163. package/dist/stripe/server/internal/html.gen.js.map +1 -1
  164. package/dist/stripe/server/internal/record-payment.d.ts +15 -0
  165. package/dist/stripe/server/internal/record-payment.d.ts.map +1 -0
  166. package/dist/stripe/server/internal/record-payment.js +42 -0
  167. package/dist/stripe/server/internal/record-payment.js.map +1 -0
  168. package/dist/stripe/server/internal/request.d.ts +25 -0
  169. package/dist/stripe/server/internal/request.d.ts.map +1 -0
  170. package/dist/stripe/server/internal/request.js +29 -0
  171. package/dist/stripe/server/internal/request.js.map +1 -0
  172. package/dist/tap/Constants.d.ts +28 -0
  173. package/dist/tap/Constants.d.ts.map +1 -0
  174. package/dist/tap/Constants.js +32 -0
  175. package/dist/tap/Constants.js.map +1 -0
  176. package/dist/tap/Types.d.ts +11 -0
  177. package/dist/tap/Types.d.ts.map +1 -0
  178. package/dist/tap/Types.js +2 -0
  179. package/dist/tap/Types.js.map +1 -0
  180. package/dist/tap/client/index.d.ts +26 -0
  181. package/dist/tap/client/index.d.ts.map +1 -0
  182. package/dist/tap/client/index.js +33 -0
  183. package/dist/tap/client/index.js.map +1 -0
  184. package/dist/tap/index.d.ts +5 -0
  185. package/dist/tap/index.d.ts.map +1 -0
  186. package/dist/tap/index.js +5 -0
  187. package/dist/tap/index.js.map +1 -0
  188. package/dist/tap/server/index.d.ts +20 -0
  189. package/dist/tap/server/index.d.ts.map +1 -0
  190. package/dist/tap/server/index.js +36 -0
  191. package/dist/tap/server/index.js.map +1 -0
  192. package/dist/tempo/Attribution.d.ts +1 -1
  193. package/dist/tempo/Methods.d.ts +60 -60
  194. package/dist/tempo/Methods.d.ts.map +1 -1
  195. package/dist/tempo/Proof.d.ts +16 -16
  196. package/dist/tempo/client/Charge.d.ts +19 -19
  197. package/dist/tempo/client/Charge.d.ts.map +1 -1
  198. package/dist/tempo/client/Charge.js +1 -7
  199. package/dist/tempo/client/Charge.js.map +1 -1
  200. package/dist/tempo/client/Methods.d.ts +38 -38
  201. package/dist/tempo/client/Methods.js.map +1 -1
  202. package/dist/tempo/client/Subscription.d.ts +23 -23
  203. package/dist/tempo/client/Subscription.js.map +1 -1
  204. package/dist/tempo/internal/address.d.ts +2 -1
  205. package/dist/tempo/internal/address.d.ts.map +1 -1
  206. package/dist/tempo/internal/address.js +3 -1
  207. package/dist/tempo/internal/address.js.map +1 -1
  208. package/dist/tempo/internal/auto-swap.d.ts.map +1 -1
  209. package/dist/tempo/internal/auto-swap.js +4 -19
  210. package/dist/tempo/internal/auto-swap.js.map +1 -1
  211. package/dist/tempo/internal/defaults.d.ts +6 -6
  212. package/dist/tempo/internal/defaults.d.ts.map +1 -1
  213. package/dist/tempo/internal/fee-payer.d.ts +12 -12
  214. package/dist/tempo/internal/fee-payer.d.ts.map +1 -1
  215. package/dist/tempo/internal/fee-payer.js.map +1 -1
  216. package/dist/tempo/internal/proof.d.ts +17 -17
  217. package/dist/tempo/internal/proof.d.ts.map +1 -1
  218. package/dist/tempo/legacy/client/Session.d.ts +20 -20
  219. package/dist/tempo/legacy/client/Session.js.map +1 -1
  220. package/dist/tempo/legacy/client/SessionManager.js.map +1 -1
  221. package/dist/tempo/legacy/index.d.ts +1 -3
  222. package/dist/tempo/legacy/index.d.ts.map +1 -1
  223. package/dist/tempo/legacy/index.js +1 -3
  224. package/dist/tempo/legacy/index.js.map +1 -1
  225. package/dist/tempo/legacy/session/escrow.abi.d.ts +374 -374
  226. package/dist/tempo/legacy/session/escrow.abi.d.ts.map +1 -1
  227. package/dist/tempo/server/Charge.d.ts +34 -12
  228. package/dist/tempo/server/Charge.d.ts.map +1 -1
  229. package/dist/tempo/server/Charge.js +44 -39
  230. package/dist/tempo/server/Charge.js.map +1 -1
  231. package/dist/tempo/server/Methods.d.ts +37 -52
  232. package/dist/tempo/server/Methods.d.ts.map +1 -1
  233. package/dist/tempo/server/Methods.js +0 -14
  234. package/dist/tempo/server/Methods.js.map +1 -1
  235. package/dist/tempo/server/Relay.d.ts +14 -5
  236. package/dist/tempo/server/Relay.d.ts.map +1 -1
  237. package/dist/tempo/server/Relay.js +6 -4
  238. package/dist/tempo/server/Relay.js.map +1 -1
  239. package/dist/tempo/server/SponsorBudget.d.ts.map +1 -1
  240. package/dist/tempo/server/SponsorBudget.js +7 -1
  241. package/dist/tempo/server/SponsorBudget.js.map +1 -1
  242. package/dist/tempo/server/Subscription.d.ts +25 -25
  243. package/dist/tempo/server/Subscription.d.ts.map +1 -1
  244. package/dist/tempo/server/Subscription.js +2 -0
  245. package/dist/tempo/server/Subscription.js.map +1 -1
  246. package/dist/tempo/server/index.d.ts +1 -1
  247. package/dist/tempo/server/index.d.ts.map +1 -1
  248. package/dist/tempo/server/index.js +1 -1
  249. package/dist/tempo/server/index.js.map +1 -1
  250. package/dist/tempo/server/internal/html.gen.d.ts +1 -1
  251. package/dist/tempo/server/internal/html.gen.d.ts.map +1 -1
  252. package/dist/tempo/server/internal/html.gen.js +1 -1
  253. package/dist/tempo/server/internal/html.gen.js.map +1 -1
  254. package/dist/tempo/server/internal/transport.d.ts +2 -0
  255. package/dist/tempo/server/internal/transport.d.ts.map +1 -1
  256. package/dist/tempo/server/internal/transport.js +9 -2
  257. package/dist/tempo/server/internal/transport.js.map +1 -1
  258. package/dist/tempo/session/client/ChannelOps.js.map +1 -1
  259. package/dist/tempo/session/client/CredentialState.d.ts +1 -1
  260. package/dist/tempo/session/client/CredentialState.js.map +1 -1
  261. package/dist/tempo/session/client/ReceiptCoordinator.js.map +1 -1
  262. package/dist/tempo/session/client/Runtime.js.map +1 -1
  263. package/dist/tempo/session/client/Session.d.ts +19 -19
  264. package/dist/tempo/session/client/Session.d.ts.map +1 -1
  265. package/dist/tempo/session/client/Session.js +128 -14
  266. package/dist/tempo/session/client/Session.js.map +1 -1
  267. package/dist/tempo/session/client/SessionManager.d.ts.map +1 -1
  268. package/dist/tempo/session/client/SessionManager.js +62 -20
  269. package/dist/tempo/session/client/SessionManager.js.map +1 -1
  270. package/dist/tempo/session/client/Transports.d.ts +9 -1
  271. package/dist/tempo/session/client/Transports.d.ts.map +1 -1
  272. package/dist/tempo/session/client/Transports.js +36 -13
  273. package/dist/tempo/session/client/Transports.js.map +1 -1
  274. package/dist/tempo/session/precompile/Chain.d.ts +27 -0
  275. package/dist/tempo/session/precompile/Chain.d.ts.map +1 -1
  276. package/dist/tempo/session/precompile/Chain.js +68 -7
  277. package/dist/tempo/session/precompile/Chain.js.map +1 -1
  278. package/dist/tempo/session/precompile/Protocol.js.map +1 -1
  279. package/dist/tempo/session/precompile/Voucher.d.ts +4 -4
  280. package/dist/tempo/session/precompile/Voucher.d.ts.map +1 -1
  281. package/dist/tempo/session/precompile/escrow.abi.d.ts +306 -306
  282. package/dist/tempo/session/precompile/escrow.abi.d.ts.map +1 -1
  283. package/dist/tempo/session/server/ChannelStore.d.ts +9 -0
  284. package/dist/tempo/session/server/ChannelStore.d.ts.map +1 -1
  285. package/dist/tempo/session/server/ChannelStore.js +16 -8
  286. package/dist/tempo/session/server/ChannelStore.js.map +1 -1
  287. package/dist/tempo/session/server/CredentialVerification.d.ts +30 -13
  288. package/dist/tempo/session/server/CredentialVerification.d.ts.map +1 -1
  289. package/dist/tempo/session/server/CredentialVerification.js +207 -13
  290. package/dist/tempo/session/server/CredentialVerification.js.map +1 -1
  291. package/dist/tempo/session/server/MeteredStream.d.ts +3 -0
  292. package/dist/tempo/session/server/MeteredStream.d.ts.map +1 -1
  293. package/dist/tempo/session/server/MeteredStream.js +3 -1
  294. package/dist/tempo/session/server/MeteredStream.js.map +1 -1
  295. package/dist/tempo/session/server/Session.d.ts +32 -21
  296. package/dist/tempo/session/server/Session.d.ts.map +1 -1
  297. package/dist/tempo/session/server/Session.js +116 -53
  298. package/dist/tempo/session/server/Session.js.map +1 -1
  299. package/dist/tempo/session/server/Sse.d.ts +3 -1
  300. package/dist/tempo/session/server/Sse.d.ts.map +1 -1
  301. package/dist/tempo/session/server/Sse.js +2 -1
  302. package/dist/tempo/session/server/Sse.js.map +1 -1
  303. package/dist/tempo/session/server/Transports.d.ts +1 -1
  304. package/dist/tempo/session/server/Transports.d.ts.map +1 -1
  305. package/dist/tempo/session/server/Transports.js +1 -0
  306. package/dist/tempo/session/server/Transports.js.map +1 -1
  307. package/dist/tempo/session/server/Ws.d.ts +6 -1
  308. package/dist/tempo/session/server/Ws.d.ts.map +1 -1
  309. package/dist/tempo/session/server/Ws.js +4 -0
  310. package/dist/tempo/session/server/Ws.js.map +1 -1
  311. package/dist/tempo/subscription/KeyAuthorization.d.ts +38 -866
  312. package/dist/tempo/subscription/KeyAuthorization.d.ts.map +1 -1
  313. package/dist/tempo/subscription/KeyAuthorization.js +14 -3
  314. package/dist/tempo/subscription/KeyAuthorization.js.map +1 -1
  315. package/dist/viem/Account.d.ts.map +1 -1
  316. package/dist/viem/Account.js.map +1 -1
  317. package/dist/viem/Client.d.ts.map +1 -1
  318. package/dist/viem/Client.js +6 -1
  319. package/dist/viem/Client.js.map +1 -1
  320. package/dist/web-bot-auth/Constants.d.ts +20 -0
  321. package/dist/web-bot-auth/Constants.d.ts.map +1 -0
  322. package/dist/web-bot-auth/Constants.js +24 -0
  323. package/dist/web-bot-auth/Constants.js.map +1 -0
  324. package/dist/web-bot-auth/Types.d.ts +10 -0
  325. package/dist/web-bot-auth/Types.d.ts.map +1 -0
  326. package/dist/web-bot-auth/Types.js +2 -0
  327. package/dist/web-bot-auth/Types.js.map +1 -0
  328. package/dist/web-bot-auth/client/index.d.ts +29 -0
  329. package/dist/web-bot-auth/client/index.d.ts.map +1 -0
  330. package/dist/web-bot-auth/client/index.js +64 -0
  331. package/dist/web-bot-auth/client/index.js.map +1 -0
  332. package/dist/web-bot-auth/index.d.ts +7 -0
  333. package/dist/web-bot-auth/index.d.ts.map +1 -0
  334. package/dist/web-bot-auth/index.js +7 -0
  335. package/dist/web-bot-auth/index.js.map +1 -0
  336. package/dist/web-bot-auth/internal/JwkThumbprint.d.ts +5 -0
  337. package/dist/web-bot-auth/internal/JwkThumbprint.d.ts.map +1 -0
  338. package/dist/web-bot-auth/internal/JwkThumbprint.js +20 -0
  339. package/dist/web-bot-auth/internal/JwkThumbprint.js.map +1 -0
  340. package/dist/web-bot-auth/internal/SignatureAgent.d.ts +3 -0
  341. package/dist/web-bot-auth/internal/SignatureAgent.d.ts.map +1 -0
  342. package/dist/web-bot-auth/internal/SignatureAgent.js +18 -0
  343. package/dist/web-bot-auth/internal/SignatureAgent.js.map +1 -0
  344. package/dist/web-bot-auth/server/index.d.ts +35 -0
  345. package/dist/web-bot-auth/server/index.d.ts.map +1 -0
  346. package/dist/web-bot-auth/server/index.js +88 -0
  347. package/dist/web-bot-auth/server/index.js.map +1 -0
  348. package/dist/x402/Assets.d.ts.map +1 -1
  349. package/dist/x402/Types.d.ts +6 -6
  350. package/dist/x402/Types.d.ts.map +1 -1
  351. package/dist/x402/server/EvmCharge.d.ts.map +1 -1
  352. package/dist/x402/server/EvmCharge.js +32 -20
  353. package/dist/x402/server/EvmCharge.js.map +1 -1
  354. package/package.json +20 -4
  355. package/src/Challenge.fuzz.test.ts +80 -47
  356. package/src/Challenge.test.ts +65 -0
  357. package/src/Challenge.ts +39 -35
  358. package/src/Method.ts +82 -68
  359. package/src/Store.test-d.ts +16 -0
  360. package/src/Store.test.ts +50 -0
  361. package/src/Store.ts +68 -0
  362. package/src/attestation/Attestation.integration.test.ts +208 -0
  363. package/src/attestation/Client.test.ts +83 -0
  364. package/src/attestation/Client.ts +34 -0
  365. package/src/attestation/Constants.ts +15 -0
  366. package/src/attestation/Server.test.ts +60 -0
  367. package/src/attestation/Server.ts +12 -0
  368. package/src/attestation/Types.test-d.ts +54 -0
  369. package/src/attestation/Types.ts +77 -0
  370. package/src/attestation/index.ts +5 -0
  371. package/src/attestation/internal/HttpMessageSignature.test.ts +101 -0
  372. package/src/attestation/internal/HttpMessageSignature.ts +429 -0
  373. package/src/attestation/internal/SigningContext.ts +13 -0
  374. package/src/bin.js +2 -0
  375. package/src/cli/cli.ts +1 -0
  376. package/src/cli/validate/payment.ts +18 -4
  377. package/src/cli/validate.test.ts +16 -0
  378. package/src/client/Mppx.test-d.ts +17 -0
  379. package/src/client/Mppx.test.ts +14 -14
  380. package/src/client/Mppx.ts +25 -4
  381. package/src/client/Transport.test.ts +12 -45
  382. package/src/client/Transport.ts +3 -24
  383. package/src/client/internal/Fetch.test.ts +77 -0
  384. package/src/client/internal/Fetch.ts +112 -14
  385. package/src/client/internal/MethodChallenge.ts +5 -0
  386. package/src/client/internal/MethodResponse.ts +28 -0
  387. package/src/discovery/OpenApi.test.ts +170 -0
  388. package/src/discovery/OpenApi.ts +16 -48
  389. package/src/discovery/internal/Metadata.ts +51 -0
  390. package/src/evm/server/Charge.ts +6 -1
  391. package/src/internal/AcceptPayment.test.ts +12 -8
  392. package/src/internal/types.ts +9 -0
  393. package/src/mcp/client/McpClient.integration.test.ts +19 -32
  394. package/src/middlewares/elysia.test.ts +2 -12
  395. package/src/middlewares/express.test.ts +2 -12
  396. package/src/middlewares/hono.test.ts +6 -9
  397. package/src/middlewares/nextjs.test.ts +2 -12
  398. package/src/proxy/Proxy.test.ts +26 -19
  399. package/src/proxy/Proxy.ts +147 -9
  400. package/src/proxy/Proxy.upstreamError.test.ts +364 -0
  401. package/src/proxy/Service.test.ts +73 -3
  402. package/src/proxy/Service.ts +50 -23
  403. package/src/proxy/services/anthropic.ts +1 -0
  404. package/src/proxy/services/hooks.test-d.ts +14 -0
  405. package/src/proxy/services/hooks.test.ts +44 -0
  406. package/src/proxy/services/openai.ts +1 -0
  407. package/src/proxy/services/stripe.ts +1 -0
  408. package/src/server/Methods.test-d.ts +88 -0
  409. package/src/server/Methods.test.ts +69 -0
  410. package/src/server/Mppx.test-d.ts +141 -7
  411. package/src/server/Mppx.test.ts +1017 -119
  412. package/src/server/Mppx.ts +350 -54
  413. package/src/stripe/internal/constants.ts +1 -1
  414. package/src/stripe/internal/types.ts +1 -0
  415. package/src/stripe/server/Charge.test-d.ts +16 -1
  416. package/src/stripe/server/Charge.test.ts +79 -0
  417. package/src/stripe/server/Charge.ts +54 -1
  418. package/src/stripe/server/Methods.test-d.ts +157 -0
  419. package/src/stripe/server/Methods.test.ts +403 -0
  420. package/src/stripe/server/Methods.ts +423 -6
  421. package/src/stripe/server/internal/deposit-address.ts +57 -0
  422. package/src/stripe/server/internal/html/node_modules/.bin/mppx +3 -3
  423. package/src/stripe/server/internal/html/package.json +1 -1
  424. package/src/stripe/server/internal/html.gen.ts +1 -1
  425. package/src/stripe/server/internal/record-payment.ts +66 -0
  426. package/src/stripe/server/internal/request.ts +49 -0
  427. package/src/tap/Constants.ts +32 -0
  428. package/src/tap/Tap.test.ts +125 -0
  429. package/src/tap/Types.ts +11 -0
  430. package/src/tap/client/index.ts +54 -0
  431. package/src/tap/index.ts +4 -0
  432. package/src/tap/server/index.ts +48 -0
  433. package/src/tempo/PublicExports.test-d.ts +3 -3
  434. package/src/tempo/client/Charge.ts +1 -19
  435. package/src/tempo/internal/address.test.ts +42 -0
  436. package/src/tempo/internal/address.ts +3 -3
  437. package/src/tempo/internal/auto-swap.test.ts +4 -4
  438. package/src/tempo/internal/auto-swap.ts +7 -50
  439. package/src/tempo/legacy/README.md +5 -5
  440. package/src/tempo/legacy/index.ts +1 -3
  441. package/src/tempo/server/AtomicStore.test-d.ts +13 -0
  442. package/src/tempo/server/Charge.test.ts +19 -84
  443. package/src/tempo/server/Charge.ts +92 -56
  444. package/src/tempo/server/Methods.ts +0 -20
  445. package/src/tempo/server/Relay.test.ts +161 -7
  446. package/src/tempo/server/Relay.ts +15 -6
  447. package/src/tempo/server/SponsorBudget.test.ts +29 -0
  448. package/src/tempo/server/SponsorBudget.ts +7 -1
  449. package/src/tempo/server/Subscription.ts +4 -1
  450. package/src/tempo/server/index.ts +1 -1
  451. package/src/tempo/server/internal/html/node_modules/.bin/mppx +3 -3
  452. package/src/tempo/server/internal/html/package.json +1 -1
  453. package/src/tempo/server/internal/html.gen.ts +1 -1
  454. package/src/tempo/server/internal/transport.test.ts +22 -3
  455. package/src/tempo/server/internal/transport.ts +15 -3
  456. package/src/tempo/session/README.md +119 -0
  457. package/src/tempo/session/client/Session.test.ts +299 -33
  458. package/src/tempo/session/client/Session.ts +152 -16
  459. package/src/tempo/session/client/SessionManager.test.ts +216 -9
  460. package/src/tempo/session/client/SessionManager.ts +63 -17
  461. package/src/tempo/session/client/Transports.test.ts +22 -0
  462. package/src/tempo/session/client/Transports.ts +58 -22
  463. package/src/tempo/session/precompile/Chain.ts +131 -11
  464. package/src/tempo/session/server/ChannelStore.ts +33 -12
  465. package/src/tempo/session/server/CredentialVerification.test.ts +4 -4
  466. package/src/tempo/session/server/CredentialVerification.ts +340 -28
  467. package/src/tempo/session/server/MeteredStream.ts +5 -1
  468. package/src/tempo/session/server/Session.test.ts +483 -36
  469. package/src/tempo/session/server/Session.ts +159 -60
  470. package/src/tempo/session/server/Sse.test.ts +77 -0
  471. package/src/tempo/session/server/Sse.ts +8 -1
  472. package/src/tempo/session/server/Transports.ts +2 -1
  473. package/src/tempo/session/server/Ws.test.ts +171 -0
  474. package/src/tempo/session/server/Ws.ts +10 -1
  475. package/src/tempo/subscription/KeyAuthorization.test.ts +70 -1
  476. package/src/tempo/subscription/KeyAuthorization.ts +14 -3
  477. package/src/viem/Client.test.ts +18 -1
  478. package/src/viem/Client.ts +7 -1
  479. package/src/web-bot-auth/Constants.ts +24 -0
  480. package/src/web-bot-auth/Types.ts +9 -0
  481. package/src/web-bot-auth/WebBotAuth.test.ts +182 -0
  482. package/src/web-bot-auth/client/index.ts +84 -0
  483. package/src/web-bot-auth/index.ts +6 -0
  484. package/src/web-bot-auth/internal/JwkThumbprint.ts +21 -0
  485. package/src/web-bot-auth/internal/SignatureAgent.ts +18 -0
  486. package/src/web-bot-auth/server/index.ts +113 -0
  487. package/src/x402/Exact.e2e.test.ts +121 -81
  488. package/src/x402/Exact.localnet.test.ts +1 -1
  489. package/src/x402/server/EvmCharge.ts +35 -19
  490. package/dist/tempo/legacy/server/Session.d.ts +0 -208
  491. package/dist/tempo/legacy/server/Session.d.ts.map +0 -1
  492. package/dist/tempo/legacy/server/Session.js +0 -698
  493. package/dist/tempo/legacy/server/Session.js.map +0 -1
  494. package/dist/tempo/legacy/server/index.d.ts +0 -5
  495. package/dist/tempo/legacy/server/index.d.ts.map +0 -1
  496. package/dist/tempo/legacy/server/index.js +0 -5
  497. package/dist/tempo/legacy/server/index.js.map +0 -1
  498. package/dist/tempo/legacy/session/ChannelStore.d.ts +0 -22
  499. package/dist/tempo/legacy/session/ChannelStore.d.ts.map +0 -1
  500. package/dist/tempo/legacy/session/ChannelStore.js +0 -6
  501. package/dist/tempo/legacy/session/ChannelStore.js.map +0 -1
  502. package/src/tempo/legacy/server/Defaults.test-d.ts +0 -9
  503. package/src/tempo/legacy/server/Session.test.ts +0 -6370
  504. package/src/tempo/legacy/server/Session.ts +0 -1024
  505. package/src/tempo/legacy/server/index.ts +0 -4
  506. package/src/tempo/legacy/session/ChannelStore.test.ts +0 -58
  507. package/src/tempo/legacy/session/ChannelStore.ts +0 -39
@@ -0,0 +1,42 @@
1
+ import { TempoAddress } from 'ox/tempo'
2
+ import { describe, expect, test } from 'vp/test'
3
+
4
+ import { isEqual } from './address.js'
5
+
6
+ const address = '0x742d35Cc6634C0532925a3b844Bc9e7595F2bD28'
7
+ const otherAddress = '0x52908400098527886E0F7030069857D2E4169EE7'
8
+
9
+ describe('isEqual', () => {
10
+ const representations = [
11
+ { name: 'mixed-case hex', value: address },
12
+ { name: 'lowercase hex', value: address.toLowerCase() as `0x${string}` },
13
+ { name: 'Tempo-formatted', value: TempoAddress.format(address) },
14
+ ] as const
15
+
16
+ const otherRepresentations = [
17
+ { name: 'mixed-case hex', value: otherAddress },
18
+ { name: 'lowercase hex', value: otherAddress.toLowerCase() as `0x${string}` },
19
+ { name: 'Tempo-formatted', value: TempoAddress.format(otherAddress) },
20
+ ] as const
21
+
22
+ test.each([
23
+ ...representations.flatMap((a) =>
24
+ representations.map((b) => ({
25
+ a: a.value,
26
+ b: b.value,
27
+ expected: true,
28
+ name: `${a.name} and ${b.name} representations of the same address`,
29
+ })),
30
+ ),
31
+ ...representations.flatMap((a) =>
32
+ otherRepresentations.map((b) => ({
33
+ a: a.value,
34
+ b: b.value,
35
+ expected: false,
36
+ name: `${a.name} and ${b.name} representations of different addresses`,
37
+ })),
38
+ ),
39
+ ])('$name', ({ a, b, expected }) => {
40
+ expect(isEqual(a, b)).toBe(expected)
41
+ })
42
+ })
@@ -1,6 +1,6 @@
1
- // TODO: Add `isEqual` to `TempoAddress`.
2
- import type { TempoAddress } from 'ox/tempo'
1
+ import { TempoAddress } from 'ox/tempo'
3
2
 
3
+ /** Returns whether two hex or Tempo-formatted addresses resolve to the same address. */
4
4
  export function isEqual(a: TempoAddress.Address, b: TempoAddress.Address) {
5
- return a.toLowerCase() === b.toLowerCase()
5
+ return TempoAddress.resolve(a).toLowerCase() === TempoAddress.resolve(b).toLowerCase()
6
6
  }
@@ -103,7 +103,7 @@ describe('resolve', () => {
103
103
  })
104
104
 
105
105
  describe('findCalls', () => {
106
- test('passes the client to viem 2.54 Tempo token call builders', async () => {
106
+ test('uses current viem Tempo call builder signatures', async () => {
107
107
  vi.resetModules()
108
108
  const account = '0x1111111111111111111111111111111111111111' as Address
109
109
  const tokenOut = '0x2222222222222222222222222222222222222222' as Address
@@ -122,8 +122,8 @@ describe('findCalls', () => {
122
122
  return { kind: 'approve' }
123
123
  }
124
124
 
125
- function buyCall(client: unknown, parameters: Record<string, unknown>) {
126
- builderCalls.push({ client, name: 'buy', parameters })
125
+ function buyCall(parameters: Record<string, unknown>) {
126
+ builderCalls.push({ client: undefined, name: 'buy', parameters })
127
127
  return { kind: 'buy' }
128
128
  }
129
129
 
@@ -158,7 +158,7 @@ describe('findCalls', () => {
158
158
  })
159
159
 
160
160
  expect(calls).toHaveLength(2)
161
- expect(builderCalls.map((call) => call.client)).toEqual([client, client, client, client])
161
+ expect(builderCalls.map((call) => call.client)).toEqual([client, client, client, undefined])
162
162
  expect(builderCalls.map((call) => call.name)).toEqual([
163
163
  'getBalance',
164
164
  'getBalance',
@@ -1,7 +1,6 @@
1
1
  import type { Address, Client } from 'viem'
2
2
  import { readContract } from 'viem/actions'
3
3
  import { Actions, Addresses } from 'viem/tempo'
4
- import type { dex as viem_dex, token as viem_token } from 'viem/tempo/actions'
5
4
 
6
5
  import * as TempoAddress from './address.js'
7
6
  import * as defaults from './defaults.js'
@@ -15,51 +14,6 @@ export const defaultCurrencies: readonly Address[] = [
15
14
  defaults.tokens.usdc as Address,
16
15
  ]
17
16
 
18
- // TODO: Remove once the minimum viem version is >=2.54.0, which uses client-first Tempo call builders.
19
- function getBalanceCall(
20
- client: Client,
21
- parameters: viem_token.getBalance.Args,
22
- ): ReturnType<typeof viem_token.getBalance.call> {
23
- const call = Actions.token.getBalance.call as unknown as {
24
- length: number
25
- (parameters: viem_token.getBalance.Args): ReturnType<typeof viem_token.getBalance.call>
26
- (
27
- client: Client,
28
- parameters: viem_token.getBalance.Args,
29
- ): ReturnType<typeof viem_token.getBalance.call>
30
- }
31
- return call.length >= 2 ? call(client, parameters) : call(parameters)
32
- }
33
-
34
- // TODO: Remove once the minimum viem version is >=2.54.0, which uses client-first Tempo call builders.
35
- function getApproveCall(
36
- client: Client,
37
- parameters: viem_token.approve.Args,
38
- ): ReturnType<typeof viem_token.approve.call> {
39
- const call = Actions.token.approve.call as unknown as {
40
- length: number
41
- (parameters: viem_token.approve.Args): ReturnType<typeof viem_token.approve.call>
42
- (
43
- client: Client,
44
- parameters: viem_token.approve.Args,
45
- ): ReturnType<typeof viem_token.approve.call>
46
- }
47
- return call.length >= 2 ? call(client, parameters) : call(parameters)
48
- }
49
-
50
- // TODO: Remove once the minimum viem version is >=2.54.0, which uses client-first Tempo call builders.
51
- function getBuyCall(
52
- client: Client,
53
- parameters: viem_dex.buy.Args,
54
- ): ReturnType<typeof viem_dex.buy.call> {
55
- const call = Actions.dex.buy.call as unknown as {
56
- length: number
57
- (parameters: viem_dex.buy.Args): ReturnType<typeof viem_dex.buy.call>
58
- (client: Client, parameters: viem_dex.buy.Args): ReturnType<typeof viem_dex.buy.call>
59
- }
60
- return call.length >= 2 ? call(client, parameters) : call(parameters)
61
- }
62
-
63
17
  /**
64
18
  * Finds the optimal swap calls to acquire `amountOut` of `tokenOut`,
65
19
  * returning an approve + buy call sequence if a viable route is found.
@@ -76,9 +30,12 @@ export async function findCalls(
76
30
  const candidates = tokenIn.filter((t) => !TempoAddress.isEqual(t, tokenOut))
77
31
 
78
32
  const balanceResults = await Promise.allSettled([
79
- readContract(client, getBalanceCall(client, { account, token: tokenOut }) as never),
33
+ readContract(
34
+ client,
35
+ Actions.token.getBalance.call(client, { account, token: tokenOut }) as never,
36
+ ),
80
37
  ...candidates.map((t) =>
81
- readContract(client, getBalanceCall(client, { account, token: t }) as never),
38
+ readContract(client, Actions.token.getBalance.call(client, { account, token: t }) as never),
82
39
  ),
83
40
  ])
84
41
 
@@ -108,12 +65,12 @@ export async function findCalls(
108
65
  const maxAmountIn =
109
66
  quotedAmountIn + (quotedAmountIn * BigInt(Math.round(slippage * 100))) / bps
110
67
  return [
111
- getApproveCall(client, {
68
+ Actions.token.approve.call(client, {
112
69
  amount: maxAmountIn,
113
70
  spender: Addresses.stablecoinDex,
114
71
  token: tokenIn,
115
72
  }),
116
- getBuyCall(client, {
73
+ Actions.dex.buy.call({
117
74
  tokenIn,
118
75
  tokenOut,
119
76
  amountOut,
@@ -1,9 +1,9 @@
1
1
  # Tempo Legacy Session
2
2
 
3
- This directory contains the legacy smart-contract-backed `tempo/session`
4
- implementation.
3
+ This directory contains the retained client for the legacy smart-contract-backed
4
+ `tempo/session` implementation.
5
5
 
6
6
  The default `tempo.session` implementation is TIP-1034 precompile-backed and
7
- lives under `src/tempo/session/precompile`. Legacy code may import shared transport and
8
- accounting helpers from `src/tempo/session`, but legacy chain, channel, voucher,
9
- client, and server implementations should stay inside this directory.
7
+ lives under `src/tempo/session/precompile`. The legacy server implementation has
8
+ been removed, while legacy chain, channel, voucher, and client code remains here
9
+ for clients migrating existing sessions.
@@ -1,6 +1,4 @@
1
1
  /** Legacy contract-backed session client surface. */
2
2
  export * as Client from './client/index.js'
3
- /** Legacy contract-backed session server surface. */
4
- export * as Server from './server/index.js'
5
- /** Legacy contract-backed session channel primitives. */
3
+ /** Legacy contract-backed session channel primitives used by the client. */
6
4
  export * as Session from './session/index.js'
@@ -19,6 +19,19 @@ test('tempo.charge store parameter requires AtomicStore', () => {
19
19
  tempo.charge({ store: Store.memory() })
20
20
  })
21
21
 
22
+ test('tempo.charge sponsor budget store requires AtomicStore', () => {
23
+ const nonAtomic = Store.from({
24
+ get: async () => null,
25
+ put: async () => {},
26
+ delete: async () => {},
27
+ })
28
+
29
+ tempo.charge({ sponsorBudget: false })
30
+ // @ts-expect-error — sponsor budget coordination requires AtomicStore
31
+ tempo.charge({ sponsorBudget: { store: nonAtomic } })
32
+ tempo.charge({ sponsorBudget: { store: Store.memory() } })
33
+ })
34
+
22
35
  test('tempo.session store parameter requires AtomicStore', () => {
23
36
  type SessionParameters = NonNullable<Parameters<typeof tempo.session>[0]>
24
37
  expectTypeOf<SessionParameters['store']>().toEqualTypeOf<Store.AtomicStore | undefined>()
@@ -16,12 +16,6 @@ import { Abis, Account, Actions, Addresses, Secp256k1, Tick, Transaction } from
16
16
  import type { token as viem_token } from 'viem/tempo/actions'
17
17
  import { beforeAll, describe, expect, test } from 'vp/test'
18
18
  import * as Http from '~test/Http.js'
19
- import {
20
- closeChannelOnChain,
21
- deployEscrow,
22
- openChannel,
23
- signVoucher,
24
- } from '~test/tempo/legacy/session.js'
25
19
  import { accounts, asset, chain, client, fundAccount, http } from '~test/tempo/viem.js'
26
20
 
27
21
  import * as Store from '../../Store.js'
@@ -58,18 +52,8 @@ function sponsoredFeeExposure(credential: string) {
58
52
  return transaction.gas * transaction.maxFeePerGas
59
53
  }
60
54
 
61
- // TODO: Remove once the minimum viem version is >=2.54.0, which uses client-first Tempo call builders.
62
55
  function tokenTransferCall(parameters: viem_token.transfer.Args) {
63
- const call = Actions.token.transfer.call as unknown as {
64
- length: number
65
- (parameters: viem_token.transfer.Args): ReturnType<typeof viem_token.transfer.call>
66
- (
67
- client: unknown,
68
- parameters: viem_token.transfer.Args,
69
- ): ReturnType<typeof viem_token.transfer.call>
70
- }
71
- if (call.length >= 2) return call(client, parameters)
72
- return call(parameters)
56
+ return Actions.token.transfer.call(client, parameters)
73
57
  }
74
58
 
75
59
  type ProofAccessKeyContext = {
@@ -92,6 +76,21 @@ const server = Mppx_server.create({
92
76
  })
93
77
 
94
78
  describe('tempo', () => {
79
+ describe('sponsor budget configuration', () => {
80
+ test('validates structured limits', () => {
81
+ expect(() => tempo_server.charge({ sponsorBudget: { maxInFlightReservations: 0 } })).toThrow(
82
+ '`sponsorBudget.maxInFlightReservations` must be a positive safe integer.',
83
+ )
84
+ expect(() => tempo_server.charge({ sponsorBudget: { maxInFlightTotalFee: 0n } })).toThrow(
85
+ '`sponsorBudget.maxInFlightTotalFee` must be greater than zero.',
86
+ )
87
+ })
88
+
89
+ test('allows aggregate exposure to be enforced externally', () => {
90
+ expect(() => tempo_server.charge({ sponsorBudget: false })).not.toThrow()
91
+ })
92
+ })
93
+
95
94
  describe('intent: charge; type: hash', () => {
96
95
  test('default', async () => {
97
96
  const mppx = Mppx_client.create({
@@ -581,72 +580,6 @@ describe('tempo', () => {
581
580
  httpServer.close()
582
581
  })
583
582
 
584
- test('behavior: rejects session settlement tx hash used as charge credential', async () => {
585
- const chargeAmount = parseUnits('1', 6)
586
- const recipient = accounts[0].address
587
- const external = accounts[3]
588
-
589
- const escrow = await deployEscrow()
590
-
591
- await fundAccount({ address: external.address, token: Addresses.pathUsd })
592
- await fundAccount({ address: external.address, token: asset })
593
-
594
- const salt = '0x0000000000000000000000000000000000000000000000000000000000000001' as Hex.Hex
595
- const { channelId } = await openChannel({
596
- escrow,
597
- payer: external,
598
- payee: recipient,
599
- token: asset,
600
- deposit: chargeAmount,
601
- salt,
602
- })
603
-
604
- const voucherSig = await signVoucher(
605
- client,
606
- external,
607
- { channelId, cumulativeAmount: chargeAmount },
608
- escrow,
609
- chain.id,
610
- )
611
-
612
- const { txHash: settleTxHash } = await closeChannelOnChain({
613
- escrow,
614
- payee: accounts[0],
615
- channelId,
616
- cumulativeAmount: chargeAmount,
617
- signature: voucherSig,
618
- })
619
-
620
- const httpServer = await Http.createServer(async (req, res) => {
621
- const result = await Mppx_server.toNodeListener(server.charge({ amount: '1' }))(req, res)
622
- if (result.status === 402) return
623
- res.end('OK')
624
- })
625
-
626
- const response = await fetch(httpServer.url)
627
- expect(response.status).toBe(402)
628
-
629
- const challenge = Challenge.fromResponse(response, {
630
- methods: [tempo_client.charge()],
631
- })
632
-
633
- const credential = Credential.from({
634
- challenge,
635
- payload: { hash: settleTxHash, type: 'hash' as const },
636
- })
637
-
638
- {
639
- const response = await fetch(httpServer.url, {
640
- headers: { Authorization: Credential.serialize(credential) },
641
- })
642
- expect(response.status).toBe(402)
643
- const body = (await response.json()) as { detail: string }
644
- expect(body.detail).toContain('Payment verification failed: no matching transfer found.')
645
- }
646
-
647
- httpServer.close()
648
- })
649
-
650
583
  test('behavior: rejects replayed transaction hash', async () => {
651
584
  const dedupServer = Mppx_server.create({
652
585
  methods: [
@@ -1976,6 +1909,7 @@ describe('tempo', () => {
1976
1909
  }),
1977
1910
  })
1978
1911
 
1912
+ const replayStore = Store.memory()
1979
1913
  const sponsoredStore = Store.memory()
1980
1914
  const serverWithSlowSimulation = Mppx_server.create({
1981
1915
  methods: [
@@ -1985,7 +1919,8 @@ describe('tempo', () => {
1985
1919
  },
1986
1920
  currency: asset,
1987
1921
  account: accounts[0],
1988
- store: sponsoredStore,
1922
+ sponsorBudget: { store: sponsoredStore },
1923
+ store: replayStore,
1989
1924
  storeKeyPrefix: 'tenant:',
1990
1925
  }),
1991
1926
  ],
@@ -67,6 +67,7 @@ export function charge<const parameters extends charge.Parameters>(
67
67
  html,
68
68
  memo,
69
69
  relay,
70
+ sponsorBudget,
70
71
  splits,
71
72
  supportedModes,
72
73
  validateSender,
@@ -75,21 +76,31 @@ export function charge<const parameters extends charge.Parameters>(
75
76
  const storeKeyPrefix = parameters.storeKeyPrefix ?? ''
76
77
  const rawStore = (parameters.store ?? Store.memory()) as Store.AtomicStore<charge.StoreItemMap>
77
78
  const store = Store.from(rawStore, { keyPrefix: storeKeyPrefix })
78
- // Aggregate exposure belongs to the actual sponsor, not a caller-specific
79
- // replay namespace. Sharing the raw store gives every tenant/process the same
80
- // atomic sponsor-wide budget.
81
- const sponsorBudgetStore = Store.from(rawStore) as Store.AtomicStore<{
82
- [key: `mppx:charge:sponsor-budget:${string}`]: SponsorBudget.State
83
- }>
84
79
  const {
85
- maxInFlightReservations = 100,
86
- maxInFlightTotalFee = (feePayerPolicy?.maxTotalFee ?? 50_000_000_000_000_000n) * 10n,
80
+ maxInFlightReservations: legacyMaxInFlightReservations,
81
+ maxInFlightTotalFee: legacyMaxInFlightTotalFee,
87
82
  ...transactionFeePayerPolicy
88
83
  } = feePayerPolicy ?? {}
89
- if (!Number.isSafeInteger(maxInFlightReservations) || maxInFlightReservations <= 0)
90
- throw new Error('`feePayerPolicy.maxInFlightReservations` must be a positive safe integer.')
91
- if (maxInFlightTotalFee <= 0n)
92
- throw new Error('`feePayerPolicy.maxInFlightTotalFee` must be greater than zero.')
84
+ const sponsorBudgetConfig = sponsorBudget === false ? undefined : (sponsorBudget ?? {})
85
+ const maxInFlightReservations =
86
+ sponsorBudgetConfig?.maxInFlightReservations ?? legacyMaxInFlightReservations ?? 100
87
+ const maxInFlightTotalFee =
88
+ sponsorBudgetConfig?.maxInFlightTotalFee ??
89
+ legacyMaxInFlightTotalFee ??
90
+ (feePayerPolicy?.maxTotalFee ?? 50_000_000_000_000_000n) * 10n
91
+ if (sponsorBudgetConfig) {
92
+ if (!Number.isSafeInteger(maxInFlightReservations) || maxInFlightReservations <= 0)
93
+ throw new Error('`sponsorBudget.maxInFlightReservations` must be a positive safe integer.')
94
+ if (maxInFlightTotalFee <= 0n)
95
+ throw new Error('`sponsorBudget.maxInFlightTotalFee` must be greater than zero.')
96
+ }
97
+ // Aggregate exposure belongs to the actual sponsor, not a caller-specific replay namespace.
98
+ // Keep it unprefixed and shared across every tenant/process using the sponsor.
99
+ const sponsorBudgetStore = sponsorBudgetConfig
100
+ ? (Store.from(sponsorBudgetConfig.store ?? rawStore) as Store.AtomicStore<{
101
+ [key: `mppx:charge:sponsor-budget:${string}`]: SponsorBudget.State
102
+ }>)
103
+ : undefined
93
104
  const proofStore = parameters.store
94
105
  ? Store.from(parameters.store as Store.AtomicStore<charge.StoreItemMap>, {
95
106
  keyPrefix: storeKeyPrefix,
@@ -360,6 +371,8 @@ export function charge<const parameters extends charge.Parameters>(
360
371
 
361
372
  type Defaults = charge.DeriveDefaults<parameters>
362
373
  const method = Method.toServer<typeof Methods.charge, Defaults>(Methods.charge, {
374
+ canOffer: parameters.canOffer,
375
+ onPaymentSuccess: parameters.onPaymentSuccess,
363
376
  defaults: {
364
377
  amount,
365
378
  currency,
@@ -475,11 +488,13 @@ export function charge<const parameters extends charge.Parameters>(
475
488
  : feePayer
476
489
  : undefined
477
490
  const expires = challenge.expires
491
+ Expires.assert(expires, challenge.id)
492
+ const replayExpires = Date.parse(expires)
478
493
 
479
494
  switch (validated.type) {
480
495
  case 'hash': {
481
496
  const { hash, receipt } = validated
482
- if (!(await markHashUsed(store, hash))) {
497
+ if (!(await tryClaimHash(store, hash, replayExpires))) {
483
498
  throw new VerificationFailedError({
484
499
  reason: 'Transaction hash has already been used',
485
500
  })
@@ -488,7 +503,7 @@ export function charge<const parameters extends charge.Parameters>(
488
503
  }
489
504
 
490
505
  case 'proof': {
491
- if (proofStore && !(await markProofUsed(proofStore, challenge.id))) {
506
+ if (proofStore && !(await tryClaimProof(proofStore, challenge.id, replayExpires))) {
492
507
  throw new VerificationFailedError({
493
508
  reason: 'Proof credential has already been used',
494
509
  })
@@ -507,7 +522,7 @@ export function charge<const parameters extends charge.Parameters>(
507
522
 
508
523
  // Pre-broadcast dedup: catch exact byte-for-byte replays early.
509
524
  const hash = keccak256(serializedTransaction)
510
- if (!(await markHashUsed(store, hash))) {
525
+ if (!(await tryClaimHash(store, hash, replayExpires))) {
511
526
  throw new VerificationFailedError({
512
527
  reason: 'Transaction hash has already been used',
513
528
  })
@@ -589,7 +604,7 @@ export function charge<const parameters extends charge.Parameters>(
589
604
 
590
605
  if (
591
606
  finalHash.toLowerCase() !== hash.toLowerCase() &&
592
- !(await markHashUsed(store, finalHash))
607
+ !(await tryClaimHash(store, finalHash, replayExpires))
593
608
  )
594
609
  throw new VerificationFailedError({
595
610
  reason: 'Transaction hash has already been used',
@@ -614,20 +629,21 @@ export function charge<const parameters extends charge.Parameters>(
614
629
  expiresAt,
615
630
  expires ? Date.parse(expires) : Number.MAX_SAFE_INTEGER,
616
631
  )
617
- reservation = await SponsorBudget.reserve(sponsorBudgetStore, {
618
- chainId: reservationChainId,
619
- expiresAt,
620
- fee: totalFee,
621
- getReceipt: (transactionHash) =>
622
- getTransactionReceipt(client, { hash: transactionHash }),
623
- id: finalHash.toLowerCase(),
624
- maxReservations: maxInFlightReservations,
625
- maxTotalFee: maxInFlightTotalFee,
626
- owner: globalThis.crypto.randomUUID(),
627
- sponsor,
628
- transactionHash: finalHash,
629
- waitUntil,
630
- })
632
+ if (sponsorBudgetStore)
633
+ reservation = await SponsorBudget.reserve(sponsorBudgetStore, {
634
+ chainId: reservationChainId,
635
+ expiresAt,
636
+ fee: totalFee,
637
+ getReceipt: (transactionHash) =>
638
+ getTransactionReceipt(client, { hash: transactionHash }),
639
+ id: finalHash.toLowerCase(),
640
+ maxReservations: maxInFlightReservations,
641
+ maxTotalFee: maxInFlightTotalFee,
642
+ owner: globalThis.crypto.randomUUID(),
643
+ sponsor,
644
+ transactionHash: finalHash,
645
+ waitUntil,
646
+ })
631
647
  Expires.assert(challenge.expires, challenge.id)
632
648
  }
633
649
 
@@ -640,7 +656,7 @@ export function charge<const parameters extends charge.Parameters>(
640
656
 
641
657
  if (
642
658
  reservation &&
643
- !(await SponsorBudget.transition(sponsorBudgetStore, reservation, 'broadcasting'))
659
+ !(await SponsorBudget.transition(sponsorBudgetStore!, reservation, 'broadcasting'))
644
660
  )
645
661
  throw new VerificationFailedError({
646
662
  reason: 'Sponsor budget reservation ownership was lost before broadcast',
@@ -651,7 +667,7 @@ export function charge<const parameters extends charge.Parameters>(
651
667
  const receipt = await sendRawTransactionSync(client, {
652
668
  serializedTransaction: serializedTransaction_final,
653
669
  })
654
- if (reservation) await SponsorBudget.release(sponsorBudgetStore, reservation)
670
+ if (reservation) await SponsorBudget.release(sponsorBudgetStore!, reservation)
655
671
  const matchedLogs = await assertTransferLogs(receipt, {
656
672
  currency,
657
673
  sender: transaction.from! as `0x${string}`,
@@ -681,7 +697,7 @@ export function charge<const parameters extends charge.Parameters>(
681
697
  })
682
698
  if (
683
699
  reservation &&
684
- !(await SponsorBudget.transition(sponsorBudgetStore, reservation, 'pending'))
700
+ !(await SponsorBudget.transition(sponsorBudgetStore!, reservation, 'pending'))
685
701
  )
686
702
  throw new VerificationFailedError({
687
703
  reason: 'Sponsor budget reservation ownership was lost after broadcast',
@@ -694,7 +710,7 @@ export function charge<const parameters extends charge.Parameters>(
694
710
  } as const
695
711
  } catch (error) {
696
712
  if (!broadcastAttempted) {
697
- if (reservation) await SponsorBudget.release(sponsorBudgetStore, reservation)
713
+ if (reservation) await SponsorBudget.release(sponsorBudgetStore!, reservation)
698
714
  if (finalHash && finalHash.toLowerCase() !== hash.toLowerCase())
699
715
  await releaseHashUse(store, finalHash)
700
716
  await releaseHashUse(store, hash)
@@ -710,7 +726,7 @@ export function charge<const parameters extends charge.Parameters>(
710
726
 
711
727
  export declare namespace charge {
712
728
  type StoreItemMap = {
713
- [key: `mppx:charge:${string}`]: number | SponsorBudget.State
729
+ [key: `mppx:charge:${string}`]: number | SponsorBudget.State | Store.ReplayMarker
714
730
  }
715
731
 
716
732
  type Defaults = LooseOmit<Method.RequestDefaults<typeof Methods.charge>, 'feePayer' | 'recipient'>
@@ -739,13 +755,8 @@ export declare namespace charge {
739
755
  /**
740
756
  * Override the fee-sponsor policy used when co-signing Tempo charge
741
757
  * transactions. Defaults resolve per chain, including a higher
742
- * priority-fee ceiling on Moderato and a bounded aggregate in-flight fee
743
- * budget. Sponsored transactions reserve their declared maximum fee
744
- * atomically; independent expiring-nonce transactions run concurrently
745
- * while capacity remains and wait for capacity when the budget is full.
746
- *
747
- * If you increase `maxGas`, `maxFeePerGas`, or `maxTotalFee`, you may also
748
- * need to raise `maxInFlightTotalFee`.
758
+ * priority-fee ceiling on Moderato. Aggregate in-flight exposure is
759
+ * configured separately with `sponsorBudget`.
749
760
  */
750
761
  feePayerPolicy?: FeePayerPolicy | undefined
751
762
  /**
@@ -785,8 +796,24 @@ export declare namespace charge {
785
796
  * By default, no prefix is applied.
786
797
  */
787
798
  storeKeyPrefix?: string | undefined
788
- /** Delegates Tempo charge credential validation and broadcast to Tempo API or a compatible MPP relay. */
799
+ /**
800
+ * Delegates Tempo charge credential validation and broadcast to Tempo API
801
+ * or a compatible MPP relay.
802
+ *
803
+ * The adapter delegates finalization to the relay for both modes. The
804
+ * relay broadcasts pull credentials, while it recognizes a push
805
+ * credential as already broadcast and returns its receipt without sending
806
+ * it again.
807
+ */
789
808
  relay?: RelayOptions | undefined
809
+ /**
810
+ * Configures aggregate in-flight fee exposure for sponsored transactions.
811
+ *
812
+ * Set to `false` only when aggregate exposure is enforced outside mppx.
813
+ * The configured store must be shared by every process using the sponsor.
814
+ * @default `{}`
815
+ */
816
+ sponsorBudget?: SponsorBudgetConfig | false | undefined
790
817
  /**
791
818
  * Whether to wait for the charge transaction to confirm on-chain before
792
819
  * responding. @default true
@@ -801,7 +828,8 @@ export declare namespace charge {
801
828
  waitForConfirmation?: boolean | undefined
802
829
  } & Client.getResolver.Parameters &
803
830
  Account.resolve.Parameters &
804
- Defaults
831
+ Defaults &
832
+ Method.ComposableHooks<typeof Methods.charge>
805
833
 
806
834
  type DeriveDefaults<parameters extends Parameters> = types.DeriveDefaults<
807
835
  parameters,
@@ -813,16 +841,28 @@ export declare namespace charge {
813
841
  >
814
842
 
815
843
  type FeePayerPolicy = Partial<FeePayer.Policy> & {
816
- /** Maximum number of sponsored transactions awaiting a terminal receipt. @default 100 */
844
+ /**
845
+ * Maximum number of sponsored transactions awaiting a terminal receipt.
846
+ * @deprecated Use `sponsorBudget.maxInFlightReservations`.
847
+ */
817
848
  maxInFlightReservations?: number | undefined
818
849
  /**
819
850
  * Maximum aggregate declared fee exposure awaiting terminal receipts.
820
851
  *
821
- * @default `maxTotalFee * 10`
852
+ * @deprecated Use `sponsorBudget.maxInFlightTotalFee`.
822
853
  */
823
854
  maxInFlightTotalFee?: bigint | undefined
824
855
  }
825
856
 
857
+ type SponsorBudgetConfig = {
858
+ /** Maximum number of sponsored transactions awaiting a terminal receipt. @default 100 */
859
+ maxInFlightReservations?: number | undefined
860
+ /** Maximum aggregate declared fee exposure. @default `feePayerPolicy.maxTotalFee * 10` */
861
+ maxInFlightTotalFee?: bigint | undefined
862
+ /** Atomic store shared by every process using the sponsor. Defaults to `store`. */
863
+ store?: Store.AtomicStore | undefined
864
+ }
865
+
826
866
  /** Tempo API relay configuration for server-side charges. */
827
867
  type RelayOptions = Relay.configure.Options
828
868
  }
@@ -1165,14 +1205,12 @@ function getProofStoreKey(challengeId: string): `mppx:charge:${string}` {
1165
1205
  return `mppx:charge:proof:${challengeId}`
1166
1206
  }
1167
1207
 
1168
- async function markHashUsed(
1208
+ async function tryClaimHash(
1169
1209
  store: Store.AtomicStore<charge.StoreItemMap>,
1170
1210
  hash: `0x${string}`,
1211
+ expires: number,
1171
1212
  ): Promise<boolean> {
1172
- return store.update(getHashStoreKey(hash), (current) => {
1173
- if (current !== null) return { op: 'noop', result: false }
1174
- return { op: 'set', value: Date.now(), result: true }
1175
- })
1213
+ return Store.tryClaim(store, getHashStoreKey(hash), expires)
1176
1214
  }
1177
1215
 
1178
1216
  /** @internal */
@@ -1199,14 +1237,12 @@ function parseHashCredentialSource(parameters: {
1199
1237
  }
1200
1238
 
1201
1239
  /** @internal */
1202
- async function markProofUsed(
1240
+ async function tryClaimProof(
1203
1241
  store: Store.AtomicStore<charge.StoreItemMap>,
1204
1242
  challengeId: string,
1243
+ expires: number,
1205
1244
  ): Promise<boolean> {
1206
- return store.update(getProofStoreKey(challengeId), (current) => {
1207
- if (current !== null) return { op: 'noop', result: false }
1208
- return { op: 'set', value: Date.now(), result: true }
1209
- })
1245
+ return Store.tryClaim(store, getProofStoreKey(challengeId), expires)
1210
1246
  }
1211
1247
 
1212
1248
  function recoverAuthorizedProofSigner(parameters: {