mppx 0.6.31 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +50 -0
- package/README.md +20 -11
- package/dist/Challenge.d.ts.map +1 -1
- package/dist/Challenge.js +27 -13
- 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/Mcp.d.ts +3 -0
- package/dist/Mcp.d.ts.map +1 -1
- package/dist/Mcp.js +2 -0
- package/dist/Mcp.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/PaymentRequest.d.ts +10 -10
- package/dist/PaymentRequest.js +8 -8
- 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/Mppx.js +2 -2
- package/dist/client/Mppx.js.map +1 -1
- package/dist/client/Transport.d.ts +11 -16
- package/dist/client/Transport.d.ts.map +1 -1
- package/dist/client/Transport.js +55 -76
- package/dist/client/Transport.js.map +1 -1
- package/dist/client/index.d.ts +5 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +3 -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 +60 -13
- package/dist/client/internal/Fetch.js.map +1 -1
- package/dist/client/internal/protocols/Mcp.d.ts +7 -0
- package/dist/client/internal/protocols/Mcp.d.ts.map +1 -0
- package/dist/client/internal/protocols/Mcp.js +159 -0
- package/dist/client/internal/protocols/Mcp.js.map +1 -0
- package/dist/client/internal/protocols/Mpp.d.ts +4 -0
- package/dist/client/internal/protocols/Mpp.d.ts.map +1 -0
- package/dist/client/internal/protocols/Mpp.js +18 -0
- package/dist/client/internal/protocols/Mpp.js.map +1 -0
- package/dist/client/internal/protocols/Protocol.d.ts +10 -0
- package/dist/client/internal/protocols/Protocol.d.ts.map +1 -0
- package/dist/client/internal/protocols/Protocol.js +2 -0
- package/dist/client/internal/protocols/Protocol.js.map +1 -0
- package/dist/client/internal/protocols/Shared.d.ts +5 -0
- package/dist/client/internal/protocols/Shared.d.ts.map +1 -0
- package/dist/client/internal/protocols/Shared.js +20 -0
- package/dist/client/internal/protocols/Shared.js.map +1 -0
- package/dist/client/internal/protocols/X402.d.ts +8 -0
- package/dist/client/internal/protocols/X402.d.ts.map +1 -0
- package/dist/client/internal/protocols/X402.js +39 -0
- package/dist/client/internal/protocols/X402.js.map +1 -0
- package/dist/evm/client/index.d.ts +1 -0
- package/dist/evm/client/index.d.ts.map +1 -1
- package/dist/evm/client/index.js +1 -0
- package/dist/evm/client/index.js.map +1 -1
- package/dist/evm/index.d.ts +2 -0
- package/dist/evm/index.d.ts.map +1 -1
- package/dist/evm/index.js +2 -0
- package/dist/evm/index.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/evm/server/index.d.ts +1 -0
- package/dist/evm/server/index.d.ts.map +1 -1
- package/dist/evm/server/index.js +1 -0
- package/dist/evm/server/index.js.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/client/McpClient.d.ts +101 -0
- package/dist/mcp/client/McpClient.d.ts.map +1 -0
- package/dist/mcp/client/McpClient.js +162 -0
- package/dist/mcp/client/McpClient.js.map +1 -0
- package/dist/mcp/client/index.d.ts.map +1 -0
- package/dist/mcp/client/index.js.map +1 -0
- package/dist/mcp/server/Transport.d.ts.map +1 -0
- package/dist/mcp/server/Transport.js.map +1 -0
- package/dist/mcp/server/index.d.ts.map +1 -0
- package/dist/mcp/server/index.js.map +1 -0
- package/dist/server/Mppx.d.ts +12 -4
- package/dist/server/Mppx.d.ts.map +1 -1
- package/dist/server/Mppx.js +85 -27
- package/dist/server/Mppx.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 +1 -1
- package/dist/server/Transport.d.ts.map +1 -1
- package/dist/server/Transport.js +5 -4
- 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/Proof.d.ts +85 -1
- package/dist/tempo/Proof.d.ts.map +1 -1
- package/dist/tempo/Proof.js +35 -0
- package/dist/tempo/Proof.js.map +1 -1
- package/dist/tempo/client/Charge.d.ts +19 -1
- package/dist/tempo/client/Charge.d.ts.map +1 -1
- package/dist/tempo/client/Charge.js +47 -27
- package/dist/tempo/client/Charge.js.map +1 -1
- package/dist/tempo/client/Methods.d.ts +41 -10
- package/dist/tempo/client/Methods.d.ts.map +1 -1
- package/dist/tempo/client/Methods.js +16 -7
- package/dist/tempo/client/Methods.js.map +1 -1
- package/dist/tempo/client/ResolveAccount.d.ts +40 -0
- package/dist/tempo/client/ResolveAccount.d.ts.map +1 -0
- package/dist/tempo/client/ResolveAccount.js +2 -0
- package/dist/tempo/client/ResolveAccount.js.map +1 -0
- 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 +29 -1
- package/dist/tempo/internal/fee-payer.d.ts.map +1 -1
- package/dist/tempo/internal/fee-payer.js +138 -4
- package/dist/tempo/internal/fee-payer.js.map +1 -1
- package/dist/tempo/internal/proof.d.ts +71 -5
- package/dist/tempo/internal/proof.d.ts.map +1 -1
- package/dist/tempo/internal/proof.js +42 -6
- package/dist/tempo/internal/proof.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 +30 -19
- 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 +12 -10
- 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 +51 -30
- package/dist/tempo/server/Charge.js.map +1 -1
- package/dist/tempo/server/Methods.d.ts +67 -8
- package/dist/tempo/server/Methods.d.ts.map +1 -1
- package/dist/tempo/server/Methods.js +40 -10
- package/dist/tempo/server/Methods.js.map +1 -1
- package/dist/tempo/server/Subscription.d.ts +11 -1
- package/dist/tempo/server/Subscription.d.ts.map +1 -1
- package/dist/tempo/server/Subscription.js +135 -23
- package/dist/tempo/server/Subscription.js.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 +81 -0
- package/dist/tempo/session/client/ChannelOps.d.ts.map +1 -0
- package/dist/tempo/session/client/ChannelOps.js +201 -0
- package/dist/tempo/session/client/ChannelOps.js.map +1 -0
- package/dist/tempo/session/client/ChannelStore.d.ts +51 -0
- package/dist/tempo/session/client/ChannelStore.d.ts.map +1 -0
- package/dist/tempo/session/client/ChannelStore.js +63 -0
- package/dist/tempo/session/client/ChannelStore.js.map +1 -0
- package/dist/tempo/session/client/CredentialState.d.ts +245 -0
- package/dist/tempo/session/client/CredentialState.d.ts.map +1 -0
- package/dist/tempo/session/client/CredentialState.js +419 -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 +138 -0
- package/dist/tempo/session/client/Session.d.ts.map +1 -0
- package/dist/tempo/session/client/Session.js +69 -0
- package/dist/tempo/session/client/Session.js.map +1 -0
- package/dist/tempo/session/client/SessionManager.d.ts +84 -0
- package/dist/tempo/session/client/SessionManager.d.ts.map +1 -0
- package/dist/tempo/session/client/SessionManager.js +577 -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 +11 -0
- package/dist/tempo/session/client/index.d.ts.map +1 -0
- package/dist/tempo/session/client/index.js +6 -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 +125 -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 +252 -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/dist/tempo/subscription/KeyAuthorization.d.ts +712 -1
- package/dist/tempo/subscription/KeyAuthorization.d.ts.map +1 -1
- package/dist/tempo/subscription/Store.d.ts +2 -0
- package/dist/tempo/subscription/Store.d.ts.map +1 -1
- package/dist/tempo/subscription/Store.js +16 -1
- package/dist/tempo/subscription/Store.js.map +1 -1
- package/dist/x402/index.d.ts +1 -0
- package/dist/x402/index.d.ts.map +1 -1
- package/dist/x402/index.js +1 -0
- package/dist/x402/index.js.map +1 -1
- package/package.json +25 -9
- package/src/Challenge.test.ts +40 -0
- package/src/Challenge.ts +28 -13
- package/src/Constants.ts +58 -0
- package/src/Credential.ts +5 -4
- package/src/Mcp.ts +4 -0
- package/src/Method.ts +46 -5
- package/src/PaymentRequest.ts +10 -10
- package/src/Receipt.ts +3 -2
- package/src/cli/cli.test.ts +38 -43
- 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 +31 -1
- package/src/client/Mppx.test.ts +76 -1
- package/src/client/Mppx.ts +2 -2
- package/src/client/Transport.test.ts +225 -178
- package/src/client/Transport.ts +77 -84
- package/src/client/index.ts +25 -1
- package/src/client/internal/Fetch.test.ts +236 -6
- package/src/client/internal/Fetch.ts +69 -11
- package/src/client/internal/protocols/Mcp.test.ts +220 -0
- package/src/client/internal/protocols/Mcp.ts +162 -0
- package/src/client/internal/protocols/Mpp.ts +21 -0
- package/src/client/internal/protocols/Protocol.ts +10 -0
- package/src/client/internal/protocols/Shared.ts +25 -0
- package/src/client/internal/protocols/X402.ts +42 -0
- package/src/discovery/OpenApi.test.ts +1 -1
- package/src/env.d.ts +1 -1
- package/src/evm/PublicInterface.test-d.ts +1 -1
- package/src/evm/client/index.ts +1 -0
- package/src/evm/index.ts +2 -0
- package/src/evm/server/Charge.test.ts +1 -1
- package/src/evm/server/index.ts +1 -0
- 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 → mcp}/client/McpClient.integration.test.ts +18 -11
- package/src/{mcp-sdk → mcp}/client/McpClient.test-d.ts +45 -11
- package/src/{mcp-sdk → mcp}/client/McpClient.test.ts +211 -5
- package/src/mcp/client/McpClient.ts +307 -0
- package/src/mcp/client/McpClient.unit.test.ts +135 -0
- package/src/middlewares/elysia.test.ts +9 -5
- package/src/middlewares/express.test.ts +9 -5
- package/src/middlewares/hono.test.ts +5 -5
- package/src/middlewares/internal/mppx.test.ts +1 -1
- package/src/middlewares/nextjs.test.ts +9 -5
- package/src/proxy/Proxy.test.ts +9 -9
- package/src/proxy/services/anthropic.test.ts +1 -1
- package/src/proxy/services/openai.test.ts +1 -1
- package/src/proxy/services/stripe.test.ts +1 -1
- package/src/server/Mppx.authorize.test.ts +1 -1
- package/src/server/Mppx.test-d.ts +55 -1
- package/src/server/Mppx.test.ts +220 -9
- package/src/server/Mppx.ts +501 -407
- package/src/server/Response.ts +2 -1
- package/src/server/Transport.test.ts +6 -6
- package/src/server/Transport.ts +5 -4
- package/src/server/index.ts +1 -0
- package/src/stripe/Charge.integration.test.ts +1 -1
- package/src/stripe/client/Charge.test.ts +21 -6
- package/src/stripe/client/Charge.ts +6 -2
- package/src/stripe/server/Charge.test.ts +115 -2
- 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/Proof.conformance.test.ts +146 -0
- package/src/tempo/Proof.test-d.ts +15 -0
- package/src/tempo/Proof.ts +52 -1
- package/src/tempo/PublicExports.test-d.ts +105 -0
- package/src/tempo/Subscription.integration.test.ts +1 -1
- package/src/tempo/client/Charge.test.ts +258 -0
- package/src/tempo/client/Charge.ts +84 -38
- package/src/tempo/client/Methods.ts +22 -8
- package/src/tempo/client/ResolveAccount.ts +46 -0
- package/src/tempo/client/index.ts +15 -4
- package/src/tempo/index.ts +1 -0
- package/src/tempo/internal/fee-payer.test.ts +296 -17
- package/src/tempo/internal/fee-payer.ts +186 -4
- package/src/tempo/internal/fee-token.test.ts +14 -9
- package/src/tempo/internal/proof.test.ts +12 -4
- package/src/tempo/internal/proof.ts +55 -6
- 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 +52 -23
- 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 +136 -71
- package/src/tempo/{server → legacy/server}/Session.ts +32 -23
- 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 +480 -31
- package/src/tempo/server/Charge.ts +54 -30
- package/src/tempo/server/Methods.ts +58 -10
- package/src/tempo/server/Sse.test.ts +2 -2
- package/src/tempo/server/Subscription.test.ts +465 -3
- package/src/tempo/server/Subscription.ts +174 -19
- package/src/tempo/server/index.ts +6 -5
- package/src/tempo/server/internal/html/package.json +2 -2
- 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 +330 -0
- package/src/tempo/session/client/ChannelStore.ts +111 -0
- package/src/tempo/session/client/CredentialState.test.ts +789 -0
- package/src/tempo/session/client/CredentialState.ts +799 -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 +774 -0
- package/src/tempo/session/client/Session.ts +123 -0
- package/src/tempo/session/client/SessionManager.test.ts +1397 -0
- package/src/tempo/session/client/SessionManager.ts +751 -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 +40 -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 +354 -0
- package/src/tempo/session/precompile/Voucher.ts +162 -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 +329 -0
- package/src/tempo/session/server/Settlement.ts +471 -0
- package/src/tempo/session/{Sse.test.ts → server/Sse.test.ts} +37 -3
- package/src/tempo/session/server/Sse.ts +254 -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 +380 -0
- package/src/tempo/session/server/index.ts +8 -0
- package/src/tempo/subscription/Store.ts +27 -9
- package/src/x402/Exact.e2e.test.ts +1 -1
- package/src/x402/PublicInterface.test-d.ts +1 -1
- package/src/x402/index.ts +1 -0
- package/dist/mcp-sdk/client/McpClient.d.ts +0 -78
- package/dist/mcp-sdk/client/McpClient.d.ts.map +0 -1
- package/dist/mcp-sdk/client/McpClient.js +0 -105
- package/dist/mcp-sdk/client/McpClient.js.map +0 -1
- package/dist/mcp-sdk/client/index.d.ts.map +0 -1
- package/dist/mcp-sdk/client/index.js.map +0 -1
- package/dist/mcp-sdk/server/Transport.d.ts.map +0 -1
- package/dist/mcp-sdk/server/Transport.js.map +0 -1
- package/dist/mcp-sdk/server/index.d.ts.map +0 -1
- package/dist/mcp-sdk/server/index.js.map +0 -1
- 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/mcp-sdk/client/McpClient.ts +0 -196
- 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/{mcp-sdk → mcp}/client/index.d.ts +0 -0
- /package/dist/{mcp-sdk → mcp}/client/index.js +0 -0
- /package/dist/{mcp-sdk → mcp}/server/Transport.d.ts +0 -0
- /package/dist/{mcp-sdk → mcp}/server/Transport.js +0 -0
- /package/dist/{mcp-sdk → mcp}/server/index.d.ts +0 -0
- /package/dist/{mcp-sdk → mcp}/server/index.js +0 -0
- /package/dist/tempo/{session → legacy/session}/Channel.js +0 -0
- /package/dist/tempo/{session → legacy/session}/Types.js +0 -0
- /package/src/{mcp-sdk → mcp}/client/index.ts +0 -0
- /package/src/{mcp-sdk → mcp}/server/Transport.test.ts +0 -0
- /package/src/{mcp-sdk → mcp}/server/Transport.ts +0 -0
- /package/src/{mcp-sdk → mcp}/server/index.ts +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,751 @@
|
|
|
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 { createChannelStore, entryKey, type ChannelStore } from '../client/ChannelStore.js'
|
|
12
|
+
import type { SessionContext } from '../client/CredentialState.js'
|
|
13
|
+
import { session as sessionPlugin } from '../client/Session.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
|
+
isTempoSessionChallenge,
|
|
38
|
+
managementInput,
|
|
39
|
+
postTopUp,
|
|
40
|
+
retryHttpPaymentRequired,
|
|
41
|
+
type TempoSessionChallenge,
|
|
42
|
+
webSocketProbeUrl,
|
|
43
|
+
} from './Transports.js'
|
|
44
|
+
import {
|
|
45
|
+
type SessionManagedWebSocket,
|
|
46
|
+
type WebSocketConstructor,
|
|
47
|
+
WebSocketReadyState,
|
|
48
|
+
} from './Transports.js'
|
|
49
|
+
import { openSseSession, type SseDriverOptions } from './Transports.js'
|
|
50
|
+
import { applyTopUpResult, resolveManualTopUp, type TopUpRequirement } from './Transports.js'
|
|
51
|
+
import {
|
|
52
|
+
openWebSocketSession,
|
|
53
|
+
prepareWebSocketSession,
|
|
54
|
+
type WebSocketDriverOptions,
|
|
55
|
+
} from './Transports.js'
|
|
56
|
+
|
|
57
|
+
export { computeFallbackCloseAmount, type FallbackCloseAmountParameters } from './Runtime.js'
|
|
58
|
+
|
|
59
|
+
/** Auto-driving client manager for HTTP, SSE, and WebSocket TIP-1034 sessions. */
|
|
60
|
+
export type SessionManager = {
|
|
61
|
+
/** Active channel ID, when a channel has been opened or recovered. */
|
|
62
|
+
readonly channelId: Hex.Hex | undefined
|
|
63
|
+
/** Local cumulative voucher authorization in raw token units. */
|
|
64
|
+
readonly cumulative: bigint
|
|
65
|
+
/** Whether the manager currently has an open local channel. */
|
|
66
|
+
readonly opened: boolean
|
|
67
|
+
/** Current pure session state-machine state. */
|
|
68
|
+
readonly state: SessionState
|
|
69
|
+
|
|
70
|
+
/** Runs the HTTP 402 probe, signs/open/top-ups as needed, retries, and returns receipt metadata. */
|
|
71
|
+
fetch(input: RequestInfo | URL, init?: RequestInit): Promise<PaymentResponse>
|
|
72
|
+
/** Opens a paid SSE stream and auto-posts vouchers/top-ups when the server requests more headroom. */
|
|
73
|
+
sse(input: RequestInfo | URL, init?: SessionManagerSseOptions): Promise<AsyncIterable<string>>
|
|
74
|
+
/** Opens a paid WebSocket session after an HTTP challenge probe and manages in-band voucher frames. */
|
|
75
|
+
ws(input: string | URL, init?: SessionManagerWebSocketOptions): Promise<SessionManagedWebSocket>
|
|
76
|
+
/** Tops up the active channel deposit. String amounts are parsed with the manager decimals; bigint amounts are raw units. */
|
|
77
|
+
topUp(amount: string | bigint): Promise<SessionReceipt | undefined>
|
|
78
|
+
/** Cooperatively closes the active channel using the latest locally authorized spend boundary. */
|
|
79
|
+
close(): Promise<SessionReceipt | undefined>
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Options for `SessionManager.sse()`. */
|
|
83
|
+
export type SessionManagerSseOptions = SseDriverOptions
|
|
84
|
+
|
|
85
|
+
/** Options for `SessionManager.ws()`. */
|
|
86
|
+
export type SessionManagerWebSocketOptions = WebSocketDriverOptions
|
|
87
|
+
|
|
88
|
+
/** HTTP response enriched with the latest session payment metadata. */
|
|
89
|
+
export type PaymentResponse = Response & {
|
|
90
|
+
/** Parsed payment receipt, when the response included one. */
|
|
91
|
+
receipt: SessionReceipt | null
|
|
92
|
+
/** Last session challenge observed by the manager. */
|
|
93
|
+
challenge: TempoSessionChallenge | null
|
|
94
|
+
/** Active channel ID, when available. */
|
|
95
|
+
channelId: Hex.Hex | null
|
|
96
|
+
/** Local cumulative voucher authorization in raw token units. */
|
|
97
|
+
cumulative: bigint
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** Normalized runtime dependencies derived from `sessionManager()` parameters. */
|
|
101
|
+
type SessionManagerConfig = {
|
|
102
|
+
/** Decimal precision used when parsing human-readable manager amounts. */
|
|
103
|
+
decimals: number
|
|
104
|
+
/** Fetch implementation used for probes, retries, and management posts. */
|
|
105
|
+
fetch: typeof globalThis.fetch
|
|
106
|
+
/** Local maximum cumulative voucher authorization, or null when uncapped. */
|
|
107
|
+
maxVoucherCumulative: bigint | null
|
|
108
|
+
/** WebSocket constructor available in the current runtime, when configured. */
|
|
109
|
+
WebSocket: WebSocketConstructor | undefined
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function isTempoChargeChallenge(challenge: Challenge.Challenge) {
|
|
113
|
+
return (
|
|
114
|
+
challenge.method === Constants.Methods.tempo && challenge.intent === Constants.Intents.charge
|
|
115
|
+
)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function isZeroAmountChargeChallenge(challenge: Challenge.Challenge) {
|
|
119
|
+
if (!isTempoChargeChallenge(challenge)) return false
|
|
120
|
+
if (typeof challenge.request.amount !== 'string') return false
|
|
121
|
+
try {
|
|
122
|
+
return BigInt(challenge.request.amount) === 0n
|
|
123
|
+
} catch {
|
|
124
|
+
return false
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/** Builds a reusable channel entry from a server session snapshot header. */
|
|
129
|
+
function entryFromSnapshot(snapshot: ReturnType<typeof deserializeSessionSnapshot>): ChannelEntry {
|
|
130
|
+
return {
|
|
131
|
+
channelId: snapshot.channelId,
|
|
132
|
+
cumulativeAmount: BigInt(snapshot.acceptedCumulative),
|
|
133
|
+
deposit: BigInt(snapshot.deposit),
|
|
134
|
+
descriptor: snapshot.descriptor,
|
|
135
|
+
escrow: snapshot.escrow,
|
|
136
|
+
chainId: snapshot.chainId,
|
|
137
|
+
opened: true,
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function requestInitWithSessionHint(
|
|
142
|
+
input: RequestInfo | URL,
|
|
143
|
+
init: RequestInit | undefined,
|
|
144
|
+
channelId: Hex.Hex | undefined,
|
|
145
|
+
): RequestInit | undefined {
|
|
146
|
+
if (!channelId) return init
|
|
147
|
+
const requestHeaders = input instanceof Request ? input.headers : undefined
|
|
148
|
+
const headers = {
|
|
149
|
+
...Fetch.normalizeHeaders(requestHeaders),
|
|
150
|
+
...Fetch.normalizeHeaders(init?.headers),
|
|
151
|
+
}
|
|
152
|
+
if (
|
|
153
|
+
Object.keys(headers).some(
|
|
154
|
+
(key) => key.toLowerCase() === Constants.Headers.paymentSession.toLowerCase(),
|
|
155
|
+
)
|
|
156
|
+
)
|
|
157
|
+
return init
|
|
158
|
+
return {
|
|
159
|
+
...init,
|
|
160
|
+
headers: {
|
|
161
|
+
...headers,
|
|
162
|
+
[Constants.Headers.paymentSession]: channelId,
|
|
163
|
+
},
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function resolveSessionManagerConfig(parameters: sessionManager.Parameters): SessionManagerConfig {
|
|
168
|
+
const decimals = parameters.decimals ?? 6
|
|
169
|
+
const WebSocket =
|
|
170
|
+
parameters.webSocket ??
|
|
171
|
+
(globalThis as typeof globalThis & { WebSocket?: WebSocketConstructor }).WebSocket
|
|
172
|
+
|
|
173
|
+
return {
|
|
174
|
+
decimals,
|
|
175
|
+
fetch: parameters.fetch ?? globalThis.fetch.bind(globalThis),
|
|
176
|
+
maxVoucherCumulative:
|
|
177
|
+
parameters.maxDeposit !== undefined ? parseUnits(parameters.maxDeposit, decimals) : null,
|
|
178
|
+
WebSocket,
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Creates a session manager that handles the full client payment lifecycle:
|
|
184
|
+
* channel open, incremental vouchers, SSE streaming, and channel close.
|
|
185
|
+
*
|
|
186
|
+
* Internally delegates to the `session()` method for all
|
|
187
|
+
* channel state management and credential creation, and to `Fetch.from`
|
|
188
|
+
* for the 402 challenge/retry flow.
|
|
189
|
+
*
|
|
190
|
+
* `channelStore` can persist reusable channels between manager instances.
|
|
191
|
+
*/
|
|
192
|
+
export function sessionManager(parameters: sessionManager.Parameters): SessionManager {
|
|
193
|
+
const config = resolveSessionManagerConfig(parameters)
|
|
194
|
+
const runtime = createSessionManagerRuntime()
|
|
195
|
+
const receipts = createSessionReceiptCoordinator({
|
|
196
|
+
getSocketSession: () => runtime.socketSession,
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
const backing = parameters.channelStore ?? createChannelStore()
|
|
200
|
+
const ignoredChannelIds = new Set<Hex.Hex>()
|
|
201
|
+
|
|
202
|
+
// Tracks one fetch's channel reuse so stale stored entries can be evicted once.
|
|
203
|
+
type ChannelUse = {
|
|
204
|
+
seenExisting: Set<string>
|
|
205
|
+
createdKeys: Set<string>
|
|
206
|
+
resumed: ChannelEntry | undefined
|
|
207
|
+
}
|
|
208
|
+
let channelUse: ChannelUse | undefined
|
|
209
|
+
|
|
210
|
+
/** Returns the backing entry for `key` only when it is open and not ignored. */
|
|
211
|
+
async function getReusable(key: string): Promise<ChannelEntry | undefined> {
|
|
212
|
+
const entry = await backing.get(key)
|
|
213
|
+
if (entry?.opened && !ignoredChannelIds.has(entry.channelId)) return entry
|
|
214
|
+
return undefined
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const store: ChannelStore = {
|
|
218
|
+
async get(key) {
|
|
219
|
+
const entry = await getReusable(key)
|
|
220
|
+
if (entry && channelUse) {
|
|
221
|
+
channelUse.seenExisting.add(key)
|
|
222
|
+
if (!channelUse.createdKeys.has(key)) channelUse.resumed ??= entry
|
|
223
|
+
}
|
|
224
|
+
return entry
|
|
225
|
+
},
|
|
226
|
+
async set(entry) {
|
|
227
|
+
const key = entryKey(entry)
|
|
228
|
+
if (entry.opened) ignoredChannelIds.delete(entry.channelId)
|
|
229
|
+
if (channelUse && !channelUse.seenExisting.has(key)) channelUse.createdKeys.add(key)
|
|
230
|
+
await backing.set(entry)
|
|
231
|
+
},
|
|
232
|
+
delete: (key) => backing.delete(key),
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/** Removes a failed channel from candidacy for the rest of this manager's life. */
|
|
236
|
+
async function ignoreChannel(entry: ChannelEntry) {
|
|
237
|
+
ignoredChannelIds.add(entry.channelId)
|
|
238
|
+
await Promise.resolve(backing.delete(entryKey(entry))).catch(() => undefined)
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function dispatch(event: Parameters<typeof dispatchSessionEvent>[1]) {
|
|
242
|
+
return dispatchSessionEvent(runtime, event)
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const method = sessionPlugin({
|
|
246
|
+
account: parameters.account,
|
|
247
|
+
getClient: parameters.client ? () => parameters.client! : parameters.getClient,
|
|
248
|
+
escrow: parameters.escrow,
|
|
249
|
+
decimals: config.decimals,
|
|
250
|
+
maxDeposit: parameters.maxDeposit,
|
|
251
|
+
channelStore: store,
|
|
252
|
+
onChannelUpdate(entry) {
|
|
253
|
+
if (entry.channelId !== runtime.channel?.channelId) runtime.spent = 0n
|
|
254
|
+
runtime.channel = entry
|
|
255
|
+
if (runtime.lastChallenge) {
|
|
256
|
+
dispatch({
|
|
257
|
+
type: 'activated',
|
|
258
|
+
challengeId: runtime.lastChallenge.id,
|
|
259
|
+
entry,
|
|
260
|
+
spent: runtime.spent.toString(),
|
|
261
|
+
units: 0,
|
|
262
|
+
})
|
|
263
|
+
}
|
|
264
|
+
},
|
|
265
|
+
})
|
|
266
|
+
const chargeMethod = chargePlugin({
|
|
267
|
+
account: parameters.account,
|
|
268
|
+
getClient: parameters.client ? () => parameters.client! : parameters.getClient,
|
|
269
|
+
})
|
|
270
|
+
|
|
271
|
+
const wrappedFetch = Fetch.from({
|
|
272
|
+
fetch: config.fetch,
|
|
273
|
+
methods: [method],
|
|
274
|
+
onChallenge: async (challenge, _helpers) => {
|
|
275
|
+
if (!isTempoSessionChallenge(challenge)) return undefined
|
|
276
|
+
runtime.lastChallenge = challenge
|
|
277
|
+
dispatch({ type: 'challengeReceived', challengeId: challenge.id })
|
|
278
|
+
if (runtime.channel?.opened && runtime.lastUrl) {
|
|
279
|
+
const requiredCumulative =
|
|
280
|
+
runtime.channel.cumulativeAmount + readSessionChallengeAmount(challenge)
|
|
281
|
+
await topUpIfNeeded({
|
|
282
|
+
challenge,
|
|
283
|
+
input: runtime.lastUrl,
|
|
284
|
+
channelId: runtime.channel.channelId,
|
|
285
|
+
deposit: runtime.channel.deposit,
|
|
286
|
+
requiredCumulative,
|
|
287
|
+
})
|
|
288
|
+
}
|
|
289
|
+
return undefined
|
|
290
|
+
},
|
|
291
|
+
})
|
|
292
|
+
|
|
293
|
+
function createSessionCredential(challenge: TempoSessionChallenge, context: SessionContext) {
|
|
294
|
+
return method.createCredential({ challenge, context })
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
function updateSpentFromReceipt(receipt: SessionReceipt | null | undefined) {
|
|
298
|
+
applySessionReceiptToRuntime({
|
|
299
|
+
maxVoucherCumulative: config.maxVoucherCumulative,
|
|
300
|
+
receipt,
|
|
301
|
+
runtime,
|
|
302
|
+
})
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function activateCurrentChannel(
|
|
306
|
+
units = runtime.state.status === 'active' ? runtime.state.units : 0,
|
|
307
|
+
) {
|
|
308
|
+
if (!runtime.channel || !runtime.lastChallenge) return
|
|
309
|
+
if (
|
|
310
|
+
runtime.state.status === 'active' ||
|
|
311
|
+
runtime.state.status === 'withdrawable' ||
|
|
312
|
+
runtime.state.status === 'closeRequested'
|
|
313
|
+
)
|
|
314
|
+
return
|
|
315
|
+
dispatch({
|
|
316
|
+
type: 'activated',
|
|
317
|
+
challengeId: runtime.lastChallenge.id,
|
|
318
|
+
entry: runtime.channel,
|
|
319
|
+
spent: runtime.spent.toString(),
|
|
320
|
+
units,
|
|
321
|
+
})
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/** Persists a server snapshot into the channel store and returns the entry. */
|
|
325
|
+
async function storeSnapshotHeader(response: Response): Promise<ChannelEntry | undefined> {
|
|
326
|
+
const header = response.headers.get(Constants.Headers.paymentSessionSnapshot)
|
|
327
|
+
if (!header) return undefined
|
|
328
|
+
const entry = entryFromSnapshot(deserializeSessionSnapshot(header))
|
|
329
|
+
await Promise.resolve(store.set(entry)).catch(() => undefined)
|
|
330
|
+
return entry
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
async function bootstrapSession(
|
|
334
|
+
input: RequestInfo | URL,
|
|
335
|
+
init?: RequestInit | undefined,
|
|
336
|
+
): Promise<ChannelEntry | undefined> {
|
|
337
|
+
if (!parameters.bootstrap) return undefined
|
|
338
|
+
if (runtime.channel?.opened) return undefined
|
|
339
|
+
|
|
340
|
+
const requestHeaders = input instanceof Request ? input.headers : undefined
|
|
341
|
+
const { body: _body, method: _method, ...bootstrapInit } = init ?? {}
|
|
342
|
+
const bootstrapInput = input instanceof Request ? input.url : input
|
|
343
|
+
const headInit: RequestInit = {
|
|
344
|
+
...bootstrapInit,
|
|
345
|
+
method: 'HEAD',
|
|
346
|
+
headers: {
|
|
347
|
+
...Fetch.normalizeHeaders(requestHeaders),
|
|
348
|
+
...Fetch.normalizeHeaders(init?.headers),
|
|
349
|
+
[Constants.Headers.acceptPayment]: `${Constants.Methods.tempo}/${Constants.Intents.charge}`,
|
|
350
|
+
},
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
try {
|
|
354
|
+
const challengeResponse = await config.fetch(bootstrapInput, headInit)
|
|
355
|
+
if (challengeResponse.status !== 402) return await storeSnapshotHeader(challengeResponse)
|
|
356
|
+
const challenge = Challenge.fromResponseList(challengeResponse).find(isTempoChargeChallenge)
|
|
357
|
+
if (!challenge) return undefined
|
|
358
|
+
if (!isZeroAmountChargeChallenge(challenge)) return undefined
|
|
359
|
+
const credential = await chargeMethod.createCredential({
|
|
360
|
+
challenge: challenge as never,
|
|
361
|
+
context: {},
|
|
362
|
+
})
|
|
363
|
+
const response = await config.fetch(bootstrapInput, {
|
|
364
|
+
...headInit,
|
|
365
|
+
headers: {
|
|
366
|
+
...Fetch.normalizeHeaders(headInit.headers),
|
|
367
|
+
[Constants.Headers.authorization]: credential,
|
|
368
|
+
},
|
|
369
|
+
})
|
|
370
|
+
if (response.ok) return await storeSnapshotHeader(response)
|
|
371
|
+
return undefined
|
|
372
|
+
} catch {
|
|
373
|
+
return undefined
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
function getFallbackCloseAmount(challenge: TempoSessionChallenge, channelId: Hex.Hex): bigint {
|
|
378
|
+
const currentSocket = runtime.socketSession
|
|
379
|
+
return computeFallbackCloseAmount({
|
|
380
|
+
challengeId: challenge.id,
|
|
381
|
+
channelId,
|
|
382
|
+
closeReadyReceipt: currentSocket?.closeReadyReceipt,
|
|
383
|
+
cumulativeAmount:
|
|
384
|
+
runtime.channel?.channelId === channelId ? runtime.channel.cumulativeAmount : 0n,
|
|
385
|
+
deliveredChunks: currentSocket?.deliveredChunks,
|
|
386
|
+
socketChallengeId: currentSocket?.challenge.id,
|
|
387
|
+
socketChannelId: currentSocket?.channelId,
|
|
388
|
+
spent: runtime.spent,
|
|
389
|
+
tickCost: currentSocket?.tickCost,
|
|
390
|
+
})
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
function getValidatedFallbackCloseAmount(target: CloseTarget) {
|
|
394
|
+
const closeAmount = getFallbackCloseAmount(target.challenge, target.channelId)
|
|
395
|
+
if (closeAmount > target.channel.cumulativeAmount) {
|
|
396
|
+
throw new Error('fallback close amount exceeds local voucher state')
|
|
397
|
+
}
|
|
398
|
+
assertVoucherWithinLocalLimit(closeAmount)
|
|
399
|
+
return closeAmount.toString()
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
function assertVoucherWithinLocalLimit(cumulativeAmount: bigint) {
|
|
403
|
+
assertVoucherWithinLocalAuthorization({
|
|
404
|
+
cumulativeAmount,
|
|
405
|
+
maxVoucherCumulative: config.maxVoucherCumulative,
|
|
406
|
+
})
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
async function postTopUpAndApply(parameters: {
|
|
410
|
+
additionalDeposit: bigint
|
|
411
|
+
challenge: TempoSessionChallenge
|
|
412
|
+
channelId: Hex.Hex
|
|
413
|
+
input: RequestInfo | URL
|
|
414
|
+
}) {
|
|
415
|
+
const receipt = await postTopUp({
|
|
416
|
+
...parameters,
|
|
417
|
+
channel: runtime.channel,
|
|
418
|
+
createSessionCredential,
|
|
419
|
+
fetch: config.fetch,
|
|
420
|
+
})
|
|
421
|
+
updateSpentFromReceipt(receipt)
|
|
422
|
+
const applied = applyTopUpResult({
|
|
423
|
+
additionalDeposit: parameters.additionalDeposit,
|
|
424
|
+
channel: runtime.channel,
|
|
425
|
+
channelId: parameters.channelId,
|
|
426
|
+
challengeId: runtime.lastChallenge?.id,
|
|
427
|
+
currentState: runtime.state,
|
|
428
|
+
receipt,
|
|
429
|
+
spent: runtime.spent,
|
|
430
|
+
})
|
|
431
|
+
if (applied?.channel && runtime.lastChallenge) {
|
|
432
|
+
dispatch({
|
|
433
|
+
type: 'activated',
|
|
434
|
+
challengeId: runtime.lastChallenge.id,
|
|
435
|
+
entry: applied.channel,
|
|
436
|
+
spent: runtime.spent.toString(),
|
|
437
|
+
units: runtime.state.status === 'active' ? runtime.state.units : 0,
|
|
438
|
+
})
|
|
439
|
+
}
|
|
440
|
+
return receipt
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
async function topUpIfNeeded(parameters: TopUpRequirement) {
|
|
444
|
+
if (parameters.requiredCumulative <= parameters.deposit) return
|
|
445
|
+
assertVoucherWithinLocalLimit(parameters.requiredCumulative)
|
|
446
|
+
await postTopUpAndApply({
|
|
447
|
+
challenge: parameters.challenge,
|
|
448
|
+
input: parameters.input,
|
|
449
|
+
channelId: parameters.channelId,
|
|
450
|
+
additionalDeposit: parameters.requiredCumulative - parameters.deposit,
|
|
451
|
+
})
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
function restoreCumulative(channelId: Hex.Hex, cumulativeAmount: bigint) {
|
|
455
|
+
const restored = restoreCumulativeAuthorization({
|
|
456
|
+
channel: runtime.channel,
|
|
457
|
+
channelId,
|
|
458
|
+
challengeId: runtime.lastChallenge?.id,
|
|
459
|
+
cumulativeAmount,
|
|
460
|
+
spent: runtime.spent,
|
|
461
|
+
state: runtime.state,
|
|
462
|
+
})
|
|
463
|
+
if (restored && runtime.channel) {
|
|
464
|
+
dispatch({
|
|
465
|
+
type: 'activated',
|
|
466
|
+
challengeId: restored.challengeId,
|
|
467
|
+
entry: runtime.channel,
|
|
468
|
+
spent: restored.spent,
|
|
469
|
+
units: restored.units,
|
|
470
|
+
})
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
function restoreRuntime(snapshot: RuntimeSnapshot) {
|
|
475
|
+
const restored = restoreRuntimeStateSnapshot(snapshot, runtime.channel)
|
|
476
|
+
runtime.channel = restored.channel
|
|
477
|
+
runtime.spent = restored.spent
|
|
478
|
+
runtime.state = restored.state
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
function toPaymentResponse(response: Response): PaymentResponse {
|
|
482
|
+
const receiptHeader = response.headers.get(Constants.Headers.paymentReceipt)
|
|
483
|
+
const receipt = receiptHeader ? deserializeSessionReceipt(receiptHeader) : null
|
|
484
|
+
updateSpentFromReceipt(receipt)
|
|
485
|
+
return Object.assign(response, {
|
|
486
|
+
receipt,
|
|
487
|
+
challenge: runtime.lastChallenge,
|
|
488
|
+
channelId: runtime.channel?.channelId ?? null,
|
|
489
|
+
cumulative: runtime.channel?.cumulativeAmount ?? 0n,
|
|
490
|
+
})
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
async function doFetch(input: RequestInfo | URL, init?: RequestInit): Promise<PaymentResponse> {
|
|
494
|
+
// The manager drives one shared `runtime` state machine, so requests are
|
|
495
|
+
// single-flight. Reject overlap loudly instead of letting concurrent calls
|
|
496
|
+
// corrupt each other's runtime and channel tracking.
|
|
497
|
+
if (channelUse)
|
|
498
|
+
throw new Error(
|
|
499
|
+
'SessionManager: a request is already in flight; concurrent requests on one manager are not supported',
|
|
500
|
+
)
|
|
501
|
+
const use: ChannelUse = { seenExisting: new Set(), createdKeys: new Set(), resumed: undefined }
|
|
502
|
+
channelUse = use
|
|
503
|
+
|
|
504
|
+
runtime.lastUrl = input
|
|
505
|
+
|
|
506
|
+
const previous = captureRuntimeStateSnapshot({
|
|
507
|
+
channel: runtime.channel,
|
|
508
|
+
spent: runtime.spent,
|
|
509
|
+
state: runtime.state,
|
|
510
|
+
})
|
|
511
|
+
|
|
512
|
+
// Cold starts resume from `channelStore` after the 402 reveals the scope.
|
|
513
|
+
const liveHint = runtime.channel?.opened ? runtime.channel.channelId : undefined
|
|
514
|
+
|
|
515
|
+
try {
|
|
516
|
+
await bootstrapSession(input, init)
|
|
517
|
+
|
|
518
|
+
let effectiveInit = requestInitWithSessionHint(input, init, liveHint)
|
|
519
|
+
// Stored channels may be stale, so retry once after evicting the resumed entry.
|
|
520
|
+
let canRetryResumed = !previous.channel?.opened
|
|
521
|
+
|
|
522
|
+
async function retryWithoutResumed(): Promise<boolean> {
|
|
523
|
+
const resumed = use.resumed
|
|
524
|
+
if (!canRetryResumed || !resumed) return false
|
|
525
|
+
canRetryResumed = false
|
|
526
|
+
await ignoreChannel(resumed)
|
|
527
|
+
effectiveInit = requestInitWithSessionHint(input, init, undefined)
|
|
528
|
+
return true
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
for (;;) {
|
|
532
|
+
let response: Response
|
|
533
|
+
try {
|
|
534
|
+
response = await wrappedFetch(input, effectiveInit)
|
|
535
|
+
} catch (error) {
|
|
536
|
+
restoreRuntime(previous)
|
|
537
|
+
if (await retryWithoutResumed()) continue
|
|
538
|
+
throw error
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
let paymentResponse = toPaymentResponse(response)
|
|
542
|
+
let attemptedHttpManagement = false
|
|
543
|
+
if (paymentResponse.status === 402) {
|
|
544
|
+
const retry = await retryHttpPaymentRequired({
|
|
545
|
+
input,
|
|
546
|
+
init: effectiveInit,
|
|
547
|
+
response: paymentResponse,
|
|
548
|
+
createSessionCredential,
|
|
549
|
+
fetch: config.fetch,
|
|
550
|
+
getChannel: () => runtime.channel,
|
|
551
|
+
restoreCumulative,
|
|
552
|
+
setChallenge(challenge) {
|
|
553
|
+
runtime.lastChallenge = challenge
|
|
554
|
+
},
|
|
555
|
+
topUpIfNeeded,
|
|
556
|
+
})
|
|
557
|
+
if (retry) {
|
|
558
|
+
attemptedHttpManagement = true
|
|
559
|
+
paymentResponse = toPaymentResponse(retry)
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
if (!attemptedHttpManagement && !paymentResponse.ok && !paymentResponse.receipt) {
|
|
563
|
+
restoreRuntime(previous)
|
|
564
|
+
if (await retryWithoutResumed()) continue
|
|
565
|
+
return paymentResponse
|
|
566
|
+
}
|
|
567
|
+
return paymentResponse
|
|
568
|
+
}
|
|
569
|
+
} finally {
|
|
570
|
+
channelUse = undefined
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
async function closeHttpSessionAndApply(
|
|
575
|
+
target: CloseTarget,
|
|
576
|
+
): Promise<SessionReceipt | undefined> {
|
|
577
|
+
const receipt = await closeHttpSession({
|
|
578
|
+
createSessionCredential,
|
|
579
|
+
fetch: config.fetch,
|
|
580
|
+
lastUrl: runtime.lastUrl,
|
|
581
|
+
signedCloseAmount: getValidatedFallbackCloseAmount(target),
|
|
582
|
+
setChallenge(challenge) {
|
|
583
|
+
runtime.lastChallenge = challenge
|
|
584
|
+
},
|
|
585
|
+
target,
|
|
586
|
+
})
|
|
587
|
+
if (receipt) {
|
|
588
|
+
activateCurrentChannel()
|
|
589
|
+
dispatch({ type: 'closeStarted' })
|
|
590
|
+
dispatch({ type: 'closed', receipt })
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
return receipt
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
const self: SessionManager = {
|
|
597
|
+
get channelId() {
|
|
598
|
+
return runtime.channel?.channelId
|
|
599
|
+
},
|
|
600
|
+
get cumulative() {
|
|
601
|
+
return runtime.channel?.cumulativeAmount ?? 0n
|
|
602
|
+
},
|
|
603
|
+
get opened() {
|
|
604
|
+
return runtime.channel?.opened ?? false
|
|
605
|
+
},
|
|
606
|
+
get state() {
|
|
607
|
+
return runtime.state
|
|
608
|
+
},
|
|
609
|
+
|
|
610
|
+
fetch: doFetch,
|
|
611
|
+
|
|
612
|
+
async topUp(amount) {
|
|
613
|
+
const target = resolveManualTopUp({
|
|
614
|
+
amount,
|
|
615
|
+
assertVoucherWithinLocalLimit,
|
|
616
|
+
channel: runtime.channel,
|
|
617
|
+
decimals: config.decimals,
|
|
618
|
+
lastChallenge: runtime.lastChallenge,
|
|
619
|
+
lastUrl: runtime.lastUrl,
|
|
620
|
+
})
|
|
621
|
+
|
|
622
|
+
return postTopUpAndApply({
|
|
623
|
+
additionalDeposit: target.additionalDeposit,
|
|
624
|
+
challenge: target.challenge,
|
|
625
|
+
channelId: target.channelId,
|
|
626
|
+
input: target.input,
|
|
627
|
+
})
|
|
628
|
+
},
|
|
629
|
+
|
|
630
|
+
async sse(input, init) {
|
|
631
|
+
return openSseSession(input, init, {
|
|
632
|
+
createSessionCredential,
|
|
633
|
+
doFetch,
|
|
634
|
+
fetch: config.fetch,
|
|
635
|
+
getChannel: () => runtime.channel,
|
|
636
|
+
getChallenge: () => runtime.lastChallenge,
|
|
637
|
+
assertVoucherWithinLocalLimit,
|
|
638
|
+
managementInput,
|
|
639
|
+
acceptReceipt(receipt) {
|
|
640
|
+
updateSpentFromReceipt(receipt)
|
|
641
|
+
},
|
|
642
|
+
topUpIfNeeded,
|
|
643
|
+
})
|
|
644
|
+
},
|
|
645
|
+
|
|
646
|
+
async ws(input, init) {
|
|
647
|
+
if (!config.WebSocket) {
|
|
648
|
+
throw new Error(
|
|
649
|
+
'No WebSocket implementation available. Pass `webSocket` to sessionManager() in this runtime.',
|
|
650
|
+
)
|
|
651
|
+
}
|
|
652
|
+
const probeUrl = webSocketProbeUrl(input)
|
|
653
|
+
const signalInit = init?.signal ? { signal: init.signal } : undefined
|
|
654
|
+
await bootstrapSession(probeUrl, signalInit)
|
|
655
|
+
// Cold starts resume from `channelStore` after the probe's 402.
|
|
656
|
+
const liveHint = runtime.channel?.opened ? runtime.channel.channelId : undefined
|
|
657
|
+
|
|
658
|
+
const prepared = await prepareWebSocketSession({
|
|
659
|
+
createSessionCredential,
|
|
660
|
+
fetch: config.fetch,
|
|
661
|
+
input,
|
|
662
|
+
onProbeUrl(httpUrl) {
|
|
663
|
+
runtime.lastUrl = httpUrl.toString()
|
|
664
|
+
},
|
|
665
|
+
probeInit: requestInitWithSessionHint(probeUrl, signalInit, liveHint),
|
|
666
|
+
signal: init?.signal,
|
|
667
|
+
})
|
|
668
|
+
const { challenge, credential, httpUrl, wsUrl } = prepared
|
|
669
|
+
runtime.lastChallenge = challenge
|
|
670
|
+
|
|
671
|
+
return openWebSocketSession({
|
|
672
|
+
challenge,
|
|
673
|
+
credential,
|
|
674
|
+
httpUrl,
|
|
675
|
+
WebSocket: config.WebSocket,
|
|
676
|
+
wsUrl,
|
|
677
|
+
options: init,
|
|
678
|
+
createSessionCredential,
|
|
679
|
+
getChannel: () => runtime.channel,
|
|
680
|
+
setSocketSession(session) {
|
|
681
|
+
runtime.socketSession = session
|
|
682
|
+
},
|
|
683
|
+
assertVoucherWithinLocalLimit,
|
|
684
|
+
acceptReceipt: updateSpentFromReceipt,
|
|
685
|
+
rejectCloseReady: receipts.rejectCloseReady,
|
|
686
|
+
rejectReceipt: receipts.rejectReceipt,
|
|
687
|
+
settleCloseReady: receipts.settleCloseReady,
|
|
688
|
+
settleReceipt: receipts.settleReceipt,
|
|
689
|
+
topUpIfNeeded,
|
|
690
|
+
waitForReceipt: receipts.waitForReceipt,
|
|
691
|
+
})
|
|
692
|
+
},
|
|
693
|
+
|
|
694
|
+
async close() {
|
|
695
|
+
const currentSocket = runtime.socketSession
|
|
696
|
+
const target = resolveCloseTarget({
|
|
697
|
+
channel: runtime.channel,
|
|
698
|
+
currentSocket,
|
|
699
|
+
lastChallenge: runtime.lastChallenge,
|
|
700
|
+
})
|
|
701
|
+
if (!target) return undefined
|
|
702
|
+
|
|
703
|
+
const activeSocket = currentSocket?.socket
|
|
704
|
+
if (currentSocket && activeSocket?.readyState === WebSocketReadyState.OPEN) {
|
|
705
|
+
const receipt = await closeSocketSession({
|
|
706
|
+
activeSocket,
|
|
707
|
+
createSessionCredential,
|
|
708
|
+
currentSocket,
|
|
709
|
+
spent: runtime.spent,
|
|
710
|
+
target,
|
|
711
|
+
waitForCloseReady: receipts.waitForCloseReady,
|
|
712
|
+
waitForReceipt: receipts.waitForReceipt,
|
|
713
|
+
})
|
|
714
|
+
activateCurrentChannel()
|
|
715
|
+
dispatch({ type: 'closeStarted' })
|
|
716
|
+
dispatch({ type: 'closed', receipt })
|
|
717
|
+
return receipt
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
return closeHttpSessionAndApply(target)
|
|
721
|
+
},
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
return self
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
/** Type helpers for `sessionManager()`. */
|
|
728
|
+
export namespace sessionManager {
|
|
729
|
+
export const serializeSnapshot = serializeSessionSnapshot
|
|
730
|
+
export const deserializeSnapshot = deserializeSessionSnapshot
|
|
731
|
+
|
|
732
|
+
export type Parameters = Account.getResolver.Parameters &
|
|
733
|
+
Client.getResolver.Parameters & {
|
|
734
|
+
/** Enables same-route HEAD bootstrap from a server session snapshot before opening a new channel. */
|
|
735
|
+
bootstrap?: boolean | undefined
|
|
736
|
+
/** Viem client instance. Shorthand for `getClient: () => client`. */
|
|
737
|
+
client?: import('viem').Client | undefined
|
|
738
|
+
/** Token decimals used to convert `maxDeposit` to raw units. Defaults to `6`. */
|
|
739
|
+
decimals?: number | undefined
|
|
740
|
+
/** TIP20EscrowChannel precompile address override. */
|
|
741
|
+
escrow?: Address | undefined
|
|
742
|
+
/** Fetch implementation used for HTTP probes, management posts, and paid retries. */
|
|
743
|
+
fetch?: typeof globalThis.fetch | undefined
|
|
744
|
+
/** Maximum deposit in human-readable units (e.g. `'10'` for 10 tokens). Converted to raw units via `decimals`. */
|
|
745
|
+
maxDeposit?: string | undefined
|
|
746
|
+
/** Store for reusable session channels. Defaults to in-memory. */
|
|
747
|
+
channelStore?: ChannelStore | undefined
|
|
748
|
+
/** Optional websocket constructor for runtimes without a global WebSocket. */
|
|
749
|
+
webSocket?: WebSocketConstructor | undefined
|
|
750
|
+
}
|
|
751
|
+
}
|