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.
- package/CHANGELOG.md +25 -0
- package/dist/Challenge.d.ts.map +1 -1
- package/dist/Challenge.js +9 -7
- package/dist/Challenge.js.map +1 -1
- package/dist/Constants.d.ts +46 -0
- package/dist/Constants.d.ts.map +1 -0
- package/dist/Constants.js +46 -0
- package/dist/Constants.js.map +1 -0
- package/dist/Credential.d.ts.map +1 -1
- package/dist/Credential.js +5 -4
- package/dist/Credential.js.map +1 -1
- package/dist/Method.d.ts +32 -4
- package/dist/Method.d.ts.map +1 -1
- package/dist/Method.js +5 -2
- package/dist/Method.js.map +1 -1
- package/dist/Receipt.d.ts.map +1 -1
- package/dist/Receipt.js +3 -2
- package/dist/Receipt.js.map +1 -1
- package/dist/cli/cli.d.ts.map +1 -1
- package/dist/cli/cli.js +19 -11
- package/dist/cli/cli.js.map +1 -1
- package/dist/cli/plugins/tempo.d.ts.map +1 -1
- package/dist/cli/plugins/tempo.js +17 -6
- package/dist/cli/plugins/tempo.js.map +1 -1
- package/dist/cli/utils.d.ts +5 -0
- package/dist/cli/utils.d.ts.map +1 -1
- package/dist/cli/utils.js +10 -0
- package/dist/cli/utils.js.map +1 -1
- package/dist/client/Methods.d.ts +5 -2
- package/dist/client/Methods.d.ts.map +1 -1
- package/dist/client/Methods.js +5 -2
- package/dist/client/Methods.js.map +1 -1
- package/dist/client/Transport.d.ts.map +1 -1
- package/dist/client/Transport.js +4 -5
- package/dist/client/Transport.js.map +1 -1
- package/dist/client/index.d.ts +2 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +2 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/internal/Fetch.d.ts.map +1 -1
- package/dist/client/internal/Fetch.js +14 -6
- package/dist/client/internal/Fetch.js.map +1 -1
- package/dist/evm/server/Methods.d.ts +1 -1
- package/dist/evm/server/Methods.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/internal/AcceptPayment.d.ts +3 -0
- package/dist/internal/AcceptPayment.d.ts.map +1 -1
- package/dist/internal/AcceptPayment.js +15 -11
- package/dist/internal/AcceptPayment.js.map +1 -1
- package/dist/mcp-sdk/client/McpClient.d.ts +12 -5
- package/dist/mcp-sdk/client/McpClient.d.ts.map +1 -1
- package/dist/mcp-sdk/client/McpClient.js +55 -42
- package/dist/mcp-sdk/client/McpClient.js.map +1 -1
- package/dist/server/Mppx.d.ts +11 -3
- package/dist/server/Mppx.d.ts.map +1 -1
- package/dist/server/Mppx.js +76 -27
- package/dist/server/Mppx.js.map +1 -1
- package/dist/server/Request.js +24 -10
- package/dist/server/Request.js.map +1 -1
- package/dist/server/Response.d.ts.map +1 -1
- package/dist/server/Response.js +2 -1
- package/dist/server/Response.js.map +1 -1
- package/dist/server/Transport.d.ts.map +1 -1
- package/dist/server/Transport.js +4 -3
- package/dist/server/Transport.js.map +1 -1
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -0
- package/dist/server/index.js.map +1 -1
- package/dist/stripe/client/Charge.d.ts +1 -1
- package/dist/stripe/client/Charge.d.ts.map +1 -1
- package/dist/stripe/client/Charge.js +3 -1
- package/dist/stripe/client/Charge.js.map +1 -1
- package/dist/stripe/server/Charge.d.ts +1 -1
- package/dist/stripe/server/Charge.d.ts.map +1 -1
- package/dist/stripe/server/Charge.js +9 -2
- package/dist/stripe/server/Charge.js.map +1 -1
- package/dist/stripe/server/Methods.d.ts +1 -1
- package/dist/stripe/server/Methods.d.ts.map +1 -1
- package/dist/stripe/server/internal/html.gen.d.ts +1 -1
- package/dist/stripe/server/internal/html.gen.d.ts.map +1 -1
- package/dist/stripe/server/internal/html.gen.js +1 -1
- package/dist/stripe/server/internal/html.gen.js.map +1 -1
- package/dist/tempo/Methods.d.ts +18 -0
- package/dist/tempo/Methods.d.ts.map +1 -1
- package/dist/tempo/Methods.js +16 -1
- package/dist/tempo/Methods.js.map +1 -1
- package/dist/tempo/client/Charge.d.ts +6 -0
- package/dist/tempo/client/Charge.d.ts.map +1 -1
- package/dist/tempo/client/Charge.js +9 -2
- package/dist/tempo/client/Charge.js.map +1 -1
- package/dist/tempo/client/Methods.d.ts +36 -7
- package/dist/tempo/client/Methods.d.ts.map +1 -1
- package/dist/tempo/client/Methods.js +12 -5
- package/dist/tempo/client/Methods.js.map +1 -1
- package/dist/tempo/client/index.d.ts +7 -4
- package/dist/tempo/client/index.d.ts.map +1 -1
- package/dist/tempo/client/index.js +5 -3
- package/dist/tempo/client/index.js.map +1 -1
- package/dist/tempo/index.d.ts +1 -0
- package/dist/tempo/index.d.ts.map +1 -1
- package/dist/tempo/index.js +1 -0
- package/dist/tempo/index.js.map +1 -1
- package/dist/tempo/internal/fee-payer.d.ts +21 -1
- package/dist/tempo/internal/fee-payer.d.ts.map +1 -1
- package/dist/tempo/internal/fee-payer.js +109 -4
- package/dist/tempo/internal/fee-payer.js.map +1 -1
- package/dist/tempo/{client → legacy/client}/ChannelOps.d.ts +19 -6
- package/dist/tempo/legacy/client/ChannelOps.d.ts.map +1 -0
- package/dist/tempo/{client → legacy/client}/ChannelOps.js +9 -3
- package/dist/tempo/legacy/client/ChannelOps.js.map +1 -0
- package/dist/tempo/{client → legacy/client}/Session.d.ts +23 -4
- package/dist/tempo/legacy/client/Session.d.ts.map +1 -0
- package/dist/tempo/{client → legacy/client}/Session.js +14 -7
- package/dist/tempo/legacy/client/Session.js.map +1 -0
- package/dist/tempo/{client → legacy/client}/SessionManager.d.ts +20 -5
- package/dist/tempo/legacy/client/SessionManager.d.ts.map +1 -0
- package/dist/tempo/{client → legacy/client}/SessionManager.js +20 -16
- package/dist/tempo/legacy/client/SessionManager.js.map +1 -0
- package/dist/tempo/legacy/client/index.d.ts +7 -0
- package/dist/tempo/legacy/client/index.d.ts.map +1 -0
- package/dist/tempo/legacy/client/index.js +5 -0
- package/dist/tempo/legacy/client/index.js.map +1 -0
- package/dist/tempo/legacy/index.d.ts +7 -0
- package/dist/tempo/legacy/index.d.ts.map +1 -0
- package/dist/tempo/legacy/index.js +7 -0
- package/dist/tempo/legacy/index.js.map +1 -0
- package/dist/tempo/{server → legacy/server}/Session.d.ts +28 -11
- package/dist/tempo/legacy/server/Session.d.ts.map +1 -0
- package/dist/tempo/{server → legacy/server}/Session.js +28 -23
- package/dist/tempo/legacy/server/Session.js.map +1 -0
- package/dist/tempo/legacy/server/index.d.ts +5 -0
- package/dist/tempo/legacy/server/index.d.ts.map +1 -0
- package/dist/tempo/legacy/server/index.js +5 -0
- package/dist/tempo/legacy/server/index.js.map +1 -0
- package/dist/tempo/{session → legacy/session}/Chain.d.ts +30 -23
- package/dist/tempo/legacy/session/Chain.d.ts.map +1 -0
- package/dist/tempo/{session → legacy/session}/Chain.js +12 -11
- package/dist/tempo/legacy/session/Chain.js.map +1 -0
- package/dist/tempo/{session → legacy/session}/Channel.d.ts +1 -0
- package/dist/tempo/legacy/session/Channel.d.ts.map +1 -0
- package/dist/tempo/legacy/session/Channel.js.map +1 -0
- package/dist/tempo/legacy/session/ChannelStore.d.ts +22 -0
- package/dist/tempo/legacy/session/ChannelStore.d.ts.map +1 -0
- package/dist/tempo/legacy/session/ChannelStore.js +6 -0
- package/dist/tempo/legacy/session/ChannelStore.js.map +1 -0
- package/dist/tempo/legacy/session/Types.d.ts +73 -0
- package/dist/tempo/legacy/session/Types.d.ts.map +1 -0
- package/dist/tempo/legacy/session/Types.js.map +1 -0
- package/dist/tempo/{session → legacy/session}/Voucher.d.ts +4 -4
- package/dist/tempo/legacy/session/Voucher.d.ts.map +1 -0
- package/dist/tempo/{session → legacy/session}/Voucher.js +1 -1
- package/dist/tempo/legacy/session/Voucher.js.map +1 -0
- package/dist/tempo/{session → legacy/session}/escrow.abi.d.ts +1 -0
- package/dist/tempo/{session → legacy/session}/escrow.abi.d.ts.map +1 -1
- package/dist/tempo/{session → legacy/session}/escrow.abi.js +1 -0
- package/dist/tempo/legacy/session/escrow.abi.js.map +1 -0
- package/dist/tempo/legacy/session/index.d.ts +9 -0
- package/dist/tempo/legacy/session/index.d.ts.map +1 -0
- package/dist/tempo/legacy/session/index.js +9 -0
- package/dist/tempo/legacy/session/index.js.map +1 -0
- package/dist/tempo/server/Charge.d.ts +1 -1
- package/dist/tempo/server/Charge.d.ts.map +1 -1
- package/dist/tempo/server/Charge.js +13 -16
- package/dist/tempo/server/Charge.js.map +1 -1
- package/dist/tempo/server/Methods.d.ts +63 -6
- package/dist/tempo/server/Methods.d.ts.map +1 -1
- package/dist/tempo/server/Methods.js +36 -8
- package/dist/tempo/server/Methods.js.map +1 -1
- package/dist/tempo/server/Subscription.d.ts +1 -1
- package/dist/tempo/server/Subscription.d.ts.map +1 -1
- package/dist/tempo/server/index.d.ts +6 -5
- package/dist/tempo/server/index.d.ts.map +1 -1
- package/dist/tempo/server/index.js +5 -5
- package/dist/tempo/server/index.js.map +1 -1
- package/dist/tempo/server/internal/html.gen.d.ts +1 -1
- package/dist/tempo/server/internal/html.gen.d.ts.map +1 -1
- package/dist/tempo/server/internal/html.gen.js +1 -1
- package/dist/tempo/server/internal/html.gen.js.map +1 -1
- package/dist/tempo/server/internal/request-body.d.ts +7 -2
- package/dist/tempo/server/internal/request-body.d.ts.map +1 -1
- package/dist/tempo/server/internal/request-body.js +20 -3
- package/dist/tempo/server/internal/request-body.js.map +1 -1
- package/dist/tempo/server/internal/transport.d.ts +8 -4
- package/dist/tempo/server/internal/transport.d.ts.map +1 -1
- package/dist/tempo/server/internal/transport.js +8 -7
- package/dist/tempo/server/internal/transport.js.map +1 -1
- package/dist/tempo/session/Snapshot.d.ts +32 -0
- package/dist/tempo/session/Snapshot.d.ts.map +1 -0
- package/dist/tempo/session/Snapshot.js +37 -0
- package/dist/tempo/session/Snapshot.js.map +1 -0
- package/dist/tempo/session/client/ChannelOps.d.ts +82 -0
- package/dist/tempo/session/client/ChannelOps.d.ts.map +1 -0
- package/dist/tempo/session/client/ChannelOps.js +204 -0
- package/dist/tempo/session/client/ChannelOps.js.map +1 -0
- package/dist/tempo/session/client/CredentialState.d.ts +262 -0
- package/dist/tempo/session/client/CredentialState.d.ts.map +1 -0
- package/dist/tempo/session/client/CredentialState.js +417 -0
- package/dist/tempo/session/client/CredentialState.js.map +1 -0
- package/dist/tempo/session/client/ReceiptCoordinator.d.ts +26 -0
- package/dist/tempo/session/client/ReceiptCoordinator.d.ts.map +1 -0
- package/dist/tempo/session/client/ReceiptCoordinator.js +61 -0
- package/dist/tempo/session/client/ReceiptCoordinator.js.map +1 -0
- package/dist/tempo/session/client/Runtime.d.ts +464 -0
- package/dist/tempo/session/client/Runtime.d.ts.map +1 -0
- package/dist/tempo/session/client/Runtime.js +499 -0
- package/dist/tempo/session/client/Runtime.js.map +1 -0
- package/dist/tempo/session/client/Session.d.ts +132 -0
- package/dist/tempo/session/client/Session.d.ts.map +1 -0
- package/dist/tempo/session/client/Session.js +55 -0
- package/dist/tempo/session/client/Session.js.map +1 -0
- package/dist/tempo/session/client/SessionManager.d.ts +120 -0
- package/dist/tempo/session/client/SessionManager.d.ts.map +1 -0
- package/dist/tempo/session/client/SessionManager.js +627 -0
- package/dist/tempo/session/client/SessionManager.js.map +1 -0
- package/dist/tempo/session/client/Transports.d.ts +449 -0
- package/dist/tempo/session/client/Transports.d.ts.map +1 -0
- package/dist/tempo/session/client/Transports.js +721 -0
- package/dist/tempo/session/client/Transports.js.map +1 -0
- package/dist/tempo/session/client/index.d.ts +12 -0
- package/dist/tempo/session/client/index.d.ts.map +1 -0
- package/dist/tempo/session/client/index.js +5 -0
- package/dist/tempo/session/client/index.js.map +1 -0
- package/dist/tempo/session/index.d.ts +7 -8
- package/dist/tempo/session/index.d.ts.map +1 -1
- package/dist/tempo/session/index.js +7 -8
- package/dist/tempo/session/index.js.map +1 -1
- package/dist/tempo/session/precompile/Chain.d.ts +319 -0
- package/dist/tempo/session/precompile/Chain.d.ts.map +1 -0
- package/dist/tempo/session/precompile/Chain.js +492 -0
- package/dist/tempo/session/precompile/Chain.js.map +1 -0
- package/dist/tempo/session/precompile/Channel.d.ts +46 -0
- package/dist/tempo/session/precompile/Channel.d.ts.map +1 -0
- package/dist/tempo/session/precompile/Channel.js +56 -0
- package/dist/tempo/session/precompile/Channel.js.map +1 -0
- package/dist/tempo/session/precompile/Protocol.d.ts +308 -0
- package/dist/tempo/session/precompile/Protocol.d.ts.map +1 -0
- package/dist/tempo/session/precompile/Protocol.js +264 -0
- package/dist/tempo/session/precompile/Protocol.js.map +1 -0
- package/dist/tempo/session/precompile/Voucher.d.ts +40 -0
- package/dist/tempo/session/precompile/Voucher.d.ts.map +1 -0
- package/dist/tempo/session/precompile/Voucher.js +126 -0
- package/dist/tempo/session/precompile/Voucher.js.map +1 -0
- package/dist/tempo/session/precompile/escrow.abi.d.ts +522 -0
- package/dist/tempo/session/precompile/escrow.abi.d.ts.map +1 -0
- package/dist/tempo/session/precompile/escrow.abi.js +224 -0
- package/dist/tempo/session/precompile/escrow.abi.js.map +1 -0
- package/dist/tempo/session/precompile/index.d.ts +24 -0
- package/dist/tempo/session/precompile/index.d.ts.map +1 -0
- package/dist/tempo/session/precompile/index.js +22 -0
- package/dist/tempo/session/precompile/index.js.map +1 -0
- package/dist/tempo/session/server/ChannelOps.d.ts +56 -0
- package/dist/tempo/session/server/ChannelOps.d.ts.map +1 -0
- package/dist/tempo/session/server/ChannelOps.js +91 -0
- package/dist/tempo/session/server/ChannelOps.js.map +1 -0
- package/dist/tempo/session/server/ChannelStore.d.ts +347 -0
- package/dist/tempo/session/server/ChannelStore.d.ts.map +1 -0
- package/dist/tempo/session/server/ChannelStore.js +404 -0
- package/dist/tempo/session/server/ChannelStore.js.map +1 -0
- package/dist/tempo/session/server/CredentialVerification.d.ts +85 -0
- package/dist/tempo/session/server/CredentialVerification.d.ts.map +1 -0
- package/dist/tempo/session/server/CredentialVerification.js +494 -0
- package/dist/tempo/session/server/CredentialVerification.js.map +1 -0
- package/dist/tempo/session/server/MeteredStream.d.ts +40 -0
- package/dist/tempo/session/server/MeteredStream.d.ts.map +1 -0
- package/dist/tempo/session/server/MeteredStream.js +42 -0
- package/dist/tempo/session/server/MeteredStream.js.map +1 -0
- package/dist/tempo/session/server/RequestState.d.ts +208 -0
- package/dist/tempo/session/server/RequestState.d.ts.map +1 -0
- package/dist/tempo/session/server/RequestState.js +252 -0
- package/dist/tempo/session/server/RequestState.js.map +1 -0
- package/dist/tempo/session/server/Session.d.ts +169 -0
- package/dist/tempo/session/server/Session.d.ts.map +1 -0
- package/dist/tempo/session/server/Session.js +351 -0
- package/dist/tempo/session/server/Session.js.map +1 -0
- package/dist/tempo/session/server/Settlement.d.ts +185 -0
- package/dist/tempo/session/server/Settlement.d.ts.map +1 -0
- package/dist/tempo/session/server/Settlement.js +250 -0
- package/dist/tempo/session/server/Settlement.js.map +1 -0
- package/dist/tempo/session/{Sse.d.ts → server/Sse.d.ts} +9 -56
- package/dist/tempo/session/server/Sse.d.ts.map +1 -0
- package/dist/tempo/session/server/Sse.js +184 -0
- package/dist/tempo/session/server/Sse.js.map +1 -0
- package/dist/tempo/session/server/Transports.d.ts +89 -0
- package/dist/tempo/session/server/Transports.d.ts.map +1 -0
- package/dist/tempo/session/server/Transports.js +149 -0
- package/dist/tempo/session/server/Transports.js.map +1 -0
- package/dist/tempo/session/server/Ws.d.ts +48 -0
- package/dist/tempo/session/server/Ws.d.ts.map +1 -0
- package/dist/tempo/session/server/Ws.js +244 -0
- package/dist/tempo/session/server/Ws.js.map +1 -0
- package/dist/tempo/session/server/index.d.ts +4 -0
- package/dist/tempo/session/server/index.d.ts.map +1 -0
- package/dist/tempo/session/server/index.js +2 -0
- package/dist/tempo/session/server/index.js.map +1 -0
- package/package.json +8 -3
- package/src/Challenge.ts +9 -7
- package/src/Constants.ts +58 -0
- package/src/Credential.ts +5 -4
- package/src/Method.ts +46 -5
- package/src/Receipt.ts +3 -2
- package/src/cli/cli.test.ts +23 -28
- package/src/cli/cli.ts +23 -10
- package/src/cli/mcp.test.ts +21 -7
- package/src/cli/plugins/tempo.ts +21 -8
- package/src/cli/utils.test.ts +25 -1
- package/src/cli/utils.ts +10 -0
- package/src/client/Methods.ts +5 -2
- package/src/client/Mppx.test-d.ts +10 -0
- package/src/client/Mppx.test.ts +75 -0
- package/src/client/Transport.ts +4 -5
- package/src/client/index.ts +11 -1
- package/src/client/internal/Fetch.test.ts +29 -4
- package/src/client/internal/Fetch.ts +17 -5
- package/src/env.d.ts +1 -1
- package/src/index.ts +1 -0
- package/src/internal/AcceptPayment.test.ts +61 -0
- package/src/internal/AcceptPayment.ts +21 -14
- package/src/mcp-sdk/client/McpClient.integration.test.ts +8 -7
- package/src/mcp-sdk/client/McpClient.test-d.ts +7 -0
- package/src/mcp-sdk/client/McpClient.ts +99 -67
- package/src/mcp-sdk/client/McpClient.unit.test.ts +131 -0
- package/src/middlewares/elysia.test.ts +8 -4
- package/src/middlewares/express.test.ts +8 -4
- package/src/middlewares/hono.test.ts +4 -4
- package/src/middlewares/nextjs.test.ts +8 -4
- package/src/proxy/Proxy.test.ts +8 -8
- package/src/server/Mppx.test-d.ts +54 -0
- package/src/server/Mppx.test.ts +274 -7
- package/src/server/Mppx.ts +487 -406
- package/src/server/Request.test.ts +81 -0
- package/src/server/Request.ts +23 -9
- package/src/server/Response.ts +2 -1
- package/src/server/Transport.ts +4 -3
- package/src/server/index.ts +1 -0
- package/src/stripe/client/Charge.test.ts +20 -5
- package/src/stripe/client/Charge.ts +6 -2
- package/src/stripe/server/Charge.test.ts +114 -1
- package/src/stripe/server/Charge.ts +13 -2
- package/src/stripe/server/internal/html/package.json +1 -1
- package/src/stripe/server/internal/html.gen.ts +1 -1
- package/src/tempo/AccessKeyAuthorization.test.ts +4 -94
- package/src/tempo/Methods.test.ts +45 -17
- package/src/tempo/Methods.ts +22 -0
- package/src/tempo/PublicExports.test-d.ts +105 -0
- package/src/tempo/client/Charge.test.ts +85 -0
- package/src/tempo/client/Charge.ts +19 -2
- package/src/tempo/client/Methods.ts +18 -6
- package/src/tempo/client/index.ts +15 -4
- package/src/tempo/index.ts +1 -0
- package/src/tempo/internal/fee-payer.test.ts +241 -17
- package/src/tempo/internal/fee-payer.ts +150 -4
- package/src/tempo/internal/fee-token.test.ts +14 -9
- package/src/tempo/legacy/AccessKeyAuthorization.test.ts +162 -0
- package/src/tempo/legacy/README.md +9 -0
- package/src/tempo/{client → legacy/client}/ChannelOps.test.ts +6 -7
- package/src/tempo/{client → legacy/client}/ChannelOps.ts +22 -9
- package/src/tempo/{client → legacy/client}/Session.test.ts +51 -9
- package/src/tempo/{client → legacy/client}/Session.ts +25 -11
- package/src/tempo/{client → legacy/client}/SessionManager.test.ts +81 -9
- package/src/tempo/{client → legacy/client}/SessionManager.ts +41 -20
- package/src/tempo/legacy/client/index.ts +6 -0
- package/src/tempo/legacy/index.ts +6 -0
- package/src/tempo/{server → legacy/server}/Session.test.ts +162 -63
- package/src/tempo/{server → legacy/server}/Session.ts +49 -37
- package/src/tempo/legacy/server/index.ts +4 -0
- package/src/tempo/{session → legacy/session}/Chain.test.ts +3 -4
- package/src/tempo/{session → legacy/session}/Chain.ts +94 -63
- package/src/tempo/{session → legacy/session}/Channel.ts +1 -0
- package/src/tempo/legacy/session/ChannelStore.test.ts +58 -0
- package/src/tempo/legacy/session/ChannelStore.ts +39 -0
- package/src/tempo/legacy/session/Types.ts +91 -0
- package/src/tempo/{session → legacy/session}/Voucher.ts +12 -8
- package/src/tempo/{session → legacy/session}/escrow.abi.ts +1 -0
- package/src/tempo/legacy/session/index.ts +8 -0
- package/src/tempo/server/AtomicStore.test-d.ts +16 -11
- package/src/tempo/server/Charge.test.ts +92 -14
- package/src/tempo/server/Charge.ts +18 -16
- package/src/tempo/server/Methods.ts +54 -8
- package/src/tempo/server/Sse.test.ts +2 -2
- package/src/tempo/server/index.ts +6 -5
- package/src/tempo/server/internal/html/package.json +1 -1
- package/src/tempo/server/internal/html.gen.ts +1 -1
- package/src/tempo/server/internal/request-body.test.ts +37 -4
- package/src/tempo/server/internal/request-body.ts +25 -6
- package/src/tempo/server/internal/transport.test.ts +4 -4
- package/src/tempo/server/internal/transport.ts +19 -10
- package/src/tempo/session/Snapshot.test.ts +41 -0
- package/src/tempo/session/Snapshot.ts +74 -0
- package/src/tempo/session/client/ChannelOps.test.ts +163 -0
- package/src/tempo/session/client/ChannelOps.ts +344 -0
- package/src/tempo/session/client/CredentialState.test.ts +645 -0
- package/src/tempo/session/client/CredentialState.ts +814 -0
- package/src/tempo/session/client/ReceiptCoordinator.ts +95 -0
- package/src/tempo/session/client/Runtime.test.ts +1092 -0
- package/src/tempo/session/client/Runtime.ts +986 -0
- package/src/tempo/session/client/Session.test.ts +734 -0
- package/src/tempo/session/client/Session.ts +97 -0
- package/src/tempo/session/client/SessionManager.test.ts +1308 -0
- package/src/tempo/session/client/SessionManager.ts +845 -0
- package/src/tempo/session/client/Transports.test.ts +837 -0
- package/src/tempo/session/client/Transports.ts +1292 -0
- package/src/tempo/session/client/index.ts +37 -0
- package/src/tempo/session/index.ts +7 -8
- package/src/tempo/session/precompile/Chain.integration.test.ts +321 -0
- package/src/tempo/session/precompile/Chain.test.ts +1258 -0
- package/src/tempo/session/precompile/Chain.ts +979 -0
- package/src/tempo/session/precompile/Channel.test.ts +138 -0
- package/src/tempo/session/precompile/Channel.ts +103 -0
- package/src/tempo/session/precompile/Protocol.test.ts +358 -0
- package/src/tempo/session/precompile/Protocol.ts +520 -0
- package/src/tempo/session/precompile/Voucher.test.ts +316 -0
- package/src/tempo/session/precompile/Voucher.ts +160 -0
- package/src/tempo/session/precompile/escrow.abi.ts +226 -0
- package/src/tempo/session/precompile/index.ts +33 -0
- package/src/tempo/session/server/ChannelOps.test.ts +129 -0
- package/src/tempo/session/server/ChannelOps.ts +157 -0
- package/src/tempo/session/{ChannelStore.test.ts → server/ChannelStore.test.ts} +536 -29
- package/src/tempo/session/server/ChannelStore.ts +835 -0
- package/src/tempo/session/server/CredentialVerification.test.ts +146 -0
- package/src/tempo/session/server/CredentialVerification.ts +710 -0
- package/src/tempo/session/server/MeteredStream.ts +88 -0
- package/src/tempo/session/server/RequestState.test.ts +531 -0
- package/src/tempo/session/server/RequestState.ts +499 -0
- package/src/tempo/session/server/Session.integration.test.ts +444 -0
- package/src/tempo/session/server/Session.test.ts +3253 -0
- package/src/tempo/session/server/Session.ts +543 -0
- package/src/tempo/session/server/Settlement.test.ts +242 -0
- package/src/tempo/session/server/Settlement.ts +470 -0
- package/src/tempo/session/{Sse.test.ts → server/Sse.test.ts} +37 -3
- package/src/tempo/session/server/Sse.ts +256 -0
- package/src/tempo/session/server/Transports.test.ts +346 -0
- package/src/tempo/session/server/Transports.ts +255 -0
- package/src/tempo/session/{Ws.test.ts → server/Ws.test.ts} +4 -4
- package/src/tempo/session/server/Ws.ts +384 -0
- package/src/tempo/session/server/index.ts +8 -0
- package/dist/tempo/client/ChannelOps.d.ts.map +0 -1
- package/dist/tempo/client/ChannelOps.js.map +0 -1
- package/dist/tempo/client/Session.d.ts.map +0 -1
- package/dist/tempo/client/Session.js.map +0 -1
- package/dist/tempo/client/SessionManager.d.ts.map +0 -1
- package/dist/tempo/client/SessionManager.js.map +0 -1
- package/dist/tempo/server/Session.d.ts.map +0 -1
- package/dist/tempo/server/Session.js.map +0 -1
- package/dist/tempo/session/Chain.d.ts.map +0 -1
- package/dist/tempo/session/Chain.js.map +0 -1
- package/dist/tempo/session/Channel.d.ts.map +0 -1
- package/dist/tempo/session/Channel.js.map +0 -1
- package/dist/tempo/session/ChannelStore.d.ts +0 -117
- package/dist/tempo/session/ChannelStore.d.ts.map +0 -1
- package/dist/tempo/session/ChannelStore.js +0 -172
- package/dist/tempo/session/ChannelStore.js.map +0 -1
- package/dist/tempo/session/Receipt.d.ts +0 -22
- package/dist/tempo/session/Receipt.d.ts.map +0 -1
- package/dist/tempo/session/Receipt.js +0 -34
- package/dist/tempo/session/Receipt.js.map +0 -1
- package/dist/tempo/session/Sse.d.ts.map +0 -1
- package/dist/tempo/session/Sse.js +0 -363
- package/dist/tempo/session/Sse.js.map +0 -1
- package/dist/tempo/session/Types.d.ts +0 -78
- package/dist/tempo/session/Types.d.ts.map +0 -1
- package/dist/tempo/session/Types.js.map +0 -1
- package/dist/tempo/session/Voucher.d.ts.map +0 -1
- package/dist/tempo/session/Voucher.js.map +0 -1
- package/dist/tempo/session/Ws.d.ts +0 -87
- package/dist/tempo/session/Ws.d.ts.map +0 -1
- package/dist/tempo/session/Ws.js +0 -443
- package/dist/tempo/session/Ws.js.map +0 -1
- package/dist/tempo/session/escrow.abi.js.map +0 -1
- package/src/tempo/session/ChannelStore.ts +0 -308
- package/src/tempo/session/Receipt.test.ts +0 -89
- package/src/tempo/session/Receipt.ts +0 -46
- package/src/tempo/session/Sse.ts +0 -462
- package/src/tempo/session/Types.ts +0 -86
- package/src/tempo/session/Ws.ts +0 -576
- /package/dist/tempo/{session → legacy/session}/Channel.js +0 -0
- /package/dist/tempo/{session → legacy/session}/Types.js +0 -0
- /package/src/tempo/{session → legacy/session}/Channel.test.ts +0 -0
- /package/src/tempo/{session → legacy/session}/Voucher.test.ts +0 -0
- /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'
|