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
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
import { Challenge, Credential, Receipt } from 'mppx'
|
|
2
2
|
import { Mppx } from 'mppx/server'
|
|
3
3
|
import { KeyAuthorization } from 'ox/tempo'
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
createClient,
|
|
6
|
+
custom,
|
|
7
|
+
decodeFunctionData,
|
|
8
|
+
encodeAbiParameters,
|
|
9
|
+
encodeEventTopics,
|
|
10
|
+
type Address,
|
|
11
|
+
type Hex,
|
|
12
|
+
} from 'viem'
|
|
5
13
|
import { privateKeyToAccount } from 'viem/accounts'
|
|
14
|
+
import { Abis, Transaction } from 'viem/tempo'
|
|
6
15
|
import { tempo as tempo_chain } from 'viem/tempo/chains'
|
|
7
16
|
import { describe, expect, test } from 'vp/test'
|
|
8
17
|
|
|
@@ -15,7 +24,7 @@ import type { SubscriptionRecord } from '../subscription/Types.js'
|
|
|
15
24
|
import { renew, subscription } from './Subscription.js'
|
|
16
25
|
|
|
17
26
|
const realm = 'api.example.com'
|
|
18
|
-
const secretKey = 'test-secret-key'
|
|
27
|
+
const secretKey = 'test-secret-key-test-secret-key-32'
|
|
19
28
|
const activeBillingAnchor = new Date(Math.floor(Date.now() / 1_000) * 1_000).toISOString()
|
|
20
29
|
const activeSubscriptionExpires = new Date(
|
|
21
30
|
Math.ceil((Date.now() + 365 * 24 * 60 * 60 * 1_000) / 1_000) * 1_000,
|
|
@@ -32,6 +41,9 @@ const subscriptionRecipient = '0x1234567890abcdef1234567890abcdef12345678'
|
|
|
32
41
|
const rootAccount = privateKeyToAccount(
|
|
33
42
|
'0x0000000000000000000000000000000000000000000000000000000000000001',
|
|
34
43
|
)
|
|
44
|
+
const otherRootAccount = privateKeyToAccount(
|
|
45
|
+
'0x0000000000000000000000000000000000000000000000000000000000000004',
|
|
46
|
+
)
|
|
35
47
|
const accessAccount = privateKeyToAccount(
|
|
36
48
|
'0x0000000000000000000000000000000000000000000000000000000000000002',
|
|
37
49
|
)
|
|
@@ -81,10 +93,11 @@ async function createCredential(
|
|
|
81
93
|
challenge: Challenge.Challenge,
|
|
82
94
|
source = rootAccount.address,
|
|
83
95
|
key: SubscriptionAccessKey = accessKey,
|
|
96
|
+
account = rootAccount,
|
|
84
97
|
) {
|
|
85
98
|
const keyAuthorization = await signSubscriptionKeyAuthorization({
|
|
86
99
|
accessKey: key,
|
|
87
|
-
account
|
|
100
|
+
account,
|
|
88
101
|
chainId,
|
|
89
102
|
request: challenge.request as ReturnType<typeof Methods.subscription.schema.request.parse>,
|
|
90
103
|
})
|
|
@@ -117,6 +130,109 @@ function createBillingClient(hashes: readonly string[]) {
|
|
|
117
130
|
return { client, rpcMethods }
|
|
118
131
|
}
|
|
119
132
|
|
|
133
|
+
const confirmedBlockHash = `0x${'f'.repeat(64)}` as const
|
|
134
|
+
// Canonical TIP-1028 ReceivePolicyGuard precompile address.
|
|
135
|
+
const receivePolicyGuard = '0xB10C000000000000000000000000000000000000' as Address
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Mock client whose `eth_sendRawTransactionSync` returns a confirmed receipt
|
|
139
|
+
* with a `TransferWithMemo` log derived from the broadcast transaction.
|
|
140
|
+
*
|
|
141
|
+
* `redirectTo` simulates a T6 (TIP-1028) held transfer (credits the guard, not
|
|
142
|
+
* the recipient); `addUnrelatedTransfer` adds a memo-less `Transfer` to the
|
|
143
|
+
* recipient. By default only the renewal (second) broadcast is affected so
|
|
144
|
+
* activation succeeds; `redirectActivation` also holds the first broadcast.
|
|
145
|
+
*/
|
|
146
|
+
function createConfirmingBillingClient(options?: {
|
|
147
|
+
addUnrelatedTransfer?: boolean
|
|
148
|
+
redirectActivation?: boolean
|
|
149
|
+
redirectTo?: Address
|
|
150
|
+
}) {
|
|
151
|
+
const rpcMethods: string[] = []
|
|
152
|
+
let broadcastIndex = 0
|
|
153
|
+
const client = createClient({
|
|
154
|
+
chain: { ...tempo_chain, id: chainId },
|
|
155
|
+
transport: custom({
|
|
156
|
+
async request({ method, params }) {
|
|
157
|
+
rpcMethods.push(method)
|
|
158
|
+
if (method === 'eth_chainId') return `0x${chainId.toString(16)}`
|
|
159
|
+
if (method === 'eth_call') return '0x'
|
|
160
|
+
if (method === 'eth_sendRawTransactionSync') {
|
|
161
|
+
const index = broadcastIndex++
|
|
162
|
+
const isRenewal = index >= 1
|
|
163
|
+
const serialized = (params as [Hex])[0]
|
|
164
|
+
const transaction = Transaction.deserialize(
|
|
165
|
+
serialized as Transaction.TransactionSerializedTempo,
|
|
166
|
+
) as unknown as {
|
|
167
|
+
from: Address
|
|
168
|
+
calls: readonly { data: Hex; to: Address }[]
|
|
169
|
+
}
|
|
170
|
+
const call = transaction.calls[0]!
|
|
171
|
+
const { args } = decodeFunctionData({
|
|
172
|
+
abi: Abis.tip20,
|
|
173
|
+
data: call.data,
|
|
174
|
+
})
|
|
175
|
+
const [recipient, amount, memo] = args as [Address, bigint, Hex]
|
|
176
|
+
const shouldRedirect = options?.redirectTo && (isRenewal || options?.redirectActivation)
|
|
177
|
+
const creditedTo = shouldRedirect ? options!.redirectTo! : recipient
|
|
178
|
+
const hash = `0x${index.toString(16).padStart(64, '0')}` as Hex
|
|
179
|
+
const baseLog = {
|
|
180
|
+
blockHash: confirmedBlockHash,
|
|
181
|
+
blockNumber: '0x1',
|
|
182
|
+
data: encodeAbiParameters([{ type: 'uint256' }], [amount]),
|
|
183
|
+
logIndex: '0x0',
|
|
184
|
+
removed: false,
|
|
185
|
+
transactionHash: hash,
|
|
186
|
+
transactionIndex: '0x0',
|
|
187
|
+
} as const
|
|
188
|
+
const logs: unknown[] = [
|
|
189
|
+
{
|
|
190
|
+
...baseLog,
|
|
191
|
+
address: call.to,
|
|
192
|
+
topics: encodeEventTopics({
|
|
193
|
+
abi: Abis.tip20,
|
|
194
|
+
args: { from: transaction.from, memo, to: creditedTo },
|
|
195
|
+
eventName: 'TransferWithMemo',
|
|
196
|
+
}),
|
|
197
|
+
},
|
|
198
|
+
]
|
|
199
|
+
// Memo-less Transfer to the recipient: must not satisfy the check.
|
|
200
|
+
if (isRenewal && options?.addUnrelatedTransfer) {
|
|
201
|
+
logs.push({
|
|
202
|
+
...baseLog,
|
|
203
|
+
address: call.to,
|
|
204
|
+
logIndex: '0x1',
|
|
205
|
+
topics: encodeEventTopics({
|
|
206
|
+
abi: Abis.tip20,
|
|
207
|
+
args: { from: transaction.from, to: recipient },
|
|
208
|
+
eventName: 'Transfer',
|
|
209
|
+
}),
|
|
210
|
+
})
|
|
211
|
+
}
|
|
212
|
+
return {
|
|
213
|
+
blockHash: confirmedBlockHash,
|
|
214
|
+
blockNumber: '0x1',
|
|
215
|
+
contractAddress: null,
|
|
216
|
+
cumulativeGasUsed: '0x0',
|
|
217
|
+
effectiveGasPrice: '0x0',
|
|
218
|
+
from: transaction.from,
|
|
219
|
+
gasUsed: '0x0',
|
|
220
|
+
logs,
|
|
221
|
+
logsBloom: `0x${'0'.repeat(512)}`,
|
|
222
|
+
status: '0x1',
|
|
223
|
+
to: call.to,
|
|
224
|
+
transactionHash: hash,
|
|
225
|
+
transactionIndex: '0x0',
|
|
226
|
+
type: '0x0',
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
throw new Error(`unexpected rpc method: ${method}`)
|
|
230
|
+
},
|
|
231
|
+
}),
|
|
232
|
+
})
|
|
233
|
+
return { client, rpcMethods }
|
|
234
|
+
}
|
|
235
|
+
|
|
120
236
|
describe('tempo.subscription', () => {
|
|
121
237
|
test('stores an activated subscription and reuses it on later requests', async () => {
|
|
122
238
|
const store = Store.memory()
|
|
@@ -271,6 +387,211 @@ describe('tempo.subscription', () => {
|
|
|
271
387
|
expect(rpcMethods.filter((method) => method === 'eth_sendRawTransaction')).toHaveLength(1)
|
|
272
388
|
})
|
|
273
389
|
|
|
390
|
+
test('requires a fresh credential for active subscription reuse when configured', async () => {
|
|
391
|
+
const store = Store.memory()
|
|
392
|
+
const subscriptions = SubscriptionStore.fromStore(store)
|
|
393
|
+
await subscriptions.put(
|
|
394
|
+
createRecord({
|
|
395
|
+
accessKey,
|
|
396
|
+
payer: { address: rootAccount.address, chainId },
|
|
397
|
+
}),
|
|
398
|
+
)
|
|
399
|
+
const method = subscription({
|
|
400
|
+
activate: async () => {
|
|
401
|
+
throw new Error('active subscription reuse should not activate')
|
|
402
|
+
},
|
|
403
|
+
amount: subscriptionAmount,
|
|
404
|
+
chainId,
|
|
405
|
+
currency: subscriptionCurrency,
|
|
406
|
+
periodCount: subscriptionPeriodCount,
|
|
407
|
+
periodUnit: subscriptionPeriodUnit,
|
|
408
|
+
recipient: subscriptionRecipient,
|
|
409
|
+
requireCredential: true,
|
|
410
|
+
resolve: async () => ({ accessKey, key: subscriptionKey }),
|
|
411
|
+
store,
|
|
412
|
+
subscriptionExpires: activeSubscriptionExpires,
|
|
413
|
+
})
|
|
414
|
+
|
|
415
|
+
const mppx = Mppx.create({ methods: [method], realm, secretKey })
|
|
416
|
+
const unauthenticated = await mppx.tempo.subscription({})(
|
|
417
|
+
new Request('https://example.com/resource'),
|
|
418
|
+
)
|
|
419
|
+
|
|
420
|
+
expect(unauthenticated.status).toBe(402)
|
|
421
|
+
if (unauthenticated.status !== 402) throw new Error('expected reuse challenge')
|
|
422
|
+
|
|
423
|
+
const challenge = Challenge.fromResponse(unauthenticated.challenge)
|
|
424
|
+
const credential = await createCredential(challenge)
|
|
425
|
+
const reused = await mppx.tempo.subscription({})(
|
|
426
|
+
new Request('https://example.com/resource', {
|
|
427
|
+
headers: { Authorization: Credential.serialize(credential) },
|
|
428
|
+
}),
|
|
429
|
+
)
|
|
430
|
+
|
|
431
|
+
expect(reused.status).toBe(200)
|
|
432
|
+
})
|
|
433
|
+
|
|
434
|
+
test('can derive the subscription lookup key only from the signed credential source', async () => {
|
|
435
|
+
const store = Store.memory()
|
|
436
|
+
const subscriptions = SubscriptionStore.fromStore(store)
|
|
437
|
+
const { client, rpcMethods } = createBillingClient([hashActivate])
|
|
438
|
+
const sourceKey = (source: { address: string; chainId: number }) =>
|
|
439
|
+
`payer:${source.chainId}:${source.address.toLowerCase()}:pro`
|
|
440
|
+
const method = subscription({
|
|
441
|
+
amount: subscriptionAmount,
|
|
442
|
+
chainId,
|
|
443
|
+
currency: subscriptionCurrency,
|
|
444
|
+
getClient: async () => client,
|
|
445
|
+
periodCount: subscriptionPeriodCount,
|
|
446
|
+
periodUnit: subscriptionPeriodUnit,
|
|
447
|
+
recipient: subscriptionRecipient,
|
|
448
|
+
requireCredential: true,
|
|
449
|
+
resolve: async ({ source }) => {
|
|
450
|
+
if (!source) return null
|
|
451
|
+
return { key: sourceKey(source) }
|
|
452
|
+
},
|
|
453
|
+
store,
|
|
454
|
+
subscriptionExpires: activeSubscriptionExpires,
|
|
455
|
+
waitForConfirmation: false,
|
|
456
|
+
})
|
|
457
|
+
|
|
458
|
+
const mppx = Mppx.create({ methods: [method], realm, secretKey })
|
|
459
|
+
const challengeResult = await mppx.tempo.subscription({})(
|
|
460
|
+
new Request('https://example.com/resource'),
|
|
461
|
+
)
|
|
462
|
+
|
|
463
|
+
expect(challengeResult.status).toBe(402)
|
|
464
|
+
if (challengeResult.status !== 402) throw new Error('expected source challenge')
|
|
465
|
+
|
|
466
|
+
const challenge = Challenge.fromResponse(challengeResult.challenge)
|
|
467
|
+
const challengeAccessKey = (
|
|
468
|
+
challenge.request as ReturnType<typeof Methods.subscription.schema.request.parse>
|
|
469
|
+
).methodDetails?.accessKey
|
|
470
|
+
if (!challengeAccessKey) throw new Error('expected challenge access key')
|
|
471
|
+
|
|
472
|
+
const credential = await createCredential(challenge, rootAccount.address, challengeAccessKey)
|
|
473
|
+
const activated = await mppx.tempo.subscription({})(
|
|
474
|
+
new Request('https://example.com/resource', {
|
|
475
|
+
headers: { Authorization: Credential.serialize(credential) },
|
|
476
|
+
}),
|
|
477
|
+
)
|
|
478
|
+
|
|
479
|
+
expect(activated.status).toBe(200)
|
|
480
|
+
const lookupKey = sourceKey({ address: rootAccount.address, chainId })
|
|
481
|
+
const record = await subscriptions.getByKey(lookupKey)
|
|
482
|
+
expect(record?.lookupKey).toBe(lookupKey)
|
|
483
|
+
expect(record?.payer?.address.toLowerCase()).toBe(rootAccount.address.toLowerCase())
|
|
484
|
+
expect(record?.accessKey).toEqual(challengeAccessKey)
|
|
485
|
+
expect(rpcMethods.filter((method) => method === 'eth_sendRawTransaction')).toHaveLength(1)
|
|
486
|
+
})
|
|
487
|
+
|
|
488
|
+
test('rejects credential reuse when the signer does not match the stored payer', async () => {
|
|
489
|
+
const store = Store.memory()
|
|
490
|
+
const subscriptions = SubscriptionStore.fromStore(store)
|
|
491
|
+
await subscriptions.put(
|
|
492
|
+
createRecord({
|
|
493
|
+
accessKey,
|
|
494
|
+
payer: { address: rootAccount.address, chainId },
|
|
495
|
+
}),
|
|
496
|
+
)
|
|
497
|
+
const method = subscription({
|
|
498
|
+
activate: async () => {
|
|
499
|
+
throw new Error('active subscription reuse should not activate')
|
|
500
|
+
},
|
|
501
|
+
amount: subscriptionAmount,
|
|
502
|
+
chainId,
|
|
503
|
+
currency: subscriptionCurrency,
|
|
504
|
+
periodCount: subscriptionPeriodCount,
|
|
505
|
+
periodUnit: subscriptionPeriodUnit,
|
|
506
|
+
recipient: subscriptionRecipient,
|
|
507
|
+
requireCredential: true,
|
|
508
|
+
resolve: async () => ({ accessKey, key: subscriptionKey }),
|
|
509
|
+
store,
|
|
510
|
+
subscriptionExpires: activeSubscriptionExpires,
|
|
511
|
+
})
|
|
512
|
+
|
|
513
|
+
const mppx = Mppx.create({ methods: [method], realm, secretKey })
|
|
514
|
+
const challengeResult = await mppx.tempo.subscription({})(
|
|
515
|
+
new Request('https://example.com/resource'),
|
|
516
|
+
)
|
|
517
|
+
if (challengeResult.status !== 402) throw new Error('expected reuse challenge')
|
|
518
|
+
|
|
519
|
+
const challenge = Challenge.fromResponse(challengeResult.challenge)
|
|
520
|
+
const credential = await createCredential(
|
|
521
|
+
challenge,
|
|
522
|
+
otherRootAccount.address,
|
|
523
|
+
accessKey,
|
|
524
|
+
otherRootAccount,
|
|
525
|
+
)
|
|
526
|
+
const rejected = await mppx.tempo.subscription({})(
|
|
527
|
+
new Request('https://example.com/resource', {
|
|
528
|
+
headers: { Authorization: Credential.serialize(credential) },
|
|
529
|
+
}),
|
|
530
|
+
)
|
|
531
|
+
|
|
532
|
+
expect(rejected.status).toBe(402)
|
|
533
|
+
if (rejected.status !== 402) throw new Error('expected payer mismatch challenge')
|
|
534
|
+
const body = await rejected.challenge.json()
|
|
535
|
+
expect(body.detail).toBe('Payment verification failed: subscription payer mismatch.')
|
|
536
|
+
})
|
|
537
|
+
|
|
538
|
+
test('renews an overdue active subscription after credential-required payer proof', async () => {
|
|
539
|
+
const store = Store.memory()
|
|
540
|
+
const subscriptions = SubscriptionStore.fromStore(store)
|
|
541
|
+
await subscriptions.put(
|
|
542
|
+
createRecord({
|
|
543
|
+
accessKey,
|
|
544
|
+
billingAnchor: new Date(Date.now() - 3 * subscriptionPeriodMilliseconds).toISOString(),
|
|
545
|
+
lastChargedPeriod: 0,
|
|
546
|
+
payer: { address: rootAccount.address, chainId },
|
|
547
|
+
reference: hashStale,
|
|
548
|
+
}),
|
|
549
|
+
)
|
|
550
|
+
const method = subscription({
|
|
551
|
+
activate: async () => {
|
|
552
|
+
throw new Error('active subscription renewal should not activate')
|
|
553
|
+
},
|
|
554
|
+
amount: subscriptionAmount,
|
|
555
|
+
chainId,
|
|
556
|
+
currency: subscriptionCurrency,
|
|
557
|
+
periodCount: subscriptionPeriodCount,
|
|
558
|
+
periodUnit: subscriptionPeriodUnit,
|
|
559
|
+
recipient: subscriptionRecipient,
|
|
560
|
+
renew: async ({ periodIndex, subscription }) => ({
|
|
561
|
+
receipt: createReceipt(subscription.subscriptionId, hashRenewed),
|
|
562
|
+
subscription: {
|
|
563
|
+
...subscription,
|
|
564
|
+
lastChargedPeriod: periodIndex,
|
|
565
|
+
reference: hashRenewed,
|
|
566
|
+
},
|
|
567
|
+
}),
|
|
568
|
+
requireCredential: true,
|
|
569
|
+
resolve: async () => ({ accessKey, key: subscriptionKey }),
|
|
570
|
+
store,
|
|
571
|
+
subscriptionExpires: activeSubscriptionExpires,
|
|
572
|
+
})
|
|
573
|
+
|
|
574
|
+
const mppx = Mppx.create({ methods: [method], realm, secretKey })
|
|
575
|
+
const challengeResult = await mppx.tempo.subscription({})(
|
|
576
|
+
new Request('https://example.com/resource'),
|
|
577
|
+
)
|
|
578
|
+
if (challengeResult.status !== 402) throw new Error('expected reuse challenge')
|
|
579
|
+
|
|
580
|
+
const challenge = Challenge.fromResponse(challengeResult.challenge)
|
|
581
|
+
const credential = await createCredential(challenge)
|
|
582
|
+
const renewed = await mppx.tempo.subscription({})(
|
|
583
|
+
new Request('https://example.com/resource', {
|
|
584
|
+
headers: { Authorization: Credential.serialize(credential) },
|
|
585
|
+
}),
|
|
586
|
+
)
|
|
587
|
+
|
|
588
|
+
expect(renewed.status).toBe(200)
|
|
589
|
+
if (renewed.status !== 200) throw new Error('expected credential renewal')
|
|
590
|
+
const receipt = Receipt.fromResponse(renewed.withReceipt(new Response('OK')))
|
|
591
|
+
expect(receipt.reference).toBe(hashRenewed)
|
|
592
|
+
expect((await subscriptions.getByKey(subscriptionKey))?.lastChargedPeriod).toBeGreaterThan(0)
|
|
593
|
+
})
|
|
594
|
+
|
|
274
595
|
test('verifyCredential activates a subscription credential with a canonical challenge request', async () => {
|
|
275
596
|
const store = Store.memory()
|
|
276
597
|
const { client } = createBillingClient([hashActivate])
|
|
@@ -357,6 +678,147 @@ describe('tempo.subscription', () => {
|
|
|
357
678
|
expect((await subscriptions.get(record.subscriptionId))?.lastChargedPeriod).toBeGreaterThan(0)
|
|
358
679
|
})
|
|
359
680
|
|
|
681
|
+
async function activateConfirmedSubscription(parameters: {
|
|
682
|
+
client: ReturnType<typeof createConfirmingBillingClient>['client']
|
|
683
|
+
store: ReturnType<typeof Store.memory>
|
|
684
|
+
}) {
|
|
685
|
+
const { client, store } = parameters
|
|
686
|
+
const method = subscription({
|
|
687
|
+
amount: subscriptionAmount,
|
|
688
|
+
chainId,
|
|
689
|
+
currency: subscriptionCurrency,
|
|
690
|
+
getClient: async () => client,
|
|
691
|
+
periodCount: subscriptionPeriodCount,
|
|
692
|
+
periodUnit: subscriptionPeriodUnit,
|
|
693
|
+
recipient: subscriptionRecipient,
|
|
694
|
+
resolve: async () => ({ key: subscriptionKey }),
|
|
695
|
+
store,
|
|
696
|
+
subscriptionExpires: activeSubscriptionExpires,
|
|
697
|
+
})
|
|
698
|
+
const mppx = Mppx.create({ methods: [method], realm, secretKey })
|
|
699
|
+
const challengeResult = await mppx.tempo.subscription({})(
|
|
700
|
+
new Request('https://example.com/resource'),
|
|
701
|
+
)
|
|
702
|
+
if (challengeResult.status !== 402) throw new Error('expected activation challenge')
|
|
703
|
+
const challenge = Challenge.fromResponse(challengeResult.challenge)
|
|
704
|
+
const accessKey = (
|
|
705
|
+
challenge.request as ReturnType<typeof Methods.subscription.schema.request.parse>
|
|
706
|
+
).methodDetails?.accessKey
|
|
707
|
+
if (!accessKey) throw new Error('expected generated access key')
|
|
708
|
+
const credential = await createCredential(challenge, rootAccount.address, accessKey)
|
|
709
|
+
const activated = await mppx.tempo.subscription({})(
|
|
710
|
+
new Request('https://example.com/resource', {
|
|
711
|
+
headers: { Authorization: Credential.serialize(credential) },
|
|
712
|
+
}),
|
|
713
|
+
)
|
|
714
|
+
expect(activated.status).toBe(200)
|
|
715
|
+
return { mppx }
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
test('renews when the confirmed receipt credits the recipient', async () => {
|
|
719
|
+
const store = Store.memory()
|
|
720
|
+
const subscriptions = SubscriptionStore.fromStore(store)
|
|
721
|
+
const { client } = createConfirmingBillingClient()
|
|
722
|
+
const { mppx } = await activateConfirmedSubscription({ client, store })
|
|
723
|
+
|
|
724
|
+
const record = await subscriptions.getByKey(subscriptionKey)
|
|
725
|
+
if (!record) throw new Error('expected subscription record')
|
|
726
|
+
await subscriptions.put({
|
|
727
|
+
...record,
|
|
728
|
+
billingAnchor: new Date(Date.now() - 3 * subscriptionPeriodMilliseconds).toISOString(),
|
|
729
|
+
lastChargedPeriod: 0,
|
|
730
|
+
})
|
|
731
|
+
|
|
732
|
+
const renewed = await mppx.tempo.subscription({})(new Request('https://example.com/resource'))
|
|
733
|
+
expect(renewed.status).toBe(200)
|
|
734
|
+
expect((await subscriptions.get(record.subscriptionId))?.lastChargedPeriod).toBeGreaterThan(0)
|
|
735
|
+
})
|
|
736
|
+
|
|
737
|
+
test('rejects renewal when a receive policy holds the confirmed transfer', async () => {
|
|
738
|
+
const store = Store.memory()
|
|
739
|
+
const subscriptions = SubscriptionStore.fromStore(store)
|
|
740
|
+
const { client } = createConfirmingBillingClient({ redirectTo: receivePolicyGuard })
|
|
741
|
+
const { mppx } = await activateConfirmedSubscription({ client, store })
|
|
742
|
+
|
|
743
|
+
const record = await subscriptions.getByKey(subscriptionKey)
|
|
744
|
+
if (!record) throw new Error('expected subscription record')
|
|
745
|
+
await subscriptions.put({
|
|
746
|
+
...record,
|
|
747
|
+
billingAnchor: new Date(Date.now() - 3 * subscriptionPeriodMilliseconds).toISOString(),
|
|
748
|
+
lastChargedPeriod: 0,
|
|
749
|
+
})
|
|
750
|
+
|
|
751
|
+
const renewed = await mppx.tempo.subscription({})(new Request('https://example.com/resource'))
|
|
752
|
+
expect(renewed.status).toBe(402)
|
|
753
|
+
// The held renewal must not advance the billing period.
|
|
754
|
+
expect((await subscriptions.get(record.subscriptionId))?.lastChargedPeriod).toBe(0)
|
|
755
|
+
})
|
|
756
|
+
|
|
757
|
+
test('rejects a held renewal even when a memo-less Transfer credits the recipient', async () => {
|
|
758
|
+
const store = Store.memory()
|
|
759
|
+
const subscriptions = SubscriptionStore.fromStore(store)
|
|
760
|
+
// Settlement is held, but the receipt also has a memo-less Transfer to the
|
|
761
|
+
// recipient; the memo-bound check must still reject it.
|
|
762
|
+
const { client } = createConfirmingBillingClient({
|
|
763
|
+
addUnrelatedTransfer: true,
|
|
764
|
+
redirectTo: receivePolicyGuard,
|
|
765
|
+
})
|
|
766
|
+
const { mppx } = await activateConfirmedSubscription({ client, store })
|
|
767
|
+
|
|
768
|
+
const record = await subscriptions.getByKey(subscriptionKey)
|
|
769
|
+
if (!record) throw new Error('expected subscription record')
|
|
770
|
+
await subscriptions.put({
|
|
771
|
+
...record,
|
|
772
|
+
billingAnchor: new Date(Date.now() - 3 * subscriptionPeriodMilliseconds).toISOString(),
|
|
773
|
+
lastChargedPeriod: 0,
|
|
774
|
+
})
|
|
775
|
+
|
|
776
|
+
const renewed = await mppx.tempo.subscription({})(new Request('https://example.com/resource'))
|
|
777
|
+
expect(renewed.status).toBe(402)
|
|
778
|
+
expect((await subscriptions.get(record.subscriptionId))?.lastChargedPeriod).toBe(0)
|
|
779
|
+
})
|
|
780
|
+
|
|
781
|
+
test('rejects activation when a receive policy holds the confirmed transfer', async () => {
|
|
782
|
+
const store = Store.memory()
|
|
783
|
+
const subscriptions = SubscriptionStore.fromStore(store)
|
|
784
|
+
const { client } = createConfirmingBillingClient({
|
|
785
|
+
redirectActivation: true,
|
|
786
|
+
redirectTo: receivePolicyGuard,
|
|
787
|
+
})
|
|
788
|
+
const method = subscription({
|
|
789
|
+
amount: subscriptionAmount,
|
|
790
|
+
chainId,
|
|
791
|
+
currency: subscriptionCurrency,
|
|
792
|
+
getClient: async () => client,
|
|
793
|
+
periodCount: subscriptionPeriodCount,
|
|
794
|
+
periodUnit: subscriptionPeriodUnit,
|
|
795
|
+
recipient: subscriptionRecipient,
|
|
796
|
+
resolve: async () => ({ key: subscriptionKey }),
|
|
797
|
+
store,
|
|
798
|
+
subscriptionExpires: activeSubscriptionExpires,
|
|
799
|
+
})
|
|
800
|
+
const mppx = Mppx.create({ methods: [method], realm, secretKey })
|
|
801
|
+
const challengeResult = await mppx.tempo.subscription({})(
|
|
802
|
+
new Request('https://example.com/resource'),
|
|
803
|
+
)
|
|
804
|
+
if (challengeResult.status !== 402) throw new Error('expected activation challenge')
|
|
805
|
+
const challenge = Challenge.fromResponse(challengeResult.challenge)
|
|
806
|
+
const generatedAccessKey = (
|
|
807
|
+
challenge.request as ReturnType<typeof Methods.subscription.schema.request.parse>
|
|
808
|
+
).methodDetails?.accessKey
|
|
809
|
+
if (!generatedAccessKey) throw new Error('expected generated access key')
|
|
810
|
+
const credential = await createCredential(challenge, rootAccount.address, generatedAccessKey)
|
|
811
|
+
const activated = await mppx.tempo.subscription({})(
|
|
812
|
+
new Request('https://example.com/resource', {
|
|
813
|
+
headers: { Authorization: Credential.serialize(credential) },
|
|
814
|
+
}),
|
|
815
|
+
)
|
|
816
|
+
|
|
817
|
+
expect(activated.status).toBe(402)
|
|
818
|
+
// A held activation must not persist an active subscription.
|
|
819
|
+
expect(await subscriptions.getByKey(subscriptionKey)).toBeNull()
|
|
820
|
+
})
|
|
821
|
+
|
|
360
822
|
test('returns a management response while renewal is already in flight', async () => {
|
|
361
823
|
const store = Store.memory()
|
|
362
824
|
const subscriptions = SubscriptionStore.fromStore(store)
|