mppx 0.6.31 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (616) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +20 -11
  3. package/dist/Challenge.d.ts.map +1 -1
  4. package/dist/Challenge.js +27 -13
  5. package/dist/Challenge.js.map +1 -1
  6. package/dist/Constants.d.ts +46 -0
  7. package/dist/Constants.d.ts.map +1 -0
  8. package/dist/Constants.js +46 -0
  9. package/dist/Constants.js.map +1 -0
  10. package/dist/Credential.d.ts.map +1 -1
  11. package/dist/Credential.js +5 -4
  12. package/dist/Credential.js.map +1 -1
  13. package/dist/Mcp.d.ts +3 -0
  14. package/dist/Mcp.d.ts.map +1 -1
  15. package/dist/Mcp.js +2 -0
  16. package/dist/Mcp.js.map +1 -1
  17. package/dist/Method.d.ts +32 -4
  18. package/dist/Method.d.ts.map +1 -1
  19. package/dist/Method.js +5 -2
  20. package/dist/Method.js.map +1 -1
  21. package/dist/PaymentRequest.d.ts +10 -10
  22. package/dist/PaymentRequest.js +8 -8
  23. package/dist/Receipt.d.ts.map +1 -1
  24. package/dist/Receipt.js +3 -2
  25. package/dist/Receipt.js.map +1 -1
  26. package/dist/cli/cli.d.ts.map +1 -1
  27. package/dist/cli/cli.js +19 -11
  28. package/dist/cli/cli.js.map +1 -1
  29. package/dist/cli/plugins/tempo.d.ts.map +1 -1
  30. package/dist/cli/plugins/tempo.js +17 -6
  31. package/dist/cli/plugins/tempo.js.map +1 -1
  32. package/dist/cli/utils.d.ts +5 -0
  33. package/dist/cli/utils.d.ts.map +1 -1
  34. package/dist/cli/utils.js +10 -0
  35. package/dist/cli/utils.js.map +1 -1
  36. package/dist/client/Methods.d.ts +5 -2
  37. package/dist/client/Methods.d.ts.map +1 -1
  38. package/dist/client/Methods.js +5 -2
  39. package/dist/client/Methods.js.map +1 -1
  40. package/dist/client/Mppx.js +2 -2
  41. package/dist/client/Mppx.js.map +1 -1
  42. package/dist/client/Transport.d.ts +11 -16
  43. package/dist/client/Transport.d.ts.map +1 -1
  44. package/dist/client/Transport.js +55 -76
  45. package/dist/client/Transport.js.map +1 -1
  46. package/dist/client/index.d.ts +5 -1
  47. package/dist/client/index.d.ts.map +1 -1
  48. package/dist/client/index.js +3 -1
  49. package/dist/client/index.js.map +1 -1
  50. package/dist/client/internal/Fetch.d.ts.map +1 -1
  51. package/dist/client/internal/Fetch.js +60 -13
  52. package/dist/client/internal/Fetch.js.map +1 -1
  53. package/dist/client/internal/protocols/Mcp.d.ts +7 -0
  54. package/dist/client/internal/protocols/Mcp.d.ts.map +1 -0
  55. package/dist/client/internal/protocols/Mcp.js +159 -0
  56. package/dist/client/internal/protocols/Mcp.js.map +1 -0
  57. package/dist/client/internal/protocols/Mpp.d.ts +4 -0
  58. package/dist/client/internal/protocols/Mpp.d.ts.map +1 -0
  59. package/dist/client/internal/protocols/Mpp.js +18 -0
  60. package/dist/client/internal/protocols/Mpp.js.map +1 -0
  61. package/dist/client/internal/protocols/Protocol.d.ts +10 -0
  62. package/dist/client/internal/protocols/Protocol.d.ts.map +1 -0
  63. package/dist/client/internal/protocols/Protocol.js +2 -0
  64. package/dist/client/internal/protocols/Protocol.js.map +1 -0
  65. package/dist/client/internal/protocols/Shared.d.ts +5 -0
  66. package/dist/client/internal/protocols/Shared.d.ts.map +1 -0
  67. package/dist/client/internal/protocols/Shared.js +20 -0
  68. package/dist/client/internal/protocols/Shared.js.map +1 -0
  69. package/dist/client/internal/protocols/X402.d.ts +8 -0
  70. package/dist/client/internal/protocols/X402.d.ts.map +1 -0
  71. package/dist/client/internal/protocols/X402.js +39 -0
  72. package/dist/client/internal/protocols/X402.js.map +1 -0
  73. package/dist/evm/client/index.d.ts +1 -0
  74. package/dist/evm/client/index.d.ts.map +1 -1
  75. package/dist/evm/client/index.js +1 -0
  76. package/dist/evm/client/index.js.map +1 -1
  77. package/dist/evm/index.d.ts +2 -0
  78. package/dist/evm/index.d.ts.map +1 -1
  79. package/dist/evm/index.js +2 -0
  80. package/dist/evm/index.js.map +1 -1
  81. package/dist/evm/server/Methods.d.ts +1 -1
  82. package/dist/evm/server/Methods.d.ts.map +1 -1
  83. package/dist/evm/server/index.d.ts +1 -0
  84. package/dist/evm/server/index.d.ts.map +1 -1
  85. package/dist/evm/server/index.js +1 -0
  86. package/dist/evm/server/index.js.map +1 -1
  87. package/dist/index.d.ts +1 -0
  88. package/dist/index.d.ts.map +1 -1
  89. package/dist/index.js +1 -0
  90. package/dist/index.js.map +1 -1
  91. package/dist/internal/AcceptPayment.d.ts +3 -0
  92. package/dist/internal/AcceptPayment.d.ts.map +1 -1
  93. package/dist/internal/AcceptPayment.js +15 -11
  94. package/dist/internal/AcceptPayment.js.map +1 -1
  95. package/dist/mcp/client/McpClient.d.ts +101 -0
  96. package/dist/mcp/client/McpClient.d.ts.map +1 -0
  97. package/dist/mcp/client/McpClient.js +162 -0
  98. package/dist/mcp/client/McpClient.js.map +1 -0
  99. package/dist/mcp/client/index.d.ts.map +1 -0
  100. package/dist/mcp/client/index.js.map +1 -0
  101. package/dist/mcp/server/Transport.d.ts.map +1 -0
  102. package/dist/mcp/server/Transport.js.map +1 -0
  103. package/dist/mcp/server/index.d.ts.map +1 -0
  104. package/dist/mcp/server/index.js.map +1 -0
  105. package/dist/server/Mppx.d.ts +12 -4
  106. package/dist/server/Mppx.d.ts.map +1 -1
  107. package/dist/server/Mppx.js +85 -27
  108. package/dist/server/Mppx.js.map +1 -1
  109. package/dist/server/Response.d.ts.map +1 -1
  110. package/dist/server/Response.js +2 -1
  111. package/dist/server/Response.js.map +1 -1
  112. package/dist/server/Transport.d.ts +1 -1
  113. package/dist/server/Transport.d.ts.map +1 -1
  114. package/dist/server/Transport.js +5 -4
  115. package/dist/server/Transport.js.map +1 -1
  116. package/dist/server/index.d.ts +1 -0
  117. package/dist/server/index.d.ts.map +1 -1
  118. package/dist/server/index.js +1 -0
  119. package/dist/server/index.js.map +1 -1
  120. package/dist/stripe/client/Charge.d.ts +1 -1
  121. package/dist/stripe/client/Charge.d.ts.map +1 -1
  122. package/dist/stripe/client/Charge.js +3 -1
  123. package/dist/stripe/client/Charge.js.map +1 -1
  124. package/dist/stripe/server/Charge.d.ts +1 -1
  125. package/dist/stripe/server/Charge.d.ts.map +1 -1
  126. package/dist/stripe/server/Charge.js +9 -2
  127. package/dist/stripe/server/Charge.js.map +1 -1
  128. package/dist/stripe/server/Methods.d.ts +1 -1
  129. package/dist/stripe/server/Methods.d.ts.map +1 -1
  130. package/dist/stripe/server/internal/html.gen.d.ts +1 -1
  131. package/dist/stripe/server/internal/html.gen.d.ts.map +1 -1
  132. package/dist/stripe/server/internal/html.gen.js +1 -1
  133. package/dist/stripe/server/internal/html.gen.js.map +1 -1
  134. package/dist/tempo/Methods.d.ts +18 -0
  135. package/dist/tempo/Methods.d.ts.map +1 -1
  136. package/dist/tempo/Methods.js +16 -1
  137. package/dist/tempo/Methods.js.map +1 -1
  138. package/dist/tempo/Proof.d.ts +85 -1
  139. package/dist/tempo/Proof.d.ts.map +1 -1
  140. package/dist/tempo/Proof.js +35 -0
  141. package/dist/tempo/Proof.js.map +1 -1
  142. package/dist/tempo/client/Charge.d.ts +19 -1
  143. package/dist/tempo/client/Charge.d.ts.map +1 -1
  144. package/dist/tempo/client/Charge.js +47 -27
  145. package/dist/tempo/client/Charge.js.map +1 -1
  146. package/dist/tempo/client/Methods.d.ts +41 -10
  147. package/dist/tempo/client/Methods.d.ts.map +1 -1
  148. package/dist/tempo/client/Methods.js +16 -7
  149. package/dist/tempo/client/Methods.js.map +1 -1
  150. package/dist/tempo/client/ResolveAccount.d.ts +40 -0
  151. package/dist/tempo/client/ResolveAccount.d.ts.map +1 -0
  152. package/dist/tempo/client/ResolveAccount.js +2 -0
  153. package/dist/tempo/client/ResolveAccount.js.map +1 -0
  154. package/dist/tempo/client/index.d.ts +7 -4
  155. package/dist/tempo/client/index.d.ts.map +1 -1
  156. package/dist/tempo/client/index.js +5 -3
  157. package/dist/tempo/client/index.js.map +1 -1
  158. package/dist/tempo/index.d.ts +1 -0
  159. package/dist/tempo/index.d.ts.map +1 -1
  160. package/dist/tempo/index.js +1 -0
  161. package/dist/tempo/index.js.map +1 -1
  162. package/dist/tempo/internal/fee-payer.d.ts +29 -1
  163. package/dist/tempo/internal/fee-payer.d.ts.map +1 -1
  164. package/dist/tempo/internal/fee-payer.js +138 -4
  165. package/dist/tempo/internal/fee-payer.js.map +1 -1
  166. package/dist/tempo/internal/proof.d.ts +71 -5
  167. package/dist/tempo/internal/proof.d.ts.map +1 -1
  168. package/dist/tempo/internal/proof.js +42 -6
  169. package/dist/tempo/internal/proof.js.map +1 -1
  170. package/dist/tempo/{client → legacy/client}/ChannelOps.d.ts +19 -6
  171. package/dist/tempo/legacy/client/ChannelOps.d.ts.map +1 -0
  172. package/dist/tempo/{client → legacy/client}/ChannelOps.js +9 -3
  173. package/dist/tempo/legacy/client/ChannelOps.js.map +1 -0
  174. package/dist/tempo/{client → legacy/client}/Session.d.ts +23 -4
  175. package/dist/tempo/legacy/client/Session.d.ts.map +1 -0
  176. package/dist/tempo/{client → legacy/client}/Session.js +14 -7
  177. package/dist/tempo/legacy/client/Session.js.map +1 -0
  178. package/dist/tempo/{client → legacy/client}/SessionManager.d.ts +20 -5
  179. package/dist/tempo/legacy/client/SessionManager.d.ts.map +1 -0
  180. package/dist/tempo/{client → legacy/client}/SessionManager.js +30 -19
  181. package/dist/tempo/legacy/client/SessionManager.js.map +1 -0
  182. package/dist/tempo/legacy/client/index.d.ts +7 -0
  183. package/dist/tempo/legacy/client/index.d.ts.map +1 -0
  184. package/dist/tempo/legacy/client/index.js +5 -0
  185. package/dist/tempo/legacy/client/index.js.map +1 -0
  186. package/dist/tempo/legacy/index.d.ts +7 -0
  187. package/dist/tempo/legacy/index.d.ts.map +1 -0
  188. package/dist/tempo/legacy/index.js +7 -0
  189. package/dist/tempo/legacy/index.js.map +1 -0
  190. package/dist/tempo/{server → legacy/server}/Session.d.ts +28 -11
  191. package/dist/tempo/legacy/server/Session.d.ts.map +1 -0
  192. package/dist/tempo/{server → legacy/server}/Session.js +12 -10
  193. package/dist/tempo/legacy/server/Session.js.map +1 -0
  194. package/dist/tempo/legacy/server/index.d.ts +5 -0
  195. package/dist/tempo/legacy/server/index.d.ts.map +1 -0
  196. package/dist/tempo/legacy/server/index.js +5 -0
  197. package/dist/tempo/legacy/server/index.js.map +1 -0
  198. package/dist/tempo/{session → legacy/session}/Chain.d.ts +30 -23
  199. package/dist/tempo/legacy/session/Chain.d.ts.map +1 -0
  200. package/dist/tempo/{session → legacy/session}/Chain.js +12 -11
  201. package/dist/tempo/legacy/session/Chain.js.map +1 -0
  202. package/dist/tempo/{session → legacy/session}/Channel.d.ts +1 -0
  203. package/dist/tempo/legacy/session/Channel.d.ts.map +1 -0
  204. package/dist/tempo/legacy/session/Channel.js.map +1 -0
  205. package/dist/tempo/legacy/session/ChannelStore.d.ts +22 -0
  206. package/dist/tempo/legacy/session/ChannelStore.d.ts.map +1 -0
  207. package/dist/tempo/legacy/session/ChannelStore.js +6 -0
  208. package/dist/tempo/legacy/session/ChannelStore.js.map +1 -0
  209. package/dist/tempo/legacy/session/Types.d.ts +73 -0
  210. package/dist/tempo/legacy/session/Types.d.ts.map +1 -0
  211. package/dist/tempo/legacy/session/Types.js.map +1 -0
  212. package/dist/tempo/{session → legacy/session}/Voucher.d.ts +4 -4
  213. package/dist/tempo/legacy/session/Voucher.d.ts.map +1 -0
  214. package/dist/tempo/{session → legacy/session}/Voucher.js +1 -1
  215. package/dist/tempo/legacy/session/Voucher.js.map +1 -0
  216. package/dist/tempo/{session → legacy/session}/escrow.abi.d.ts +1 -0
  217. package/dist/tempo/{session → legacy/session}/escrow.abi.d.ts.map +1 -1
  218. package/dist/tempo/{session → legacy/session}/escrow.abi.js +1 -0
  219. package/dist/tempo/legacy/session/escrow.abi.js.map +1 -0
  220. package/dist/tempo/legacy/session/index.d.ts +9 -0
  221. package/dist/tempo/legacy/session/index.d.ts.map +1 -0
  222. package/dist/tempo/legacy/session/index.js +9 -0
  223. package/dist/tempo/legacy/session/index.js.map +1 -0
  224. package/dist/tempo/server/Charge.d.ts +1 -1
  225. package/dist/tempo/server/Charge.d.ts.map +1 -1
  226. package/dist/tempo/server/Charge.js +51 -30
  227. package/dist/tempo/server/Charge.js.map +1 -1
  228. package/dist/tempo/server/Methods.d.ts +67 -8
  229. package/dist/tempo/server/Methods.d.ts.map +1 -1
  230. package/dist/tempo/server/Methods.js +40 -10
  231. package/dist/tempo/server/Methods.js.map +1 -1
  232. package/dist/tempo/server/Subscription.d.ts +11 -1
  233. package/dist/tempo/server/Subscription.d.ts.map +1 -1
  234. package/dist/tempo/server/Subscription.js +135 -23
  235. package/dist/tempo/server/Subscription.js.map +1 -1
  236. package/dist/tempo/server/index.d.ts +6 -5
  237. package/dist/tempo/server/index.d.ts.map +1 -1
  238. package/dist/tempo/server/index.js +5 -5
  239. package/dist/tempo/server/index.js.map +1 -1
  240. package/dist/tempo/server/internal/html.gen.d.ts +1 -1
  241. package/dist/tempo/server/internal/html.gen.d.ts.map +1 -1
  242. package/dist/tempo/server/internal/html.gen.js +1 -1
  243. package/dist/tempo/server/internal/html.gen.js.map +1 -1
  244. package/dist/tempo/server/internal/request-body.d.ts +7 -2
  245. package/dist/tempo/server/internal/request-body.d.ts.map +1 -1
  246. package/dist/tempo/server/internal/request-body.js +20 -3
  247. package/dist/tempo/server/internal/request-body.js.map +1 -1
  248. package/dist/tempo/server/internal/transport.d.ts +8 -4
  249. package/dist/tempo/server/internal/transport.d.ts.map +1 -1
  250. package/dist/tempo/server/internal/transport.js +8 -7
  251. package/dist/tempo/server/internal/transport.js.map +1 -1
  252. package/dist/tempo/session/Snapshot.d.ts +32 -0
  253. package/dist/tempo/session/Snapshot.d.ts.map +1 -0
  254. package/dist/tempo/session/Snapshot.js +37 -0
  255. package/dist/tempo/session/Snapshot.js.map +1 -0
  256. package/dist/tempo/session/client/ChannelOps.d.ts +81 -0
  257. package/dist/tempo/session/client/ChannelOps.d.ts.map +1 -0
  258. package/dist/tempo/session/client/ChannelOps.js +201 -0
  259. package/dist/tempo/session/client/ChannelOps.js.map +1 -0
  260. package/dist/tempo/session/client/ChannelStore.d.ts +51 -0
  261. package/dist/tempo/session/client/ChannelStore.d.ts.map +1 -0
  262. package/dist/tempo/session/client/ChannelStore.js +63 -0
  263. package/dist/tempo/session/client/ChannelStore.js.map +1 -0
  264. package/dist/tempo/session/client/CredentialState.d.ts +245 -0
  265. package/dist/tempo/session/client/CredentialState.d.ts.map +1 -0
  266. package/dist/tempo/session/client/CredentialState.js +419 -0
  267. package/dist/tempo/session/client/CredentialState.js.map +1 -0
  268. package/dist/tempo/session/client/ReceiptCoordinator.d.ts +26 -0
  269. package/dist/tempo/session/client/ReceiptCoordinator.d.ts.map +1 -0
  270. package/dist/tempo/session/client/ReceiptCoordinator.js +61 -0
  271. package/dist/tempo/session/client/ReceiptCoordinator.js.map +1 -0
  272. package/dist/tempo/session/client/Runtime.d.ts +464 -0
  273. package/dist/tempo/session/client/Runtime.d.ts.map +1 -0
  274. package/dist/tempo/session/client/Runtime.js +499 -0
  275. package/dist/tempo/session/client/Runtime.js.map +1 -0
  276. package/dist/tempo/session/client/Session.d.ts +138 -0
  277. package/dist/tempo/session/client/Session.d.ts.map +1 -0
  278. package/dist/tempo/session/client/Session.js +69 -0
  279. package/dist/tempo/session/client/Session.js.map +1 -0
  280. package/dist/tempo/session/client/SessionManager.d.ts +84 -0
  281. package/dist/tempo/session/client/SessionManager.d.ts.map +1 -0
  282. package/dist/tempo/session/client/SessionManager.js +577 -0
  283. package/dist/tempo/session/client/SessionManager.js.map +1 -0
  284. package/dist/tempo/session/client/Transports.d.ts +449 -0
  285. package/dist/tempo/session/client/Transports.d.ts.map +1 -0
  286. package/dist/tempo/session/client/Transports.js +721 -0
  287. package/dist/tempo/session/client/Transports.js.map +1 -0
  288. package/dist/tempo/session/client/index.d.ts +11 -0
  289. package/dist/tempo/session/client/index.d.ts.map +1 -0
  290. package/dist/tempo/session/client/index.js +6 -0
  291. package/dist/tempo/session/client/index.js.map +1 -0
  292. package/dist/tempo/session/index.d.ts +7 -8
  293. package/dist/tempo/session/index.d.ts.map +1 -1
  294. package/dist/tempo/session/index.js +7 -8
  295. package/dist/tempo/session/index.js.map +1 -1
  296. package/dist/tempo/session/precompile/Chain.d.ts +319 -0
  297. package/dist/tempo/session/precompile/Chain.d.ts.map +1 -0
  298. package/dist/tempo/session/precompile/Chain.js +492 -0
  299. package/dist/tempo/session/precompile/Chain.js.map +1 -0
  300. package/dist/tempo/session/precompile/Channel.d.ts +46 -0
  301. package/dist/tempo/session/precompile/Channel.d.ts.map +1 -0
  302. package/dist/tempo/session/precompile/Channel.js +56 -0
  303. package/dist/tempo/session/precompile/Channel.js.map +1 -0
  304. package/dist/tempo/session/precompile/Protocol.d.ts +308 -0
  305. package/dist/tempo/session/precompile/Protocol.d.ts.map +1 -0
  306. package/dist/tempo/session/precompile/Protocol.js +264 -0
  307. package/dist/tempo/session/precompile/Protocol.js.map +1 -0
  308. package/dist/tempo/session/precompile/Voucher.d.ts +40 -0
  309. package/dist/tempo/session/precompile/Voucher.d.ts.map +1 -0
  310. package/dist/tempo/session/precompile/Voucher.js +125 -0
  311. package/dist/tempo/session/precompile/Voucher.js.map +1 -0
  312. package/dist/tempo/session/precompile/escrow.abi.d.ts +522 -0
  313. package/dist/tempo/session/precompile/escrow.abi.d.ts.map +1 -0
  314. package/dist/tempo/session/precompile/escrow.abi.js +224 -0
  315. package/dist/tempo/session/precompile/escrow.abi.js.map +1 -0
  316. package/dist/tempo/session/precompile/index.d.ts +24 -0
  317. package/dist/tempo/session/precompile/index.d.ts.map +1 -0
  318. package/dist/tempo/session/precompile/index.js +22 -0
  319. package/dist/tempo/session/precompile/index.js.map +1 -0
  320. package/dist/tempo/session/server/ChannelOps.d.ts +56 -0
  321. package/dist/tempo/session/server/ChannelOps.d.ts.map +1 -0
  322. package/dist/tempo/session/server/ChannelOps.js +91 -0
  323. package/dist/tempo/session/server/ChannelOps.js.map +1 -0
  324. package/dist/tempo/session/server/ChannelStore.d.ts +347 -0
  325. package/dist/tempo/session/server/ChannelStore.d.ts.map +1 -0
  326. package/dist/tempo/session/server/ChannelStore.js +404 -0
  327. package/dist/tempo/session/server/ChannelStore.js.map +1 -0
  328. package/dist/tempo/session/server/CredentialVerification.d.ts +85 -0
  329. package/dist/tempo/session/server/CredentialVerification.d.ts.map +1 -0
  330. package/dist/tempo/session/server/CredentialVerification.js +494 -0
  331. package/dist/tempo/session/server/CredentialVerification.js.map +1 -0
  332. package/dist/tempo/session/server/MeteredStream.d.ts +40 -0
  333. package/dist/tempo/session/server/MeteredStream.d.ts.map +1 -0
  334. package/dist/tempo/session/server/MeteredStream.js +42 -0
  335. package/dist/tempo/session/server/MeteredStream.js.map +1 -0
  336. package/dist/tempo/session/server/RequestState.d.ts +208 -0
  337. package/dist/tempo/session/server/RequestState.d.ts.map +1 -0
  338. package/dist/tempo/session/server/RequestState.js +252 -0
  339. package/dist/tempo/session/server/RequestState.js.map +1 -0
  340. package/dist/tempo/session/server/Session.d.ts +169 -0
  341. package/dist/tempo/session/server/Session.d.ts.map +1 -0
  342. package/dist/tempo/session/server/Session.js +351 -0
  343. package/dist/tempo/session/server/Session.js.map +1 -0
  344. package/dist/tempo/session/server/Settlement.d.ts +185 -0
  345. package/dist/tempo/session/server/Settlement.d.ts.map +1 -0
  346. package/dist/tempo/session/server/Settlement.js +252 -0
  347. package/dist/tempo/session/server/Settlement.js.map +1 -0
  348. package/dist/tempo/session/{Sse.d.ts → server/Sse.d.ts} +9 -56
  349. package/dist/tempo/session/server/Sse.d.ts.map +1 -0
  350. package/dist/tempo/session/server/Sse.js +184 -0
  351. package/dist/tempo/session/server/Sse.js.map +1 -0
  352. package/dist/tempo/session/server/Transports.d.ts +89 -0
  353. package/dist/tempo/session/server/Transports.d.ts.map +1 -0
  354. package/dist/tempo/session/server/Transports.js +149 -0
  355. package/dist/tempo/session/server/Transports.js.map +1 -0
  356. package/dist/tempo/session/server/Ws.d.ts +48 -0
  357. package/dist/tempo/session/server/Ws.d.ts.map +1 -0
  358. package/dist/tempo/session/server/Ws.js +244 -0
  359. package/dist/tempo/session/server/Ws.js.map +1 -0
  360. package/dist/tempo/session/server/index.d.ts +4 -0
  361. package/dist/tempo/session/server/index.d.ts.map +1 -0
  362. package/dist/tempo/session/server/index.js +2 -0
  363. package/dist/tempo/session/server/index.js.map +1 -0
  364. package/dist/tempo/subscription/KeyAuthorization.d.ts +712 -1
  365. package/dist/tempo/subscription/KeyAuthorization.d.ts.map +1 -1
  366. package/dist/tempo/subscription/Store.d.ts +2 -0
  367. package/dist/tempo/subscription/Store.d.ts.map +1 -1
  368. package/dist/tempo/subscription/Store.js +16 -1
  369. package/dist/tempo/subscription/Store.js.map +1 -1
  370. package/dist/x402/index.d.ts +1 -0
  371. package/dist/x402/index.d.ts.map +1 -1
  372. package/dist/x402/index.js +1 -0
  373. package/dist/x402/index.js.map +1 -1
  374. package/package.json +25 -9
  375. package/src/Challenge.test.ts +40 -0
  376. package/src/Challenge.ts +28 -13
  377. package/src/Constants.ts +58 -0
  378. package/src/Credential.ts +5 -4
  379. package/src/Mcp.ts +4 -0
  380. package/src/Method.ts +46 -5
  381. package/src/PaymentRequest.ts +10 -10
  382. package/src/Receipt.ts +3 -2
  383. package/src/cli/cli.test.ts +38 -43
  384. package/src/cli/cli.ts +23 -10
  385. package/src/cli/mcp.test.ts +21 -7
  386. package/src/cli/plugins/tempo.ts +21 -8
  387. package/src/cli/utils.test.ts +25 -1
  388. package/src/cli/utils.ts +10 -0
  389. package/src/client/Methods.ts +5 -2
  390. package/src/client/Mppx.test-d.ts +31 -1
  391. package/src/client/Mppx.test.ts +76 -1
  392. package/src/client/Mppx.ts +2 -2
  393. package/src/client/Transport.test.ts +225 -178
  394. package/src/client/Transport.ts +77 -84
  395. package/src/client/index.ts +25 -1
  396. package/src/client/internal/Fetch.test.ts +236 -6
  397. package/src/client/internal/Fetch.ts +69 -11
  398. package/src/client/internal/protocols/Mcp.test.ts +220 -0
  399. package/src/client/internal/protocols/Mcp.ts +162 -0
  400. package/src/client/internal/protocols/Mpp.ts +21 -0
  401. package/src/client/internal/protocols/Protocol.ts +10 -0
  402. package/src/client/internal/protocols/Shared.ts +25 -0
  403. package/src/client/internal/protocols/X402.ts +42 -0
  404. package/src/discovery/OpenApi.test.ts +1 -1
  405. package/src/env.d.ts +1 -1
  406. package/src/evm/PublicInterface.test-d.ts +1 -1
  407. package/src/evm/client/index.ts +1 -0
  408. package/src/evm/index.ts +2 -0
  409. package/src/evm/server/Charge.test.ts +1 -1
  410. package/src/evm/server/index.ts +1 -0
  411. package/src/index.ts +1 -0
  412. package/src/internal/AcceptPayment.test.ts +61 -0
  413. package/src/internal/AcceptPayment.ts +21 -14
  414. package/src/{mcp-sdk → mcp}/client/McpClient.integration.test.ts +18 -11
  415. package/src/{mcp-sdk → mcp}/client/McpClient.test-d.ts +45 -11
  416. package/src/{mcp-sdk → mcp}/client/McpClient.test.ts +211 -5
  417. package/src/mcp/client/McpClient.ts +307 -0
  418. package/src/mcp/client/McpClient.unit.test.ts +135 -0
  419. package/src/middlewares/elysia.test.ts +9 -5
  420. package/src/middlewares/express.test.ts +9 -5
  421. package/src/middlewares/hono.test.ts +5 -5
  422. package/src/middlewares/internal/mppx.test.ts +1 -1
  423. package/src/middlewares/nextjs.test.ts +9 -5
  424. package/src/proxy/Proxy.test.ts +9 -9
  425. package/src/proxy/services/anthropic.test.ts +1 -1
  426. package/src/proxy/services/openai.test.ts +1 -1
  427. package/src/proxy/services/stripe.test.ts +1 -1
  428. package/src/server/Mppx.authorize.test.ts +1 -1
  429. package/src/server/Mppx.test-d.ts +55 -1
  430. package/src/server/Mppx.test.ts +220 -9
  431. package/src/server/Mppx.ts +501 -407
  432. package/src/server/Response.ts +2 -1
  433. package/src/server/Transport.test.ts +6 -6
  434. package/src/server/Transport.ts +5 -4
  435. package/src/server/index.ts +1 -0
  436. package/src/stripe/Charge.integration.test.ts +1 -1
  437. package/src/stripe/client/Charge.test.ts +21 -6
  438. package/src/stripe/client/Charge.ts +6 -2
  439. package/src/stripe/server/Charge.test.ts +115 -2
  440. package/src/stripe/server/Charge.ts +13 -2
  441. package/src/stripe/server/internal/html/package.json +1 -1
  442. package/src/stripe/server/internal/html.gen.ts +1 -1
  443. package/src/tempo/AccessKeyAuthorization.test.ts +4 -94
  444. package/src/tempo/Methods.test.ts +45 -17
  445. package/src/tempo/Methods.ts +22 -0
  446. package/src/tempo/Proof.conformance.test.ts +146 -0
  447. package/src/tempo/Proof.test-d.ts +15 -0
  448. package/src/tempo/Proof.ts +52 -1
  449. package/src/tempo/PublicExports.test-d.ts +105 -0
  450. package/src/tempo/Subscription.integration.test.ts +1 -1
  451. package/src/tempo/client/Charge.test.ts +258 -0
  452. package/src/tempo/client/Charge.ts +84 -38
  453. package/src/tempo/client/Methods.ts +22 -8
  454. package/src/tempo/client/ResolveAccount.ts +46 -0
  455. package/src/tempo/client/index.ts +15 -4
  456. package/src/tempo/index.ts +1 -0
  457. package/src/tempo/internal/fee-payer.test.ts +296 -17
  458. package/src/tempo/internal/fee-payer.ts +186 -4
  459. package/src/tempo/internal/fee-token.test.ts +14 -9
  460. package/src/tempo/internal/proof.test.ts +12 -4
  461. package/src/tempo/internal/proof.ts +55 -6
  462. package/src/tempo/legacy/AccessKeyAuthorization.test.ts +162 -0
  463. package/src/tempo/legacy/README.md +9 -0
  464. package/src/tempo/{client → legacy/client}/ChannelOps.test.ts +6 -7
  465. package/src/tempo/{client → legacy/client}/ChannelOps.ts +22 -9
  466. package/src/tempo/{client → legacy/client}/Session.test.ts +51 -9
  467. package/src/tempo/{client → legacy/client}/Session.ts +25 -11
  468. package/src/tempo/{client → legacy/client}/SessionManager.test.ts +81 -9
  469. package/src/tempo/{client → legacy/client}/SessionManager.ts +52 -23
  470. package/src/tempo/legacy/client/index.ts +6 -0
  471. package/src/tempo/legacy/index.ts +6 -0
  472. package/src/tempo/{server → legacy/server}/Session.test.ts +136 -71
  473. package/src/tempo/{server → legacy/server}/Session.ts +32 -23
  474. package/src/tempo/legacy/server/index.ts +4 -0
  475. package/src/tempo/{session → legacy/session}/Chain.test.ts +3 -4
  476. package/src/tempo/{session → legacy/session}/Chain.ts +94 -63
  477. package/src/tempo/{session → legacy/session}/Channel.ts +1 -0
  478. package/src/tempo/legacy/session/ChannelStore.test.ts +58 -0
  479. package/src/tempo/legacy/session/ChannelStore.ts +39 -0
  480. package/src/tempo/legacy/session/Types.ts +91 -0
  481. package/src/tempo/{session → legacy/session}/Voucher.ts +12 -8
  482. package/src/tempo/{session → legacy/session}/escrow.abi.ts +1 -0
  483. package/src/tempo/legacy/session/index.ts +8 -0
  484. package/src/tempo/server/AtomicStore.test-d.ts +16 -11
  485. package/src/tempo/server/Charge.test.ts +480 -31
  486. package/src/tempo/server/Charge.ts +54 -30
  487. package/src/tempo/server/Methods.ts +58 -10
  488. package/src/tempo/server/Sse.test.ts +2 -2
  489. package/src/tempo/server/Subscription.test.ts +465 -3
  490. package/src/tempo/server/Subscription.ts +174 -19
  491. package/src/tempo/server/index.ts +6 -5
  492. package/src/tempo/server/internal/html/package.json +2 -2
  493. package/src/tempo/server/internal/html.gen.ts +1 -1
  494. package/src/tempo/server/internal/request-body.test.ts +37 -4
  495. package/src/tempo/server/internal/request-body.ts +25 -6
  496. package/src/tempo/server/internal/transport.test.ts +4 -4
  497. package/src/tempo/server/internal/transport.ts +19 -10
  498. package/src/tempo/session/Snapshot.test.ts +41 -0
  499. package/src/tempo/session/Snapshot.ts +74 -0
  500. package/src/tempo/session/client/ChannelOps.test.ts +163 -0
  501. package/src/tempo/session/client/ChannelOps.ts +330 -0
  502. package/src/tempo/session/client/ChannelStore.ts +111 -0
  503. package/src/tempo/session/client/CredentialState.test.ts +789 -0
  504. package/src/tempo/session/client/CredentialState.ts +799 -0
  505. package/src/tempo/session/client/ReceiptCoordinator.ts +95 -0
  506. package/src/tempo/session/client/Runtime.test.ts +1092 -0
  507. package/src/tempo/session/client/Runtime.ts +986 -0
  508. package/src/tempo/session/client/Session.test.ts +774 -0
  509. package/src/tempo/session/client/Session.ts +123 -0
  510. package/src/tempo/session/client/SessionManager.test.ts +1397 -0
  511. package/src/tempo/session/client/SessionManager.ts +751 -0
  512. package/src/tempo/session/client/Transports.test.ts +837 -0
  513. package/src/tempo/session/client/Transports.ts +1292 -0
  514. package/src/tempo/session/client/index.ts +40 -0
  515. package/src/tempo/session/index.ts +7 -8
  516. package/src/tempo/session/precompile/Chain.integration.test.ts +321 -0
  517. package/src/tempo/session/precompile/Chain.test.ts +1258 -0
  518. package/src/tempo/session/precompile/Chain.ts +979 -0
  519. package/src/tempo/session/precompile/Channel.test.ts +138 -0
  520. package/src/tempo/session/precompile/Channel.ts +103 -0
  521. package/src/tempo/session/precompile/Protocol.test.ts +358 -0
  522. package/src/tempo/session/precompile/Protocol.ts +520 -0
  523. package/src/tempo/session/precompile/Voucher.test.ts +354 -0
  524. package/src/tempo/session/precompile/Voucher.ts +162 -0
  525. package/src/tempo/session/precompile/escrow.abi.ts +226 -0
  526. package/src/tempo/session/precompile/index.ts +33 -0
  527. package/src/tempo/session/server/ChannelOps.test.ts +129 -0
  528. package/src/tempo/session/server/ChannelOps.ts +157 -0
  529. package/src/tempo/session/{ChannelStore.test.ts → server/ChannelStore.test.ts} +536 -29
  530. package/src/tempo/session/server/ChannelStore.ts +835 -0
  531. package/src/tempo/session/server/CredentialVerification.test.ts +146 -0
  532. package/src/tempo/session/server/CredentialVerification.ts +710 -0
  533. package/src/tempo/session/server/MeteredStream.ts +88 -0
  534. package/src/tempo/session/server/RequestState.test.ts +531 -0
  535. package/src/tempo/session/server/RequestState.ts +499 -0
  536. package/src/tempo/session/server/Session.integration.test.ts +444 -0
  537. package/src/tempo/session/server/Session.test.ts +3253 -0
  538. package/src/tempo/session/server/Session.ts +543 -0
  539. package/src/tempo/session/server/Settlement.test.ts +329 -0
  540. package/src/tempo/session/server/Settlement.ts +471 -0
  541. package/src/tempo/session/{Sse.test.ts → server/Sse.test.ts} +37 -3
  542. package/src/tempo/session/server/Sse.ts +254 -0
  543. package/src/tempo/session/server/Transports.test.ts +346 -0
  544. package/src/tempo/session/server/Transports.ts +255 -0
  545. package/src/tempo/session/{Ws.test.ts → server/Ws.test.ts} +4 -4
  546. package/src/tempo/session/server/Ws.ts +380 -0
  547. package/src/tempo/session/server/index.ts +8 -0
  548. package/src/tempo/subscription/Store.ts +27 -9
  549. package/src/x402/Exact.e2e.test.ts +1 -1
  550. package/src/x402/PublicInterface.test-d.ts +1 -1
  551. package/src/x402/index.ts +1 -0
  552. package/dist/mcp-sdk/client/McpClient.d.ts +0 -78
  553. package/dist/mcp-sdk/client/McpClient.d.ts.map +0 -1
  554. package/dist/mcp-sdk/client/McpClient.js +0 -105
  555. package/dist/mcp-sdk/client/McpClient.js.map +0 -1
  556. package/dist/mcp-sdk/client/index.d.ts.map +0 -1
  557. package/dist/mcp-sdk/client/index.js.map +0 -1
  558. package/dist/mcp-sdk/server/Transport.d.ts.map +0 -1
  559. package/dist/mcp-sdk/server/Transport.js.map +0 -1
  560. package/dist/mcp-sdk/server/index.d.ts.map +0 -1
  561. package/dist/mcp-sdk/server/index.js.map +0 -1
  562. package/dist/tempo/client/ChannelOps.d.ts.map +0 -1
  563. package/dist/tempo/client/ChannelOps.js.map +0 -1
  564. package/dist/tempo/client/Session.d.ts.map +0 -1
  565. package/dist/tempo/client/Session.js.map +0 -1
  566. package/dist/tempo/client/SessionManager.d.ts.map +0 -1
  567. package/dist/tempo/client/SessionManager.js.map +0 -1
  568. package/dist/tempo/server/Session.d.ts.map +0 -1
  569. package/dist/tempo/server/Session.js.map +0 -1
  570. package/dist/tempo/session/Chain.d.ts.map +0 -1
  571. package/dist/tempo/session/Chain.js.map +0 -1
  572. package/dist/tempo/session/Channel.d.ts.map +0 -1
  573. package/dist/tempo/session/Channel.js.map +0 -1
  574. package/dist/tempo/session/ChannelStore.d.ts +0 -117
  575. package/dist/tempo/session/ChannelStore.d.ts.map +0 -1
  576. package/dist/tempo/session/ChannelStore.js +0 -172
  577. package/dist/tempo/session/ChannelStore.js.map +0 -1
  578. package/dist/tempo/session/Receipt.d.ts +0 -22
  579. package/dist/tempo/session/Receipt.d.ts.map +0 -1
  580. package/dist/tempo/session/Receipt.js +0 -34
  581. package/dist/tempo/session/Receipt.js.map +0 -1
  582. package/dist/tempo/session/Sse.d.ts.map +0 -1
  583. package/dist/tempo/session/Sse.js +0 -363
  584. package/dist/tempo/session/Sse.js.map +0 -1
  585. package/dist/tempo/session/Types.d.ts +0 -78
  586. package/dist/tempo/session/Types.d.ts.map +0 -1
  587. package/dist/tempo/session/Types.js.map +0 -1
  588. package/dist/tempo/session/Voucher.d.ts.map +0 -1
  589. package/dist/tempo/session/Voucher.js.map +0 -1
  590. package/dist/tempo/session/Ws.d.ts +0 -87
  591. package/dist/tempo/session/Ws.d.ts.map +0 -1
  592. package/dist/tempo/session/Ws.js +0 -443
  593. package/dist/tempo/session/Ws.js.map +0 -1
  594. package/dist/tempo/session/escrow.abi.js.map +0 -1
  595. package/src/mcp-sdk/client/McpClient.ts +0 -196
  596. package/src/tempo/session/ChannelStore.ts +0 -308
  597. package/src/tempo/session/Receipt.test.ts +0 -89
  598. package/src/tempo/session/Receipt.ts +0 -46
  599. package/src/tempo/session/Sse.ts +0 -462
  600. package/src/tempo/session/Types.ts +0 -86
  601. package/src/tempo/session/Ws.ts +0 -576
  602. /package/dist/{mcp-sdk → mcp}/client/index.d.ts +0 -0
  603. /package/dist/{mcp-sdk → mcp}/client/index.js +0 -0
  604. /package/dist/{mcp-sdk → mcp}/server/Transport.d.ts +0 -0
  605. /package/dist/{mcp-sdk → mcp}/server/Transport.js +0 -0
  606. /package/dist/{mcp-sdk → mcp}/server/index.d.ts +0 -0
  607. /package/dist/{mcp-sdk → mcp}/server/index.js +0 -0
  608. /package/dist/tempo/{session → legacy/session}/Channel.js +0 -0
  609. /package/dist/tempo/{session → legacy/session}/Types.js +0 -0
  610. /package/src/{mcp-sdk → mcp}/client/index.ts +0 -0
  611. /package/src/{mcp-sdk → mcp}/server/Transport.test.ts +0 -0
  612. /package/src/{mcp-sdk → mcp}/server/Transport.ts +0 -0
  613. /package/src/{mcp-sdk → mcp}/server/index.ts +0 -0
  614. /package/src/tempo/{session → legacy/session}/Channel.test.ts +0 -0
  615. /package/src/tempo/{session → legacy/session}/Voucher.test.ts +0 -0
  616. /package/src/tempo/session/{Sse.fuzz.test.ts → server/Sse.fuzz.test.ts} +0 -0
