mppx 0.6.30 → 0.7.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 (483) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/Challenge.d.ts.map +1 -1
  3. package/dist/Challenge.js +9 -7
  4. package/dist/Challenge.js.map +1 -1
  5. package/dist/Constants.d.ts +46 -0
  6. package/dist/Constants.d.ts.map +1 -0
  7. package/dist/Constants.js +46 -0
  8. package/dist/Constants.js.map +1 -0
  9. package/dist/Credential.d.ts.map +1 -1
  10. package/dist/Credential.js +5 -4
  11. package/dist/Credential.js.map +1 -1
  12. package/dist/Method.d.ts +32 -4
  13. package/dist/Method.d.ts.map +1 -1
  14. package/dist/Method.js +5 -2
  15. package/dist/Method.js.map +1 -1
  16. package/dist/Receipt.d.ts.map +1 -1
  17. package/dist/Receipt.js +3 -2
  18. package/dist/Receipt.js.map +1 -1
  19. package/dist/cli/cli.d.ts.map +1 -1
  20. package/dist/cli/cli.js +19 -11
  21. package/dist/cli/cli.js.map +1 -1
  22. package/dist/cli/plugins/tempo.d.ts.map +1 -1
  23. package/dist/cli/plugins/tempo.js +17 -6
  24. package/dist/cli/plugins/tempo.js.map +1 -1
  25. package/dist/cli/utils.d.ts +5 -0
  26. package/dist/cli/utils.d.ts.map +1 -1
  27. package/dist/cli/utils.js +10 -0
  28. package/dist/cli/utils.js.map +1 -1
  29. package/dist/client/Methods.d.ts +5 -2
  30. package/dist/client/Methods.d.ts.map +1 -1
  31. package/dist/client/Methods.js +5 -2
  32. package/dist/client/Methods.js.map +1 -1
  33. package/dist/client/Transport.d.ts.map +1 -1
  34. package/dist/client/Transport.js +4 -5
  35. package/dist/client/Transport.js.map +1 -1
  36. package/dist/client/index.d.ts +2 -1
  37. package/dist/client/index.d.ts.map +1 -1
  38. package/dist/client/index.js +2 -1
  39. package/dist/client/index.js.map +1 -1
  40. package/dist/client/internal/Fetch.d.ts.map +1 -1
  41. package/dist/client/internal/Fetch.js +14 -6
  42. package/dist/client/internal/Fetch.js.map +1 -1
  43. package/dist/evm/server/Methods.d.ts +1 -1
  44. package/dist/evm/server/Methods.d.ts.map +1 -1
  45. package/dist/index.d.ts +1 -0
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +1 -0
  48. package/dist/index.js.map +1 -1
  49. package/dist/internal/AcceptPayment.d.ts +3 -0
  50. package/dist/internal/AcceptPayment.d.ts.map +1 -1
  51. package/dist/internal/AcceptPayment.js +15 -11
  52. package/dist/internal/AcceptPayment.js.map +1 -1
  53. package/dist/mcp-sdk/client/McpClient.d.ts +12 -5
  54. package/dist/mcp-sdk/client/McpClient.d.ts.map +1 -1
  55. package/dist/mcp-sdk/client/McpClient.js +55 -42
  56. package/dist/mcp-sdk/client/McpClient.js.map +1 -1
  57. package/dist/server/Mppx.d.ts +11 -3
  58. package/dist/server/Mppx.d.ts.map +1 -1
  59. package/dist/server/Mppx.js +76 -27
  60. package/dist/server/Mppx.js.map +1 -1
  61. package/dist/server/Request.js +24 -10
  62. package/dist/server/Request.js.map +1 -1
  63. package/dist/server/Response.d.ts.map +1 -1
  64. package/dist/server/Response.js +2 -1
  65. package/dist/server/Response.js.map +1 -1
  66. package/dist/server/Transport.d.ts.map +1 -1
  67. package/dist/server/Transport.js +4 -3
  68. package/dist/server/Transport.js.map +1 -1
  69. package/dist/server/index.d.ts +1 -0
  70. package/dist/server/index.d.ts.map +1 -1
  71. package/dist/server/index.js +1 -0
  72. package/dist/server/index.js.map +1 -1
  73. package/dist/stripe/client/Charge.d.ts +1 -1
  74. package/dist/stripe/client/Charge.d.ts.map +1 -1
  75. package/dist/stripe/client/Charge.js +3 -1
  76. package/dist/stripe/client/Charge.js.map +1 -1
  77. package/dist/stripe/server/Charge.d.ts +1 -1
  78. package/dist/stripe/server/Charge.d.ts.map +1 -1
  79. package/dist/stripe/server/Charge.js +9 -2
  80. package/dist/stripe/server/Charge.js.map +1 -1
  81. package/dist/stripe/server/Methods.d.ts +1 -1
  82. package/dist/stripe/server/Methods.d.ts.map +1 -1
  83. package/dist/stripe/server/internal/html.gen.d.ts +1 -1
  84. package/dist/stripe/server/internal/html.gen.d.ts.map +1 -1
  85. package/dist/stripe/server/internal/html.gen.js +1 -1
  86. package/dist/stripe/server/internal/html.gen.js.map +1 -1
  87. package/dist/tempo/Methods.d.ts +18 -0
  88. package/dist/tempo/Methods.d.ts.map +1 -1
  89. package/dist/tempo/Methods.js +16 -1
  90. package/dist/tempo/Methods.js.map +1 -1
  91. package/dist/tempo/client/Charge.d.ts +6 -0
  92. package/dist/tempo/client/Charge.d.ts.map +1 -1
  93. package/dist/tempo/client/Charge.js +9 -2
  94. package/dist/tempo/client/Charge.js.map +1 -1
  95. package/dist/tempo/client/Methods.d.ts +36 -7
  96. package/dist/tempo/client/Methods.d.ts.map +1 -1
  97. package/dist/tempo/client/Methods.js +12 -5
  98. package/dist/tempo/client/Methods.js.map +1 -1
  99. package/dist/tempo/client/index.d.ts +7 -4
  100. package/dist/tempo/client/index.d.ts.map +1 -1
  101. package/dist/tempo/client/index.js +5 -3
  102. package/dist/tempo/client/index.js.map +1 -1
  103. package/dist/tempo/index.d.ts +1 -0
  104. package/dist/tempo/index.d.ts.map +1 -1
  105. package/dist/tempo/index.js +1 -0
  106. package/dist/tempo/index.js.map +1 -1
  107. package/dist/tempo/internal/fee-payer.d.ts +21 -1
  108. package/dist/tempo/internal/fee-payer.d.ts.map +1 -1
  109. package/dist/tempo/internal/fee-payer.js +109 -4
  110. package/dist/tempo/internal/fee-payer.js.map +1 -1
  111. package/dist/tempo/{client → legacy/client}/ChannelOps.d.ts +19 -6
  112. package/dist/tempo/legacy/client/ChannelOps.d.ts.map +1 -0
  113. package/dist/tempo/{client → legacy/client}/ChannelOps.js +9 -3
  114. package/dist/tempo/legacy/client/ChannelOps.js.map +1 -0
  115. package/dist/tempo/{client → legacy/client}/Session.d.ts +23 -4
  116. package/dist/tempo/legacy/client/Session.d.ts.map +1 -0
  117. package/dist/tempo/{client → legacy/client}/Session.js +14 -7
  118. package/dist/tempo/legacy/client/Session.js.map +1 -0
  119. package/dist/tempo/{client → legacy/client}/SessionManager.d.ts +20 -5
  120. package/dist/tempo/legacy/client/SessionManager.d.ts.map +1 -0
  121. package/dist/tempo/{client → legacy/client}/SessionManager.js +20 -16
  122. package/dist/tempo/legacy/client/SessionManager.js.map +1 -0
  123. package/dist/tempo/legacy/client/index.d.ts +7 -0
  124. package/dist/tempo/legacy/client/index.d.ts.map +1 -0
  125. package/dist/tempo/legacy/client/index.js +5 -0
  126. package/dist/tempo/legacy/client/index.js.map +1 -0
  127. package/dist/tempo/legacy/index.d.ts +7 -0
  128. package/dist/tempo/legacy/index.d.ts.map +1 -0
  129. package/dist/tempo/legacy/index.js +7 -0
  130. package/dist/tempo/legacy/index.js.map +1 -0
  131. package/dist/tempo/{server → legacy/server}/Session.d.ts +28 -11
  132. package/dist/tempo/legacy/server/Session.d.ts.map +1 -0
  133. package/dist/tempo/{server → legacy/server}/Session.js +28 -23
  134. package/dist/tempo/legacy/server/Session.js.map +1 -0
  135. package/dist/tempo/legacy/server/index.d.ts +5 -0
  136. package/dist/tempo/legacy/server/index.d.ts.map +1 -0
  137. package/dist/tempo/legacy/server/index.js +5 -0
  138. package/dist/tempo/legacy/server/index.js.map +1 -0
  139. package/dist/tempo/{session → legacy/session}/Chain.d.ts +30 -23
  140. package/dist/tempo/legacy/session/Chain.d.ts.map +1 -0
  141. package/dist/tempo/{session → legacy/session}/Chain.js +12 -11
  142. package/dist/tempo/legacy/session/Chain.js.map +1 -0
  143. package/dist/tempo/{session → legacy/session}/Channel.d.ts +1 -0
  144. package/dist/tempo/legacy/session/Channel.d.ts.map +1 -0
  145. package/dist/tempo/legacy/session/Channel.js.map +1 -0
  146. package/dist/tempo/legacy/session/ChannelStore.d.ts +22 -0
  147. package/dist/tempo/legacy/session/ChannelStore.d.ts.map +1 -0
  148. package/dist/tempo/legacy/session/ChannelStore.js +6 -0
  149. package/dist/tempo/legacy/session/ChannelStore.js.map +1 -0
  150. package/dist/tempo/legacy/session/Types.d.ts +73 -0
  151. package/dist/tempo/legacy/session/Types.d.ts.map +1 -0
  152. package/dist/tempo/legacy/session/Types.js.map +1 -0
  153. package/dist/tempo/{session → legacy/session}/Voucher.d.ts +4 -4
  154. package/dist/tempo/legacy/session/Voucher.d.ts.map +1 -0
  155. package/dist/tempo/{session → legacy/session}/Voucher.js +1 -1
  156. package/dist/tempo/legacy/session/Voucher.js.map +1 -0
  157. package/dist/tempo/{session → legacy/session}/escrow.abi.d.ts +1 -0
  158. package/dist/tempo/{session → legacy/session}/escrow.abi.d.ts.map +1 -1
  159. package/dist/tempo/{session → legacy/session}/escrow.abi.js +1 -0
  160. package/dist/tempo/legacy/session/escrow.abi.js.map +1 -0
  161. package/dist/tempo/legacy/session/index.d.ts +9 -0
  162. package/dist/tempo/legacy/session/index.d.ts.map +1 -0
  163. package/dist/tempo/legacy/session/index.js +9 -0
  164. package/dist/tempo/legacy/session/index.js.map +1 -0
  165. package/dist/tempo/server/Charge.d.ts +1 -1
  166. package/dist/tempo/server/Charge.d.ts.map +1 -1
  167. package/dist/tempo/server/Charge.js +13 -16
  168. package/dist/tempo/server/Charge.js.map +1 -1
  169. package/dist/tempo/server/Methods.d.ts +63 -6
  170. package/dist/tempo/server/Methods.d.ts.map +1 -1
  171. package/dist/tempo/server/Methods.js +36 -8
  172. package/dist/tempo/server/Methods.js.map +1 -1
  173. package/dist/tempo/server/Subscription.d.ts +1 -1
  174. package/dist/tempo/server/Subscription.d.ts.map +1 -1
  175. package/dist/tempo/server/index.d.ts +6 -5
  176. package/dist/tempo/server/index.d.ts.map +1 -1
  177. package/dist/tempo/server/index.js +5 -5
  178. package/dist/tempo/server/index.js.map +1 -1
  179. package/dist/tempo/server/internal/html.gen.d.ts +1 -1
  180. package/dist/tempo/server/internal/html.gen.d.ts.map +1 -1
  181. package/dist/tempo/server/internal/html.gen.js +1 -1
  182. package/dist/tempo/server/internal/html.gen.js.map +1 -1
  183. package/dist/tempo/server/internal/request-body.d.ts +7 -2
  184. package/dist/tempo/server/internal/request-body.d.ts.map +1 -1
  185. package/dist/tempo/server/internal/request-body.js +20 -3
  186. package/dist/tempo/server/internal/request-body.js.map +1 -1
  187. package/dist/tempo/server/internal/transport.d.ts +8 -4
  188. package/dist/tempo/server/internal/transport.d.ts.map +1 -1
  189. package/dist/tempo/server/internal/transport.js +8 -7
  190. package/dist/tempo/server/internal/transport.js.map +1 -1
  191. package/dist/tempo/session/Snapshot.d.ts +32 -0
  192. package/dist/tempo/session/Snapshot.d.ts.map +1 -0
  193. package/dist/tempo/session/Snapshot.js +37 -0
  194. package/dist/tempo/session/Snapshot.js.map +1 -0
  195. package/dist/tempo/session/client/ChannelOps.d.ts +82 -0
  196. package/dist/tempo/session/client/ChannelOps.d.ts.map +1 -0
  197. package/dist/tempo/session/client/ChannelOps.js +204 -0
  198. package/dist/tempo/session/client/ChannelOps.js.map +1 -0
  199. package/dist/tempo/session/client/CredentialState.d.ts +262 -0
  200. package/dist/tempo/session/client/CredentialState.d.ts.map +1 -0
  201. package/dist/tempo/session/client/CredentialState.js +417 -0
  202. package/dist/tempo/session/client/CredentialState.js.map +1 -0
  203. package/dist/tempo/session/client/ReceiptCoordinator.d.ts +26 -0
  204. package/dist/tempo/session/client/ReceiptCoordinator.d.ts.map +1 -0
  205. package/dist/tempo/session/client/ReceiptCoordinator.js +61 -0
  206. package/dist/tempo/session/client/ReceiptCoordinator.js.map +1 -0
  207. package/dist/tempo/session/client/Runtime.d.ts +464 -0
  208. package/dist/tempo/session/client/Runtime.d.ts.map +1 -0
  209. package/dist/tempo/session/client/Runtime.js +499 -0
  210. package/dist/tempo/session/client/Runtime.js.map +1 -0
  211. package/dist/tempo/session/client/Session.d.ts +132 -0
  212. package/dist/tempo/session/client/Session.d.ts.map +1 -0
  213. package/dist/tempo/session/client/Session.js +55 -0
  214. package/dist/tempo/session/client/Session.js.map +1 -0
  215. package/dist/tempo/session/client/SessionManager.d.ts +120 -0
  216. package/dist/tempo/session/client/SessionManager.d.ts.map +1 -0
  217. package/dist/tempo/session/client/SessionManager.js +627 -0
  218. package/dist/tempo/session/client/SessionManager.js.map +1 -0
  219. package/dist/tempo/session/client/Transports.d.ts +449 -0
  220. package/dist/tempo/session/client/Transports.d.ts.map +1 -0
  221. package/dist/tempo/session/client/Transports.js +721 -0
  222. package/dist/tempo/session/client/Transports.js.map +1 -0
  223. package/dist/tempo/session/client/index.d.ts +12 -0
  224. package/dist/tempo/session/client/index.d.ts.map +1 -0
  225. package/dist/tempo/session/client/index.js +5 -0
  226. package/dist/tempo/session/client/index.js.map +1 -0
  227. package/dist/tempo/session/index.d.ts +7 -8
  228. package/dist/tempo/session/index.d.ts.map +1 -1
  229. package/dist/tempo/session/index.js +7 -8
  230. package/dist/tempo/session/index.js.map +1 -1
  231. package/dist/tempo/session/precompile/Chain.d.ts +319 -0
  232. package/dist/tempo/session/precompile/Chain.d.ts.map +1 -0
  233. package/dist/tempo/session/precompile/Chain.js +492 -0
  234. package/dist/tempo/session/precompile/Chain.js.map +1 -0
  235. package/dist/tempo/session/precompile/Channel.d.ts +46 -0
  236. package/dist/tempo/session/precompile/Channel.d.ts.map +1 -0
  237. package/dist/tempo/session/precompile/Channel.js +56 -0
  238. package/dist/tempo/session/precompile/Channel.js.map +1 -0
  239. package/dist/tempo/session/precompile/Protocol.d.ts +308 -0
  240. package/dist/tempo/session/precompile/Protocol.d.ts.map +1 -0
  241. package/dist/tempo/session/precompile/Protocol.js +264 -0
  242. package/dist/tempo/session/precompile/Protocol.js.map +1 -0
  243. package/dist/tempo/session/precompile/Voucher.d.ts +40 -0
  244. package/dist/tempo/session/precompile/Voucher.d.ts.map +1 -0
  245. package/dist/tempo/session/precompile/Voucher.js +126 -0
  246. package/dist/tempo/session/precompile/Voucher.js.map +1 -0
  247. package/dist/tempo/session/precompile/escrow.abi.d.ts +522 -0
  248. package/dist/tempo/session/precompile/escrow.abi.d.ts.map +1 -0
  249. package/dist/tempo/session/precompile/escrow.abi.js +224 -0
  250. package/dist/tempo/session/precompile/escrow.abi.js.map +1 -0
  251. package/dist/tempo/session/precompile/index.d.ts +24 -0
  252. package/dist/tempo/session/precompile/index.d.ts.map +1 -0
  253. package/dist/tempo/session/precompile/index.js +22 -0
  254. package/dist/tempo/session/precompile/index.js.map +1 -0
  255. package/dist/tempo/session/server/ChannelOps.d.ts +56 -0
  256. package/dist/tempo/session/server/ChannelOps.d.ts.map +1 -0
  257. package/dist/tempo/session/server/ChannelOps.js +91 -0
  258. package/dist/tempo/session/server/ChannelOps.js.map +1 -0
  259. package/dist/tempo/session/server/ChannelStore.d.ts +347 -0
  260. package/dist/tempo/session/server/ChannelStore.d.ts.map +1 -0
  261. package/dist/tempo/session/server/ChannelStore.js +404 -0
  262. package/dist/tempo/session/server/ChannelStore.js.map +1 -0
  263. package/dist/tempo/session/server/CredentialVerification.d.ts +85 -0
  264. package/dist/tempo/session/server/CredentialVerification.d.ts.map +1 -0
  265. package/dist/tempo/session/server/CredentialVerification.js +494 -0
  266. package/dist/tempo/session/server/CredentialVerification.js.map +1 -0
  267. package/dist/tempo/session/server/MeteredStream.d.ts +40 -0
  268. package/dist/tempo/session/server/MeteredStream.d.ts.map +1 -0
  269. package/dist/tempo/session/server/MeteredStream.js +42 -0
  270. package/dist/tempo/session/server/MeteredStream.js.map +1 -0
  271. package/dist/tempo/session/server/RequestState.d.ts +208 -0
  272. package/dist/tempo/session/server/RequestState.d.ts.map +1 -0
  273. package/dist/tempo/session/server/RequestState.js +252 -0
  274. package/dist/tempo/session/server/RequestState.js.map +1 -0
  275. package/dist/tempo/session/server/Session.d.ts +169 -0
  276. package/dist/tempo/session/server/Session.d.ts.map +1 -0
  277. package/dist/tempo/session/server/Session.js +351 -0
  278. package/dist/tempo/session/server/Session.js.map +1 -0
  279. package/dist/tempo/session/server/Settlement.d.ts +185 -0
  280. package/dist/tempo/session/server/Settlement.d.ts.map +1 -0
  281. package/dist/tempo/session/server/Settlement.js +250 -0
  282. package/dist/tempo/session/server/Settlement.js.map +1 -0
  283. package/dist/tempo/session/{Sse.d.ts → server/Sse.d.ts} +9 -56
  284. package/dist/tempo/session/server/Sse.d.ts.map +1 -0
  285. package/dist/tempo/session/server/Sse.js +184 -0
  286. package/dist/tempo/session/server/Sse.js.map +1 -0
  287. package/dist/tempo/session/server/Transports.d.ts +89 -0
  288. package/dist/tempo/session/server/Transports.d.ts.map +1 -0
  289. package/dist/tempo/session/server/Transports.js +149 -0
  290. package/dist/tempo/session/server/Transports.js.map +1 -0
  291. package/dist/tempo/session/server/Ws.d.ts +48 -0
  292. package/dist/tempo/session/server/Ws.d.ts.map +1 -0
  293. package/dist/tempo/session/server/Ws.js +244 -0
  294. package/dist/tempo/session/server/Ws.js.map +1 -0
  295. package/dist/tempo/session/server/index.d.ts +4 -0
  296. package/dist/tempo/session/server/index.d.ts.map +1 -0
  297. package/dist/tempo/session/server/index.js +2 -0
  298. package/dist/tempo/session/server/index.js.map +1 -0
  299. package/package.json +8 -3
  300. package/src/Challenge.ts +9 -7
  301. package/src/Constants.ts +58 -0
  302. package/src/Credential.ts +5 -4
  303. package/src/Method.ts +46 -5
  304. package/src/Receipt.ts +3 -2
  305. package/src/cli/cli.test.ts +23 -28
  306. package/src/cli/cli.ts +23 -10
  307. package/src/cli/mcp.test.ts +21 -7
  308. package/src/cli/plugins/tempo.ts +21 -8
  309. package/src/cli/utils.test.ts +25 -1
  310. package/src/cli/utils.ts +10 -0
  311. package/src/client/Methods.ts +5 -2
  312. package/src/client/Mppx.test-d.ts +10 -0
  313. package/src/client/Mppx.test.ts +75 -0
  314. package/src/client/Transport.ts +4 -5
  315. package/src/client/index.ts +11 -1
  316. package/src/client/internal/Fetch.test.ts +29 -4
  317. package/src/client/internal/Fetch.ts +17 -5
  318. package/src/env.d.ts +1 -1
  319. package/src/index.ts +1 -0
  320. package/src/internal/AcceptPayment.test.ts +61 -0
  321. package/src/internal/AcceptPayment.ts +21 -14
  322. package/src/mcp-sdk/client/McpClient.integration.test.ts +8 -7
  323. package/src/mcp-sdk/client/McpClient.test-d.ts +7 -0
  324. package/src/mcp-sdk/client/McpClient.ts +99 -67
  325. package/src/mcp-sdk/client/McpClient.unit.test.ts +131 -0
  326. package/src/middlewares/elysia.test.ts +8 -4
  327. package/src/middlewares/express.test.ts +8 -4
  328. package/src/middlewares/hono.test.ts +4 -4
  329. package/src/middlewares/nextjs.test.ts +8 -4
  330. package/src/proxy/Proxy.test.ts +8 -8
  331. package/src/server/Mppx.test-d.ts +54 -0
  332. package/src/server/Mppx.test.ts +274 -7
  333. package/src/server/Mppx.ts +487 -406
  334. package/src/server/Request.test.ts +81 -0
  335. package/src/server/Request.ts +23 -9
  336. package/src/server/Response.ts +2 -1
  337. package/src/server/Transport.ts +4 -3
  338. package/src/server/index.ts +1 -0
  339. package/src/stripe/client/Charge.test.ts +20 -5
  340. package/src/stripe/client/Charge.ts +6 -2
  341. package/src/stripe/server/Charge.test.ts +114 -1
  342. package/src/stripe/server/Charge.ts +13 -2
  343. package/src/stripe/server/internal/html/package.json +1 -1
  344. package/src/stripe/server/internal/html.gen.ts +1 -1
  345. package/src/tempo/AccessKeyAuthorization.test.ts +4 -94
  346. package/src/tempo/Methods.test.ts +45 -17
  347. package/src/tempo/Methods.ts +22 -0
  348. package/src/tempo/PublicExports.test-d.ts +105 -0
  349. package/src/tempo/client/Charge.test.ts +85 -0
  350. package/src/tempo/client/Charge.ts +19 -2
  351. package/src/tempo/client/Methods.ts +18 -6
  352. package/src/tempo/client/index.ts +15 -4
  353. package/src/tempo/index.ts +1 -0
  354. package/src/tempo/internal/fee-payer.test.ts +241 -17
  355. package/src/tempo/internal/fee-payer.ts +150 -4
  356. package/src/tempo/internal/fee-token.test.ts +14 -9
  357. package/src/tempo/legacy/AccessKeyAuthorization.test.ts +162 -0
  358. package/src/tempo/legacy/README.md +9 -0
  359. package/src/tempo/{client → legacy/client}/ChannelOps.test.ts +6 -7
  360. package/src/tempo/{client → legacy/client}/ChannelOps.ts +22 -9
  361. package/src/tempo/{client → legacy/client}/Session.test.ts +51 -9
  362. package/src/tempo/{client → legacy/client}/Session.ts +25 -11
  363. package/src/tempo/{client → legacy/client}/SessionManager.test.ts +81 -9
  364. package/src/tempo/{client → legacy/client}/SessionManager.ts +41 -20
  365. package/src/tempo/legacy/client/index.ts +6 -0
  366. package/src/tempo/legacy/index.ts +6 -0
  367. package/src/tempo/{server → legacy/server}/Session.test.ts +162 -63
  368. package/src/tempo/{server → legacy/server}/Session.ts +49 -37
  369. package/src/tempo/legacy/server/index.ts +4 -0
  370. package/src/tempo/{session → legacy/session}/Chain.test.ts +3 -4
  371. package/src/tempo/{session → legacy/session}/Chain.ts +94 -63
  372. package/src/tempo/{session → legacy/session}/Channel.ts +1 -0
  373. package/src/tempo/legacy/session/ChannelStore.test.ts +58 -0
  374. package/src/tempo/legacy/session/ChannelStore.ts +39 -0
  375. package/src/tempo/legacy/session/Types.ts +91 -0
  376. package/src/tempo/{session → legacy/session}/Voucher.ts +12 -8
  377. package/src/tempo/{session → legacy/session}/escrow.abi.ts +1 -0
  378. package/src/tempo/legacy/session/index.ts +8 -0
  379. package/src/tempo/server/AtomicStore.test-d.ts +16 -11
  380. package/src/tempo/server/Charge.test.ts +92 -14
  381. package/src/tempo/server/Charge.ts +18 -16
  382. package/src/tempo/server/Methods.ts +54 -8
  383. package/src/tempo/server/Sse.test.ts +2 -2
  384. package/src/tempo/server/index.ts +6 -5
  385. package/src/tempo/server/internal/html/package.json +1 -1
  386. package/src/tempo/server/internal/html.gen.ts +1 -1
  387. package/src/tempo/server/internal/request-body.test.ts +37 -4
  388. package/src/tempo/server/internal/request-body.ts +25 -6
  389. package/src/tempo/server/internal/transport.test.ts +4 -4
  390. package/src/tempo/server/internal/transport.ts +19 -10
  391. package/src/tempo/session/Snapshot.test.ts +41 -0
  392. package/src/tempo/session/Snapshot.ts +74 -0
  393. package/src/tempo/session/client/ChannelOps.test.ts +163 -0
  394. package/src/tempo/session/client/ChannelOps.ts +344 -0
  395. package/src/tempo/session/client/CredentialState.test.ts +645 -0
  396. package/src/tempo/session/client/CredentialState.ts +814 -0
  397. package/src/tempo/session/client/ReceiptCoordinator.ts +95 -0
  398. package/src/tempo/session/client/Runtime.test.ts +1092 -0
  399. package/src/tempo/session/client/Runtime.ts +986 -0
  400. package/src/tempo/session/client/Session.test.ts +734 -0
  401. package/src/tempo/session/client/Session.ts +97 -0
  402. package/src/tempo/session/client/SessionManager.test.ts +1308 -0
  403. package/src/tempo/session/client/SessionManager.ts +845 -0
  404. package/src/tempo/session/client/Transports.test.ts +837 -0
  405. package/src/tempo/session/client/Transports.ts +1292 -0
  406. package/src/tempo/session/client/index.ts +37 -0
  407. package/src/tempo/session/index.ts +7 -8
  408. package/src/tempo/session/precompile/Chain.integration.test.ts +321 -0
  409. package/src/tempo/session/precompile/Chain.test.ts +1258 -0
  410. package/src/tempo/session/precompile/Chain.ts +979 -0
  411. package/src/tempo/session/precompile/Channel.test.ts +138 -0
  412. package/src/tempo/session/precompile/Channel.ts +103 -0
  413. package/src/tempo/session/precompile/Protocol.test.ts +358 -0
  414. package/src/tempo/session/precompile/Protocol.ts +520 -0
  415. package/src/tempo/session/precompile/Voucher.test.ts +316 -0
  416. package/src/tempo/session/precompile/Voucher.ts +160 -0
  417. package/src/tempo/session/precompile/escrow.abi.ts +226 -0
  418. package/src/tempo/session/precompile/index.ts +33 -0
  419. package/src/tempo/session/server/ChannelOps.test.ts +129 -0
  420. package/src/tempo/session/server/ChannelOps.ts +157 -0
  421. package/src/tempo/session/{ChannelStore.test.ts → server/ChannelStore.test.ts} +536 -29
  422. package/src/tempo/session/server/ChannelStore.ts +835 -0
  423. package/src/tempo/session/server/CredentialVerification.test.ts +146 -0
  424. package/src/tempo/session/server/CredentialVerification.ts +710 -0
  425. package/src/tempo/session/server/MeteredStream.ts +88 -0
  426. package/src/tempo/session/server/RequestState.test.ts +531 -0
  427. package/src/tempo/session/server/RequestState.ts +499 -0
  428. package/src/tempo/session/server/Session.integration.test.ts +444 -0
  429. package/src/tempo/session/server/Session.test.ts +3253 -0
  430. package/src/tempo/session/server/Session.ts +543 -0
  431. package/src/tempo/session/server/Settlement.test.ts +242 -0
  432. package/src/tempo/session/server/Settlement.ts +470 -0
  433. package/src/tempo/session/{Sse.test.ts → server/Sse.test.ts} +37 -3
  434. package/src/tempo/session/server/Sse.ts +256 -0
  435. package/src/tempo/session/server/Transports.test.ts +346 -0
  436. package/src/tempo/session/server/Transports.ts +255 -0
  437. package/src/tempo/session/{Ws.test.ts → server/Ws.test.ts} +4 -4
  438. package/src/tempo/session/server/Ws.ts +384 -0
  439. package/src/tempo/session/server/index.ts +8 -0
  440. package/dist/tempo/client/ChannelOps.d.ts.map +0 -1
  441. package/dist/tempo/client/ChannelOps.js.map +0 -1
  442. package/dist/tempo/client/Session.d.ts.map +0 -1
  443. package/dist/tempo/client/Session.js.map +0 -1
  444. package/dist/tempo/client/SessionManager.d.ts.map +0 -1
  445. package/dist/tempo/client/SessionManager.js.map +0 -1
  446. package/dist/tempo/server/Session.d.ts.map +0 -1
  447. package/dist/tempo/server/Session.js.map +0 -1
  448. package/dist/tempo/session/Chain.d.ts.map +0 -1
  449. package/dist/tempo/session/Chain.js.map +0 -1
  450. package/dist/tempo/session/Channel.d.ts.map +0 -1
  451. package/dist/tempo/session/Channel.js.map +0 -1
  452. package/dist/tempo/session/ChannelStore.d.ts +0 -117
  453. package/dist/tempo/session/ChannelStore.d.ts.map +0 -1
  454. package/dist/tempo/session/ChannelStore.js +0 -172
  455. package/dist/tempo/session/ChannelStore.js.map +0 -1
  456. package/dist/tempo/session/Receipt.d.ts +0 -22
  457. package/dist/tempo/session/Receipt.d.ts.map +0 -1
  458. package/dist/tempo/session/Receipt.js +0 -34
  459. package/dist/tempo/session/Receipt.js.map +0 -1
  460. package/dist/tempo/session/Sse.d.ts.map +0 -1
  461. package/dist/tempo/session/Sse.js +0 -363
  462. package/dist/tempo/session/Sse.js.map +0 -1
  463. package/dist/tempo/session/Types.d.ts +0 -78
  464. package/dist/tempo/session/Types.d.ts.map +0 -1
  465. package/dist/tempo/session/Types.js.map +0 -1
  466. package/dist/tempo/session/Voucher.d.ts.map +0 -1
  467. package/dist/tempo/session/Voucher.js.map +0 -1
  468. package/dist/tempo/session/Ws.d.ts +0 -87
  469. package/dist/tempo/session/Ws.d.ts.map +0 -1
  470. package/dist/tempo/session/Ws.js +0 -443
  471. package/dist/tempo/session/Ws.js.map +0 -1
  472. package/dist/tempo/session/escrow.abi.js.map +0 -1
  473. package/src/tempo/session/ChannelStore.ts +0 -308
  474. package/src/tempo/session/Receipt.test.ts +0 -89
  475. package/src/tempo/session/Receipt.ts +0 -46
  476. package/src/tempo/session/Sse.ts +0 -462
  477. package/src/tempo/session/Types.ts +0 -86
  478. package/src/tempo/session/Ws.ts +0 -576
  479. /package/dist/tempo/{session → legacy/session}/Channel.js +0 -0
  480. /package/dist/tempo/{session → legacy/session}/Types.js +0 -0
  481. /package/src/tempo/{session → legacy/session}/Channel.test.ts +0 -0
  482. /package/src/tempo/{session → legacy/session}/Voucher.test.ts +0 -0
  483. /package/src/tempo/session/{Sse.fuzz.test.ts → server/Sse.fuzz.test.ts} +0 -0
