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
@@ -0,0 +1,520 @@
1
+ import { Base64 } from 'ox'
2
+ import type { Address, Hex } from 'viem'
3
+
4
+ import type * as Challenge from '../../../Challenge.js'
5
+
6
+ const maxUint96 = (1n << 96n) - 1n
7
+
8
+ /** Amount encoded by TIP20EscrowChannel as a `uint96` on-chain value. */
9
+ export type Uint96 = bigint
10
+
11
+ /** Decimal string containing raw token units, before applying token decimals. */
12
+ export type RawAmountString = string
13
+
14
+ /** Returns whether a bigint can be encoded as a TIP20EscrowChannel `uint96` amount. */
15
+ export function isUint96(value: bigint): value is Uint96 {
16
+ return value >= 0n && value <= maxUint96
17
+ }
18
+
19
+ /** Converts a bigint into a TIP20EscrowChannel `uint96` amount after validating bounds. */
20
+ export function uint96(value: bigint): Uint96 {
21
+ assertUint96(value)
22
+ return value
23
+ }
24
+
25
+ /** Asserts that a bigint can be encoded as a TIP20EscrowChannel `uint96` amount. */
26
+ export function assertUint96(value: bigint): void {
27
+ if (!isUint96(value)) throw new Error(`Value ${value} is outside uint96 bounds.`)
28
+ }
29
+
30
+ /** Full TIP-1034 channel descriptor used to derive and verify a channel ID. */
31
+ export type ChannelDescriptor = {
32
+ /** Wallet that funds the channel and authorizes voucher spend. */
33
+ payer: Address
34
+ /** Wallet that receives settlement from the channel. */
35
+ payee: Address
36
+ /** Optional payee-side operator authorized for channel operations; zero address means unset. */
37
+ operator: Address
38
+ /** TIP-20 token escrowed by the channel. */
39
+ token: Address
40
+ /** Payer-selected entropy that makes otherwise identical descriptors unique. */
41
+ salt: Hex
42
+ /** Address authorized to sign vouchers; zero address delegates to `payer`. */
43
+ authorizedSigner: Address
44
+ /** Hash of the signed expiring-nonce open transaction required by TIP-1034. */
45
+ expiringNonceHash: Hex
46
+ }
47
+
48
+ /** Public descriptor for a TIP-1034 session channel. */
49
+ export type SessionDescriptor = ChannelDescriptor
50
+
51
+ /**
52
+ * Voucher for cumulative payment.
53
+ * Cumulative monotonicity prevents replay attacks.
54
+ */
55
+ export type Voucher = {
56
+ channelId: Hex
57
+ cumulativeAmount: bigint
58
+ }
59
+
60
+ /**
61
+ * Signed voucher with EIP-712 signature.
62
+ */
63
+ export type SignedVoucher = Voucher & { signature: Hex }
64
+
65
+ /**
66
+ * Credential payload that opens a TIP-1034 precompile channel and authorizes initial spend.
67
+ */
68
+ export type OpenCredentialPayload = {
69
+ action: 'open'
70
+ type: 'transaction'
71
+ /** TIP-1034 channel ID derived from descriptor, escrow, and chain ID. */
72
+ channelId: Hex
73
+ /** Signed Tempo transaction containing the precompile `open` call. */
74
+ transaction: Hex
75
+ /** Voucher signature for `cumulativeAmount`. */
76
+ signature: Hex
77
+ /** Descriptor needed to recover and verify the channel. */
78
+ descriptor: ChannelDescriptor
79
+ /** Initial cumulative spend authorized by the opening voucher, as raw units. */
80
+ cumulativeAmount: RawAmountString
81
+ /** Voucher signer selected for the opened channel. */
82
+ authorizedSigner?: Address | undefined
83
+ }
84
+
85
+ /**
86
+ * Credential payload that adds deposit to an existing TIP-1034 precompile channel.
87
+ */
88
+ export type TopUpCredentialPayload = {
89
+ action: 'topUp'
90
+ type: 'transaction'
91
+ /** TIP-1034 channel ID being topped up. */
92
+ channelId: Hex
93
+ /** Signed Tempo transaction containing the precompile `topUp` call. */
94
+ transaction: Hex
95
+ /** Descriptor for the channel being topped up. */
96
+ descriptor: ChannelDescriptor
97
+ /** Additional deposit to add, as raw units. */
98
+ additionalDeposit: RawAmountString
99
+ }
100
+
101
+ /**
102
+ * Credential payload that increases cumulative spend authorization.
103
+ */
104
+ export type VoucherCredentialPayload = {
105
+ action: 'voucher'
106
+ /** TIP-1034 channel ID the voucher applies to. */
107
+ channelId: Hex
108
+ /** Descriptor for the voucher's channel. */
109
+ descriptor: ChannelDescriptor
110
+ /** Highest cumulative spend authorized by this voucher, as raw units. */
111
+ cumulativeAmount: RawAmountString
112
+ /** Voucher signature for `cumulativeAmount`. */
113
+ signature: Hex
114
+ }
115
+
116
+ /**
117
+ * Credential payload that cooperatively closes a channel at final cumulative spend.
118
+ */
119
+ export type CloseCredentialPayload = {
120
+ action: 'close'
121
+ /** TIP-1034 channel ID being closed. */
122
+ channelId: Hex
123
+ /** Descriptor for the channel being closed. */
124
+ descriptor: ChannelDescriptor
125
+ /** Final cumulative spend authorized at close, as raw units. */
126
+ cumulativeAmount: RawAmountString
127
+ /** Voucher signature for `cumulativeAmount`. */
128
+ signature: Hex
129
+ }
130
+
131
+ /**
132
+ * TIP20EscrowChannel precompile session credential payload (discriminated union).
133
+ */
134
+ export type SessionCredentialPayload =
135
+ | OpenCredentialPayload
136
+ | TopUpCredentialPayload
137
+ | VoucherCredentialPayload
138
+ | CloseCredentialPayload
139
+
140
+ const sessionCredentialActions = new Set(['open', 'topUp', 'voucher', 'close'])
141
+
142
+ function isObject(value: unknown): value is Record<string, unknown> {
143
+ return value !== null && typeof value === 'object'
144
+ }
145
+
146
+ /**
147
+ * Backend-neutral voucher for cumulative payment.
148
+ * Cumulative monotonicity prevents replay attacks.
149
+ */
150
+ export interface SessionVoucher {
151
+ channelId: Hex
152
+ cumulativeAmount: bigint
153
+ }
154
+
155
+ /**
156
+ * Backend-neutral signed voucher with EIP-712 signature.
157
+ */
158
+ export interface SessionSignedVoucher extends SessionVoucher {
159
+ signature: Hex
160
+ }
161
+
162
+ /**
163
+ * Management action names shared by session credential payloads.
164
+ */
165
+ export type SessionCredentialAction = 'open' | 'topUp' | 'voucher' | 'close'
166
+
167
+ /**
168
+ * Minimal credential shape shared by transport helpers that only need routing context.
169
+ */
170
+ export type SessionCredentialContext = {
171
+ /** Session channel ID referenced by the authorization payload. */
172
+ channelId: Hex
173
+ /** Session management action when the payload is a management credential. */
174
+ action?: SessionCredentialAction | undefined
175
+ }
176
+
177
+ /** Returns whether a value is a supported session credential action. */
178
+ export function isSessionCredentialAction(value: unknown): value is SessionCredentialAction {
179
+ return typeof value === 'string' && sessionCredentialActions.has(value)
180
+ }
181
+
182
+ /** Returns whether a value has the session credential fields needed by transports. */
183
+ export function isSessionCredentialContext(value: unknown): value is SessionCredentialContext {
184
+ if (value === null || typeof value !== 'object') return false
185
+ const candidate = value as { action?: unknown; channelId?: unknown }
186
+ if (typeof candidate.channelId !== 'string') return false
187
+ if (candidate.action !== undefined && !isSessionCredentialAction(candidate.action)) return false
188
+ return true
189
+ }
190
+
191
+ /** Reads the shared session credential context or throws the provided error message. */
192
+ export function requireSessionCredentialContext(
193
+ value: unknown,
194
+ errorMessage = 'No session credential context available.',
195
+ ): SessionCredentialContext {
196
+ if (!isSessionCredentialContext(value)) throw new Error(errorMessage)
197
+ return value
198
+ }
199
+
200
+ /** Reads the raw per-unit session amount from a payment challenge. */
201
+ export function readSessionChallengeAmount(challenge: Challenge.Challenge): bigint {
202
+ const amount = challenge.request.amount
203
+ if (typeof amount !== 'string') throw new Error('Session challenge is missing amount.')
204
+ return BigInt(amount)
205
+ }
206
+
207
+ /**
208
+ * SSE event emitted when session balance is exhausted mid-stream.
209
+ * The client responds by sending a new voucher credential.
210
+ *
211
+ * Per spec §11.6, the event data contains:
212
+ * - `channelId` — channel identifier
213
+ * - `requiredCumulative` — minimum cumulative amount the next voucher must authorize
214
+ * - `acceptedCumulative` — current highest accepted voucher amount
215
+ * - `deposit` — current on-chain deposit ceiling; when `requiredCumulative > deposit`
216
+ * the client must top up the channel before sending a new voucher
217
+ */
218
+ export interface NeedVoucherEvent {
219
+ channelId: Hex
220
+ /** Minimum cumulative voucher amount required to continue, as raw token units. */
221
+ requiredCumulative: RawAmountString
222
+ /** Highest cumulative voucher amount currently accepted by the server, as raw token units. */
223
+ acceptedCumulative: RawAmountString
224
+ /** Current channel deposit ceiling, as raw token units. */
225
+ deposit: RawAmountString
226
+ }
227
+
228
+ /** Returns whether a value is a typed need-voucher event payload. */
229
+ export function isNeedVoucherEvent(value: unknown): value is NeedVoucherEvent {
230
+ if (!isObject(value)) return false
231
+ return (
232
+ typeof value.channelId === 'string' &&
233
+ typeof value.requiredCumulative === 'string' &&
234
+ typeof value.acceptedCumulative === 'string' &&
235
+ typeof value.deposit === 'string'
236
+ )
237
+ }
238
+
239
+ /**
240
+ * Session receipt returned in Payment-Receipt header.
241
+ */
242
+ export interface SessionReceipt {
243
+ /** Payment method that produced the receipt. */
244
+ method: 'tempo'
245
+ /** Payment intent that produced the receipt. */
246
+ intent: 'session'
247
+ /** Receipt status. */
248
+ status: 'success'
249
+ /** ISO timestamp when the receipt was created. */
250
+ timestamp: string
251
+ /** Payment reference (channelId). Satisfies Receipt.Receipt contract. */
252
+ reference: string
253
+ /** Challenge ID that this receipt settles or acknowledges. */
254
+ challengeId: string
255
+ /** TIP-1034 channel ID. */
256
+ channelId: Hex
257
+ /** Highest cumulative voucher amount accepted by the server, as raw token units. */
258
+ acceptedCumulative: RawAmountString
259
+ /** Amount actually consumed by delivered work/content, as raw token units. */
260
+ spent: RawAmountString
261
+ /** Paid units delivered by the server, when the transport reports them. */
262
+ units?: number | undefined
263
+ /** On-chain transaction hash when this receipt came from settlement or close. */
264
+ txHash?: Hex | undefined
265
+ }
266
+
267
+ /** Returns whether a value is a typed session payment receipt. */
268
+ export function isSessionReceipt(value: unknown): value is SessionReceipt {
269
+ if (!isObject(value)) return false
270
+ return (
271
+ value.method === 'tempo' &&
272
+ value.intent === 'session' &&
273
+ value.status === 'success' &&
274
+ typeof value.timestamp === 'string' &&
275
+ typeof value.reference === 'string' &&
276
+ typeof value.challengeId === 'string' &&
277
+ typeof value.channelId === 'string' &&
278
+ typeof value.acceptedCumulative === 'string' &&
279
+ typeof value.spent === 'string' &&
280
+ (value.units === undefined || typeof value.units === 'number') &&
281
+ (value.txHash === undefined || typeof value.txHash === 'string')
282
+ )
283
+ }
284
+
285
+ /**
286
+ * Create a session receipt.
287
+ */
288
+ export function createSessionReceipt(params: {
289
+ challengeId: string
290
+ channelId: Hex
291
+ acceptedCumulative: bigint
292
+ spent: bigint
293
+ units?: number | undefined
294
+ txHash?: Hex | undefined
295
+ }): SessionReceipt {
296
+ return {
297
+ method: 'tempo',
298
+ intent: 'session',
299
+ status: 'success',
300
+ timestamp: new Date().toISOString(),
301
+ reference: params.channelId,
302
+ challengeId: params.challengeId,
303
+ channelId: params.channelId,
304
+ acceptedCumulative: params.acceptedCumulative.toString(),
305
+ spent: params.spent.toString(),
306
+ ...(params.units !== undefined && { units: params.units }),
307
+ ...(params.txHash !== undefined && { txHash: params.txHash }),
308
+ }
309
+ }
310
+
311
+ /**
312
+ * Serialize a session receipt to the Payment-Receipt header format.
313
+ */
314
+ export function serializeSessionReceipt(receipt: SessionReceipt): string {
315
+ const json = JSON.stringify(receipt)
316
+ return Base64.fromString(json, { pad: false, url: true })
317
+ }
318
+
319
+ /**
320
+ * Deserialize a Payment-Receipt header value to a session receipt.
321
+ */
322
+ export function deserializeSessionReceipt(encoded: string): SessionReceipt {
323
+ const json = Base64.toString(encoded)
324
+ const value: unknown = JSON.parse(json)
325
+ if (!isSessionReceipt(value)) throw new Error('Invalid session receipt.')
326
+ return value
327
+ }
328
+
329
+ /**
330
+ * Parsed SSE event (discriminated union by `type`).
331
+ */
332
+ export type SseEvent =
333
+ | { type: 'message'; data: string }
334
+ | { type: 'payment-need-voucher'; data: NeedVoucherEvent }
335
+ | { type: 'payment-receipt'; data: SessionReceipt }
336
+
337
+ /** Returns whether a response carries an SSE event stream. */
338
+ export function isEventStream(response: Response): boolean {
339
+ const ct = response.headers.get('content-type')
340
+ return ct?.toLowerCase().startsWith('text/event-stream') ?? false
341
+ }
342
+
343
+ /**
344
+ * Format a session receipt as a Server-Sent Event.
345
+ *
346
+ * Produces a valid SSE event string with `event: payment-receipt`
347
+ * and the receipt JSON as the `data` field.
348
+ */
349
+ export function formatReceiptEvent(receipt: SessionReceipt): string {
350
+ return `event: payment-receipt\ndata: ${JSON.stringify(receipt)}\n\n`
351
+ }
352
+
353
+ /**
354
+ * Format a need-voucher event as a Server-Sent Event.
355
+ *
356
+ * Emitted when the channel balance is exhausted mid-stream.
357
+ */
358
+ export function formatNeedVoucherEvent(params: NeedVoucherEvent): string {
359
+ return `event: payment-need-voucher\ndata: ${JSON.stringify(params)}\n\n`
360
+ }
361
+
362
+ /**
363
+ * Format an application message as SSE, preserving embedded newlines.
364
+ *
365
+ * SSE requires multi-line payloads to be emitted as separate `data:` fields.
366
+ */
367
+ export function formatMessageEvent(value: string): string {
368
+ const data = String(value)
369
+ .split('\n')
370
+ .map((line) => `data: ${line}`)
371
+ .join('\n')
372
+ return `event: message\n${data}\n\n`
373
+ }
374
+
375
+ /**
376
+ * Parse a raw SSE event string into a typed event.
377
+ *
378
+ * Unknown event names fall back to `message`, which preserves compatibility
379
+ * with generic SSE producers.
380
+ */
381
+ export function parseEvent(raw: string): SseEvent | null {
382
+ let eventType = 'message'
383
+ const dataLines: string[] = []
384
+
385
+ for (const line of raw.split('\n')) {
386
+ if (line.startsWith('event: ')) {
387
+ eventType = line.slice(7).trim()
388
+ } else if (line.startsWith('data: ')) {
389
+ dataLines.push(line.slice(6))
390
+ } else if (line === 'data:') {
391
+ dataLines.push('')
392
+ }
393
+ }
394
+
395
+ if (dataLines.length === 0) return null
396
+ const data = dataLines.join('\n')
397
+
398
+ switch (eventType) {
399
+ case 'message':
400
+ return { type: 'message', data }
401
+ case 'payment-need-voucher': {
402
+ const parsed = parseJson(data)
403
+ return isNeedVoucherEvent(parsed) ? { type: 'payment-need-voucher', data: parsed } : null
404
+ }
405
+ case 'payment-receipt': {
406
+ const parsed = parseJson(data)
407
+ return isSessionReceipt(parsed) ? { type: 'payment-receipt', data: parsed } : null
408
+ }
409
+ default:
410
+ return { type: 'message', data }
411
+ }
412
+ }
413
+
414
+ function parseJson(raw: string): unknown {
415
+ try {
416
+ return JSON.parse(raw)
417
+ } catch {
418
+ return null
419
+ }
420
+ }
421
+
422
+ /** Extracts the `data:` field value from a single SSE event block. */
423
+ export function extractData(event: string): string | null {
424
+ const dataLines: string[] = []
425
+ for (const line of event.split('\n')) {
426
+ if (line.startsWith('data: ')) dataLines.push(line.slice(6))
427
+ else if (line === 'data:') dataLines.push('')
428
+ }
429
+ return dataLines.length > 0 ? dataLines.join('\n') : null
430
+ }
431
+
432
+ /** In-band WebSocket payment protocol frame. */
433
+ export type Message =
434
+ | { mpp: 'authorization'; authorization: string }
435
+ | { mpp: 'message'; data: string }
436
+ | { mpp: 'payment-close-request' }
437
+ | { mpp: 'payment-close-ready'; data: SessionReceipt }
438
+ | { mpp: 'payment-error'; status: number; message: string }
439
+ | { mpp: 'payment-need-voucher'; data: NeedVoucherEvent }
440
+ | { mpp: 'payment-receipt'; data: SessionReceipt }
441
+
442
+ /** Input for formatting a WebSocket payment protocol error frame. */
443
+ export type ErrorMessageParameters = {
444
+ /** Human-readable error message. */
445
+ message: string
446
+ /** HTTP-style payment error status. */
447
+ status: number
448
+ }
449
+
450
+ /** Formats the initial or follow-up payment authorization frame. */
451
+ export function formatAuthorizationMessage(authorization: string): string {
452
+ return JSON.stringify({ mpp: 'authorization', authorization } satisfies Message)
453
+ }
454
+
455
+ /** Formats an application payload frame. */
456
+ export function formatApplicationMessage(data: string): string {
457
+ return JSON.stringify({ mpp: 'message', data } satisfies Message)
458
+ }
459
+
460
+ /** Formats the client request for a final close-ready receipt. */
461
+ export function formatCloseRequestMessage(): string {
462
+ return JSON.stringify({ mpp: 'payment-close-request' } satisfies Message)
463
+ }
464
+
465
+ /** Formats the server close-ready receipt frame. */
466
+ export function formatCloseReadyMessage(receipt: SessionReceipt): string {
467
+ return JSON.stringify({ mpp: 'payment-close-ready', data: receipt } satisfies Message)
468
+ }
469
+
470
+ /** Formats a server request for a larger voucher. */
471
+ export function formatNeedVoucherMessage(params: NeedVoucherEvent): string {
472
+ return JSON.stringify({ mpp: 'payment-need-voucher', data: params } satisfies Message)
473
+ }
474
+
475
+ /** Formats an intermediate or final payment receipt frame. */
476
+ export function formatReceiptMessage(receipt: SessionReceipt): string {
477
+ return JSON.stringify({ mpp: 'payment-receipt', data: receipt } satisfies Message)
478
+ }
479
+
480
+ /** Formats a payment protocol error frame. */
481
+ export function formatErrorMessage(parameters: ErrorMessageParameters): string {
482
+ return JSON.stringify({ mpp: 'payment-error', ...parameters } satisfies Message)
483
+ }
484
+
485
+ /** Parses a WebSocket payment protocol frame, returning null for application data. */
486
+ export function parseMessage(raw: string): Message | null {
487
+ const parsed = parseJsonObject(raw)
488
+ if (!parsed) return null
489
+ if (parsed.mpp === 'authorization' && typeof parsed.authorization === 'string')
490
+ return { mpp: 'authorization', authorization: parsed.authorization }
491
+ if (parsed.mpp === 'message' && typeof parsed.data === 'string')
492
+ return { mpp: 'message', data: parsed.data }
493
+ if (parsed.mpp === 'payment-close-request') return { mpp: 'payment-close-request' }
494
+ if (parsed.mpp === 'payment-close-ready' && isSessionReceipt(parsed.data))
495
+ return { mpp: 'payment-close-ready', data: parsed.data }
496
+ if (
497
+ parsed.mpp === 'payment-error' &&
498
+ typeof parsed.status === 'number' &&
499
+ typeof parsed.message === 'string'
500
+ )
501
+ return { mpp: 'payment-error', status: parsed.status, message: parsed.message }
502
+ if (parsed.mpp === 'payment-need-voucher' && isNeedVoucherEvent(parsed.data))
503
+ return { mpp: 'payment-need-voucher', data: parsed.data }
504
+ if (parsed.mpp === 'payment-receipt' && isSessionReceipt(parsed.data))
505
+ return { mpp: 'payment-receipt', data: parsed.data }
506
+ return null
507
+ }
508
+
509
+ function parseJsonObject(raw: string): Record<string, unknown> | null {
510
+ try {
511
+ const value: unknown = JSON.parse(raw)
512
+ if (value === null || typeof value !== 'object') return null
513
+ return value as Record<string, unknown>
514
+ } catch {
515
+ return null
516
+ }
517
+ }
518
+
519
+ /** Canonical TIP-1034 TIP-20 Channel Escrow precompile address. */
520
+ export const tip20ChannelEscrow = '0x4d50500000000000000000000000000000000000'