@@ -1,8 +1,17 @@
1
1
  import { Challenge, Credential, Receipt } from 'mppx'
2
2
  import { Mppx } from 'mppx/server'
3
3
  import { KeyAuthorization } from 'ox/tempo'
4
- import { createClient, custom } from 'viem'
4
+ import {
5
+ createClient,
6
+ custom,
7
+ decodeFunctionData,
8
+ encodeAbiParameters,
9
+ encodeEventTopics,
10
+ type Address,
11
+ type Hex,
12
+ } from 'viem'
5
13
  import { privateKeyToAccount } from 'viem/accounts'
14
+ import { Abis, Transaction } from 'viem/tempo'
6
15
  import { tempo as tempo_chain } from 'viem/tempo/chains'
7
16
  import { describe, expect, test } from 'vp/test'
8
17
 
@@ -15,7 +24,7 @@ import type { SubscriptionRecord } from '../subscription/Types.js'
15
24
  import { renew, subscription } from './Subscription.js'
16
25
 
17
26
  const realm = 'api.example.com'
18
- const secretKey = 'test-secret-key'
27
+ const secretKey = 'test-secret-key-test-secret-key-32'
19
28
  const activeBillingAnchor = new Date(Math.floor(Date.now() / 1_000) * 1_000).toISOString()
