mppx 0.6.31 → 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 +17 -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/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 +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 +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 +6 -1
- 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 +200 -7
- package/src/server/Mppx.ts +487 -406
- 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.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 +45 -45
- 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 +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.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,470 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isAddress,
|
|
3
|
+
isAddressEqual,
|
|
4
|
+
parseUnits,
|
|
5
|
+
zeroAddress,
|
|
6
|
+
type Account as viem_Account,
|
|
7
|
+
type Address,
|
|
8
|
+
type Hex,
|
|
9
|
+
} from 'viem'
|
|
10
|
+
|
|
11
|
+
import type * as Credential from '../../../Credential.js'
|
|
12
|
+
import {
|
|
13
|
+
BadRequestError,
|
|
14
|
+
ChannelClosedError,
|
|
15
|
+
ChannelNotFoundError,
|
|
16
|
+
InsufficientBalanceError,
|
|
17
|
+
VerificationFailedError,
|
|
18
|
+
} from '../../../Errors.js'
|
|
19
|
+
import type * as Method from '../../../Method.js'
|
|
20
|
+
import * as Store from '../../../Store.js'
|
|
21
|
+
import type * as FeePayer from '../../internal/fee-payer.js'
|
|
22
|
+
import { isSessionContentRequest } from '../../server/internal/request-body.js'
|
|
23
|
+
import * as Chain from '../precompile/Chain.js'
|
|
24
|
+
import { readSettledReceiptFields } from '../precompile/Chain.js'
|
|
25
|
+
import {
|
|
26
|
+
uint96,
|
|
27
|
+
type SessionCredentialPayload,
|
|
28
|
+
type SessionReceipt,
|
|
29
|
+
} from '../precompile/Protocol.js'
|
|
30
|
+
import * as ChannelStore from './ChannelStore.js'
|
|
31
|
+
|
|
32
|
+
/** Fee-payer parameter accepted by the server session method. */
|
|
33
|
+
export type ParameterFeePayer = viem_Account | string | true | undefined
|
|
34
|
+
|
|
35
|
+
/** Minimum method details needed to decide credential-time fee sponsorship. */
|
|
36
|
+
export type CredentialFeePayerMethodDetails = {
|
|
37
|
+
/** Whether the challenge advertised fee-payer support. */
|
|
38
|
+
feePayer?: boolean | undefined
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Inputs used to resolve request-time fee sponsorship policy. */
|
|
42
|
+
export type ResolveRequestFeePayerParameters = {
|
|
43
|
+
/** Incoming credential, present for verification/management requests. */
|
|
44
|
+
credential: Credential.Credential | null | undefined
|
|
45
|
+
/** Default fee-payer account resolved from server parameters. */
|
|
46
|
+
defaultFeePayer?: viem_Account | undefined
|
|
47
|
+
/** Server-level fee-payer parameter. */
|
|
48
|
+
parameterFeePayer?: ParameterFeePayer
|
|
49
|
+
/** Per-request fee-payer override. */
|
|
50
|
+
requestFeePayer?: boolean | viem_Account | undefined
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Inputs used to resolve credential-time fee sponsorship account. */
|
|
54
|
+
export type ResolveCredentialFeePayerParameters = {
|
|
55
|
+
/** Request object being verified. */
|
|
56
|
+
request: unknown
|
|
57
|
+
/** Challenge method details echoed by the credential. */
|
|
58
|
+
methodDetails: CredentialFeePayerMethodDetails
|
|
59
|
+
/** Default fee-payer account resolved from server parameters. */
|
|
60
|
+
feePayer?: viem_Account | undefined
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Fee-payer value read from an untrusted credential challenge request. */
|
|
64
|
+
export type RequestFeePayerValue = boolean | viem_Account | undefined
|
|
65
|
+
|
|
66
|
+
function isObject(value: unknown): value is Record<string, unknown> {
|
|
67
|
+
return typeof value === 'object' && value !== null
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function isAccount(value: unknown): value is viem_Account {
|
|
71
|
+
return isObject(value) && typeof value.address === 'string' && isAddress(value.address)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Reads the optional `feePayer` field from an untrusted request object. */
|
|
75
|
+
export function readRequestFeePayer(value: unknown): RequestFeePayerValue {
|
|
76
|
+
if (!isObject(value)) return undefined
|
|
77
|
+
const feePayer = value.feePayer
|
|
78
|
+
if (feePayer === undefined || typeof feePayer === 'boolean') return feePayer
|
|
79
|
+
if (isAccount(feePayer)) return feePayer
|
|
80
|
+
return undefined
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** Resolves whether a challenge should advertise fee sponsorship or a credential can use it. */
|
|
84
|
+
export function resolveRequestFeePayer(
|
|
85
|
+
parameters: ResolveRequestFeePayerParameters,
|
|
86
|
+
): boolean | viem_Account | undefined {
|
|
87
|
+
const { credential, defaultFeePayer, parameterFeePayer, requestFeePayer } = parameters
|
|
88
|
+
if (requestFeePayer === false) return credential ? false : undefined
|
|
89
|
+
|
|
90
|
+
const account = typeof requestFeePayer === 'object' ? requestFeePayer : defaultFeePayer
|
|
91
|
+
if (credential) return account ?? undefined
|
|
92
|
+
if (account || defaultFeePayer || parameterFeePayer === true) return true
|
|
93
|
+
return undefined
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** Resolves the fee-payer account allowed for an incoming credential. */
|
|
97
|
+
export function resolveCredentialFeePayer(
|
|
98
|
+
parameters: ResolveCredentialFeePayerParameters,
|
|
99
|
+
): viem_Account | undefined {
|
|
100
|
+
const { feePayer, methodDetails, request } = parameters
|
|
101
|
+
const requestFeePayer = readRequestFeePayer(request)
|
|
102
|
+
const requestAllowsFeePayer =
|
|
103
|
+
requestFeePayer === undefined || requestFeePayer === true || typeof requestFeePayer === 'object'
|
|
104
|
+
if (methodDetails.feePayer !== true || !requestAllowsFeePayer) return undefined
|
|
105
|
+
return typeof requestFeePayer === 'object' ? requestFeePayer : feePayer
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** Declarative server-side settlement cadence for automatic session settlement. */
|
|
109
|
+
export type SettlementSchedule = {
|
|
110
|
+
/** Settle after this many additional paid units since the previous scheduled settlement. */
|
|
111
|
+
units?: number | undefined
|
|
112
|
+
/** Settle after this much additional settlement amount since the previous scheduled settlement. */
|
|
113
|
+
amount?: string | bigint | undefined
|
|
114
|
+
/** Settle after this many milliseconds since the previous scheduled settlement. */
|
|
115
|
+
intervalMs?: number | undefined
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** Settlement schedule normalized into raw token units. */
|
|
119
|
+
export type ResolvedSettlementSchedule = {
|
|
120
|
+
/** Raw token amount threshold. */
|
|
121
|
+
amount?: bigint | undefined
|
|
122
|
+
/** Elapsed-time threshold since previous settlement. */
|
|
123
|
+
intervalMs?: number | undefined
|
|
124
|
+
/** Paid unit threshold. */
|
|
125
|
+
units?: number | undefined
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/** Progress counters compared against a server-owned settlement schedule. */
|
|
129
|
+
export type SettlementProgress = {
|
|
130
|
+
/** Additional raw spend since the previous scheduled settlement boundary. */
|
|
131
|
+
amount: bigint
|
|
132
|
+
/** Milliseconds elapsed since the previous scheduled settlement boundary. */
|
|
133
|
+
elapsedMs?: number | undefined
|
|
134
|
+
/** Additional paid units since the previous scheduled settlement boundary. */
|
|
135
|
+
units: number
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** Inputs used to mark a channel after automatic scheduled settlement succeeds. */
|
|
139
|
+
export type MarkSettlementCompleteParameters = {
|
|
140
|
+
channelId: ChannelStore.State['channelId']
|
|
141
|
+
settledAt?: string | undefined
|
|
142
|
+
store: ChannelStore.ChannelStore
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/** Converts a public settlement schedule into raw-unit thresholds. */
|
|
146
|
+
export function resolveSettlementSchedule(
|
|
147
|
+
schedule: SettlementSchedule | undefined,
|
|
148
|
+
decimals: number,
|
|
149
|
+
): ResolvedSettlementSchedule | undefined {
|
|
150
|
+
if (!schedule) return undefined
|
|
151
|
+
return {
|
|
152
|
+
...(schedule.amount !== undefined && {
|
|
153
|
+
amount:
|
|
154
|
+
typeof schedule.amount === 'bigint'
|
|
155
|
+
? schedule.amount
|
|
156
|
+
: parseUnits(schedule.amount, decimals),
|
|
157
|
+
}),
|
|
158
|
+
...(schedule.intervalMs !== undefined && { intervalMs: schedule.intervalMs }),
|
|
159
|
+
...(schedule.units !== undefined && { units: schedule.units }),
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Computes the schedule progress for an unsettled precompile-backed channel.
|
|
165
|
+
*
|
|
166
|
+
* Returns `undefined` for channels that cannot be scheduled: non-precompile
|
|
167
|
+
* records, channels without an accepted voucher, or channels with no unsettled
|
|
168
|
+
* voucher amount.
|
|
169
|
+
*/
|
|
170
|
+
export function resolveSettlementProgress(
|
|
171
|
+
channel: ChannelStore.State,
|
|
172
|
+
): SettlementProgress | undefined {
|
|
173
|
+
if (!ChannelStore.isPrecompileState(channel)) return undefined
|
|
174
|
+
if (!channel.highestVoucher) return undefined
|
|
175
|
+
if (channel.highestVoucher.cumulativeAmount <= channel.settledOnChain) return undefined
|
|
176
|
+
|
|
177
|
+
const amountBoundary = channel.lastSettlementSpent ?? channel.settledOnChain
|
|
178
|
+
const timestampBoundary = Date.parse(channel.lastSettlementAt ?? channel.createdAt)
|
|
179
|
+
|
|
180
|
+
return {
|
|
181
|
+
amount: channel.spent - amountBoundary,
|
|
182
|
+
...(Number.isFinite(timestampBoundary) && {
|
|
183
|
+
elapsedMs: Date.now() - timestampBoundary,
|
|
184
|
+
}),
|
|
185
|
+
units: channel.units - (channel.lastSettlementUnits ?? 0),
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/** Returns whether the precompile channel has crossed any configured settlement threshold. */
|
|
190
|
+
export function isSettlementDue(
|
|
191
|
+
channel: ChannelStore.State,
|
|
192
|
+
schedule: ResolvedSettlementSchedule | undefined,
|
|
193
|
+
): boolean {
|
|
194
|
+
if (!schedule) return false
|
|
195
|
+
const progress = resolveSettlementProgress(channel)
|
|
196
|
+
if (!progress) return false
|
|
197
|
+
|
|
198
|
+
if (schedule.units !== undefined && progress.units >= schedule.units) return true
|
|
199
|
+
|
|
200
|
+
if (schedule.amount !== undefined && progress.amount >= schedule.amount) return true
|
|
201
|
+
|
|
202
|
+
if (schedule.intervalMs !== undefined && (progress.elapsedMs ?? 0) >= schedule.intervalMs)
|
|
203
|
+
return true
|
|
204
|
+
|
|
205
|
+
return false
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/** Records the channel spend/unit counters that a scheduled settlement captured. */
|
|
209
|
+
export async function markSettlementComplete(parameters: MarkSettlementCompleteParameters) {
|
|
210
|
+
const { channelId, store, settledAt = new Date().toISOString() } = parameters
|
|
211
|
+
await store.updateChannel(channelId, (current) =>
|
|
212
|
+
current
|
|
213
|
+
? {
|
|
214
|
+
...current,
|
|
215
|
+
lastSettlementAt: settledAt,
|
|
216
|
+
lastSettlementSpent: current.spent,
|
|
217
|
+
lastSettlementUnits: current.units,
|
|
218
|
+
}
|
|
219
|
+
: current,
|
|
220
|
+
)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/** Callback used by post-verification accounting to deduct spend from a channel. */
|
|
224
|
+
export type ChargeSessionChannel = (channelId: Hex, amount: bigint) => Promise<ChannelStore.State>
|
|
225
|
+
|
|
226
|
+
/** Callback used by post-verification accounting to run server-owned settlement policy. */
|
|
227
|
+
export type SettleChargedSessionChannel = (channel: ChannelStore.State) => Promise<Hex | undefined>
|
|
228
|
+
|
|
229
|
+
/** Inputs for charging a precompile-backed session channel. */
|
|
230
|
+
export type ChargeParameters = {
|
|
231
|
+
/** Server-side channel store. */
|
|
232
|
+
store: ChannelStore.ChannelStore
|
|
233
|
+
/** Channel ID to deduct from. */
|
|
234
|
+
channelId: Hex
|
|
235
|
+
/** Raw token amount to charge. */
|
|
236
|
+
amount: bigint
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/** Inputs used to apply default HTTP request/response accounting after credential verification. */
|
|
240
|
+
export type ApplyVerifiedHttpAccountingParameters = {
|
|
241
|
+
/** Captured request metadata from the verified envelope, when this is a request-backed flow. */
|
|
242
|
+
capturedRequest?: Method.CapturedRequest | undefined
|
|
243
|
+
/** Deducts the configured request amount from channel spend. */
|
|
244
|
+
charge: ChargeSessionChannel
|
|
245
|
+
/** Returns the raw request amount to deduct for one content response. Called only when charging. */
|
|
246
|
+
getRequestAmount: () => bigint
|
|
247
|
+
/** Credential action that produced the receipt. Only open/voucher can pay for content. */
|
|
248
|
+
payloadAction: SessionCredentialPayload['action']
|
|
249
|
+
/** Receipt returned by credential verification before content accounting. */
|
|
250
|
+
receipt: SessionReceipt
|
|
251
|
+
/** Marks an SSE receipt whose first content unit was charged during verification. */
|
|
252
|
+
markPrepaidReceipt?: ((receipt: SessionReceipt) => SessionReceipt) | undefined
|
|
253
|
+
/** Whether SSE transport is enabled. SSE accounting is stream-driven, not HTTP-response-driven. */
|
|
254
|
+
sseEnabled: boolean
|
|
255
|
+
/** Runs optional server settlement policy after a successful content charge. */
|
|
256
|
+
settleCharged: SettleChargedSessionChannel
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/** Applies the default HTTP content charge after a session credential has been accepted. */
|
|
260
|
+
export async function applyVerifiedHttpAccounting(
|
|
261
|
+
parameters: ApplyVerifiedHttpAccountingParameters,
|
|
262
|
+
): Promise<SessionReceipt> {
|
|
263
|
+
const { capturedRequest, payloadAction, receipt, sseEnabled } = parameters
|
|
264
|
+
if (!capturedRequest) return receipt
|
|
265
|
+
if (!isSessionContentRequest(capturedRequest)) return receipt
|
|
266
|
+
if (payloadAction !== 'open' && payloadAction !== 'voucher') return receipt
|
|
267
|
+
|
|
268
|
+
const requestAmount = parameters.getRequestAmount()
|
|
269
|
+
const charged = await parameters.charge(receipt.channelId, requestAmount)
|
|
270
|
+
const settlementTxHash = await parameters.settleCharged(charged)
|
|
271
|
+
const chargedReceipt = {
|
|
272
|
+
...receipt,
|
|
273
|
+
spent: charged.spent.toString(),
|
|
274
|
+
units: charged.units,
|
|
275
|
+
...(settlementTxHash ? { txHash: settlementTxHash } : {}),
|
|
276
|
+
}
|
|
277
|
+
return sseEnabled
|
|
278
|
+
? (parameters.markPrepaidReceipt?.(chargedReceipt) ?? chargedReceipt)
|
|
279
|
+
: chargedReceipt
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/** Atomically deducts spend from a channel and maps store failures to typed session errors. */
|
|
283
|
+
export async function chargeSessionChannel(
|
|
284
|
+
parameters: ChargeParameters,
|
|
285
|
+
): Promise<ChannelStore.State> {
|
|
286
|
+
const { store, channelId, amount } = parameters
|
|
287
|
+
let result: Awaited<ReturnType<typeof ChannelStore.deductFromChannel>>
|
|
288
|
+
try {
|
|
289
|
+
result = await ChannelStore.deductFromChannel(store, channelId, amount)
|
|
290
|
+
} catch {
|
|
291
|
+
throw new ChannelClosedError({ reason: 'channel not found' })
|
|
292
|
+
}
|
|
293
|
+
if (!result.ok) {
|
|
294
|
+
if (result.channel.finalized) throw new ChannelClosedError({ reason: 'channel is finalized' })
|
|
295
|
+
if (result.channel.closeRequestedAt !== 0n)
|
|
296
|
+
throw new ChannelClosedError({ reason: 'channel has a pending close request' })
|
|
297
|
+
const available = result.channel.highestVoucherAmount - result.channel.spent
|
|
298
|
+
throw new InsufficientBalanceError({
|
|
299
|
+
reason: `requested ${amount}, available ${available}`,
|
|
300
|
+
})
|
|
301
|
+
}
|
|
302
|
+
return result.channel
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/** Store accepted by public settlement controls. */
|
|
306
|
+
export type SessionStoreInput = Store.Store | ChannelStore.ChannelStore
|
|
307
|
+
|
|
308
|
+
/** Inputs used to validate who may submit payee-side settlement transactions. */
|
|
309
|
+
export type SettlementSenderParameters = {
|
|
310
|
+
channelId: Hex
|
|
311
|
+
operation: 'close' | 'settle'
|
|
312
|
+
operator: Address
|
|
313
|
+
payee: Address
|
|
314
|
+
sender: Address | undefined
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/** Options for server-driven precompile settlement transactions. */
|
|
318
|
+
export type SettlementTransactionOptions = {
|
|
319
|
+
/** Account used to send the settlement transaction. Defaults to the viem client account. */
|
|
320
|
+
account?: viem_Account | undefined
|
|
321
|
+
/** Candidate fee tokens for sponsored settlement. Defaults to the channel token. */
|
|
322
|
+
candidateFeeTokens?: readonly Address[] | undefined
|
|
323
|
+
/** TIP20EscrowChannel precompile address override. */
|
|
324
|
+
escrowContract?: Address | undefined
|
|
325
|
+
/** Optional fee-payer account for sponsored settlement. */
|
|
326
|
+
feePayer?: viem_Account | undefined
|
|
327
|
+
/** Optional policy for sponsored settlement. */
|
|
328
|
+
feePayerPolicy?: Partial<FeePayer.Policy> | undefined
|
|
329
|
+
/** Optional fee token override for settlement. */
|
|
330
|
+
feeToken?: Address | undefined
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/** Inputs for applying a server-owned automatic settlement schedule. */
|
|
334
|
+
export type MaybeSettleScheduledParameters = {
|
|
335
|
+
/** Account used to send the settlement transaction. */
|
|
336
|
+
account?: viem_Account | undefined
|
|
337
|
+
/** Channel that was just charged. */
|
|
338
|
+
channel: ChannelStore.State
|
|
339
|
+
/** viem client used to settle on-chain. */
|
|
340
|
+
client: Chain.TransactionClient
|
|
341
|
+
/** Optional fee-payer account for sponsored settlement. */
|
|
342
|
+
feePayer?: viem_Account | undefined
|
|
343
|
+
/** Optional policy for sponsored settlement. */
|
|
344
|
+
feePayerPolicy?: Partial<FeePayer.Policy> | undefined
|
|
345
|
+
/** Optional fee token override for settlement. */
|
|
346
|
+
feeToken?: Address | undefined
|
|
347
|
+
/** Resolved server-owned settlement cadence. */
|
|
348
|
+
schedule: ResolvedSettlementSchedule | undefined
|
|
349
|
+
/** Server-side channel store. */
|
|
350
|
+
store: ChannelStore.ChannelStore
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/** Resolves either a generic mppx store or an already-wrapped channel store. */
|
|
354
|
+
export function resolveChannelStore(store: SessionStoreInput): ChannelStore.ChannelStore {
|
|
355
|
+
return 'getChannel' in store ? store : ChannelStore.fromStore(store)
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/** Returns the account attached to a viem client, when one exists. */
|
|
359
|
+
export function getClientAccount(client: { account?: viem_Account | undefined }) {
|
|
360
|
+
return client.account
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/** Validates that the transaction sender is the channel payee or nonzero operator. */
|
|
364
|
+
export function assertSettlementSender(parameters: SettlementSenderParameters) {
|
|
365
|
+
const { operation, channelId, operator, payee, sender } = parameters
|
|
366
|
+
if (!sender)
|
|
367
|
+
throw new Error(
|
|
368
|
+
`Cannot ${operation} precompile channel ${channelId}: no account available. Pass an account override, or provide a getClient() that returns an account-bearing client.`,
|
|
369
|
+
)
|
|
370
|
+
if (isAddressEqual(sender, payee)) return
|
|
371
|
+
if (!isAddressEqual(operator, zeroAddress) && isAddressEqual(sender, operator)) return
|
|
372
|
+
throw new BadRequestError({
|
|
373
|
+
reason:
|
|
374
|
+
`Cannot ${operation} precompile channel ${channelId}: tx sender ${sender} is not the channel payee ${payee}` +
|
|
375
|
+
(isAddressEqual(operator, zeroAddress) ? '.' : ` or operator ${operator}.`) +
|
|
376
|
+
' If using an access key, pass a Tempo access-key account whose address is the payee/operator wallet, not the raw delegated key address.',
|
|
377
|
+
})
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/** Applies automatic settlement when the server-owned schedule is due. */
|
|
381
|
+
export async function maybeSettleScheduled(
|
|
382
|
+
parameters: MaybeSettleScheduledParameters,
|
|
383
|
+
): Promise<Hex | undefined> {
|
|
384
|
+
const { channel, schedule, store } = parameters
|
|
385
|
+
if (!isSettlementDue(channel, schedule)) return undefined
|
|
386
|
+
const txHash = await settle(store, parameters.client, channel.channelId, {
|
|
387
|
+
account: parameters.account,
|
|
388
|
+
...(parameters.feePayer ? { feePayer: parameters.feePayer } : {}),
|
|
389
|
+
...(parameters.feePayerPolicy ? { feePayerPolicy: parameters.feePayerPolicy } : {}),
|
|
390
|
+
...(parameters.feeToken ? { feeToken: parameters.feeToken } : {}),
|
|
391
|
+
})
|
|
392
|
+
await markSettlementComplete({ channelId: channel.channelId, store })
|
|
393
|
+
return txHash
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/** Settles the highest accepted voucher for a precompile-backed session channel. */
|
|
397
|
+
export async function settle(
|
|
398
|
+
store_: SessionStoreInput,
|
|
399
|
+
client: Chain.TransactionClient,
|
|
400
|
+
channelId_: Hex,
|
|
401
|
+
options?: SettlementTransactionOptions,
|
|
402
|
+
): Promise<Hex> {
|
|
403
|
+
const store = resolveChannelStore(store_)
|
|
404
|
+
const channelId = ChannelStore.normalizeChannelId(channelId_)
|
|
405
|
+
const channel = await store.getChannel(channelId)
|
|
406
|
+
if (!channel) throw new ChannelNotFoundError({ reason: 'channel not found' })
|
|
407
|
+
if (!ChannelStore.isPrecompileState(channel))
|
|
408
|
+
throw new VerificationFailedError({ reason: 'channel is not precompile-backed' })
|
|
409
|
+
if (!channel.highestVoucher) throw new VerificationFailedError({ reason: 'no voucher to settle' })
|
|
410
|
+
const escrow = options?.escrowContract ?? channel.escrowContract
|
|
411
|
+
const account = options?.account ?? getClientAccount(client)
|
|
412
|
+
assertSettlementSender({
|
|
413
|
+
operation: 'settle',
|
|
414
|
+
channelId,
|
|
415
|
+
operator: channel.operator,
|
|
416
|
+
payee: channel.payee,
|
|
417
|
+
sender: account?.address,
|
|
418
|
+
})
|
|
419
|
+
const amount = uint96(channel.highestVoucher.cumulativeAmount)
|
|
420
|
+
const txHash = await Chain.settleOnChain(
|
|
421
|
+
client,
|
|
422
|
+
channel.descriptor,
|
|
423
|
+
amount,
|
|
424
|
+
channel.highestVoucher.signature,
|
|
425
|
+
escrow,
|
|
426
|
+
account
|
|
427
|
+
? {
|
|
428
|
+
account,
|
|
429
|
+
...(options?.feePayer ? { feePayer: options.feePayer } : {}),
|
|
430
|
+
...(options?.feePayerPolicy ? { feePayerPolicy: options.feePayerPolicy } : {}),
|
|
431
|
+
...(options?.feeToken ? { feeToken: options.feeToken } : {}),
|
|
432
|
+
candidateFeeTokens: options?.candidateFeeTokens ?? [channel.token],
|
|
433
|
+
}
|
|
434
|
+
: undefined,
|
|
435
|
+
)
|
|
436
|
+
const receipt = await Chain.waitForSuccessfulReceipt(client, txHash)
|
|
437
|
+
const settled = readSettledReceiptFields(Chain.getChannelEvent(receipt, 'Settled', channelId))
|
|
438
|
+
const { newSettled } = settled
|
|
439
|
+
if (newSettled < amount)
|
|
440
|
+
throw new VerificationFailedError({ reason: 'Settled event is below voucher amount' })
|
|
441
|
+
const state = await Chain.getChannelState(client, channelId, escrow)
|
|
442
|
+
if (state.settled !== newSettled)
|
|
443
|
+
throw new VerificationFailedError({
|
|
444
|
+
reason: 'on-chain channel state does not match settle receipt',
|
|
445
|
+
})
|
|
446
|
+
await store.updateChannel(channelId, (current) =>
|
|
447
|
+
current
|
|
448
|
+
? {
|
|
449
|
+
...current,
|
|
450
|
+
settledOnChain: newSettled > current.settledOnChain ? newSettled : current.settledOnChain,
|
|
451
|
+
lastSettlementAt: new Date().toISOString(),
|
|
452
|
+
lastSettlementSpent: current.spent,
|
|
453
|
+
lastSettlementUnits: current.units,
|
|
454
|
+
}
|
|
455
|
+
: current,
|
|
456
|
+
)
|
|
457
|
+
return txHash
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
/** Settles multiple precompile-backed session channels with the same validation as {@link settle}. */
|
|
461
|
+
export async function settleBatch(
|
|
462
|
+
store: SessionStoreInput,
|
|
463
|
+
client: Chain.TransactionClient,
|
|
464
|
+
channelIds: readonly Hex[],
|
|
465
|
+
options?: SettlementTransactionOptions,
|
|
466
|
+
): Promise<Hex[]> {
|
|
467
|
+
const hashes: Hex[] = []
|
|
468
|
+
for (const channelId of channelIds) hashes.push(await settle(store, client, channelId, options))
|
|
469
|
+
return hashes
|
|
470
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { Address, Hex } from 'viem'
|
|
2
2
|
import { describe, expect, test } from 'vp/test'
|
|
3
3
|
|
|
4
|
-
import { ChannelClosedError } from '
|
|
5
|
-
import { chainId, escrowContract as escrowContractDefaults } from '
|
|
4
|
+
import { ChannelClosedError } from '../../../Errors.js'
|
|
5
|
+
import { chainId, escrowContract as escrowContractDefaults } from '../../internal/defaults.js'
|
|
6
|
+
import type { NeedVoucherEvent, SessionReceipt } from '../precompile/Protocol.js'
|
|
6
7
|
import type * as ChannelStore from './ChannelStore.js'
|
|
7
8
|
import { formatNeedVoucherEvent, formatReceiptEvent, parseEvent, serve } from './Sse.js'
|
|
8
|
-
import type { NeedVoucherEvent, SessionReceipt } from './Types.js'
|
|
9
9
|
|
|
10
10
|
const channelId = '0x0000000000000000000000000000000000000000000000000000000000000001' as Hex
|
|
11
11
|
const challengeId = 'challenge-1'
|
|
@@ -369,6 +369,40 @@ describe('serve', () => {
|
|
|
369
369
|
expect(all).toContain('event: payment-receipt\n')
|
|
370
370
|
})
|
|
371
371
|
|
|
372
|
+
test('resumes when the client updates voucher state before reading the next stream chunk', async () => {
|
|
373
|
+
const storage = memoryStore()
|
|
374
|
+
await seedChannel(storage, 1000000n)
|
|
375
|
+
|
|
376
|
+
const streamResult = serve({
|
|
377
|
+
store: storage,
|
|
378
|
+
channelId,
|
|
379
|
+
challengeId,
|
|
380
|
+
tickCost: 1000000n,
|
|
381
|
+
generate: generate(['first', 'second']),
|
|
382
|
+
pollIntervalMs: 10,
|
|
383
|
+
})
|
|
384
|
+
|
|
385
|
+
const reader = streamResult.getReader()
|
|
386
|
+
const decoder = new TextDecoder()
|
|
387
|
+
|
|
388
|
+
const first = await reader.read()
|
|
389
|
+
expect(decoder.decode(first.value, { stream: true })).toContain(
|
|
390
|
+
'event: message\ndata: first\n\n',
|
|
391
|
+
)
|
|
392
|
+
|
|
393
|
+
const need = await reader.read()
|
|
394
|
+
expect(decoder.decode(need.value, { stream: true })).toContain('event: payment-need-voucher\n')
|
|
395
|
+
|
|
396
|
+
await storage.updateChannel(channelId, (current) =>
|
|
397
|
+
current ? { ...current, highestVoucherAmount: 2000000n } : current,
|
|
398
|
+
)
|
|
399
|
+
|
|
400
|
+
const second = await reader.read()
|
|
401
|
+
expect(decoder.decode(second.value, { stream: true })).toContain(
|
|
402
|
+
'event: message\ndata: second\n\n',
|
|
403
|
+
)
|
|
404
|
+
})
|
|
405
|
+
|
|
372
406
|
test('respects abort signal', async () => {
|
|
373
407
|
const storage = memoryStore()
|
|
374
408
|
await seedChannel(storage, 10000000n)
|