@@ -1,576 +0,0 @@
1
- import * as Credential from '../../Credential.js'
2
- import { ChannelClosedError } from '../../Errors.js'
3
- import * as ChannelStore from './ChannelStore.js'
4
- import { deserializeSessionReceipt } from './Receipt.js'
5
- import { createSessionReceipt } from './Receipt.js'
6
- import type { SessionController } from './Sse.js'
7
- import type { NeedVoucherEvent, SessionCredentialPayload, SessionReceipt } from './Types.js'
8
-
9
- export type { SessionController } from './Sse.js'
10
-
11
- export type SessionRouteResult =
12
- | { status: 402; challenge: Response }
13
- | { status: 200; withReceipt(response?: Response): Response }
14
-
15
- export type SessionRoute = (request: Request) => Promise<SessionRouteResult>
16
-
17
- export type Socket = {
18
- close(code?: number, reason?: string): unknown
19
- send(data: string): unknown
20
- addEventListener?: (
21
- type: 'close' | 'error' | 'message',
22
- listener: ((event: any) => void) | { handleEvent(event: any): void },
23
- ) => unknown
24
- removeEventListener?: (
25
- type: 'close' | 'error' | 'message',
26
- listener: ((event: any) => void) | { handleEvent(event: any): void },
27
- ) => unknown
28
- on?: (type: 'close' | 'error' | 'message', listener: (...args: any[]) => void) => unknown
29
- off?: (type: 'close' | 'error' | 'message', listener: (...args: any[]) => void) => unknown
30
- }
31
-
32
- export type Message =
33
- | { mpp: 'authorization'; authorization: string }
34
- | { mpp: 'message'; data: string }
35
- | { mpp: 'payment-close-request' }
36
- | { mpp: 'payment-close-ready'; data: SessionReceipt }
37
- | { mpp: 'payment-error'; status: number; message: string }
38
- | { mpp: 'payment-need-voucher'; data: NeedVoucherEvent }
39
- | { mpp: 'payment-receipt'; data: SessionReceipt }
40
-
41
- export function formatAuthorizationMessage(authorization: string): string {
42
- return JSON.stringify({ mpp: 'authorization', authorization } satisfies Message)
43
- }
44
-
45
- export function formatApplicationMessage(data: string): string {
46
- return JSON.stringify({ mpp: 'message', data } satisfies Message)
47
- }
48
-
49
- export function formatCloseRequestMessage(): string {
50
- return JSON.stringify({ mpp: 'payment-close-request' } satisfies Message)
51
- }
52
-
53
- export function formatCloseReadyMessage(receipt: SessionReceipt): string {
54
- return JSON.stringify({ mpp: 'payment-close-ready', data: receipt } satisfies Message)
55
- }
56
-
57
- export function formatNeedVoucherMessage(params: NeedVoucherEvent): string {
58
- return JSON.stringify({ mpp: 'payment-need-voucher', data: params } satisfies Message)
59
- }
60
-
61
- export function formatReceiptMessage(receipt: SessionReceipt): string {
62
- return JSON.stringify({ mpp: 'payment-receipt', data: receipt } satisfies Message)
63
- }
64
-
65
- export function formatErrorMessage(parameters: { message: string; status: number }): string {
66
- return JSON.stringify({ mpp: 'payment-error', ...parameters } satisfies Message)
67
- }
68
-
69
- export function parseMessage(raw: string): Message | null {
70
- try {
71
- const parsed = JSON.parse(raw) as Record<string, unknown>
72
- if (parsed.mpp === 'authorization' && typeof parsed.authorization === 'string') {
73
- return { mpp: 'authorization', authorization: parsed.authorization }
74
- }
75
- if (parsed.mpp === 'message' && typeof parsed.data === 'string') {
76
- return { mpp: 'message', data: parsed.data }
77
- }
78
- if (parsed.mpp === 'payment-close-request') {
79
- return { mpp: 'payment-close-request' }
80
- }
81
- if (parsed.mpp === 'payment-close-ready' && isSessionReceipt(parsed.data)) {
82
- return { mpp: 'payment-close-ready', data: parsed.data }
83
- }
84
- if (
85
- parsed.mpp === 'payment-error' &&
86
- typeof parsed.status === 'number' &&
87
- typeof parsed.message === 'string'
88
- ) {
89
- return { mpp: 'payment-error', status: parsed.status, message: parsed.message }
90
- }
91
- if (parsed.mpp === 'payment-need-voucher' && isNeedVoucherEvent(parsed.data)) {
92
- return { mpp: 'payment-need-voucher', data: parsed.data }
93
- }
94
- if (parsed.mpp === 'payment-receipt' && isSessionReceipt(parsed.data)) {
95
- return { mpp: 'payment-receipt', data: parsed.data }
96
- }
97
- return null
98
- } catch {
99
- return null
100
- }
101
- }
102
-
103
- /**
104
- * Bridge a WebSocket connection to a Tempo session payment flow.
105
- *
106
- * Credential verification is performed by routing each in-band authorization
107
- * frame through `route` as a **synthetic `POST` request** that carries only
108
- * the `Authorization` header. The synthetic request does not include cookies,
109
- * bodies, query parameters, or other headers from the original WebSocket
110
- * upgrade request. Do not wrap `route` with middleware that depends on
111
- * HTTP-specific context beyond the `Authorization` header.
112
- */
113
- export async function serve(options: serve.Options): Promise<void> {
114
- const {
115
- amount: expectedAmount,
116
- generate,
117
- pollIntervalMs = 100,
118
- route,
119
- socket,
120
- store: rawStore,
121
- url,
122
- } = options
123
- const store = 'getChannel' in rawStore ? rawStore : ChannelStore.fromStore(rawStore)
124
- const requestUrl = normalizeHttpUrl(url)
125
- const maxQueuedPaymentMessages = 32
126
-
127
- const abortController = new AbortController()
128
- let closed = false
129
- let closeReadySent = false
130
- let closeRequestHandled = false
131
- let closeRequested = false
132
- let streamStarted = false
133
- let streamTask: Promise<void> | null = null
134
- let streamContext: {
135
- challengeId: string
136
- channelId: SessionCredentialPayload['channelId']
137
- tickCost: bigint
138
- } | null = null
139
- let action = Promise.resolve()
140
- let queuedActions = 0
141
-
142
- const close = async (code = 1000, reason?: string) => {
143
- if (closed) return
144
- closed = true
145
- abortController.abort()
146
- unsubscribe()
147
- await Promise.resolve(socket.close(code, reason))
148
- }
149
-
150
- const sendCloseReady = async () => {
151
- if (closeReadySent || !streamContext || closed) return
152
- closeReadySent = true
153
-
154
- const channel = await store.getChannel(streamContext.channelId)
155
- if (!channel) throw new Error('channel not found')
156
-
157
- const receipt = createSessionReceipt({
158
- challengeId: streamContext.challengeId,
159
- channelId: streamContext.channelId,
160
- acceptedCumulative: channel.highestVoucherAmount,
161
- spent: channel.spent,
162
- units: channel.units,
163
- })
164
- await send(socket, formatCloseReadyMessage(receipt))
165
- }
166
-
167
- const runStream = async (context: {
168
- challengeId: string
169
- channelId: SessionCredentialPayload['channelId']
170
- tickCost: bigint
171
- }) => {
172
- let reservedAmount = 0n
173
- let reservedUnits = 0
174
-
175
- const charge = () =>
176
- reserveChargeOrWait({
177
- amount: context.tickCost,
178
- channelId: context.channelId,
179
- reservedAmount,
180
- emit: (message) => send(socket, message),
181
- pollIntervalMs,
182
- signal: abortController.signal,
183
- store,
184
- }).then(() => {
185
- reservedAmount += context.tickCost
186
- reservedUnits += 1
187
- })
188
-
189
- const iterable: AsyncIterable<string> =
190
- typeof generate === 'function' ? generate({ charge }) : generate
191
-
192
- try {
193
- for await (const value of iterable) {
194
- if (abortController.signal.aborted) break
195
- if (typeof generate !== 'function') await charge()
196
- await commitReservedCharges({
197
- store,
198
- channelId: context.channelId,
199
- amount: reservedAmount,
200
- units: reservedUnits,
201
- })
202
- reservedAmount = 0n
203
- reservedUnits = 0
204
- await send(socket, formatApplicationMessage(value))
205
- }
206
-
207
- if (!abortController.signal.aborted) await sendCloseReady()
208
- } catch (error) {
209
- if (!abortController.signal.aborted) {
210
- await send(
211
- socket,
212
- formatErrorMessage({
213
- message: error instanceof Error ? error.message : 'websocket session failed',
214
- status: 500,
215
- }),
216
- )
217
- await close(1011, 'websocket session failed')
218
- }
219
- } finally {
220
- streamTask = null
221
- }
222
- }
223
-
224
- const requestClose = async () => {
225
- if (closed) return
226
- if (closeRequestHandled) return
227
- closeRequestHandled = true
228
- closeRequested = true
229
- abortController.abort()
230
- await streamTask?.catch(() => {})
231
- await sendCloseReady()
232
- }
233
-
234
- const processAuthorization = async (authorization: string) => {
235
- if (closed) return
236
- const credential = Credential.deserialize<SessionCredentialPayload>(authorization)
237
- const payload = credential.payload
238
- if (payload.action === 'close') closeRequested = true
239
-
240
- if (expectedAmount && credential.challenge.request.amount !== expectedAmount) {
241
- await send(
242
- socket,
243
- formatErrorMessage({
244
- message: 'credential amount does not match this endpoint',
245
- status: 402,
246
- }),
247
- )
248
- await close(1008, 'credential amount does not match this endpoint')
249
- return
250
- }
251
-
252
- const result = await route(
253
- new Request(requestUrl, {
254
- method: 'POST',
255
- headers: { Authorization: authorization },
256
- }),
257
- )
258
-
259
- if (result.status === 402) {
260
- const response = result.challenge
261
- const message =
262
- (await response.text().catch(() => '')) ||
263
- response.statusText ||
264
- 'payment verification failed'
265
- await send(socket, formatErrorMessage({ message, status: response.status }))
266
- await close(1008, message)
267
- return
268
- }
269
-
270
- const response = result.withReceipt(new Response(null, { status: 204 }))
271
- const receiptHeader = response.headers.get('Payment-Receipt')
272
- if (!receiptHeader) {
273
- throw new Error('management response missing Payment-Receipt header')
274
- }
275
-
276
- const receipt = deserializeSessionReceipt(receiptHeader)
277
- await send(socket, formatReceiptMessage(receipt))
278
-
279
- if (payload.action === 'close') {
280
- await close(1000, 'payment session closed')
281
- return
282
- }
283
-
284
- if (payload.action === 'topUp') return
285
- if (streamStarted || closeRequested) return
286
- streamStarted = true
287
- streamContext = {
288
- challengeId: credential.challenge.id,
289
- channelId: payload.channelId,
290
- tickCost: BigInt(credential.challenge.request.amount as string),
291
- }
292
- // Defer the first application frame until after the client receives the
293
- // auth receipt and has a chance to install its own message listeners.
294
- setTimeout(() => {
295
- if (closeRequested || closed || !streamContext) return
296
- streamTask = runStream(streamContext)
297
- }, 0)
298
- }
299
-
300
- const onMessage = (payload: unknown) => {
301
- if (closed) return
302
- const raw = toText(payload)
303
- if (!raw) return
304
- const message = parseMessage(raw)
305
- if (!message) return
306
-
307
- if (message.mpp === 'payment-close-request') {
308
- closeRequested = true
309
- abortController.abort()
310
- }
311
-
312
- const work =
313
- message.mpp === 'authorization'
314
- ? () => processAuthorization(message.authorization)
315
- : message.mpp === 'payment-close-request'
316
- ? () => requestClose()
317
- : null
318
-
319
- if (!work) return
320
- if (queuedActions >= maxQueuedPaymentMessages) {
321
- void send(
322
- socket,
323
- formatErrorMessage({
324
- message: 'too many queued payment messages',
325
- status: 429,
326
- }),
327
- ).catch(() => {})
328
- void close(1008, 'too many queued payment messages')
329
- return
330
- }
331
-
332
- queuedActions++
333
- action = action
334
- .then(async () => {
335
- try {
336
- if (closed) return
337
- await work()
338
- } finally {
339
- queuedActions--
340
- }
341
- })
342
- .catch(async (error) => {
343
- if (!closed) {
344
- await send(
345
- socket,
346
- formatErrorMessage({
347
- message: error instanceof Error ? error.message : 'invalid payment message',
348
- status: 400,
349
- }),
350
- )
351
- await close(1008, 'invalid payment message')
352
- }
353
- })
354
- }
355
-
356
- const onClose = () => {
357
- if (closed) return
358
- closed = true
359
- abortController.abort()
360
- unsubscribe()
361
- }
362
-
363
- const unsubscribe = subscribe(socket, {
364
- close: onClose,
365
- error: onClose,
366
- message: onMessage,
367
- })
368
- }
369
-
370
- export declare namespace serve {
371
- type Options = {
372
- /** Expected per-tick amount in raw units. When set, credentials whose
373
- * challenge `request.amount` does not match are rejected. Use this to
374
- * pin the price when the route is backed by `Mppx.compose()` with
375
- * multiple offers — otherwise a client can select the cheapest offer
376
- * and still receive the same stream. */
377
- amount?: string | undefined
378
- generate: AsyncIterable<string> | ((stream: SessionController) => AsyncIterable<string>)
379
- pollIntervalMs?: number | undefined
380
- /** Payment route handler. Receives synthetic `POST` requests with only
381
- * the `Authorization` header — no cookies, bodies, or upgrade headers. */
382
- route: SessionRoute
383
- socket: Socket
384
- store: ChannelStore.ChannelStore | import('../../Store.js').Store
385
- url: string | URL
386
- }
387
- }
388
-
389
- function normalizeHttpUrl(value: string | URL): string {
390
- const url = new URL(value.toString())
391
- if (url.protocol === 'ws:') url.protocol = 'http:'
392
- if (url.protocol === 'wss:') url.protocol = 'https:'
393
- return url.toString()
394
- }
395
-
396
- async function reserveChargeOrWait(options: {
397
- amount: bigint
398
- channelId: SessionCredentialPayload['channelId']
399
- reservedAmount: bigint
400
- emit: (message: string) => Promise<void>
401
- pollIntervalMs: number
402
- signal: AbortSignal
403
- store: ChannelStore.ChannelStore
404
- }): Promise<void> {
405
- const { amount, channelId, emit, pollIntervalMs, reservedAmount, signal, store } = options
406
-
407
- let channel = await store.getChannel(channelId)
408
- if (!channel) throw new Error('channel not found')
409
- throwIfChannelClosed(channel)
410
-
411
- const hasHeadroom = (state: ChannelStore.State) =>
412
- state.highestVoucherAmount - state.spent - reservedAmount >= amount
413
-
414
- if (hasHeadroom(channel)) return
415
-
416
- await emit(
417
- formatNeedVoucherMessage({
418
- channelId,
419
- requiredCumulative: (channel.spent + reservedAmount + amount).toString(),
420
- acceptedCumulative: channel.highestVoucherAmount.toString(),
421
- deposit: channel.deposit.toString(),
422
- }),
423
- )
424
-
425
- while (!hasHeadroom(channel)) {
426
- await waitForUpdate(store, channelId, pollIntervalMs, signal)
427
- channel = await store.getChannel(channelId)
428
- if (!channel) throw new Error('channel not found')
429
- throwIfChannelClosed(channel)
430
- }
431
- }
432
-
433
- async function commitReservedCharges(options: {
434
- amount: bigint
435
- channelId: SessionCredentialPayload['channelId']
436
- units: number
437
- store: ChannelStore.ChannelStore
438
- }): Promise<void> {
439
- const { amount, channelId, units, store } = options
440
- if (amount === 0n || units === 0) return
441
-
442
- let committed = false
443
- const channel = await store.updateChannel(channelId, (current) => {
444
- if (!current) return null
445
- if (current.finalized) return current
446
- if (current.closeRequestedAt !== 0n) return current
447
- if (current.highestVoucherAmount - current.spent < amount) return current
448
- committed = true
449
- return {
450
- ...current,
451
- spent: current.spent + amount,
452
- units: current.units + units,
453
- }
454
- })
455
-
456
- if (!channel) throw new Error('channel not found')
457
- if (channel.finalized) throw new ChannelClosedError({ reason: 'channel is finalized' })
458
- if (channel.closeRequestedAt !== 0n)
459
- throw new ChannelClosedError({ reason: 'channel has a pending close request' })
460
- if (!committed) throw new Error('reserved voucher coverage is no longer available')
461
- }
462
-
463
- function throwIfChannelClosed(channel: ChannelStore.State): void {
464
- if (channel.finalized) throw new ChannelClosedError({ reason: 'channel is finalized' })
465
- if (channel.closeRequestedAt !== 0n)
466
- throw new ChannelClosedError({ reason: 'channel has a pending close request' })
467
- }
468
-
469
- async function waitForUpdate(
470
- store: ChannelStore.ChannelStore,
471
- channelId: SessionCredentialPayload['channelId'],
472
- pollIntervalMs: number,
473
- signal: AbortSignal,
474
- ): Promise<void> {
475
- throwIfAborted(signal)
476
-
477
- if (store.waitForUpdate) {
478
- await Promise.race([store.waitForUpdate(channelId), onceAborted(signal)])
479
- return
480
- }
481
-
482
- await sleep(pollIntervalMs, signal)
483
- }
484
-
485
- function subscribe(
486
- socket: Socket,
487
- handlers: {
488
- close: () => void
489
- error: () => void
490
- message: (payload: unknown) => void
491
- },
492
- ) {
493
- if (socket.addEventListener && socket.removeEventListener) {
494
- const onMessage = (event: Event | MessageEvent) => {
495
- const data = (event as MessageEvent).data
496
- handlers.message(data)
497
- }
498
- socket.addEventListener('message', onMessage)
499
- socket.addEventListener('close', handlers.close)
500
- socket.addEventListener('error', handlers.error)
501
- return () => {
502
- socket.removeEventListener?.('message', onMessage)
503
- socket.removeEventListener?.('close', handlers.close)
504
- socket.removeEventListener?.('error', handlers.error)
505
- }
506
- }
507
-
508
- if (socket.on && socket.off) {
509
- const onMessage = (data: unknown) => handlers.message(data)
510
- socket.on('message', onMessage)
511
- socket.on('close', handlers.close)
512
- socket.on('error', handlers.error)
513
- return () => {
514
- socket.off?.('message', onMessage)
515
- socket.off?.('close', handlers.close)
516
- socket.off?.('error', handlers.error)
517
- }
518
- }
519
-
520
- throw new Error('unsupported websocket implementation')
521
- }
522
-
523
- async function send(socket: Socket, data: string) {
524
- await Promise.resolve(socket.send(data))
525
- }
526
-
527
- function toText(value: unknown): string | null {
528
- if (typeof value === 'string') return value
529
- if (value instanceof ArrayBuffer) return new TextDecoder().decode(value)
530
- if (ArrayBuffer.isView(value)) {
531
- return new TextDecoder().decode(value)
532
- }
533
- return null
534
- }
535
-
536
- function sleep(ms: number, signal: AbortSignal) {
537
- return new Promise<void>((resolve, reject) => {
538
- const timeout = setTimeout(() => {
539
- signal.removeEventListener('abort', onAbort)
540
- resolve()
541
- }, ms)
542
- const onAbort = () => {
543
- clearTimeout(timeout)
544
- reject(signal.reason ?? new Error('aborted'))
545
- }
546
- signal.addEventListener('abort', onAbort, { once: true })
547
- })
548
- }
549
-
550
- function onceAborted(signal: AbortSignal) {
551
- return new Promise<never>((_, reject) => {
552
- if (signal.aborted) {
553
- reject(signal.reason ?? new Error('aborted'))
554
- return
555
- }
556
- signal.addEventListener('abort', () => reject(signal.reason ?? new Error('aborted')), {
557
- once: true,
558
- })
559
- })
560
- }
561
-
562
- function throwIfAborted(signal: AbortSignal) {
563
- if (signal.aborted) throw signal.reason ?? new Error('aborted')
564
- }
565
-
566
- function isSessionReceipt(value: unknown): value is SessionReceipt {
567
- if (typeof value !== 'object' || value === null) return false
568
- const v = value as Record<string, unknown>
569
- return typeof v.challengeId === 'string' && typeof v.channelId === 'string'
570
- }
571
-
572
- function isNeedVoucherEvent(value: unknown): value is NeedVoucherEvent {
573
- if (typeof value !== 'object' || value === null) return false
574
- const v = value as Record<string, unknown>
575
- return typeof v.channelId === 'string' && typeof v.requiredCumulative === 'string'
576
- }
File without changes