20
29
  const activeSubscriptionExpires = new Date(
21
30
  Math.ceil((Date.now() + 365 * 24 * 60 * 60 * 1_000) / 1_000) * 1_000,
@@ -32,6 +41,9 @@ const subscriptionRecipient = '0x1234567890abcdef1234567890abcdef12345678'
32
41
  const rootAccount = privateKeyToAccount(
33
42
  '0x0000000000000000000000000000000000000000000000000000000000000001',
34
43
  )
44
+ const otherRootAccount = privateKeyToAccount(
45
+ '0x0000000000000000000000000000000000000000000000000000000000000004',
46
+ )
35
47
  const accessAccount = privateKeyToAccount(
36
48
  '0x0000000000000000000000000000000000000000000000000000000000000002',
37
49
  )
@@ -81,10 +93,11 @@ async function createCredential(
81
93
  challenge: Challenge.Challenge,
82
94
  source = rootAccount.address,
83
95
  key: SubscriptionAccessKey = accessKey,
96
+ account = rootAccount,
84
97
  ) {
85
98
  const keyAuthorization = await signSubscriptionKeyAuthorization({
86
99
  accessKey: key,
87
- account: rootAccount,
100
+ account,
88
101
  chainId,
89
102
  request: challenge.request as ReturnType<typeof Methods.subscription.schema.request.parse>,
90
103
  })
@@ -117,6 +130,109 @@ function createBillingClient(hashes: readonly string[]) {
117
130
  return { client, rpcMethods }
118
131
  }
119
132
 
133
+ const confirmedBlockHash = `0x${'f'.repeat(64)}` as const
134
+ // Canonical TIP-1028 ReceivePolicyGuard precompile address.
135
+ const receivePolicyGuard = '0xB10C000000000000000000000000000000000000' as Address
136
+
137
+ /**
138
+ * Mock client whose `eth_sendRawTransactionSync` returns a confirmed receipt
139
+ * with a `TransferWithMemo` log derived from the broadcast transaction.
140
+ *
141
+ * `redirectTo` simulates a T6 (TIP-1028) held transfer (credits the guard, not
142
+ * the recipient); `addUnrelatedTransfer` adds a memo-less `Transfer` to the
143
+ * recipient. By default only the renewal (second) broadcast is affected so
144
+ * activation succeeds; `redirectActivation` also holds the first broadcast.
145
+ */
146
+ function createConfirmingBillingClient(options?: {
147
+ addUnrelatedTransfer?: boolean
148
+ redirectActivation?: boolean
149
+ redirectTo?: Address
150
+ }) {
151
+ const rpcMethods: string[] = []
152
+ let broadcastIndex = 0
153
+ const client = createClient({
154
+ chain: { ...tempo_chain, id: chainId },
155
+ transport: custom({
156
+ async request({ method, params }) {
157
+ rpcMethods.push(method)
158
+ if (method === 'eth_chainId') return `0x${chainId.toString(16)}`
159
+ if (method === 'eth_call') return '0x'
160
+ if (method === 'eth_sendRawTransactionSync') {
161
+ const index = broadcastIndex++
162
+ const isRenewal = index >= 1
163
+ const serialized = (params as [Hex])[0]
164
+ const transaction = Transaction.deserialize(
165
+ serialized as Transaction.TransactionSerializedTempo,
166
+ ) as unknown as {
167
+ from: Address
168
+ calls: readonly { data: Hex; to: Address }[]
169
+ }
170
+ const call = transaction.calls[0]!
171
+ const { args } = decodeFunctionData({
172
+ abi: Abis.tip20,
173
+ data: call.data,
174
+ })
175
+ const [recipient, amount, memo] = args as [Address, bigint, Hex]
176
+ const shouldRedirect = options?.redirectTo && (isRenewal || options?.redirectActivation)
177
+ const creditedTo = shouldRedirect ? options!.redirectTo! : recipient
178
+ const hash = `0x${index.toString(16).padStart(64, '0')}` as Hex
179
+ const baseLog = {
180
+ blockHash: confirmedBlockHash,
181
+ blockNumber: '0x1',
182
+ data: encodeAbiParameters([{ type: 'uint256' }], [amount]),
183
+ logIndex: '0x0',
184
+ removed: false,
185
+ transactionHash: hash,
186
+ transactionIndex: '0x0',
187
+ } as const
188
+ const logs: unknown[] = [
189
+ {
190
+ ...baseLog,
191
+ address: call.to,
192
+ topics: encodeEventTopics({
193
+ abi: Abis.tip20,
194
+ args: { from: transaction.from, memo, to: creditedTo },
195
+ eventName: 'TransferWithMemo',
196
+ }),
197
+ },
198
+ ]
199
+ // Memo-less Transfer to the recipient: must not satisfy the check.
200
+ if (isRenewal && options?.addUnrelatedTransfer) {
201
+ logs.push({
202
+ ...baseLog,
203
+ address: call.to,
204
+ logIndex: '0x1',
205
+ topics: encodeEventTopics({
206
+ abi: Abis.tip20,
207
+ args: { from: transaction.from, to: recipient },
208
+ eventName: 'Transfer',
209
+ }),
210
+ })
211
+ }
212
+ return {
213
+ blockHash: confirmedBlockHash,
214
+ blockNumber: '0x1',
215
+ contractAddress: null,
216
+ cumulativeGasUsed: '0x0',
217
+ effectiveGasPrice: '0x0',
218
+ from: transaction.from,
219
+ gasUsed: '0x0',
220
+ logs,
221
+ logsBloom: `0x${'0'.repeat(512)}`,
222
+ status: '0x1',
223
+ to: call.to,
224
+ transactionHash: hash,
225
+ transactionIndex: '0x0',
226
+ type: '0x0',
227
+ }
228
+ }
229
+ throw new Error(`unexpected rpc method: ${method}`)
230
+ },
231
+ }),
232
+ })
233
+ return { client, rpcMethods }
234
+ }
235
+
120
236
  describe('tempo.subscription', () => {
121
237
  test('stores an activated subscription and reuses it on later requests', async () => {
122
238
  const store = Store.memory()
@@ -271,6 +387,211 @@ describe('tempo.subscription', () => {
271
387
  expect(rpcMethods.filter((method) => method === 'eth_sendRawTransaction')).toHaveLength(1)
272
388
  })
273
389
 
390
+ test('requires a fresh credential for active subscription reuse when configured', async () => {
391
+ const store = Store.memory()
392
+ const subscriptions = SubscriptionStore.fromStore(store)
393
+ await subscriptions.put(
394
+ createRecord({
395
+ accessKey,
396
+ payer: { address: rootAccount.address, chainId },
397
+ }),
398
+ )
399
+ const method = subscription({
400
+ activate: async () => {
401
+ throw new Error('active subscription reuse should not activate')
402
+ },
403
+ amount: subscriptionAmount,
404
+ chainId,
405
+ currency: subscriptionCurrency,
406
+ periodCount: subscriptionPeriodCount,
407
+ periodUnit: subscriptionPeriodUnit,
408
+ recipient: subscriptionRecipient,
409
+ requireCredential: true,
410
+ resolve: async () => ({ accessKey, key: subscriptionKey }),
411
+ store,
412
+ subscriptionExpires: activeSubscriptionExpires,
413
+ })
414
+
415
+ const mppx = Mppx.create({ methods: [method], realm, secretKey })
416
+ const unauthenticated = await mppx.tempo.subscription({})(
417
+ new Request('https://example.com/resource'),
418
+ )
419
+
420
+ expect(unauthenticated.status).toBe(402)
421
+ if (unauthenticated.status !== 402) throw new Error('expected reuse challenge')
422
+
423
+ const challenge = Challenge.fromResponse(unauthenticated.challenge)
424
+ const credential = await createCredential(challenge)
425
+ const reused = await mppx.tempo.subscription({})(
426
+ new Request('https://example.com/resource', {
427
+ headers: { Authorization: Credential.serialize(credential) },
428
+ }),
429
+ )
430
+
431
+ expect(reused.status).toBe(200)
432
+ })
433
+
434
+ test('can derive the subscription lookup key only from the signed credential source', async () => {
435
+ const store = Store.memory()
436
+ const subscriptions = SubscriptionStore.fromStore(store)
437
+ const { client, rpcMethods } = createBillingClient([hashActivate])
438
+ const sourceKey = (source: { address: string; chainId: number }) =>
439
+ `payer:${source.chainId}:${source.address.toLowerCase()}:pro`
440
+ const method = subscription({
441
+ amount: subscriptionAmount,
442
+ chainId,
443
+ currency: subscriptionCurrency,
444
+ getClient: async () => client,
445
+ periodCount: subscriptionPeriodCount,
446
+ periodUnit: subscriptionPeriodUnit,
447
+ recipient: subscriptionRecipient,
448
+ requireCredential: true,
449
+ resolve: async ({ source }) => {
450
+ if (!source) return null
451
+ return { key: sourceKey(source) }
452
+ },
453
+ store,
454
+ subscriptionExpires: activeSubscriptionExpires,
455
+ waitForConfirmation: false,
456
+ })
457
+
458
+ const mppx = Mppx.create({ methods: [method], realm, secretKey })
459
+ const challengeResult = await mppx.tempo.subscription({})(
460
+ new Request('https://example.com/resource'),
461
+ )
462
+
463
+ expect(challengeResult.status).toBe(402)
464
+ if (challengeResult.status !== 402) throw new Error('expected source challenge')
465
+
466
+ const challenge = Challenge.fromResponse(challengeResult.challenge)
467
+ const challengeAccessKey = (
468
+ challenge.request as ReturnType<typeof Methods.subscription.schema.request.parse>
469
+ ).methodDetails?.accessKey
470
+ if (!challengeAccessKey) throw new Error('expected challenge access key')
471
+
472
+ const credential = await createCredential(challenge, rootAccount.address, challengeAccessKey)
473
+ const activated = await mppx.tempo.subscription({})(
474
+ new Request('https://example.com/resource', {
475
+ headers: { Authorization: Credential.serialize(credential) },
476
+ }),
477
+ )
478
+
479
+ expect(activated.status).toBe(200)
480
+ const lookupKey = sourceKey({ address: rootAccount.address, chainId })
481
+ const record = await subscriptions.getByKey(lookupKey)
482
+ expect(record?.lookupKey).toBe(lookupKey)
483
+ expect(record?.payer?.address.toLowerCase()).toBe(rootAccount.address.toLowerCase())
484
+ expect(record?.accessKey).toEqual(challengeAccessKey)
485
+ expect(rpcMethods.filter((method) => method === 'eth_sendRawTransaction')).toHaveLength(1)
486
+ })
487
+
488
+ test('rejects credential reuse when the signer does not match the stored payer', async () => {
489
+ const store = Store.memory()
490
+ const subscriptions = SubscriptionStore.fromStore(store)
491
+ await subscriptions.put(
492
+ createRecord({
493
+ accessKey,
494
+ payer: { address: rootAccount.address, chainId },
495
+ }),
496
+ )
497
+ const method = subscription({
498
+ activate: async () => {
499
+ throw new Error('active subscription reuse should not activate')
500
+ },
501
+ amount: subscriptionAmount,
502
+ chainId,
503
+ currency: subscriptionCurrency,
504
+ periodCount: subscriptionPeriodCount,
505
+ periodUnit: subscriptionPeriodUnit,
506
+ recipient: subscriptionRecipient,
507
+ requireCredential: true,
508
+ resolve: async () => ({ accessKey, key: subscriptionKey }),
509
+ store,
510
+ subscriptionExpires: activeSubscriptionExpires,
511
+ })
512
+
513
+ const mppx = Mppx.create({ methods: [method], realm, secretKey })
514
+ const challengeResult = await mppx.tempo.subscription({})(
515
+ new Request('https://example.com/resource'),
516
+ )
517
+ if (challengeResult.status !== 402) throw new Error('expected reuse challenge')
518
+
519
+ const challenge = Challenge.fromResponse(challengeResult.challenge)
520
+ const credential = await createCredential(
521
+ challenge,
522
+ otherRootAccount.address,
523
+ accessKey,
524
+ otherRootAccount,
525
+ )
526
+ const rejected = await mppx.tempo.subscription({})(
527
+ new Request('https://example.com/resource', {
528
+ headers: { Authorization: Credential.serialize(credential) },
529
+ }),
530
+ )
531
+
532
+ expect(rejected.status).toBe(402)
533
+ if (rejected.status !== 402) throw new Error('expected payer mismatch challenge')
534
+ const body = await rejected.challenge.json()
535
+ expect(body.detail).toBe('Payment verification failed: subscription payer mismatch.')
536
+ })
537
+
538
+ test('renews an overdue active subscription after credential-required payer proof', async () => {
539
+ const store = Store.memory()
540
+ const subscriptions = SubscriptionStore.fromStore(store)
541
+ await subscriptions.put(
542
+ createRecord({
543
+ accessKey,
544
+ billingAnchor: new Date(Date.now() - 3 * subscriptionPeriodMilliseconds).toISOString(),
545
+ lastChargedPeriod: 0,
546
+ payer: { address: rootAccount.address, chainId },
547
+ reference: hashStale,
548
+ }),
549
+ )
550
+ const method = subscription({
551
+ activate: async () => {
552
+ throw new Error('active subscription renewal should not activate')
553
+ },
554
+ amount: subscriptionAmount,
555
+ chainId,
556
+ currency: subscriptionCurrency,
557
+ periodCount: subscriptionPeriodCount,
558
+ periodUnit: subscriptionPeriodUnit,
559
+ recipient: subscriptionRecipient,
560
+ renew: async ({ periodIndex, subscription }) => ({
561
+ receipt: createReceipt(subscription.subscriptionId, hashRenewed),
562
+ subscription: {
563
+ ...subscription,
564
+ lastChargedPeriod: periodIndex,
565
+ reference: hashRenewed,
566
+ },
567
+ }),
568
+ requireCredential: true,
569
+ resolve: async () => ({ accessKey, key: subscriptionKey }),
570
+ store,
571
+ subscriptionExpires: activeSubscriptionExpires,
572
+ })
573
+
574
+ const mppx = Mppx.create({ methods: [method], realm, secretKey })
575
+ const challengeResult = await mppx.tempo.subscription({})(
576
+ new Request('https://example.com/resource'),
577
+ )
578
+ if (challengeResult.status !== 402) throw new Error('expected reuse challenge')
579
+
580
+ const challenge = Challenge.fromResponse(challengeResult.challenge)
581
+ const credential = await createCredential(challenge)
582
+ const renewed = await mppx.tempo.subscription({})(
583
+ new Request('https://example.com/resource', {
584
+ headers: { Authorization: Credential.serialize(credential) },
585
+ }),
586
+ )
587
+
588
+ expect(renewed.status).toBe(200)
589
+ if (renewed.status !== 200) throw new Error('expected credential renewal')
590
+ const receipt = Receipt.fromResponse(renewed.withReceipt(new Response('OK')))
591
+ expect(receipt.reference).toBe(hashRenewed)
592
+ expect((await subscriptions.getByKey(subscriptionKey))?.lastChargedPeriod).toBeGreaterThan(0)
593
+ })
594
+
274
595
  test('verifyCredential activates a subscription credential with a canonical challenge request', async () => {
275
596
  const store = Store.memory()
276
597
  const { client } = createBillingClient([hashActivate])
@@ -357,6 +678,147 @@ describe('tempo.subscription', () => {
357
678
  expect((await subscriptions.get(record.subscriptionId))?.lastChargedPeriod).toBeGreaterThan(0)
358
679
  })
359
680
 
681
+ async function activateConfirmedSubscription(parameters: {
682
+ client: ReturnType<typeof createConfirmingBillingClient>['client']
683
+ store: ReturnType<typeof Store.memory>
684
+ }) {
685
+ const { client, store } = parameters
686
+ const method = subscription({
687
+ amount: subscriptionAmount,
688
+ chainId,
689
+ currency: subscriptionCurrency,
690
+ getClient: async () => client,
691
+ periodCount: subscriptionPeriodCount,
692
+ periodUnit: subscriptionPeriodUnit,
693
+ recipient: subscriptionRecipient,
694
+ resolve: async () => ({ key: subscriptionKey }),
695
+ store,
696
+ subscriptionExpires: activeSubscriptionExpires,
697
+ })
698
+ const mppx = Mppx.create({ methods: [method], realm, secretKey })
699
+ const challengeResult = await mppx.tempo.subscription({})(
700
+ new Request('https://example.com/resource'),
701
+ )
702
+ if (challengeResult.status !== 402) throw new Error('expected activation challenge')
703
+ const challenge = Challenge.fromResponse(challengeResult.challenge)
704
+ const accessKey = (
705
+ challenge.request as ReturnType<typeof Methods.subscription.schema.request.parse>
706
+ ).methodDetails?.accessKey
707
+ if (!accessKey) throw new Error('expected generated access key')
708
+ const credential = await createCredential(challenge, rootAccount.address, accessKey)
709
+ const activated = await mppx.tempo.subscription({})(
710
+ new Request('https://example.com/resource', {
711
+ headers: { Authorization: Credential.serialize(credential) },
712
+ }),
713
+ )
714
+ expect(activated.status).toBe(200)
715
+ return { mppx }
716
+ }
717
+
718
+ test('renews when the confirmed receipt credits the recipient', async () => {
719
+ const store = Store.memory()
720
+ const subscriptions = SubscriptionStore.fromStore(store)
721
+ const { client } = createConfirmingBillingClient()
722
+ const { mppx } = await activateConfirmedSubscription({ client, store })
723
+
724
+ const record = await subscriptions.getByKey(subscriptionKey)
725
+ if (!record) throw new Error('expected subscription record')
726
+ await subscriptions.put({
727
+ ...record,
728
+ billingAnchor: new Date(Date.now() - 3 * subscriptionPeriodMilliseconds).toISOString(),
729
+ lastChargedPeriod: 0,
730
+ })
731
+
732
+ const renewed = await mppx.tempo.subscription({})(new Request('https://example.com/resource'))
733
+ expect(renewed.status).toBe(200)
734
+ expect((await subscriptions.get(record.subscriptionId))?.lastChargedPeriod).toBeGreaterThan(0)
735
+ })
736
+
737
+ test('rejects renewal when a receive policy holds the confirmed transfer', async () => {
738
+ const store = Store.memory()
739
+ const subscriptions = SubscriptionStore.fromStore(store)
740
+ const { client } = createConfirmingBillingClient({ redirectTo: receivePolicyGuard })
741
+ const { mppx } = await activateConfirmedSubscription({ client, store })
742
+
743
+ const record = await subscriptions.getByKey(subscriptionKey)
744
+ if (!record) throw new Error('expected subscription record')
745
+ await subscriptions.put({
746
+ ...record,
747
+ billingAnchor: new Date(Date.now() - 3 * subscriptionPeriodMilliseconds).toISOString(),
748
+ lastChargedPeriod: 0,
749
+ })
750
+
751
+ const renewed = await mppx.tempo.subscription({})(new Request('https://example.com/resource'))
752
+ expect(renewed.status).toBe(402)
753
+ // The held renewal must not advance the billing period.
754
+ expect((await subscriptions.get(record.subscriptionId))?.lastChargedPeriod).toBe(0)
755
+ })
756
+
757
+ test('rejects a held renewal even when a memo-less Transfer credits the recipient', async () => {
758
+ const store = Store.memory()
759
+ const subscriptions = SubscriptionStore.fromStore(store)
760
+ // Settlement is held, but the receipt also has a memo-less Transfer to the
761
+ // recipient; the memo-bound check must still reject it.
762
+ const { client } = createConfirmingBillingClient({
763
+ addUnrelatedTransfer: true,
764
+ redirectTo: receivePolicyGuard,
765
+ })
766
+ const { mppx } = await activateConfirmedSubscription({ client, store })
767
+
768
+ const record = await subscriptions.getByKey(subscriptionKey)
769
+ if (!record) throw new Error('expected subscription record')
770
+ await subscriptions.put({
771
+ ...record,
772
+ billingAnchor: new Date(Date.now() - 3 * subscriptionPeriodMilliseconds).toISOString(),
773
+ lastChargedPeriod: 0,
774
+ })
775
+
776
+ const renewed = await mppx.tempo.subscription({})(new Request('https://example.com/resource'))
777
+ expect(renewed.status).toBe(402)
778
+ expect((await subscriptions.get(record.subscriptionId))?.lastChargedPeriod).toBe(0)
779
+ })
780
+
781
+ test('rejects activation when a receive policy holds the confirmed transfer', async () => {
782
+ const store = Store.memory()
783
+ const subscriptions = SubscriptionStore.fromStore(store)
784
+ const { client } = createConfirmingBillingClient({
785
+ redirectActivation: true,
786
+ redirectTo: receivePolicyGuard,
787
+ })
788
+ const method = subscription({
789
+ amount: subscriptionAmount,
790
+ chainId,
791
+ currency: subscriptionCurrency,
792
+ getClient: async () => client,
793
+ periodCount: subscriptionPeriodCount,
794
+ periodUnit: subscriptionPeriodUnit,
795
+ recipient: subscriptionRecipient,
796
+ resolve: async () => ({ key: subscriptionKey }),
797
+ store,
798
+ subscriptionExpires: activeSubscriptionExpires,
799
+ })
800
+ const mppx = Mppx.create({ methods: [method], realm, secretKey })
801
+ const challengeResult = await mppx.tempo.subscription({})(
802
+ new Request('https://example.com/resource'),
803
+ )
804
+ if (challengeResult.status !== 402) throw new Error('expected activation challenge')
805
+ const challenge = Challenge.fromResponse(challengeResult.challenge)
806
+ const generatedAccessKey = (
807
+ challenge.request as ReturnType<typeof Methods.subscription.schema.request.parse>
808
+ ).methodDetails?.accessKey
809
+ if (!generatedAccessKey) throw new Error('expected generated access key')
810
+ const credential = await createCredential(challenge, rootAccount.address, generatedAccessKey)
811
+ const activated = await mppx.tempo.subscription({})(
812
+ new Request('https://example.com/resource', {
813
+ headers: { Authorization: Credential.serialize(credential) },
814
+ }),
815
+ )
816
+
817
+ expect(activated.status).toBe(402)
818
+ // A held activation must not persist an active subscription.
819
+ expect(await subscriptions.getByKey(subscriptionKey)).toBeNull()
820
+ })
821
+
360
822
  test('returns a management response while renewal is already in flight', async () => {
361
823
  const store = Store.memory()
362
824
  const subscriptions = SubscriptionStore.fromStore(store)