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,845 @@
|
|
|
1
|
+
import type { Hex } from 'ox'
|
|
2
|
+
import { parseUnits, type Address } from 'viem'
|
|
3
|
+
|
|
4
|
+
import * as Challenge from '../../../Challenge.js'
|
|
5
|
+
import * as Fetch from '../../../client/internal/Fetch.js'
|
|
6
|
+
import * as Constants from '../../../Constants.js'
|
|
7
|
+
import type * as Account from '../../../viem/Account.js'
|
|
8
|
+
import type * as Client from '../../../viem/Client.js'
|
|
9
|
+
import { charge as chargePlugin } from '../../client/Charge.js'
|
|
10
|
+
import type { ChannelEntry } from '../client/ChannelOps.js'
|
|
11
|
+
import type { SessionContext } from '../client/CredentialState.js'
|
|
12
|
+
import { session as sessionPlugin } from '../client/Session.js'
|
|
13
|
+
import type { ChannelDescriptor } from '../precompile/Protocol.js'
|
|
14
|
+
import { deserializeSessionReceipt } from '../precompile/Protocol.js'
|
|
15
|
+
import { readSessionChallengeAmount, type SessionReceipt } from '../precompile/Protocol.js'
|
|
16
|
+
import {
|
|
17
|
+
deserializeSnapshot as deserializeSessionSnapshot,
|
|
18
|
+
serializeSnapshot as serializeSessionSnapshot,
|
|
19
|
+
} from '../Snapshot.js'
|
|
20
|
+
import { createSessionReceiptCoordinator } from './ReceiptCoordinator.js'
|
|
21
|
+
import { resolveCloseTarget, type CloseTarget } from './Runtime.js'
|
|
22
|
+
import { assertVoucherWithinLocalLimit as assertVoucherWithinLocalAuthorization } from './Runtime.js'
|
|
23
|
+
import type { SessionState } from './Runtime.js'
|
|
24
|
+
import {
|
|
25
|
+
applySessionReceiptToRuntime,
|
|
26
|
+
captureRuntimeSnapshot as captureRuntimeStateSnapshot,
|
|
27
|
+
computeFallbackCloseAmount,
|
|
28
|
+
createSessionManagerRuntime,
|
|
29
|
+
dispatchSessionEvent,
|
|
30
|
+
restoreCumulativeAuthorization,
|
|
31
|
+
restoreRuntimeSnapshot as restoreRuntimeStateSnapshot,
|
|
32
|
+
type RuntimeSnapshot,
|
|
33
|
+
} from './Runtime.js'
|
|
34
|
+
import { closeSocketSession } from './Runtime.js'
|
|
35
|
+
import {
|
|
36
|
+
closeHttpSession,
|
|
37
|
+
getSessionSnapshot,
|
|
38
|
+
isTempoSessionChallenge,
|
|
39
|
+
managementInput,
|
|
40
|
+
postTopUp,
|
|
41
|
+
retryHttpPaymentRequired,
|
|
42
|
+
type TempoSessionChallenge,
|
|
43
|
+
webSocketProbeUrl,
|
|
44
|
+
} from './Transports.js'
|
|
45
|
+
import {
|
|
46
|
+
type SessionManagedWebSocket,
|
|
47
|
+
type WebSocketConstructor,
|
|
48
|
+
WebSocketReadyState,
|
|
49
|
+
} from './Transports.js'
|
|
50
|
+
import { openSseSession, type SseDriverOptions } from './Transports.js'
|
|
51
|
+
import { applyTopUpResult, resolveManualTopUp, type TopUpRequirement } from './Transports.js'
|
|
52
|
+
import {
|
|
53
|
+
openWebSocketSession,
|
|
54
|
+
prepareWebSocketSession,
|
|
55
|
+
type WebSocketDriverOptions,
|
|
56
|
+
} from './Transports.js'
|
|
57
|
+
|
|
58
|
+
export { computeFallbackCloseAmount, type FallbackCloseAmountParameters } from './Runtime.js'
|
|
59
|
+
|
|
60
|
+
/** Auto-driving client manager for HTTP, SSE, and WebSocket TIP-1034 sessions. */
|
|
61
|
+
export type SessionManager = {
|
|
62
|
+
/** Active channel ID, when a channel has been opened or recovered. */
|
|
63
|
+
readonly channelId: Hex.Hex | undefined
|
|
64
|
+
/** Local cumulative voucher authorization in raw token units. */
|
|
65
|
+
readonly cumulative: bigint
|
|
66
|
+
/** Whether the manager currently has an open local channel. */
|
|
67
|
+
readonly opened: boolean
|
|
68
|
+
/** Current pure session state-machine state. */
|
|
69
|
+
readonly state: SessionState
|
|
70
|
+
|
|
71
|
+
/** Runs the HTTP 402 probe, signs/open/top-ups as needed, retries, and returns receipt metadata. */
|
|
72
|
+
fetch(input: RequestInfo | URL, init?: RequestInit): Promise<PaymentResponse>
|
|
73
|
+
/** Opens a paid SSE stream and auto-posts vouchers/top-ups when the server requests more headroom. */
|
|
74
|
+
sse(input: RequestInfo | URL, init?: SessionManagerSseOptions): Promise<AsyncIterable<string>>
|
|
75
|
+
/** Opens a paid WebSocket session after an HTTP challenge probe and manages in-band voucher frames. */
|
|
76
|
+
ws(input: string | URL, init?: SessionManagerWebSocketOptions): Promise<SessionManagedWebSocket>
|
|
77
|
+
/** Tops up the active channel deposit. String amounts are parsed with the manager decimals; bigint amounts are raw units. */
|
|
78
|
+
topUp(amount: string | bigint): Promise<SessionReceipt | undefined>
|
|
79
|
+
/** Cooperatively closes the active channel using the latest locally authorized spend boundary. */
|
|
80
|
+
close(): Promise<SessionReceipt | undefined>
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** Options for `SessionManager.sse()`. */
|
|
84
|
+
export type SessionManagerSseOptions = SseDriverOptions
|
|
85
|
+
|
|
86
|
+
/** Options for `SessionManager.ws()`. */
|
|
87
|
+
export type SessionManagerWebSocketOptions = WebSocketDriverOptions
|
|
88
|
+
|
|
89
|
+
/** HTTP response enriched with the latest session payment metadata. */
|
|
90
|
+
export type PaymentResponse = Response & {
|
|
91
|
+
/** Parsed payment receipt, when the response included one. */
|
|
92
|
+
receipt: SessionReceipt | null
|
|
93
|
+
/** Last session challenge observed by the manager. */
|
|
94
|
+
challenge: TempoSessionChallenge | null
|
|
95
|
+
/** Active channel ID, when available. */
|
|
96
|
+
channelId: Hex.Hex | null
|
|
97
|
+
/** Local cumulative voucher authorization in raw token units. */
|
|
98
|
+
cumulative: bigint
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** Serializable client-side channel snapshot stored between manager instances. */
|
|
102
|
+
export type StoredSessionChannel = {
|
|
103
|
+
/** Latest known channel ID. Used as the next request's channel hint. */
|
|
104
|
+
channelId: Hex.Hex
|
|
105
|
+
/** Latest local cumulative voucher authorization in raw token units. */
|
|
106
|
+
cumulativeAmount: string
|
|
107
|
+
/** Latest known deposit in raw token units. */
|
|
108
|
+
deposit: string
|
|
109
|
+
/** TIP-1034 channel descriptor, used as a fallback when the server cannot snapshot. */
|
|
110
|
+
descriptor: ChannelDescriptor
|
|
111
|
+
/** Escrow address used to derive the channel ID. */
|
|
112
|
+
escrow: Address
|
|
113
|
+
/** Chain ID used to derive the channel ID. */
|
|
114
|
+
chainId: number
|
|
115
|
+
/** Whether the channel was open when stored. Closed channels are not used as hints. */
|
|
116
|
+
opened: boolean
|
|
117
|
+
/** Client timestamp for debugging or app-level eviction. */
|
|
118
|
+
updatedAt: number
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** Optional per-manager store for channel hints and restart recovery. */
|
|
122
|
+
export type SessionStore = {
|
|
123
|
+
/** Reads the latest stored channel snapshot for this manager scope. */
|
|
124
|
+
get(): Promise<StoredSessionChannel | null | undefined> | StoredSessionChannel | null | undefined
|
|
125
|
+
/** Persists the latest channel snapshot. */
|
|
126
|
+
set(channel: StoredSessionChannel): Promise<void> | void
|
|
127
|
+
/** Deletes the stored snapshot when a channel is closed, when supported. */
|
|
128
|
+
delete?(): Promise<void> | void
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** Normalized runtime dependencies derived from `sessionManager()` parameters. */
|
|
132
|
+
type SessionManagerConfig = {
|
|
133
|
+
/** Decimal precision used when parsing human-readable manager amounts. */
|
|
134
|
+
decimals: number
|
|
135
|
+
/** Fetch implementation used for probes, retries, and management posts. */
|
|
136
|
+
fetch: typeof globalThis.fetch
|
|
137
|
+
/** Local maximum cumulative voucher authorization, or null when uncapped. */
|
|
138
|
+
maxVoucherCumulative: bigint | null
|
|
139
|
+
/** WebSocket constructor available in the current runtime, when configured. */
|
|
140
|
+
WebSocket: WebSocketConstructor | undefined
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function isTempoChargeChallenge(challenge: Challenge.Challenge) {
|
|
144
|
+
return (
|
|
145
|
+
challenge.method === Constants.Methods.tempo && challenge.intent === Constants.Intents.charge
|
|
146
|
+
)
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function isZeroAmountChargeChallenge(challenge: Challenge.Challenge) {
|
|
150
|
+
if (!isTempoChargeChallenge(challenge)) return false
|
|
151
|
+
if (typeof challenge.request.amount !== 'string') return false
|
|
152
|
+
try {
|
|
153
|
+
return BigInt(challenge.request.amount) === 0n
|
|
154
|
+
} catch {
|
|
155
|
+
return false
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function storedChannelFromEntry(entry: ChannelEntry): StoredSessionChannel {
|
|
160
|
+
return {
|
|
161
|
+
channelId: entry.channelId,
|
|
162
|
+
cumulativeAmount: entry.cumulativeAmount.toString(),
|
|
163
|
+
deposit: entry.deposit.toString(),
|
|
164
|
+
descriptor: entry.descriptor,
|
|
165
|
+
escrow: entry.escrow,
|
|
166
|
+
chainId: entry.chainId,
|
|
167
|
+
opened: entry.opened,
|
|
168
|
+
updatedAt: Date.now(),
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function storedChannelContext(channel: StoredSessionChannel): SessionContext {
|
|
173
|
+
return {
|
|
174
|
+
channelId: channel.channelId,
|
|
175
|
+
cumulativeAmountRaw: channel.cumulativeAmount,
|
|
176
|
+
descriptor: channel.descriptor,
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function storedChannelFromSnapshot(
|
|
181
|
+
snapshot: ReturnType<typeof deserializeSessionSnapshot>,
|
|
182
|
+
): StoredSessionChannel {
|
|
183
|
+
return {
|
|
184
|
+
channelId: snapshot.channelId,
|
|
185
|
+
cumulativeAmount: snapshot.acceptedCumulative,
|
|
186
|
+
deposit: snapshot.deposit,
|
|
187
|
+
descriptor: snapshot.descriptor,
|
|
188
|
+
escrow: snapshot.escrow,
|
|
189
|
+
chainId: snapshot.chainId,
|
|
190
|
+
opened: true,
|
|
191
|
+
updatedAt: Date.now(),
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
type CredentialContextResolution = {
|
|
196
|
+
context: SessionContext
|
|
197
|
+
usedStoredChannel: boolean
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function resolveCredentialContext(parameters: {
|
|
201
|
+
channel: ChannelEntry | null
|
|
202
|
+
challenge: TempoSessionChallenge
|
|
203
|
+
context: SessionContext
|
|
204
|
+
storedChannel: StoredSessionChannel | null
|
|
205
|
+
}): CredentialContextResolution {
|
|
206
|
+
const { channel, challenge, context, storedChannel } = parameters
|
|
207
|
+
if (
|
|
208
|
+
context.action ||
|
|
209
|
+
channel?.opened ||
|
|
210
|
+
!storedChannel?.opened ||
|
|
211
|
+
getSessionSnapshot(challenge)
|
|
212
|
+
) {
|
|
213
|
+
return { context, usedStoredChannel: false }
|
|
214
|
+
}
|
|
215
|
+
return {
|
|
216
|
+
context: { ...context, ...storedChannelContext(storedChannel) },
|
|
217
|
+
usedStoredChannel: true,
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function requestInitWithSessionHint(
|
|
222
|
+
input: RequestInfo | URL,
|
|
223
|
+
init: RequestInit | undefined,
|
|
224
|
+
channelId: Hex.Hex | undefined,
|
|
225
|
+
): RequestInit | undefined {
|
|
226
|
+
if (!channelId) return init
|
|
227
|
+
const requestHeaders = input instanceof Request ? input.headers : undefined
|
|
228
|
+
const headers = {
|
|
229
|
+
...Fetch.normalizeHeaders(requestHeaders),
|
|
230
|
+
...Fetch.normalizeHeaders(init?.headers),
|
|
231
|
+
}
|
|
232
|
+
if (
|
|
233
|
+
Object.keys(headers).some(
|
|
234
|
+
(key) => key.toLowerCase() === Constants.Headers.paymentSession.toLowerCase(),
|
|
235
|
+
)
|
|
236
|
+
)
|
|
237
|
+
return init
|
|
238
|
+
return {
|
|
239
|
+
...init,
|
|
240
|
+
headers: {
|
|
241
|
+
...headers,
|
|
242
|
+
[Constants.Headers.paymentSession]: channelId,
|
|
243
|
+
},
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function resolveSessionManagerConfig(parameters: sessionManager.Parameters): SessionManagerConfig {
|
|
248
|
+
const decimals = parameters.decimals ?? 6
|
|
249
|
+
const WebSocket =
|
|
250
|
+
parameters.webSocket ??
|
|
251
|
+
(globalThis as typeof globalThis & { WebSocket?: WebSocketConstructor }).WebSocket
|
|
252
|
+
|
|
253
|
+
return {
|
|
254
|
+
decimals,
|
|
255
|
+
fetch: parameters.fetch ?? globalThis.fetch.bind(globalThis),
|
|
256
|
+
maxVoucherCumulative:
|
|
257
|
+
parameters.maxDeposit !== undefined ? parseUnits(parameters.maxDeposit, decimals) : null,
|
|
258
|
+
WebSocket,
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Creates a session manager that handles the full client payment lifecycle:
|
|
264
|
+
* channel open, incremental vouchers, SSE streaming, and channel close.
|
|
265
|
+
*
|
|
266
|
+
* Internally delegates to the `session()` method for all
|
|
267
|
+
* channel state management and credential creation, and to `Fetch.from`
|
|
268
|
+
* for the 402 challenge/retry flow.
|
|
269
|
+
*
|
|
270
|
+
* ## Session resumption
|
|
271
|
+
*
|
|
272
|
+
* The manager only keeps active client transport state in memory. Channel
|
|
273
|
+
* descriptors and cumulative voucher state are hydrated from server snapshots
|
|
274
|
+
* when challenges include them; otherwise the next request opens a fresh
|
|
275
|
+
* TIP-1034 channel. `maxDeposit` remains the local cap for all automatic
|
|
276
|
+
* voucher and top-up decisions.
|
|
277
|
+
*/
|
|
278
|
+
export function sessionManager(parameters: sessionManager.Parameters): SessionManager {
|
|
279
|
+
const config = resolveSessionManagerConfig(parameters)
|
|
280
|
+
const sessionStore = parameters.sessionStore
|
|
281
|
+
let storedChannel: StoredSessionChannel | null = null
|
|
282
|
+
let bootstrapChannelId: Hex.Hex | null = null
|
|
283
|
+
const ignoredStoredChannelIds = new Set<Hex.Hex>()
|
|
284
|
+
const runtime = createSessionManagerRuntime()
|
|
285
|
+
const receipts = createSessionReceiptCoordinator({
|
|
286
|
+
getSocketSession: () => runtime.socketSession,
|
|
287
|
+
})
|
|
288
|
+
|
|
289
|
+
function dispatch(event: Parameters<typeof dispatchSessionEvent>[1]) {
|
|
290
|
+
return dispatchSessionEvent(runtime, event)
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
const method = sessionPlugin({
|
|
294
|
+
account: parameters.account,
|
|
295
|
+
authorizedSigner: parameters.authorizedSigner,
|
|
296
|
+
getClient: parameters.client ? () => parameters.client! : parameters.getClient,
|
|
297
|
+
escrow: parameters.escrow,
|
|
298
|
+
decimals: config.decimals,
|
|
299
|
+
maxDeposit: parameters.maxDeposit,
|
|
300
|
+
onChannelUpdate(entry) {
|
|
301
|
+
if (entry.channelId !== runtime.channel?.channelId) runtime.spent = 0n
|
|
302
|
+
runtime.channel = entry
|
|
303
|
+
persistStoredChannel(entry)
|
|
304
|
+
if (runtime.lastChallenge) {
|
|
305
|
+
dispatch({
|
|
306
|
+
type: 'activated',
|
|
307
|
+
challengeId: runtime.lastChallenge.id,
|
|
308
|
+
entry,
|
|
309
|
+
spent: runtime.spent.toString(),
|
|
310
|
+
units: 0,
|
|
311
|
+
})
|
|
312
|
+
}
|
|
313
|
+
},
|
|
314
|
+
})
|
|
315
|
+
const chargeMethod = chargePlugin({
|
|
316
|
+
account: parameters.account,
|
|
317
|
+
getClient: parameters.client ? () => parameters.client! : parameters.getClient,
|
|
318
|
+
})
|
|
319
|
+
|
|
320
|
+
const wrappedFetch = Fetch.from({
|
|
321
|
+
fetch: config.fetch,
|
|
322
|
+
methods: [method],
|
|
323
|
+
onChallenge: async (challenge, _helpers) => {
|
|
324
|
+
if (!isTempoSessionChallenge(challenge)) return undefined
|
|
325
|
+
runtime.lastChallenge = challenge
|
|
326
|
+
dispatch({ type: 'challengeReceived', challengeId: challenge.id })
|
|
327
|
+
if (runtime.channel?.opened && runtime.lastUrl) {
|
|
328
|
+
const requiredCumulative =
|
|
329
|
+
runtime.channel.cumulativeAmount + readSessionChallengeAmount(challenge)
|
|
330
|
+
await topUpIfNeeded({
|
|
331
|
+
challenge,
|
|
332
|
+
input: runtime.lastUrl,
|
|
333
|
+
channelId: runtime.channel.channelId,
|
|
334
|
+
deposit: runtime.channel.deposit,
|
|
335
|
+
requiredCumulative,
|
|
336
|
+
})
|
|
337
|
+
}
|
|
338
|
+
const resolved = resolveCredentialContext({
|
|
339
|
+
challenge,
|
|
340
|
+
channel: runtime.channel,
|
|
341
|
+
context: {},
|
|
342
|
+
storedChannel,
|
|
343
|
+
})
|
|
344
|
+
if (resolved.usedStoredChannel) return _helpers.createCredential(resolved.context)
|
|
345
|
+
return undefined
|
|
346
|
+
},
|
|
347
|
+
})
|
|
348
|
+
|
|
349
|
+
function createSessionCredential(challenge: TempoSessionChallenge, context: SessionContext) {
|
|
350
|
+
const resolved = resolveCredentialContext({
|
|
351
|
+
challenge,
|
|
352
|
+
channel: runtime.channel,
|
|
353
|
+
context,
|
|
354
|
+
storedChannel,
|
|
355
|
+
})
|
|
356
|
+
return method.createCredential({
|
|
357
|
+
challenge,
|
|
358
|
+
context: resolved.context,
|
|
359
|
+
})
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
function updateSpentFromReceipt(receipt: SessionReceipt | null | undefined) {
|
|
363
|
+
applySessionReceiptToRuntime({
|
|
364
|
+
maxVoucherCumulative: config.maxVoucherCumulative,
|
|
365
|
+
receipt,
|
|
366
|
+
runtime,
|
|
367
|
+
})
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
function activateCurrentChannel(
|
|
371
|
+
units = runtime.state.status === 'active' ? runtime.state.units : 0,
|
|
372
|
+
) {
|
|
373
|
+
if (!runtime.channel || !runtime.lastChallenge) return
|
|
374
|
+
if (
|
|
375
|
+
runtime.state.status === 'active' ||
|
|
376
|
+
runtime.state.status === 'withdrawable' ||
|
|
377
|
+
runtime.state.status === 'closeRequested'
|
|
378
|
+
)
|
|
379
|
+
return
|
|
380
|
+
dispatch({
|
|
381
|
+
type: 'activated',
|
|
382
|
+
challengeId: runtime.lastChallenge.id,
|
|
383
|
+
entry: runtime.channel,
|
|
384
|
+
spent: runtime.spent.toString(),
|
|
385
|
+
units,
|
|
386
|
+
})
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
async function getStoredChannel() {
|
|
390
|
+
if (!sessionStore) return null
|
|
391
|
+
if (storedChannel) return storedChannel
|
|
392
|
+
const channel = await sessionStore.get()
|
|
393
|
+
storedChannel =
|
|
394
|
+
channel?.opened && !ignoredStoredChannelIds.has(channel.channelId) ? channel : null
|
|
395
|
+
return storedChannel
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
async function clearStoredChannel() {
|
|
399
|
+
if (!sessionStore) {
|
|
400
|
+
storedChannel = null
|
|
401
|
+
bootstrapChannelId = null
|
|
402
|
+
return
|
|
403
|
+
}
|
|
404
|
+
const channel = storedChannel
|
|
405
|
+
if (channel) ignoredStoredChannelIds.add(channel.channelId)
|
|
406
|
+
storedChannel = null
|
|
407
|
+
bootstrapChannelId = null
|
|
408
|
+
if (sessionStore.delete) {
|
|
409
|
+
await Promise.resolve(sessionStore.delete()).catch(() => undefined)
|
|
410
|
+
return
|
|
411
|
+
}
|
|
412
|
+
if (channel) {
|
|
413
|
+
await Promise.resolve(
|
|
414
|
+
sessionStore.set({ ...channel, opened: false, updatedAt: Date.now() }),
|
|
415
|
+
).catch(() => undefined)
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
async function storeSnapshotHeader(response: Response) {
|
|
420
|
+
const header = response.headers.get(Constants.Headers.paymentSessionSnapshot)
|
|
421
|
+
if (!header) return
|
|
422
|
+
const snapshot = deserializeSessionSnapshot(header)
|
|
423
|
+
bootstrapChannelId = snapshot.channelId
|
|
424
|
+
const channel = storedChannelFromSnapshot(snapshot)
|
|
425
|
+
storedChannel = channel
|
|
426
|
+
if (sessionStore) await Promise.resolve(sessionStore.set(channel)).catch(() => undefined)
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
async function bootstrapSession(input: RequestInfo | URL, init?: RequestInit | undefined) {
|
|
430
|
+
if (!parameters.bootstrap) return
|
|
431
|
+
if (runtime.channel?.opened) return
|
|
432
|
+
if (await getStoredChannel()) return
|
|
433
|
+
|
|
434
|
+
const requestHeaders = input instanceof Request ? input.headers : undefined
|
|
435
|
+
const { body: _body, method: _method, ...bootstrapInit } = init ?? {}
|
|
436
|
+
const bootstrapInput = input instanceof Request ? input.url : input
|
|
437
|
+
const headInit: RequestInit = {
|
|
438
|
+
...bootstrapInit,
|
|
439
|
+
method: 'HEAD',
|
|
440
|
+
headers: {
|
|
441
|
+
...Fetch.normalizeHeaders(requestHeaders),
|
|
442
|
+
...Fetch.normalizeHeaders(init?.headers),
|
|
443
|
+
[Constants.Headers.acceptPayment]: `${Constants.Methods.tempo}/${Constants.Intents.charge}`,
|
|
444
|
+
},
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
try {
|
|
448
|
+
const challengeResponse = await config.fetch(bootstrapInput, headInit)
|
|
449
|
+
if (challengeResponse.status !== 402) {
|
|
450
|
+
await storeSnapshotHeader(challengeResponse)
|
|
451
|
+
return
|
|
452
|
+
}
|
|
453
|
+
const challenge = Challenge.fromResponseList(challengeResponse).find(isTempoChargeChallenge)
|
|
454
|
+
if (!challenge) return
|
|
455
|
+
if (!isZeroAmountChargeChallenge(challenge)) return
|
|
456
|
+
const credential = await chargeMethod.createCredential({
|
|
457
|
+
challenge: challenge as never,
|
|
458
|
+
context: {},
|
|
459
|
+
})
|
|
460
|
+
const response = await config.fetch(bootstrapInput, {
|
|
461
|
+
...headInit,
|
|
462
|
+
headers: {
|
|
463
|
+
...Fetch.normalizeHeaders(headInit.headers),
|
|
464
|
+
[Constants.Headers.authorization]: credential,
|
|
465
|
+
},
|
|
466
|
+
})
|
|
467
|
+
if (response.ok) await storeSnapshotHeader(response)
|
|
468
|
+
} catch {
|
|
469
|
+
return
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
function persistStoredChannel(entry: ChannelEntry) {
|
|
474
|
+
if (!sessionStore) return
|
|
475
|
+
const channel = storedChannelFromEntry(entry)
|
|
476
|
+
ignoredStoredChannelIds.delete(channel.channelId)
|
|
477
|
+
const operation =
|
|
478
|
+
entry.opened || !sessionStore.delete ? sessionStore.set(channel) : sessionStore.delete()
|
|
479
|
+
void Promise.resolve(operation).catch(() => undefined)
|
|
480
|
+
storedChannel = entry.opened ? channel : null
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
function getFallbackCloseAmount(challenge: TempoSessionChallenge, channelId: Hex.Hex): bigint {
|
|
484
|
+
const currentSocket = runtime.socketSession
|
|
485
|
+
return computeFallbackCloseAmount({
|
|
486
|
+
challengeId: challenge.id,
|
|
487
|
+
channelId,
|
|
488
|
+
closeReadyReceipt: currentSocket?.closeReadyReceipt,
|
|
489
|
+
cumulativeAmount:
|
|
490
|
+
runtime.channel?.channelId === channelId ? runtime.channel.cumulativeAmount : 0n,
|
|
491
|
+
deliveredChunks: currentSocket?.deliveredChunks,
|
|
492
|
+
socketChallengeId: currentSocket?.challenge.id,
|
|
493
|
+
socketChannelId: currentSocket?.channelId,
|
|
494
|
+
spent: runtime.spent,
|
|
495
|
+
tickCost: currentSocket?.tickCost,
|
|
496
|
+
})
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
function getValidatedFallbackCloseAmount(target: CloseTarget) {
|
|
500
|
+
const closeAmount = getFallbackCloseAmount(target.challenge, target.channelId)
|
|
501
|
+
if (closeAmount > target.channel.cumulativeAmount) {
|
|
502
|
+
throw new Error('fallback close amount exceeds local voucher state')
|
|
503
|
+
}
|
|
504
|
+
assertVoucherWithinLocalLimit(closeAmount)
|
|
505
|
+
return closeAmount.toString()
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
function assertVoucherWithinLocalLimit(cumulativeAmount: bigint) {
|
|
509
|
+
assertVoucherWithinLocalAuthorization({
|
|
510
|
+
cumulativeAmount,
|
|
511
|
+
maxVoucherCumulative: config.maxVoucherCumulative,
|
|
512
|
+
})
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
async function postTopUpAndApply(parameters: {
|
|
516
|
+
additionalDeposit: bigint
|
|
517
|
+
challenge: TempoSessionChallenge
|
|
518
|
+
channelId: Hex.Hex
|
|
519
|
+
input: RequestInfo | URL
|
|
520
|
+
}) {
|
|
521
|
+
const receipt = await postTopUp({
|
|
522
|
+
...parameters,
|
|
523
|
+
channel: runtime.channel,
|
|
524
|
+
createSessionCredential,
|
|
525
|
+
fetch: config.fetch,
|
|
526
|
+
})
|
|
527
|
+
updateSpentFromReceipt(receipt)
|
|
528
|
+
const applied = applyTopUpResult({
|
|
529
|
+
additionalDeposit: parameters.additionalDeposit,
|
|
530
|
+
channel: runtime.channel,
|
|
531
|
+
channelId: parameters.channelId,
|
|
532
|
+
challengeId: runtime.lastChallenge?.id,
|
|
533
|
+
currentState: runtime.state,
|
|
534
|
+
receipt,
|
|
535
|
+
spent: runtime.spent,
|
|
536
|
+
})
|
|
537
|
+
if (applied?.channel && runtime.lastChallenge) {
|
|
538
|
+
dispatch({
|
|
539
|
+
type: 'activated',
|
|
540
|
+
challengeId: runtime.lastChallenge.id,
|
|
541
|
+
entry: applied.channel,
|
|
542
|
+
spent: runtime.spent.toString(),
|
|
543
|
+
units: runtime.state.status === 'active' ? runtime.state.units : 0,
|
|
544
|
+
})
|
|
545
|
+
}
|
|
546
|
+
return receipt
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
async function topUpIfNeeded(parameters: TopUpRequirement) {
|
|
550
|
+
if (parameters.requiredCumulative <= parameters.deposit) return
|
|
551
|
+
assertVoucherWithinLocalLimit(parameters.requiredCumulative)
|
|
552
|
+
await postTopUpAndApply({
|
|
553
|
+
challenge: parameters.challenge,
|
|
554
|
+
input: parameters.input,
|
|
555
|
+
channelId: parameters.channelId,
|
|
556
|
+
additionalDeposit: parameters.requiredCumulative - parameters.deposit,
|
|
557
|
+
})
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
function restoreCumulative(channelId: Hex.Hex, cumulativeAmount: bigint) {
|
|
561
|
+
const restored = restoreCumulativeAuthorization({
|
|
562
|
+
channel: runtime.channel,
|
|
563
|
+
channelId,
|
|
564
|
+
challengeId: runtime.lastChallenge?.id,
|
|
565
|
+
cumulativeAmount,
|
|
566
|
+
spent: runtime.spent,
|
|
567
|
+
state: runtime.state,
|
|
568
|
+
})
|
|
569
|
+
if (restored && runtime.channel) {
|
|
570
|
+
dispatch({
|
|
571
|
+
type: 'activated',
|
|
572
|
+
challengeId: restored.challengeId,
|
|
573
|
+
entry: runtime.channel,
|
|
574
|
+
spent: restored.spent,
|
|
575
|
+
units: restored.units,
|
|
576
|
+
})
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
function restoreRuntime(snapshot: RuntimeSnapshot) {
|
|
581
|
+
const restored = restoreRuntimeStateSnapshot(snapshot, runtime.channel)
|
|
582
|
+
runtime.channel = restored.channel
|
|
583
|
+
runtime.spent = restored.spent
|
|
584
|
+
runtime.state = restored.state
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
function toPaymentResponse(response: Response): PaymentResponse {
|
|
588
|
+
const receiptHeader = response.headers.get(Constants.Headers.paymentReceipt)
|
|
589
|
+
const receipt = receiptHeader ? deserializeSessionReceipt(receiptHeader) : null
|
|
590
|
+
updateSpentFromReceipt(receipt)
|
|
591
|
+
return Object.assign(response, {
|
|
592
|
+
receipt,
|
|
593
|
+
challenge: runtime.lastChallenge,
|
|
594
|
+
channelId: runtime.channel?.channelId ?? null,
|
|
595
|
+
cumulative: runtime.channel?.cumulativeAmount ?? 0n,
|
|
596
|
+
})
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
async function doFetch(input: RequestInfo | URL, init?: RequestInit): Promise<PaymentResponse> {
|
|
600
|
+
runtime.lastUrl = input
|
|
601
|
+
const stored = await getStoredChannel()
|
|
602
|
+
await bootstrapSession(input, init)
|
|
603
|
+
const hintedInit = requestInitWithSessionHint(
|
|
604
|
+
input,
|
|
605
|
+
init,
|
|
606
|
+
(await getStoredChannel())?.channelId ?? bootstrapChannelId ?? stored?.channelId,
|
|
607
|
+
)
|
|
608
|
+
const previous = captureRuntimeStateSnapshot({
|
|
609
|
+
channel: runtime.channel,
|
|
610
|
+
spent: runtime.spent,
|
|
611
|
+
state: runtime.state,
|
|
612
|
+
})
|
|
613
|
+
|
|
614
|
+
let effectiveInit = hintedInit
|
|
615
|
+
let canRetryWithoutStoredHint = Boolean(stored?.opened && !previous.channel?.opened)
|
|
616
|
+
|
|
617
|
+
for (;;) {
|
|
618
|
+
let response: Response
|
|
619
|
+
try {
|
|
620
|
+
response = await wrappedFetch(input, effectiveInit)
|
|
621
|
+
} catch (error) {
|
|
622
|
+
restoreRuntime(previous)
|
|
623
|
+
if (!canRetryWithoutStoredHint) throw error
|
|
624
|
+
canRetryWithoutStoredHint = false
|
|
625
|
+
await clearStoredChannel()
|
|
626
|
+
await bootstrapSession(input, init)
|
|
627
|
+
effectiveInit = requestInitWithSessionHint(input, init, bootstrapChannelId ?? undefined)
|
|
628
|
+
continue
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
let paymentResponse = toPaymentResponse(response)
|
|
632
|
+
let attemptedHttpManagement = false
|
|
633
|
+
if (paymentResponse.status === 402) {
|
|
634
|
+
const retry = await retryHttpPaymentRequired({
|
|
635
|
+
input,
|
|
636
|
+
init: effectiveInit,
|
|
637
|
+
response: paymentResponse,
|
|
638
|
+
createSessionCredential,
|
|
639
|
+
fetch: config.fetch,
|
|
640
|
+
getChannel: () => runtime.channel,
|
|
641
|
+
restoreCumulative,
|
|
642
|
+
setChallenge(challenge) {
|
|
643
|
+
runtime.lastChallenge = challenge
|
|
644
|
+
},
|
|
645
|
+
topUpIfNeeded,
|
|
646
|
+
})
|
|
647
|
+
if (retry) {
|
|
648
|
+
attemptedHttpManagement = true
|
|
649
|
+
paymentResponse = toPaymentResponse(retry)
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
if (!attemptedHttpManagement && !paymentResponse.ok && !paymentResponse.receipt) {
|
|
653
|
+
restoreRuntime(previous)
|
|
654
|
+
if (!canRetryWithoutStoredHint) return paymentResponse
|
|
655
|
+
canRetryWithoutStoredHint = false
|
|
656
|
+
await clearStoredChannel()
|
|
657
|
+
await bootstrapSession(input, init)
|
|
658
|
+
effectiveInit = requestInitWithSessionHint(input, init, bootstrapChannelId ?? undefined)
|
|
659
|
+
continue
|
|
660
|
+
}
|
|
661
|
+
return paymentResponse
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
async function closeHttpSessionAndApply(
|
|
666
|
+
target: CloseTarget,
|
|
667
|
+
): Promise<SessionReceipt | undefined> {
|
|
668
|
+
const receipt = await closeHttpSession({
|
|
669
|
+
createSessionCredential,
|
|
670
|
+
fetch: config.fetch,
|
|
671
|
+
lastUrl: runtime.lastUrl,
|
|
672
|
+
signedCloseAmount: getValidatedFallbackCloseAmount(target),
|
|
673
|
+
setChallenge(challenge) {
|
|
674
|
+
runtime.lastChallenge = challenge
|
|
675
|
+
},
|
|
676
|
+
target,
|
|
677
|
+
})
|
|
678
|
+
if (receipt) {
|
|
679
|
+
activateCurrentChannel()
|
|
680
|
+
dispatch({ type: 'closeStarted' })
|
|
681
|
+
dispatch({ type: 'closed', receipt })
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
return receipt
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
const self: SessionManager = {
|
|
688
|
+
get channelId() {
|
|
689
|
+
return runtime.channel?.channelId
|
|
690
|
+
},
|
|
691
|
+
get cumulative() {
|
|
692
|
+
return runtime.channel?.cumulativeAmount ?? 0n
|
|
693
|
+
},
|
|
694
|
+
get opened() {
|
|
695
|
+
return runtime.channel?.opened ?? false
|
|
696
|
+
},
|
|
697
|
+
get state() {
|
|
698
|
+
return runtime.state
|
|
699
|
+
},
|
|
700
|
+
|
|
701
|
+
fetch: doFetch,
|
|
702
|
+
|
|
703
|
+
async topUp(amount) {
|
|
704
|
+
const target = resolveManualTopUp({
|
|
705
|
+
amount,
|
|
706
|
+
assertVoucherWithinLocalLimit,
|
|
707
|
+
channel: runtime.channel,
|
|
708
|
+
decimals: config.decimals,
|
|
709
|
+
lastChallenge: runtime.lastChallenge,
|
|
710
|
+
lastUrl: runtime.lastUrl,
|
|
711
|
+
})
|
|
712
|
+
|
|
713
|
+
return postTopUpAndApply({
|
|
714
|
+
additionalDeposit: target.additionalDeposit,
|
|
715
|
+
challenge: target.challenge,
|
|
716
|
+
channelId: target.channelId,
|
|
717
|
+
input: target.input,
|
|
718
|
+
})
|
|
719
|
+
},
|
|
720
|
+
|
|
721
|
+
async sse(input, init) {
|
|
722
|
+
return openSseSession(input, init, {
|
|
723
|
+
createSessionCredential,
|
|
724
|
+
doFetch,
|
|
725
|
+
fetch: config.fetch,
|
|
726
|
+
getChannel: () => runtime.channel,
|
|
727
|
+
getChallenge: () => runtime.lastChallenge,
|
|
728
|
+
assertVoucherWithinLocalLimit,
|
|
729
|
+
managementInput,
|
|
730
|
+
acceptReceipt(receipt) {
|
|
731
|
+
updateSpentFromReceipt(receipt)
|
|
732
|
+
},
|
|
733
|
+
topUpIfNeeded,
|
|
734
|
+
})
|
|
735
|
+
},
|
|
736
|
+
|
|
737
|
+
async ws(input, init) {
|
|
738
|
+
if (!config.WebSocket) {
|
|
739
|
+
throw new Error(
|
|
740
|
+
'No WebSocket implementation available. Pass `webSocket` to sessionManager() in this runtime.',
|
|
741
|
+
)
|
|
742
|
+
}
|
|
743
|
+
const probeUrl = webSocketProbeUrl(input)
|
|
744
|
+
await bootstrapSession(probeUrl, init?.signal ? { signal: init.signal } : undefined)
|
|
745
|
+
|
|
746
|
+
const prepared = await prepareWebSocketSession({
|
|
747
|
+
createSessionCredential,
|
|
748
|
+
fetch: config.fetch,
|
|
749
|
+
input,
|
|
750
|
+
onProbeUrl(httpUrl) {
|
|
751
|
+
runtime.lastUrl = httpUrl.toString()
|
|
752
|
+
},
|
|
753
|
+
probeInit: requestInitWithSessionHint(
|
|
754
|
+
probeUrl,
|
|
755
|
+
init?.signal ? { signal: init.signal } : undefined,
|
|
756
|
+
(await getStoredChannel())?.channelId ?? bootstrapChannelId ?? undefined,
|
|
757
|
+
),
|
|
758
|
+
signal: init?.signal,
|
|
759
|
+
})
|
|
760
|
+
const { challenge, credential, httpUrl, wsUrl } = prepared
|
|
761
|
+
runtime.lastChallenge = challenge
|
|
762
|
+
|
|
763
|
+
return openWebSocketSession({
|
|
764
|
+
challenge,
|
|
765
|
+
credential,
|
|
766
|
+
httpUrl,
|
|
767
|
+
WebSocket: config.WebSocket,
|
|
768
|
+
wsUrl,
|
|
769
|
+
options: init,
|
|
770
|
+
createSessionCredential,
|
|
771
|
+
getChannel: () => runtime.channel,
|
|
772
|
+
setSocketSession(session) {
|
|
773
|
+
runtime.socketSession = session
|
|
774
|
+
},
|
|
775
|
+
assertVoucherWithinLocalLimit,
|
|
776
|
+
acceptReceipt: updateSpentFromReceipt,
|
|
777
|
+
rejectCloseReady: receipts.rejectCloseReady,
|
|
778
|
+
rejectReceipt: receipts.rejectReceipt,
|
|
779
|
+
settleCloseReady: receipts.settleCloseReady,
|
|
780
|
+
settleReceipt: receipts.settleReceipt,
|
|
781
|
+
topUpIfNeeded,
|
|
782
|
+
waitForReceipt: receipts.waitForReceipt,
|
|
783
|
+
})
|
|
784
|
+
},
|
|
785
|
+
|
|
786
|
+
async close() {
|
|
787
|
+
const currentSocket = runtime.socketSession
|
|
788
|
+
const target = resolveCloseTarget({
|
|
789
|
+
channel: runtime.channel,
|
|
790
|
+
currentSocket,
|
|
791
|
+
lastChallenge: runtime.lastChallenge,
|
|
792
|
+
})
|
|
793
|
+
if (!target) return undefined
|
|
794
|
+
|
|
795
|
+
const activeSocket = currentSocket?.socket
|
|
796
|
+
if (currentSocket && activeSocket?.readyState === WebSocketReadyState.OPEN) {
|
|
797
|
+
const receipt = await closeSocketSession({
|
|
798
|
+
activeSocket,
|
|
799
|
+
createSessionCredential,
|
|
800
|
+
currentSocket,
|
|
801
|
+
spent: runtime.spent,
|
|
802
|
+
target,
|
|
803
|
+
waitForCloseReady: receipts.waitForCloseReady,
|
|
804
|
+
waitForReceipt: receipts.waitForReceipt,
|
|
805
|
+
})
|
|
806
|
+
activateCurrentChannel()
|
|
807
|
+
dispatch({ type: 'closeStarted' })
|
|
808
|
+
dispatch({ type: 'closed', receipt })
|
|
809
|
+
return receipt
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
return closeHttpSessionAndApply(target)
|
|
813
|
+
},
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
return self
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
/** Type helpers for `sessionManager()`. */
|
|
820
|
+
export namespace sessionManager {
|
|
821
|
+
export const serializeSnapshot = serializeSessionSnapshot
|
|
822
|
+
export const deserializeSnapshot = deserializeSessionSnapshot
|
|
823
|
+
|
|
824
|
+
export type Parameters = Account.getResolver.Parameters &
|
|
825
|
+
Client.getResolver.Parameters & {
|
|
826
|
+
/** Address authorized to sign vouchers. Defaults to the account access key address when available, otherwise the account address. */
|
|
827
|
+
authorizedSigner?: Address | undefined
|
|
828
|
+
/** Enables same-route HEAD bootstrap from a server session snapshot before opening a new channel. */
|
|
829
|
+
bootstrap?: boolean | undefined
|
|
830
|
+
/** Viem client instance. Shorthand for `getClient: () => client`. */
|
|
831
|
+
client?: import('viem').Client | undefined
|
|
832
|
+
/** Token decimals used to convert `maxDeposit` to raw units. Defaults to `6`. */
|
|
833
|
+
decimals?: number | undefined
|
|
834
|
+
/** TIP20EscrowChannel precompile address override. */
|
|
835
|
+
escrow?: Address | undefined
|
|
836
|
+
/** Fetch implementation used for HTTP probes, management posts, and paid retries. */
|
|
837
|
+
fetch?: typeof globalThis.fetch | undefined
|
|
838
|
+
/** Maximum deposit in human-readable units (e.g. `'10'` for 10 tokens). Converted to raw units via `decimals`. */
|
|
839
|
+
maxDeposit?: string | undefined
|
|
840
|
+
/** Optional per-manager store for persisted channel hints and restart recovery. */
|
|
841
|
+
sessionStore?: SessionStore | undefined
|
|
842
|
+
/** Optional websocket constructor for runtimes without a global WebSocket. */
|
|
843
|
+
webSocket?: WebSocketConstructor | undefined
|
|
844
|
+
}
|
|
845
|
+
}
|