mppx 0.8.14 → 0.8.17
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 +57 -0
- package/dist/Challenge.d.ts.map +1 -1
- package/dist/Challenge.js +40 -35
- package/dist/Challenge.js.map +1 -1
- package/dist/Constants.d.ts +17 -17
- package/dist/Constants.d.ts.map +1 -1
- package/dist/Credential.d.ts.map +1 -1
- package/dist/Errors.d.ts +3 -3
- package/dist/Errors.d.ts.map +1 -1
- package/dist/Errors.js.map +1 -1
- package/dist/Method.d.ts +35 -5
- package/dist/Method.d.ts.map +1 -1
- package/dist/Method.js +7 -22
- package/dist/Method.js.map +1 -1
- package/dist/Store.d.ts +19 -0
- package/dist/Store.d.ts.map +1 -1
- package/dist/Store.js +43 -0
- package/dist/Store.js.map +1 -1
- package/dist/attestation/Client.d.ts +17 -0
- package/dist/attestation/Client.d.ts.map +1 -0
- package/dist/attestation/Client.js +28 -0
- package/dist/attestation/Client.js.map +1 -0
- package/dist/attestation/Constants.d.ts +15 -0
- package/dist/attestation/Constants.d.ts.map +1 -0
- package/dist/attestation/Constants.js +15 -0
- package/dist/attestation/Constants.js.map +1 -0
- package/dist/attestation/Server.d.ts +4 -0
- package/dist/attestation/Server.d.ts.map +1 -0
- package/dist/attestation/Server.js +8 -0
- package/dist/attestation/Server.js.map +1 -0
- package/dist/attestation/Types.d.ts +76 -0
- package/dist/attestation/Types.d.ts.map +1 -0
- package/dist/attestation/Types.js +2 -0
- package/dist/attestation/Types.js.map +1 -0
- package/dist/attestation/index.d.ts +6 -0
- package/dist/attestation/index.d.ts.map +1 -0
- package/dist/attestation/index.js +6 -0
- package/dist/attestation/index.js.map +1 -0
- package/dist/attestation/internal/HttpMessageSignature.d.ts +73 -0
- package/dist/attestation/internal/HttpMessageSignature.d.ts.map +1 -0
- package/dist/attestation/internal/HttpMessageSignature.js +320 -0
- package/dist/attestation/internal/HttpMessageSignature.js.map +1 -0
- package/dist/attestation/internal/SigningContext.d.ts +4 -0
- package/dist/attestation/internal/SigningContext.d.ts.map +1 -0
- package/dist/attestation/internal/SigningContext.js +11 -0
- package/dist/attestation/internal/SigningContext.js.map +1 -0
- package/dist/cli/account.d.ts +14 -14
- package/dist/cli/account.d.ts.map +1 -1
- package/dist/cli/cli.d.ts +6 -6
- package/dist/cli/cli.d.ts.map +1 -1
- package/dist/cli/cli.js +1 -0
- package/dist/cli/cli.js.map +1 -1
- package/dist/cli/plugins/tempo.js.map +1 -1
- package/dist/cli/sessions/commands.d.ts +4 -4
- package/dist/cli/sessions/commands.d.ts.map +1 -1
- package/dist/cli/sessions/commands.js.map +1 -1
- package/dist/cli/sessions/store.d.ts.map +1 -1
- package/dist/cli/sessions/store.js.map +1 -1
- package/dist/cli/utils.d.ts +1 -1
- package/dist/cli/utils.d.ts.map +1 -1
- package/dist/cli/utils.js.map +1 -1
- package/dist/cli/validate/discovery.js.map +1 -1
- package/dist/cli/validate/index.d.ts +3 -3
- package/dist/cli/validate/index.d.ts.map +1 -1
- package/dist/cli/validate/payment.d.ts.map +1 -1
- package/dist/cli/validate/payment.js +18 -4
- package/dist/cli/validate/payment.js.map +1 -1
- package/dist/client/Mppx.d.ts +3 -0
- package/dist/client/Mppx.d.ts.map +1 -1
- package/dist/client/Mppx.js +13 -5
- package/dist/client/Mppx.js.map +1 -1
- package/dist/client/Transport.d.ts +3 -5
- package/dist/client/Transport.d.ts.map +1 -1
- package/dist/client/Transport.js +1 -17
- package/dist/client/Transport.js.map +1 -1
- package/dist/client/internal/Fetch.d.ts.map +1 -1
- package/dist/client/internal/Fetch.js +92 -13
- package/dist/client/internal/Fetch.js.map +1 -1
- package/dist/client/internal/MethodChallenge.d.ts +2 -0
- package/dist/client/internal/MethodChallenge.d.ts.map +1 -1
- package/dist/client/internal/MethodChallenge.js +4 -0
- package/dist/client/internal/MethodChallenge.js.map +1 -1
- package/dist/client/internal/MethodResponse.d.ts +15 -0
- package/dist/client/internal/MethodResponse.d.ts.map +1 -1
- package/dist/client/internal/MethodResponse.js +10 -0
- package/dist/client/internal/MethodResponse.js.map +1 -1
- package/dist/client/node.js.map +1 -1
- package/dist/discovery/OpenApi.d.ts +3 -5
- package/dist/discovery/OpenApi.d.ts.map +1 -1
- package/dist/discovery/OpenApi.js +13 -34
- package/dist/discovery/OpenApi.js.map +1 -1
- package/dist/discovery/internal/Metadata.d.ts +20 -0
- package/dist/discovery/internal/Metadata.d.ts.map +1 -0
- package/dist/discovery/internal/Metadata.js +36 -0
- package/dist/discovery/internal/Metadata.js.map +1 -0
- package/dist/evm/Methods.d.ts +11 -11
- package/dist/evm/Methods.d.ts.map +1 -1
- package/dist/evm/Types.d.ts +17 -17
- package/dist/evm/Types.d.ts.map +1 -1
- package/dist/evm/client/Charge.d.ts +11 -11
- package/dist/evm/client/Methods.d.ts +11 -11
- package/dist/evm/server/Charge.d.ts +1 -1
- package/dist/evm/server/Charge.d.ts.map +1 -1
- package/dist/evm/server/Charge.js +2 -0
- package/dist/evm/server/Charge.js.map +1 -1
- package/dist/evm/server/Methods.d.ts +11 -11
- package/dist/internal/HeaderCodec.d.ts +2 -2
- package/dist/internal/HeaderCodec.d.ts.map +1 -1
- package/dist/internal/types.d.ts +6 -0
- package/dist/internal/types.d.ts.map +1 -1
- package/dist/middlewares/elysia.js.map +1 -1
- package/dist/middlewares/express.js.map +1 -1
- package/dist/middlewares/hono.js.map +1 -1
- package/dist/middlewares/nextjs.js.map +1 -1
- package/dist/proxy/Proxy.d.ts +2 -0
- package/dist/proxy/Proxy.d.ts.map +1 -1
- package/dist/proxy/Proxy.js +117 -9
- package/dist/proxy/Proxy.js.map +1 -1
- package/dist/proxy/Service.d.ts +36 -1
- package/dist/proxy/Service.d.ts.map +1 -1
- package/dist/proxy/Service.js +9 -8
- package/dist/proxy/Service.js.map +1 -1
- package/dist/proxy/services/anthropic.d.ts.map +1 -1
- package/dist/proxy/services/anthropic.js +1 -0
- package/dist/proxy/services/anthropic.js.map +1 -1
- package/dist/proxy/services/openai.d.ts.map +1 -1
- package/dist/proxy/services/openai.js +1 -0
- package/dist/proxy/services/openai.js.map +1 -1
- package/dist/proxy/services/stripe.d.ts.map +1 -1
- package/dist/proxy/services/stripe.js +1 -0
- package/dist/proxy/services/stripe.js.map +1 -1
- package/dist/server/Mppx.d.ts +75 -13
- package/dist/server/Mppx.d.ts.map +1 -1
- package/dist/server/Mppx.js +201 -23
- package/dist/server/Mppx.js.map +1 -1
- package/dist/server/internal/html/config.d.ts +9 -9
- package/dist/server/internal/html/config.d.ts.map +1 -1
- package/dist/server/internal/html/constants.d.ts +17 -17
- package/dist/server/internal/html/constants.d.ts.map +1 -1
- package/dist/stripe/Methods.d.ts +10 -10
- package/dist/stripe/Methods.d.ts.map +1 -1
- package/dist/stripe/client/Charge.d.ts +10 -10
- package/dist/stripe/client/Methods.d.ts +10 -10
- package/dist/stripe/internal/constants.d.ts +1 -1
- package/dist/stripe/internal/constants.js +1 -1
- package/dist/stripe/internal/types.d.ts +1 -0
- package/dist/stripe/internal/types.d.ts.map +1 -1
- package/dist/stripe/server/Charge.d.ts +11 -11
- package/dist/stripe/server/Charge.d.ts.map +1 -1
- package/dist/stripe/server/Charge.js +49 -1
- package/dist/stripe/server/Charge.js.map +1 -1
- package/dist/stripe/server/Methods.d.ts +137 -48
- package/dist/stripe/server/Methods.d.ts.map +1 -1
- package/dist/stripe/server/Methods.js +259 -4
- package/dist/stripe/server/Methods.js.map +1 -1
- package/dist/stripe/server/internal/deposit-address.d.ts +13 -0
- package/dist/stripe/server/internal/deposit-address.d.ts.map +1 -0
- package/dist/stripe/server/internal/deposit-address.js +28 -0
- package/dist/stripe/server/internal/deposit-address.js.map +1 -0
- 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/stripe/server/internal/record-payment.d.ts +15 -0
- package/dist/stripe/server/internal/record-payment.d.ts.map +1 -0
- package/dist/stripe/server/internal/record-payment.js +42 -0
- package/dist/stripe/server/internal/record-payment.js.map +1 -0
- package/dist/stripe/server/internal/request.d.ts +25 -0
- package/dist/stripe/server/internal/request.d.ts.map +1 -0
- package/dist/stripe/server/internal/request.js +29 -0
- package/dist/stripe/server/internal/request.js.map +1 -0
- package/dist/tap/Constants.d.ts +28 -0
- package/dist/tap/Constants.d.ts.map +1 -0
- package/dist/tap/Constants.js +32 -0
- package/dist/tap/Constants.js.map +1 -0
- package/dist/tap/Types.d.ts +11 -0
- package/dist/tap/Types.d.ts.map +1 -0
- package/dist/tap/Types.js +2 -0
- package/dist/tap/Types.js.map +1 -0
- package/dist/tap/client/index.d.ts +26 -0
- package/dist/tap/client/index.d.ts.map +1 -0
- package/dist/tap/client/index.js +33 -0
- package/dist/tap/client/index.js.map +1 -0
- package/dist/tap/index.d.ts +5 -0
- package/dist/tap/index.d.ts.map +1 -0
- package/dist/tap/index.js +5 -0
- package/dist/tap/index.js.map +1 -0
- package/dist/tap/server/index.d.ts +20 -0
- package/dist/tap/server/index.d.ts.map +1 -0
- package/dist/tap/server/index.js +36 -0
- package/dist/tap/server/index.js.map +1 -0
- package/dist/tempo/Attribution.d.ts +1 -1
- package/dist/tempo/Methods.d.ts +60 -60
- package/dist/tempo/Methods.d.ts.map +1 -1
- package/dist/tempo/Proof.d.ts +16 -16
- package/dist/tempo/client/Charge.d.ts +19 -19
- package/dist/tempo/client/Charge.d.ts.map +1 -1
- package/dist/tempo/client/Charge.js +1 -7
- package/dist/tempo/client/Charge.js.map +1 -1
- package/dist/tempo/client/Methods.d.ts +38 -38
- package/dist/tempo/client/Methods.js.map +1 -1
- package/dist/tempo/client/Subscription.d.ts +23 -23
- package/dist/tempo/client/Subscription.js.map +1 -1
- package/dist/tempo/internal/address.d.ts +2 -1
- package/dist/tempo/internal/address.d.ts.map +1 -1
- package/dist/tempo/internal/address.js +3 -1
- package/dist/tempo/internal/address.js.map +1 -1
- package/dist/tempo/internal/auto-swap.d.ts.map +1 -1
- package/dist/tempo/internal/auto-swap.js +4 -19
- package/dist/tempo/internal/auto-swap.js.map +1 -1
- package/dist/tempo/internal/defaults.d.ts +6 -6
- package/dist/tempo/internal/defaults.d.ts.map +1 -1
- package/dist/tempo/internal/fee-payer.d.ts +12 -12
- package/dist/tempo/internal/fee-payer.d.ts.map +1 -1
- package/dist/tempo/internal/fee-payer.js.map +1 -1
- package/dist/tempo/internal/proof.d.ts +17 -17
- package/dist/tempo/internal/proof.d.ts.map +1 -1
- package/dist/tempo/legacy/client/Session.d.ts +20 -20
- package/dist/tempo/legacy/client/Session.js.map +1 -1
- package/dist/tempo/legacy/client/SessionManager.js.map +1 -1
- package/dist/tempo/legacy/index.d.ts +1 -3
- package/dist/tempo/legacy/index.d.ts.map +1 -1
- package/dist/tempo/legacy/index.js +1 -3
- package/dist/tempo/legacy/index.js.map +1 -1
- package/dist/tempo/legacy/session/escrow.abi.d.ts +374 -374
- package/dist/tempo/legacy/session/escrow.abi.d.ts.map +1 -1
- package/dist/tempo/server/Charge.d.ts +34 -12
- package/dist/tempo/server/Charge.d.ts.map +1 -1
- package/dist/tempo/server/Charge.js +44 -39
- package/dist/tempo/server/Charge.js.map +1 -1
- package/dist/tempo/server/Methods.d.ts +37 -52
- package/dist/tempo/server/Methods.d.ts.map +1 -1
- package/dist/tempo/server/Methods.js +0 -14
- package/dist/tempo/server/Methods.js.map +1 -1
- package/dist/tempo/server/Relay.d.ts +14 -5
- package/dist/tempo/server/Relay.d.ts.map +1 -1
- package/dist/tempo/server/Relay.js +6 -4
- package/dist/tempo/server/Relay.js.map +1 -1
- package/dist/tempo/server/SponsorBudget.d.ts.map +1 -1
- package/dist/tempo/server/SponsorBudget.js +7 -1
- package/dist/tempo/server/SponsorBudget.js.map +1 -1
- package/dist/tempo/server/Subscription.d.ts +25 -25
- package/dist/tempo/server/Subscription.d.ts.map +1 -1
- package/dist/tempo/server/Subscription.js +2 -0
- package/dist/tempo/server/Subscription.js.map +1 -1
- package/dist/tempo/server/index.d.ts +1 -1
- package/dist/tempo/server/index.d.ts.map +1 -1
- package/dist/tempo/server/index.js +1 -1
- 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/transport.d.ts +2 -0
- package/dist/tempo/server/internal/transport.d.ts.map +1 -1
- package/dist/tempo/server/internal/transport.js +9 -2
- package/dist/tempo/server/internal/transport.js.map +1 -1
- package/dist/tempo/session/client/ChannelOps.js.map +1 -1
- package/dist/tempo/session/client/CredentialState.d.ts +1 -1
- package/dist/tempo/session/client/CredentialState.js.map +1 -1
- package/dist/tempo/session/client/ReceiptCoordinator.js.map +1 -1
- package/dist/tempo/session/client/Runtime.js.map +1 -1
- package/dist/tempo/session/client/Session.d.ts +19 -19
- package/dist/tempo/session/client/Session.d.ts.map +1 -1
- package/dist/tempo/session/client/Session.js +128 -14
- package/dist/tempo/session/client/Session.js.map +1 -1
- package/dist/tempo/session/client/SessionManager.d.ts.map +1 -1
- package/dist/tempo/session/client/SessionManager.js +62 -20
- package/dist/tempo/session/client/SessionManager.js.map +1 -1
- package/dist/tempo/session/client/Transports.d.ts +9 -1
- package/dist/tempo/session/client/Transports.d.ts.map +1 -1
- package/dist/tempo/session/client/Transports.js +36 -13
- package/dist/tempo/session/client/Transports.js.map +1 -1
- package/dist/tempo/session/precompile/Chain.d.ts +27 -0
- package/dist/tempo/session/precompile/Chain.d.ts.map +1 -1
- package/dist/tempo/session/precompile/Chain.js +68 -7
- package/dist/tempo/session/precompile/Chain.js.map +1 -1
- package/dist/tempo/session/precompile/Protocol.js.map +1 -1
- package/dist/tempo/session/precompile/Voucher.d.ts +4 -4
- package/dist/tempo/session/precompile/Voucher.d.ts.map +1 -1
- package/dist/tempo/session/precompile/escrow.abi.d.ts +306 -306
- package/dist/tempo/session/precompile/escrow.abi.d.ts.map +1 -1
- package/dist/tempo/session/server/ChannelStore.d.ts +9 -0
- package/dist/tempo/session/server/ChannelStore.d.ts.map +1 -1
- package/dist/tempo/session/server/ChannelStore.js +16 -8
- package/dist/tempo/session/server/ChannelStore.js.map +1 -1
- package/dist/tempo/session/server/CredentialVerification.d.ts +30 -13
- package/dist/tempo/session/server/CredentialVerification.d.ts.map +1 -1
- package/dist/tempo/session/server/CredentialVerification.js +207 -13
- package/dist/tempo/session/server/CredentialVerification.js.map +1 -1
- package/dist/tempo/session/server/MeteredStream.d.ts +3 -0
- package/dist/tempo/session/server/MeteredStream.d.ts.map +1 -1
- package/dist/tempo/session/server/MeteredStream.js +3 -1
- package/dist/tempo/session/server/MeteredStream.js.map +1 -1
- package/dist/tempo/session/server/Session.d.ts +32 -21
- package/dist/tempo/session/server/Session.d.ts.map +1 -1
- package/dist/tempo/session/server/Session.js +116 -53
- package/dist/tempo/session/server/Session.js.map +1 -1
- package/dist/tempo/session/server/Sse.d.ts +3 -1
- package/dist/tempo/session/server/Sse.d.ts.map +1 -1
- package/dist/tempo/session/server/Sse.js +2 -1
- package/dist/tempo/session/server/Sse.js.map +1 -1
- package/dist/tempo/session/server/Transports.d.ts +1 -1
- package/dist/tempo/session/server/Transports.d.ts.map +1 -1
- package/dist/tempo/session/server/Transports.js +1 -0
- package/dist/tempo/session/server/Transports.js.map +1 -1
- package/dist/tempo/session/server/Ws.d.ts +6 -1
- package/dist/tempo/session/server/Ws.d.ts.map +1 -1
- package/dist/tempo/session/server/Ws.js +4 -0
- package/dist/tempo/session/server/Ws.js.map +1 -1
- package/dist/tempo/subscription/KeyAuthorization.d.ts +38 -866
- package/dist/tempo/subscription/KeyAuthorization.d.ts.map +1 -1
- package/dist/tempo/subscription/KeyAuthorization.js +14 -3
- package/dist/tempo/subscription/KeyAuthorization.js.map +1 -1
- package/dist/viem/Account.d.ts.map +1 -1
- package/dist/viem/Account.js.map +1 -1
- package/dist/viem/Client.d.ts.map +1 -1
- package/dist/viem/Client.js +6 -1
- package/dist/viem/Client.js.map +1 -1
- package/dist/web-bot-auth/Constants.d.ts +20 -0
- package/dist/web-bot-auth/Constants.d.ts.map +1 -0
- package/dist/web-bot-auth/Constants.js +24 -0
- package/dist/web-bot-auth/Constants.js.map +1 -0
- package/dist/web-bot-auth/Types.d.ts +10 -0
- package/dist/web-bot-auth/Types.d.ts.map +1 -0
- package/dist/web-bot-auth/Types.js +2 -0
- package/dist/web-bot-auth/Types.js.map +1 -0
- package/dist/web-bot-auth/client/index.d.ts +29 -0
- package/dist/web-bot-auth/client/index.d.ts.map +1 -0
- package/dist/web-bot-auth/client/index.js +64 -0
- package/dist/web-bot-auth/client/index.js.map +1 -0
- package/dist/web-bot-auth/index.d.ts +7 -0
- package/dist/web-bot-auth/index.d.ts.map +1 -0
- package/dist/web-bot-auth/index.js +7 -0
- package/dist/web-bot-auth/index.js.map +1 -0
- package/dist/web-bot-auth/internal/JwkThumbprint.d.ts +5 -0
- package/dist/web-bot-auth/internal/JwkThumbprint.d.ts.map +1 -0
- package/dist/web-bot-auth/internal/JwkThumbprint.js +20 -0
- package/dist/web-bot-auth/internal/JwkThumbprint.js.map +1 -0
- package/dist/web-bot-auth/internal/SignatureAgent.d.ts +3 -0
- package/dist/web-bot-auth/internal/SignatureAgent.d.ts.map +1 -0
- package/dist/web-bot-auth/internal/SignatureAgent.js +18 -0
- package/dist/web-bot-auth/internal/SignatureAgent.js.map +1 -0
- package/dist/web-bot-auth/server/index.d.ts +35 -0
- package/dist/web-bot-auth/server/index.d.ts.map +1 -0
- package/dist/web-bot-auth/server/index.js +88 -0
- package/dist/web-bot-auth/server/index.js.map +1 -0
- package/dist/x402/Assets.d.ts.map +1 -1
- package/dist/x402/Types.d.ts +6 -6
- package/dist/x402/Types.d.ts.map +1 -1
- package/dist/x402/server/EvmCharge.d.ts.map +1 -1
- package/dist/x402/server/EvmCharge.js +32 -20
- package/dist/x402/server/EvmCharge.js.map +1 -1
- package/package.json +20 -4
- package/src/Challenge.fuzz.test.ts +80 -47
- package/src/Challenge.test.ts +65 -0
- package/src/Challenge.ts +39 -35
- package/src/Method.ts +82 -68
- package/src/Store.test-d.ts +16 -0
- package/src/Store.test.ts +50 -0
- package/src/Store.ts +68 -0
- package/src/attestation/Attestation.integration.test.ts +208 -0
- package/src/attestation/Client.test.ts +83 -0
- package/src/attestation/Client.ts +34 -0
- package/src/attestation/Constants.ts +15 -0
- package/src/attestation/Server.test.ts +60 -0
- package/src/attestation/Server.ts +12 -0
- package/src/attestation/Types.test-d.ts +54 -0
- package/src/attestation/Types.ts +77 -0
- package/src/attestation/index.ts +5 -0
- package/src/attestation/internal/HttpMessageSignature.test.ts +101 -0
- package/src/attestation/internal/HttpMessageSignature.ts +429 -0
- package/src/attestation/internal/SigningContext.ts +13 -0
- package/src/bin.js +2 -0
- package/src/cli/cli.ts +1 -0
- package/src/cli/validate/payment.ts +18 -4
- package/src/cli/validate.test.ts +16 -0
- package/src/client/Mppx.test-d.ts +17 -0
- package/src/client/Mppx.test.ts +14 -14
- package/src/client/Mppx.ts +25 -4
- package/src/client/Transport.test.ts +12 -45
- package/src/client/Transport.ts +3 -24
- package/src/client/internal/Fetch.test.ts +77 -0
- package/src/client/internal/Fetch.ts +112 -14
- package/src/client/internal/MethodChallenge.ts +5 -0
- package/src/client/internal/MethodResponse.ts +28 -0
- package/src/discovery/OpenApi.test.ts +170 -0
- package/src/discovery/OpenApi.ts +16 -48
- package/src/discovery/internal/Metadata.ts +51 -0
- package/src/evm/server/Charge.ts +6 -1
- package/src/internal/AcceptPayment.test.ts +12 -8
- package/src/internal/types.ts +9 -0
- package/src/mcp/client/McpClient.integration.test.ts +19 -32
- package/src/middlewares/elysia.test.ts +2 -12
- package/src/middlewares/express.test.ts +2 -12
- package/src/middlewares/hono.test.ts +6 -9
- package/src/middlewares/nextjs.test.ts +2 -12
- package/src/proxy/Proxy.test.ts +26 -19
- package/src/proxy/Proxy.ts +147 -9
- package/src/proxy/Proxy.upstreamError.test.ts +364 -0
- package/src/proxy/Service.test.ts +73 -3
- package/src/proxy/Service.ts +50 -23
- package/src/proxy/services/anthropic.ts +1 -0
- package/src/proxy/services/hooks.test-d.ts +14 -0
- package/src/proxy/services/hooks.test.ts +44 -0
- package/src/proxy/services/openai.ts +1 -0
- package/src/proxy/services/stripe.ts +1 -0
- package/src/server/Methods.test-d.ts +88 -0
- package/src/server/Methods.test.ts +69 -0
- package/src/server/Mppx.test-d.ts +141 -7
- package/src/server/Mppx.test.ts +1017 -119
- package/src/server/Mppx.ts +350 -54
- package/src/stripe/internal/constants.ts +1 -1
- package/src/stripe/internal/types.ts +1 -0
- package/src/stripe/server/Charge.test-d.ts +16 -1
- package/src/stripe/server/Charge.test.ts +79 -0
- package/src/stripe/server/Charge.ts +54 -1
- package/src/stripe/server/Methods.test-d.ts +157 -0
- package/src/stripe/server/Methods.test.ts +403 -0
- package/src/stripe/server/Methods.ts +423 -6
- package/src/stripe/server/internal/deposit-address.ts +57 -0
- package/src/stripe/server/internal/html/node_modules/.bin/mppx +3 -3
- package/src/stripe/server/internal/html/package.json +1 -1
- package/src/stripe/server/internal/html.gen.ts +1 -1
- package/src/stripe/server/internal/record-payment.ts +66 -0
- package/src/stripe/server/internal/request.ts +49 -0
- package/src/tap/Constants.ts +32 -0
- package/src/tap/Tap.test.ts +125 -0
- package/src/tap/Types.ts +11 -0
- package/src/tap/client/index.ts +54 -0
- package/src/tap/index.ts +4 -0
- package/src/tap/server/index.ts +48 -0
- package/src/tempo/PublicExports.test-d.ts +3 -3
- package/src/tempo/client/Charge.ts +1 -19
- package/src/tempo/internal/address.test.ts +42 -0
- package/src/tempo/internal/address.ts +3 -3
- package/src/tempo/internal/auto-swap.test.ts +4 -4
- package/src/tempo/internal/auto-swap.ts +7 -50
- package/src/tempo/legacy/README.md +5 -5
- package/src/tempo/legacy/index.ts +1 -3
- package/src/tempo/server/AtomicStore.test-d.ts +13 -0
- package/src/tempo/server/Charge.test.ts +19 -84
- package/src/tempo/server/Charge.ts +92 -56
- package/src/tempo/server/Methods.ts +0 -20
- package/src/tempo/server/Relay.test.ts +161 -7
- package/src/tempo/server/Relay.ts +15 -6
- package/src/tempo/server/SponsorBudget.test.ts +29 -0
- package/src/tempo/server/SponsorBudget.ts +7 -1
- package/src/tempo/server/Subscription.ts +4 -1
- package/src/tempo/server/index.ts +1 -1
- package/src/tempo/server/internal/html/node_modules/.bin/mppx +3 -3
- package/src/tempo/server/internal/html/package.json +1 -1
- package/src/tempo/server/internal/html.gen.ts +1 -1
- package/src/tempo/server/internal/transport.test.ts +22 -3
- package/src/tempo/server/internal/transport.ts +15 -3
- package/src/tempo/session/README.md +119 -0
- package/src/tempo/session/client/Session.test.ts +299 -33
- package/src/tempo/session/client/Session.ts +152 -16
- package/src/tempo/session/client/SessionManager.test.ts +216 -9
- package/src/tempo/session/client/SessionManager.ts +63 -17
- package/src/tempo/session/client/Transports.test.ts +22 -0
- package/src/tempo/session/client/Transports.ts +58 -22
- package/src/tempo/session/precompile/Chain.ts +131 -11
- package/src/tempo/session/server/ChannelStore.ts +33 -12
- package/src/tempo/session/server/CredentialVerification.test.ts +4 -4
- package/src/tempo/session/server/CredentialVerification.ts +340 -28
- package/src/tempo/session/server/MeteredStream.ts +5 -1
- package/src/tempo/session/server/Session.test.ts +483 -36
- package/src/tempo/session/server/Session.ts +159 -60
- package/src/tempo/session/server/Sse.test.ts +77 -0
- package/src/tempo/session/server/Sse.ts +8 -1
- package/src/tempo/session/server/Transports.ts +2 -1
- package/src/tempo/session/server/Ws.test.ts +171 -0
- package/src/tempo/session/server/Ws.ts +10 -1
- package/src/tempo/subscription/KeyAuthorization.test.ts +70 -1
- package/src/tempo/subscription/KeyAuthorization.ts +14 -3
- package/src/viem/Client.test.ts +18 -1
- package/src/viem/Client.ts +7 -1
- package/src/web-bot-auth/Constants.ts +24 -0
- package/src/web-bot-auth/Types.ts +9 -0
- package/src/web-bot-auth/WebBotAuth.test.ts +182 -0
- package/src/web-bot-auth/client/index.ts +84 -0
- package/src/web-bot-auth/index.ts +6 -0
- package/src/web-bot-auth/internal/JwkThumbprint.ts +21 -0
- package/src/web-bot-auth/internal/SignatureAgent.ts +18 -0
- package/src/web-bot-auth/server/index.ts +113 -0
- package/src/x402/Exact.e2e.test.ts +121 -81
- package/src/x402/Exact.localnet.test.ts +1 -1
- package/src/x402/server/EvmCharge.ts +35 -19
- package/dist/tempo/legacy/server/Session.d.ts +0 -208
- package/dist/tempo/legacy/server/Session.d.ts.map +0 -1
- package/dist/tempo/legacy/server/Session.js +0 -698
- package/dist/tempo/legacy/server/Session.js.map +0 -1
- package/dist/tempo/legacy/server/index.d.ts +0 -5
- package/dist/tempo/legacy/server/index.d.ts.map +0 -1
- package/dist/tempo/legacy/server/index.js +0 -5
- package/dist/tempo/legacy/server/index.js.map +0 -1
- package/dist/tempo/legacy/session/ChannelStore.d.ts +0 -22
- package/dist/tempo/legacy/session/ChannelStore.d.ts.map +0 -1
- package/dist/tempo/legacy/session/ChannelStore.js +0 -6
- package/dist/tempo/legacy/session/ChannelStore.js.map +0 -1
- package/src/tempo/legacy/server/Defaults.test-d.ts +0 -9
- package/src/tempo/legacy/server/Session.test.ts +0 -6370
- package/src/tempo/legacy/server/Session.ts +0 -1024
- package/src/tempo/legacy/server/index.ts +0 -4
- package/src/tempo/legacy/session/ChannelStore.test.ts +0 -58
- package/src/tempo/legacy/session/ChannelStore.ts +0 -39
|
@@ -4,6 +4,8 @@ import { serve } from '@hono/node-server'
|
|
|
4
4
|
import { Hono } from 'hono'
|
|
5
5
|
import { Challenge, Constants, Credential } from 'mppx'
|
|
6
6
|
import { Mppx as Mppx_server, tempo as tempo_server } from 'mppx/server'
|
|
7
|
+
import { Secp256k1 } from 'ox'
|
|
8
|
+
import { TxEnvelopeTempo } from 'ox/tempo'
|
|
7
9
|
import {
|
|
8
10
|
type Address,
|
|
9
11
|
createClient,
|
|
@@ -14,6 +16,7 @@ import {
|
|
|
14
16
|
encodeFunctionData,
|
|
15
17
|
encodeFunctionResult,
|
|
16
18
|
type Hex,
|
|
19
|
+
maxUint256,
|
|
17
20
|
zeroAddress,
|
|
18
21
|
} from 'viem'
|
|
19
22
|
import { privateKeyToAccount } from 'viem/accounts'
|
|
@@ -40,9 +43,8 @@ import * as ChannelStore from './ChannelStore.js'
|
|
|
40
43
|
import { charge, session, type ResolveSessionChannelId } from './Session.js'
|
|
41
44
|
import * as TempoWs from './Ws.js'
|
|
42
45
|
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
)
|
|
46
|
+
const payerPrivateKey = '0xac0974bec39a17e36ba6a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'
|
|
47
|
+
const payer = privateKeyToAccount(payerPrivateKey)
|
|
46
48
|
const wrongPayer = privateKeyToAccount(
|
|
47
49
|
'0x59c6995e998f97a5a0044966f094538a009d74290f5811cfba6a6b4d238ff944',
|
|
48
50
|
)
|
|
@@ -88,10 +90,16 @@ function createServerClient(
|
|
|
88
90
|
_eventChannelId: Hex = `0x${'00'.repeat(32)}` as Hex,
|
|
89
91
|
options: {
|
|
90
92
|
descriptor?: Channel.ChannelDescriptor
|
|
91
|
-
receipt?:
|
|
92
|
-
|
|
93
|
+
receipt?:
|
|
94
|
+
| Record<string, unknown>
|
|
95
|
+
| (() => Record<string, unknown> | Promise<Record<string, unknown>>)
|
|
96
|
+
sentReceipt?:
|
|
97
|
+
| Record<string, unknown>
|
|
98
|
+
| (() => Record<string, unknown> | Promise<Record<string, unknown>>)
|
|
99
|
+
state?: ChainState | (() => ChainState | Promise<ChainState>)
|
|
93
100
|
} = {},
|
|
94
101
|
) {
|
|
102
|
+
let sentTransaction = false
|
|
95
103
|
return createClient({
|
|
96
104
|
...(account ? { account } : {}),
|
|
97
105
|
chain: testChain,
|
|
@@ -103,11 +111,24 @@ function createServerClient(
|
|
|
103
111
|
if (args.method === 'eth_estimateGas') return '0x5208'
|
|
104
112
|
if (args.method === 'eth_maxPriorityFeePerGas') return '0x1'
|
|
105
113
|
if (args.method === 'eth_getBlockByNumber') return { baseFeePerGas: '0x1' }
|
|
106
|
-
if (args.method === 'eth_sendRawTransaction')
|
|
107
|
-
|
|
108
|
-
|
|
114
|
+
if (args.method === 'eth_sendRawTransaction') {
|
|
115
|
+
sentTransaction = true
|
|
116
|
+
return `0x${'aa'.repeat(32)}`
|
|
117
|
+
}
|
|
118
|
+
if (args.method === 'eth_getTransactionReceipt') {
|
|
119
|
+
const receipt = sentTransaction
|
|
120
|
+
? (options.sentReceipt ?? options.receipt)
|
|
121
|
+
: options.receipt
|
|
122
|
+
return typeof receipt === 'function' ? receipt() : (receipt ?? null)
|
|
123
|
+
}
|
|
124
|
+
if (args.method === 'eth_sendTransaction') {
|
|
125
|
+
sentTransaction = true
|
|
126
|
+
return `0x${'bb'.repeat(32)}`
|
|
127
|
+
}
|
|
109
128
|
if (args.method === 'eth_call') {
|
|
110
|
-
const
|
|
129
|
+
const configuredState =
|
|
130
|
+
typeof options.state === 'function' ? await options.state() : options.state
|
|
131
|
+
const state = configuredState ?? { settled: 100n, deposit: 1_000n, closeRequestedAt: 0 }
|
|
111
132
|
const data = (args.params as [{ data?: Hex }])[0].data
|
|
112
133
|
const getChannelSelector = options.descriptor
|
|
113
134
|
? encodeFunctionData({
|
|
@@ -315,6 +336,52 @@ async function createOpenPayload(
|
|
|
315
336
|
}
|
|
316
337
|
}
|
|
317
338
|
|
|
339
|
+
function sponsorTransaction(
|
|
340
|
+
serializedTransaction: Hex,
|
|
341
|
+
options: { gas?: bigint | undefined } = {},
|
|
342
|
+
): Hex {
|
|
343
|
+
const transaction = Transaction.deserialize(
|
|
344
|
+
serializedTransaction as Transaction.TransactionSerializedTempo,
|
|
345
|
+
)
|
|
346
|
+
const envelope = TxEnvelopeTempo.from({
|
|
347
|
+
...transaction,
|
|
348
|
+
feePayerSignature: null,
|
|
349
|
+
gas: options.gas ?? 100_000n,
|
|
350
|
+
maxFeePerGas: 1n,
|
|
351
|
+
maxPriorityFeePerGas: 1n,
|
|
352
|
+
nonceKey: maxUint256,
|
|
353
|
+
validBefore: Math.floor(Date.now() / 1_000) + 600,
|
|
354
|
+
} as never)
|
|
355
|
+
return TxEnvelopeTempo.serialize(envelope, {
|
|
356
|
+
signature: Secp256k1.sign({
|
|
357
|
+
payload: TxEnvelopeTempo.getSignPayload(envelope),
|
|
358
|
+
privateKey: payerPrivateKey,
|
|
359
|
+
}),
|
|
360
|
+
}) as Hex
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
async function createSponsoredOpenPayload(): Promise<
|
|
364
|
+
Extract<SessionCredentialPayload, { action: 'open' }>
|
|
365
|
+
> {
|
|
366
|
+
const payload = await createOpenPayload()
|
|
367
|
+
const transaction = sponsorTransaction(payload.transaction)
|
|
368
|
+
const signed = Transaction.deserialize(transaction as Transaction.TransactionSerializedTempo)
|
|
369
|
+
const expiringNonceHash = Channel.computeExpiringNonceHash(
|
|
370
|
+
Channel.transactionForExpiringNonceHash({ feePayer: true, transaction: signed }),
|
|
371
|
+
{ sender: payer.address },
|
|
372
|
+
)
|
|
373
|
+
const descriptor = { ...payload.descriptor, expiringNonceHash }
|
|
374
|
+
const channelId = Channel.computeId({ ...descriptor, chainId, escrow: tip20ChannelEscrow })
|
|
375
|
+
const signature = await Voucher.signVoucher(
|
|
376
|
+
createSigningClient(),
|
|
377
|
+
payer,
|
|
378
|
+
{ channelId, cumulativeAmount: BigInt(payload.cumulativeAmount) },
|
|
379
|
+
tip20ChannelEscrow,
|
|
380
|
+
chainId,
|
|
381
|
+
)
|
|
382
|
+
return { ...payload, channelId, transaction, signature, descriptor }
|
|
383
|
+
}
|
|
384
|
+
|
|
318
385
|
function transactionReceipt(logs: readonly Record<string, unknown>[]) {
|
|
319
386
|
return {
|
|
320
387
|
blockHash: `0x${'01'.repeat(32)}`,
|
|
@@ -757,6 +824,133 @@ describe('precompile server session unit guardrails', () => {
|
|
|
757
824
|
).rejects.toThrow('Client not configured with chainId 1.')
|
|
758
825
|
})
|
|
759
826
|
|
|
827
|
+
test('fully validates a session credential without broadcasting or changing channel state', async () => {
|
|
828
|
+
const { method, rpcCalls, store } = createServer()
|
|
829
|
+
const openPayload = await createOpenPayload()
|
|
830
|
+
await persistPrecompileChannel(store, openPayload)
|
|
831
|
+
const payload = await ClientOps.createVoucherPayload(
|
|
832
|
+
createSigningClient(),
|
|
833
|
+
payer,
|
|
834
|
+
openPayload.descriptor,
|
|
835
|
+
Types.uint96(200n),
|
|
836
|
+
chainId,
|
|
837
|
+
)
|
|
838
|
+
|
|
839
|
+
const validation = await method.validate!({
|
|
840
|
+
credential: {
|
|
841
|
+
challenge: makeChallenge(openPayload.channelId),
|
|
842
|
+
payload,
|
|
843
|
+
source: sourceFor(),
|
|
844
|
+
},
|
|
845
|
+
request: verifyRequest(openPayload.channelId),
|
|
846
|
+
})
|
|
847
|
+
|
|
848
|
+
await method.validate!({
|
|
849
|
+
credential: {
|
|
850
|
+
challenge: makeChallenge(openPayload.channelId),
|
|
851
|
+
payload,
|
|
852
|
+
source: sourceFor(),
|
|
853
|
+
},
|
|
854
|
+
request: verifyRequest(openPayload.channelId),
|
|
855
|
+
})
|
|
856
|
+
|
|
857
|
+
expect(validation.details).toEqual({ action: 'voucher', channelId: openPayload.channelId })
|
|
858
|
+
expect(await store.getChannel(openPayload.channelId)).toMatchObject({
|
|
859
|
+
highestVoucherAmount: 100n,
|
|
860
|
+
spent: 0n,
|
|
861
|
+
units: 0,
|
|
862
|
+
})
|
|
863
|
+
expect(rpcCalls.map(({ method }) => method)).toEqual(['eth_call'])
|
|
864
|
+
expect(rpcCalls.map(({ method }) => method)).not.toContain('eth_sendRawTransaction')
|
|
865
|
+
expect(rpcCalls.map(({ method }) => method)).not.toContain('eth_sendRawTransactionSync')
|
|
866
|
+
})
|
|
867
|
+
|
|
868
|
+
test('simulates unsponsored open and top-up credentials during validation', async () => {
|
|
869
|
+
const { method, rpcCalls, store } = createServer()
|
|
870
|
+
const openPayload = await createOpenPayload()
|
|
871
|
+
|
|
872
|
+
await method.validate!({
|
|
873
|
+
credential: { challenge: makeChallenge(openPayload.channelId), payload: openPayload },
|
|
874
|
+
request: verifyRequest(openPayload.channelId),
|
|
875
|
+
})
|
|
876
|
+
await persistPrecompileChannel(store, openPayload)
|
|
877
|
+
const topUpPayload = await createTopUpPayload(openPayload.descriptor, 100n)
|
|
878
|
+
|
|
879
|
+
await method.validate!({
|
|
880
|
+
credential: { challenge: makeChallenge(topUpPayload.channelId), payload: topUpPayload },
|
|
881
|
+
request: verifyRequest(topUpPayload.channelId),
|
|
882
|
+
})
|
|
883
|
+
|
|
884
|
+
expect(rpcCalls.map(({ method }) => method)).toEqual(['eth_call', 'eth_call', 'eth_call'])
|
|
885
|
+
expect(await store.getChannel(openPayload.channelId)).toMatchObject({
|
|
886
|
+
deposit: 1_000n,
|
|
887
|
+
highestVoucherAmount: 100n,
|
|
888
|
+
})
|
|
889
|
+
})
|
|
890
|
+
|
|
891
|
+
test('does not simulate sponsored credentials during validation but checks top-up state', async () => {
|
|
892
|
+
const { method, rpcCalls, store } = createServer({ feePayer: payer })
|
|
893
|
+
const openPayload = await createSponsoredOpenPayload()
|
|
894
|
+
|
|
895
|
+
await method.validate!({
|
|
896
|
+
credential: { challenge: makeChallenge(openPayload.channelId), payload: openPayload },
|
|
897
|
+
request: verifyRequestWithFeePayer(openPayload.channelId, payer),
|
|
898
|
+
})
|
|
899
|
+
await persistPrecompileChannel(store, openPayload)
|
|
900
|
+
const topUpPayload = await createTopUpPayload(openPayload.descriptor, 100n)
|
|
901
|
+
topUpPayload.transaction = sponsorTransaction(topUpPayload.transaction)
|
|
902
|
+
|
|
903
|
+
await method.validate!({
|
|
904
|
+
credential: { challenge: makeChallenge(topUpPayload.channelId), payload: topUpPayload },
|
|
905
|
+
request: verifyRequestWithFeePayer(topUpPayload.channelId, payer),
|
|
906
|
+
})
|
|
907
|
+
|
|
908
|
+
expect(rpcCalls.map(({ method }) => method)).toEqual(['eth_call'])
|
|
909
|
+
expect(await store.getChannel(openPayload.channelId)).toMatchObject({
|
|
910
|
+
deposit: 1_000n,
|
|
911
|
+
highestVoucherAmount: 100n,
|
|
912
|
+
})
|
|
913
|
+
})
|
|
914
|
+
|
|
915
|
+
test('rejects sponsored credentials that exceed the fee-payer policy during validation', async () => {
|
|
916
|
+
const { method, rpcCalls } = createServer({
|
|
917
|
+
feePayer: payer,
|
|
918
|
+
feePayerPolicy: { maxGas: 1n },
|
|
919
|
+
})
|
|
920
|
+
const payload = await createSponsoredOpenPayload()
|
|
921
|
+
|
|
922
|
+
payload.transaction = sponsorTransaction(payload.transaction, { gas: 2n })
|
|
923
|
+
|
|
924
|
+
await expect(
|
|
925
|
+
method.validate!({
|
|
926
|
+
credential: { challenge: makeChallenge(payload.channelId), payload },
|
|
927
|
+
request: verifyRequestWithFeePayer(payload.channelId, payer),
|
|
928
|
+
}),
|
|
929
|
+
).rejects.toThrow(/fee-sponsored transaction gas exceeds sponsor policy/)
|
|
930
|
+
expect(rpcCalls).toEqual([])
|
|
931
|
+
})
|
|
932
|
+
|
|
933
|
+
test('validates close credentials without marking the channel pending', async () => {
|
|
934
|
+
const { method, rpcCalls, store } = createServer()
|
|
935
|
+
const openPayload = await createOpenPayload()
|
|
936
|
+
await persistPrecompileChannel(store, openPayload, { payee: payer.address })
|
|
937
|
+
const payload = await ClientOps.createClosePayload(
|
|
938
|
+
createSigningClient(),
|
|
939
|
+
payer,
|
|
940
|
+
openPayload.descriptor,
|
|
941
|
+
Types.uint96(100n),
|
|
942
|
+
chainId,
|
|
943
|
+
)
|
|
944
|
+
|
|
945
|
+
await method.validate!({
|
|
946
|
+
credential: { challenge: makeChallenge(openPayload.channelId), payload },
|
|
947
|
+
request: verifyRequest(openPayload.channelId),
|
|
948
|
+
})
|
|
949
|
+
|
|
950
|
+
expect((await store.getChannel(openPayload.channelId))?.closeRequestedAt).toBe(0n)
|
|
951
|
+
expect(rpcCalls.map(({ method }) => method)).toEqual(['eth_call'])
|
|
952
|
+
})
|
|
953
|
+
|
|
760
954
|
test('rejects open transactions targeting the wrong address', async () => {
|
|
761
955
|
const { method } = createServer()
|
|
762
956
|
const payload = await createOpenPayload({ escrow: wrongTarget })
|
|
@@ -1409,7 +1603,7 @@ describe('precompile server session unit guardrails', () => {
|
|
|
1409
1603
|
expect(stored?.units).toBe(4)
|
|
1410
1604
|
})
|
|
1411
1605
|
|
|
1412
|
-
test('rejects
|
|
1606
|
+
test('rejects top-up validation when on-chain state has pending close', async () => {
|
|
1413
1607
|
const rawStore = Store.memory()
|
|
1414
1608
|
const store = channelStore(rawStore)
|
|
1415
1609
|
const openPayload = await createOpenPayload({ initialAmount: 100n })
|
|
@@ -1431,7 +1625,7 @@ describe('precompile server session unit guardrails', () => {
|
|
|
1431
1625
|
})
|
|
1432
1626
|
|
|
1433
1627
|
await expect(
|
|
1434
|
-
method.
|
|
1628
|
+
method.validate!({
|
|
1435
1629
|
credential: {
|
|
1436
1630
|
challenge: makeChallenge(openPayload.channelId),
|
|
1437
1631
|
payload: topUpPayload,
|
|
@@ -2172,14 +2366,23 @@ describe('precompile server session unit guardrails', () => {
|
|
|
2172
2366
|
|
|
2173
2367
|
describe('SSE parity', () => {
|
|
2174
2368
|
function createManagedSseFetch(
|
|
2175
|
-
options: {
|
|
2369
|
+
options: {
|
|
2370
|
+
amount?: string
|
|
2371
|
+
chunkDelayMs?: number
|
|
2372
|
+
maxDeposit?: bigint
|
|
2373
|
+
onSessionSettlement?: session.Parameters['onSessionSettlement']
|
|
2374
|
+
settlementSchedule?: session.Parameters['settlementSchedule']
|
|
2375
|
+
unitType?: 'request' | 'token'
|
|
2376
|
+
} = {},
|
|
2176
2377
|
) {
|
|
2177
2378
|
const rawStore = Store.memory()
|
|
2379
|
+
let activeChannelId: Hex | undefined
|
|
2178
2380
|
let currentPayload: SessionCredentialPayload | undefined
|
|
2179
2381
|
let voucherPosts = 0
|
|
2180
2382
|
const amount = options.amount ?? '1'
|
|
2181
2383
|
const maxDeposit = options.maxDeposit ?? 3n
|
|
2182
2384
|
let deposit = maxDeposit
|
|
2385
|
+
let settled = 0n
|
|
2183
2386
|
const unitType = options.unitType ?? 'token'
|
|
2184
2387
|
const route = Mppx_server.create({
|
|
2185
2388
|
methods: [
|
|
@@ -2189,6 +2392,8 @@ describe('precompile server session unit guardrails', () => {
|
|
|
2189
2392
|
currency: token,
|
|
2190
2393
|
decimals: 0,
|
|
2191
2394
|
recipient: payer.address,
|
|
2395
|
+
onSessionSettlement: options.onSessionSettlement,
|
|
2396
|
+
settlementSchedule: options.settlementSchedule,
|
|
2192
2397
|
sse: true,
|
|
2193
2398
|
store: rawStore,
|
|
2194
2399
|
unitType,
|
|
@@ -2206,20 +2411,24 @@ describe('precompile server session unit guardrails', () => {
|
|
|
2206
2411
|
receipt: transactionReceipt([
|
|
2207
2412
|
closedLog(payload.channelId, BigInt(payload.cumulativeAmount), 0n),
|
|
2208
2413
|
]),
|
|
2209
|
-
state: { settled
|
|
2414
|
+
state: { settled, deposit, closeRequestedAt: 0 },
|
|
2210
2415
|
})
|
|
2211
2416
|
}
|
|
2212
2417
|
if (payload?.action === 'topUp') {
|
|
2213
2418
|
deposit += BigInt(payload.additionalDeposit)
|
|
2214
2419
|
return createServerClient([], payer, payload.channelId, {
|
|
2215
2420
|
receipt: transactionReceipt([topUpLog(payload, deposit)]),
|
|
2216
|
-
state: { settled
|
|
2421
|
+
state: { settled, deposit, closeRequestedAt: 0 },
|
|
2217
2422
|
})
|
|
2218
2423
|
}
|
|
2219
|
-
return
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2424
|
+
return createServerClient([], payer, undefined, {
|
|
2425
|
+
sentReceipt: async () => {
|
|
2426
|
+
if (!activeChannelId) throw new Error('missing channel context')
|
|
2427
|
+
const channel = await channelStore(rawStore).getChannel(activeChannelId)
|
|
2428
|
+
settled = channel?.highestVoucherAmount ?? settled
|
|
2429
|
+
return transactionReceipt([settledLog(activeChannelId, settled)])
|
|
2430
|
+
},
|
|
2431
|
+
state: () => ({ settled, deposit, closeRequestedAt: 0 }),
|
|
2223
2432
|
})
|
|
2224
2433
|
},
|
|
2225
2434
|
}),
|
|
@@ -2233,6 +2442,7 @@ describe('precompile server session unit guardrails', () => {
|
|
|
2233
2442
|
if (request.headers.has('Authorization')) {
|
|
2234
2443
|
try {
|
|
2235
2444
|
currentPayload = Credential.fromRequest<SessionCredentialPayload>(request).payload
|
|
2445
|
+
activeChannelId = currentPayload.channelId
|
|
2236
2446
|
if (currentPayload.action === 'voucher') voucherPosts++
|
|
2237
2447
|
} catch {}
|
|
2238
2448
|
}
|
|
@@ -2259,9 +2469,12 @@ describe('precompile server session unit guardrails', () => {
|
|
|
2259
2469
|
)
|
|
2260
2470
|
}
|
|
2261
2471
|
|
|
2472
|
+
currentPayload = undefined
|
|
2262
2473
|
return result.withReceipt(async function* (stream) {
|
|
2263
2474
|
await stream.charge()
|
|
2264
2475
|
yield 'chunk-1'
|
|
2476
|
+
if (options.chunkDelayMs)
|
|
2477
|
+
await new Promise((resolve) => setTimeout(resolve, options.chunkDelayMs))
|
|
2265
2478
|
await stream.charge()
|
|
2266
2479
|
yield 'chunk-2'
|
|
2267
2480
|
await stream.charge()
|
|
@@ -2312,6 +2525,49 @@ describe('precompile server session unit guardrails', () => {
|
|
|
2312
2525
|
expect(persisted?.finalized).toBe(true)
|
|
2313
2526
|
})
|
|
2314
2527
|
|
|
2528
|
+
test.each([
|
|
2529
|
+
['unit', { units: 2 }, 0],
|
|
2530
|
+
['amount', { amount: '2' }, 0],
|
|
2531
|
+
['interval', { intervalMs: 500 }, 750],
|
|
2532
|
+
] as const)(
|
|
2533
|
+
'applies the %s settlement schedule after SSE charges',
|
|
2534
|
+
async (_label, settlementSchedule, chunkDelayMs) => {
|
|
2535
|
+
const settlements: Array<{ delta: bigint; trigger: string }> = []
|
|
2536
|
+
const harness = createManagedSseFetch({
|
|
2537
|
+
chunkDelayMs,
|
|
2538
|
+
maxDeposit: 3n,
|
|
2539
|
+
settlementSchedule,
|
|
2540
|
+
onSessionSettlement(context) {
|
|
2541
|
+
settlements.push({ delta: context.delta, trigger: context.trigger })
|
|
2542
|
+
},
|
|
2543
|
+
})
|
|
2544
|
+
const manager = precompileSessionManager({
|
|
2545
|
+
account: payer,
|
|
2546
|
+
client: createSigningClient(),
|
|
2547
|
+
decimals: 0,
|
|
2548
|
+
fetch: harness.fetch,
|
|
2549
|
+
maxDeposit: '3',
|
|
2550
|
+
})
|
|
2551
|
+
|
|
2552
|
+
const chunks: string[] = []
|
|
2553
|
+
for await (const chunk of await manager.sse('https://api.example.com/stream')) {
|
|
2554
|
+
chunks.push(chunk)
|
|
2555
|
+
}
|
|
2556
|
+
|
|
2557
|
+
expect(chunks).toEqual(['chunk-1', 'chunk-2', 'chunk-3'])
|
|
2558
|
+
expect(harness.voucherPosts).toBeGreaterThan(0)
|
|
2559
|
+
expect(settlements).toEqual([{ delta: 2n, trigger: 'scheduled' }])
|
|
2560
|
+
const persisted = await channelStore(harness.rawStore).getChannel(manager.channelId!)
|
|
2561
|
+
expect(persisted?.lastSettlementUnits).toBe(2)
|
|
2562
|
+
|
|
2563
|
+
await manager.close()
|
|
2564
|
+
expect(settlements).toEqual([
|
|
2565
|
+
{ delta: 2n, trigger: 'scheduled' },
|
|
2566
|
+
{ delta: 1n, trigger: 'close' },
|
|
2567
|
+
])
|
|
2568
|
+
},
|
|
2569
|
+
)
|
|
2570
|
+
|
|
2315
2571
|
test('handles empty management POST streams through a Node adapter', async () => {
|
|
2316
2572
|
const harness = createManagedSseFetch({ maxDeposit: 1n })
|
|
2317
2573
|
const managementPosts: Array<{
|
|
@@ -2421,19 +2677,31 @@ describe('precompile server session unit guardrails', () => {
|
|
|
2421
2677
|
})
|
|
2422
2678
|
|
|
2423
2679
|
describe('WebSocket parity', () => {
|
|
2424
|
-
async function createManagedWsHarness(
|
|
2680
|
+
async function createManagedWsHarness(
|
|
2681
|
+
options: {
|
|
2682
|
+
challengeTtlMs?: number
|
|
2683
|
+
maxDeposit?: bigint
|
|
2684
|
+
onSessionSettlement?: session.Parameters['onSessionSettlement']
|
|
2685
|
+
settlementSchedule?: session.Parameters['settlementSchedule']
|
|
2686
|
+
} = {},
|
|
2687
|
+
) {
|
|
2425
2688
|
const rawStore = Store.memory()
|
|
2689
|
+
let activeChannelId: Hex | undefined
|
|
2690
|
+
let challengeRequests = 0
|
|
2426
2691
|
let currentPayload: SessionCredentialPayload | undefined
|
|
2692
|
+
let settled = 0n
|
|
2427
2693
|
let voucherPosts = 0
|
|
2428
2694
|
const maxDeposit = options.maxDeposit ?? 3n
|
|
2429
|
-
const
|
|
2695
|
+
const payment = Mppx_server.create({
|
|
2430
2696
|
methods: [
|
|
2431
2697
|
tempo_server.session({
|
|
2432
2698
|
amount: '1',
|
|
2433
2699
|
chainId,
|
|
2434
2700
|
currency: token,
|
|
2435
2701
|
decimals: 0,
|
|
2702
|
+
onSessionSettlement: options.onSessionSettlement,
|
|
2436
2703
|
recipient: payer.address,
|
|
2704
|
+
settlementSchedule: options.settlementSchedule,
|
|
2437
2705
|
store: rawStore,
|
|
2438
2706
|
unitType: 'token',
|
|
2439
2707
|
getClient: () => {
|
|
@@ -2450,30 +2718,45 @@ describe('precompile server session unit guardrails', () => {
|
|
|
2450
2718
|
receipt: transactionReceipt([
|
|
2451
2719
|
closedLog(payload.channelId, BigInt(payload.cumulativeAmount), 0n),
|
|
2452
2720
|
]),
|
|
2453
|
-
state: { settled
|
|
2721
|
+
state: { settled, deposit: maxDeposit, closeRequestedAt: 0 },
|
|
2454
2722
|
})
|
|
2455
2723
|
}
|
|
2456
|
-
return
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2724
|
+
return createServerClient([], payer, undefined, {
|
|
2725
|
+
sentReceipt: async () => {
|
|
2726
|
+
if (!activeChannelId) throw new Error('missing channel context')
|
|
2727
|
+
const channel = await channelStore(rawStore).getChannel(activeChannelId)
|
|
2728
|
+
settled = channel?.highestVoucherAmount ?? settled
|
|
2729
|
+
return transactionReceipt([settledLog(activeChannelId, settled)])
|
|
2730
|
+
},
|
|
2731
|
+
state: () => ({ settled, deposit: maxDeposit, closeRequestedAt: 0 }),
|
|
2460
2732
|
})
|
|
2461
2733
|
},
|
|
2462
2734
|
}),
|
|
2463
2735
|
],
|
|
2464
2736
|
realm: 'api.example.com',
|
|
2465
2737
|
secretKey: 'test-secret-key-test-secret-key-32',
|
|
2466
|
-
})
|
|
2738
|
+
})
|
|
2467
2739
|
|
|
2740
|
+
const routeOptions = () => ({
|
|
2741
|
+
amount: '1',
|
|
2742
|
+
decimals: 0,
|
|
2743
|
+
suggestedDeposit: maxDeposit.toString(),
|
|
2744
|
+
...(options.challengeTtlMs === undefined
|
|
2745
|
+
? {}
|
|
2746
|
+
: { expires: new Date(Date.now() + options.challengeTtlMs) }),
|
|
2747
|
+
})
|
|
2468
2748
|
const route = async (request: Request) => {
|
|
2469
2749
|
currentPayload = undefined
|
|
2470
2750
|
if (request.headers.has('Authorization')) {
|
|
2471
2751
|
try {
|
|
2472
2752
|
currentPayload = Credential.fromRequest<SessionCredentialPayload>(request).payload
|
|
2753
|
+
activeChannelId = currentPayload.channelId
|
|
2473
2754
|
if (currentPayload.action === 'voucher') voucherPosts++
|
|
2474
2755
|
} catch {}
|
|
2475
|
-
}
|
|
2476
|
-
|
|
2756
|
+
} else challengeRequests++
|
|
2757
|
+
const result = await payment.session(routeOptions())(request)
|
|
2758
|
+
currentPayload = undefined
|
|
2759
|
+
return result
|
|
2477
2760
|
}
|
|
2478
2761
|
|
|
2479
2762
|
const httpHandler = NodeRequest.toNodeListener(async (request) => {
|
|
@@ -2505,11 +2788,15 @@ describe('precompile server session unit guardrails', () => {
|
|
|
2505
2788
|
return {
|
|
2506
2789
|
rawStore,
|
|
2507
2790
|
route,
|
|
2791
|
+
serveWebSocket: payment.session.serveWebSocket,
|
|
2508
2792
|
server,
|
|
2509
2793
|
wsServer,
|
|
2510
2794
|
get port() {
|
|
2511
2795
|
return port
|
|
2512
2796
|
},
|
|
2797
|
+
get challengeRequests() {
|
|
2798
|
+
return challengeRequests
|
|
2799
|
+
},
|
|
2513
2800
|
get voucherPosts() {
|
|
2514
2801
|
return voucherPosts
|
|
2515
2802
|
},
|
|
@@ -2520,12 +2807,58 @@ describe('precompile server session unit guardrails', () => {
|
|
|
2520
2807
|
}
|
|
2521
2808
|
}
|
|
2522
2809
|
|
|
2810
|
+
test('refreshes an expired challenge before sending a later websocket voucher', async () => {
|
|
2811
|
+
const harness = await createManagedWsHarness({ challengeTtlMs: 2_000, maxDeposit: 2n })
|
|
2812
|
+
harness.wsServer.on('connection', (socket: import('ws').WebSocket) => {
|
|
2813
|
+
void harness.serveWebSocket({
|
|
2814
|
+
socket,
|
|
2815
|
+
url: `${harness.server.url}/ws`,
|
|
2816
|
+
route: harness.route,
|
|
2817
|
+
generate: async function* (stream: TempoWs.SessionController) {
|
|
2818
|
+
await stream.charge()
|
|
2819
|
+
yield 'chunk-1'
|
|
2820
|
+
await new Promise((resolve) => setTimeout(resolve, 2_200))
|
|
2821
|
+
await stream.charge()
|
|
2822
|
+
yield 'chunk-2'
|
|
2823
|
+
},
|
|
2824
|
+
})
|
|
2825
|
+
})
|
|
2826
|
+
|
|
2827
|
+
try {
|
|
2828
|
+
const manager = precompileSessionManager({
|
|
2829
|
+
account: payer,
|
|
2830
|
+
client: createSigningClient(),
|
|
2831
|
+
decimals: 0,
|
|
2832
|
+
fetch: globalThis.fetch,
|
|
2833
|
+
maxDeposit: '2',
|
|
2834
|
+
webSocket: WebSocket as never,
|
|
2835
|
+
})
|
|
2836
|
+
const ws = await manager.ws(`ws://localhost:${harness.port}/ws`)
|
|
2837
|
+
const chunks: string[] = []
|
|
2838
|
+
|
|
2839
|
+
await new Promise<void>((resolve, reject) => {
|
|
2840
|
+
ws.addEventListener('message', (event) => {
|
|
2841
|
+
if (typeof event.data === 'string') chunks.push(event.data)
|
|
2842
|
+
})
|
|
2843
|
+
ws.addEventListener('close', () => resolve(), { once: true })
|
|
2844
|
+
ws.addEventListener('error', () => reject(new Error('websocket stream failed')), {
|
|
2845
|
+
once: true,
|
|
2846
|
+
})
|
|
2847
|
+
})
|
|
2848
|
+
|
|
2849
|
+
expect(chunks).toEqual(['chunk-1', 'chunk-2'])
|
|
2850
|
+
expect(harness.challengeRequests).toBeGreaterThan(1)
|
|
2851
|
+
expect(harness.voucherPosts).toBe(1)
|
|
2852
|
+
} finally {
|
|
2853
|
+
harness.close()
|
|
2854
|
+
}
|
|
2855
|
+
})
|
|
2856
|
+
|
|
2523
2857
|
test('open -> stream -> need-voucher -> resume -> close', async () => {
|
|
2524
2858
|
const harness = await createManagedWsHarness({ maxDeposit: 3n })
|
|
2525
2859
|
harness.wsServer.on('connection', (socket: import('ws').WebSocket) => {
|
|
2526
|
-
void
|
|
2860
|
+
void harness.serveWebSocket({
|
|
2527
2861
|
socket,
|
|
2528
|
-
store: harness.rawStore,
|
|
2529
2862
|
url: `${harness.server.url}/ws`,
|
|
2530
2863
|
route: harness.route,
|
|
2531
2864
|
generate: async function* (stream: TempoWs.SessionController) {
|
|
@@ -2579,6 +2912,75 @@ describe('precompile server session unit guardrails', () => {
|
|
|
2579
2912
|
}
|
|
2580
2913
|
})
|
|
2581
2914
|
|
|
2915
|
+
test.each([
|
|
2916
|
+
['unit', { units: 2 }, 0],
|
|
2917
|
+
['amount', { amount: '2' }, 0],
|
|
2918
|
+
['interval', { intervalMs: 500 }, 750],
|
|
2919
|
+
] as const)(
|
|
2920
|
+
'applies the %s settlement schedule after websocket charges',
|
|
2921
|
+
async (_label, settlementSchedule, chunkDelayMs) => {
|
|
2922
|
+
const settlements: Array<{ delta: bigint; trigger: string }> = []
|
|
2923
|
+
const harness = await createManagedWsHarness({
|
|
2924
|
+
maxDeposit: 3n,
|
|
2925
|
+
settlementSchedule,
|
|
2926
|
+
onSessionSettlement(context) {
|
|
2927
|
+
settlements.push({ delta: context.delta, trigger: context.trigger })
|
|
2928
|
+
},
|
|
2929
|
+
})
|
|
2930
|
+
harness.wsServer.on('connection', (socket: import('ws').WebSocket) => {
|
|
2931
|
+
void harness.serveWebSocket({
|
|
2932
|
+
socket,
|
|
2933
|
+
url: `${harness.server.url}/ws`,
|
|
2934
|
+
route: harness.route,
|
|
2935
|
+
generate: async function* (stream: TempoWs.SessionController) {
|
|
2936
|
+
for (const chunk of ['chunk-1', 'chunk-2', 'chunk-3']) {
|
|
2937
|
+
if (chunk === 'chunk-2' && chunkDelayMs)
|
|
2938
|
+
await new Promise((resolve) => setTimeout(resolve, chunkDelayMs))
|
|
2939
|
+
await stream.charge()
|
|
2940
|
+
yield chunk
|
|
2941
|
+
}
|
|
2942
|
+
},
|
|
2943
|
+
})
|
|
2944
|
+
})
|
|
2945
|
+
|
|
2946
|
+
try {
|
|
2947
|
+
const manager = precompileSessionManager({
|
|
2948
|
+
account: payer,
|
|
2949
|
+
client: createSigningClient(),
|
|
2950
|
+
decimals: 0,
|
|
2951
|
+
fetch: globalThis.fetch,
|
|
2952
|
+
maxDeposit: '3',
|
|
2953
|
+
webSocket: WebSocket as never,
|
|
2954
|
+
})
|
|
2955
|
+
const ws = await manager.ws(`ws://localhost:${harness.port}/ws`)
|
|
2956
|
+
const chunks: string[] = []
|
|
2957
|
+
|
|
2958
|
+
await new Promise<void>((resolve, reject) => {
|
|
2959
|
+
ws.addEventListener('message', (event) => {
|
|
2960
|
+
if (typeof event.data === 'string') chunks.push(event.data)
|
|
2961
|
+
})
|
|
2962
|
+
ws.addEventListener('close', () => resolve(), { once: true })
|
|
2963
|
+
ws.addEventListener('error', () => reject(new Error('websocket stream failed')), {
|
|
2964
|
+
once: true,
|
|
2965
|
+
})
|
|
2966
|
+
})
|
|
2967
|
+
|
|
2968
|
+
expect(chunks).toEqual(['chunk-1', 'chunk-2', 'chunk-3'])
|
|
2969
|
+
expect(harness.voucherPosts).toBeGreaterThan(0)
|
|
2970
|
+
expect(settlements).toEqual([{ delta: 2n, trigger: 'scheduled' }])
|
|
2971
|
+
await manager.close()
|
|
2972
|
+
expect(settlements).toEqual([
|
|
2973
|
+
{ delta: 2n, trigger: 'scheduled' },
|
|
2974
|
+
{ delta: 1n, trigger: 'close' },
|
|
2975
|
+
])
|
|
2976
|
+
const persisted = await channelStore(harness.rawStore).getChannel(manager.channelId!)
|
|
2977
|
+
expect(persisted?.lastSettlementUnits).toBe(2)
|
|
2978
|
+
} finally {
|
|
2979
|
+
harness.close()
|
|
2980
|
+
}
|
|
2981
|
+
},
|
|
2982
|
+
)
|
|
2983
|
+
|
|
2582
2984
|
test('treats control-shaped application payloads as content', async () => {
|
|
2583
2985
|
const harness = await createManagedWsHarness({ maxDeposit: 1n })
|
|
2584
2986
|
const controlLookingChunk = JSON.stringify({
|
|
@@ -2591,9 +2993,8 @@ describe('precompile server session unit guardrails', () => {
|
|
|
2591
2993
|
},
|
|
2592
2994
|
})
|
|
2593
2995
|
harness.wsServer.on('connection', (socket: import('ws').WebSocket) => {
|
|
2594
|
-
void
|
|
2996
|
+
void harness.serveWebSocket({
|
|
2595
2997
|
socket,
|
|
2596
|
-
store: harness.rawStore,
|
|
2597
2998
|
url: `${harness.server.url}/ws`,
|
|
2598
2999
|
route: harness.route,
|
|
2599
3000
|
generate: async function* (stream: TempoWs.SessionController) {
|
|
@@ -2641,9 +3042,8 @@ describe('precompile server session unit guardrails', () => {
|
|
|
2641
3042
|
test('refuses websocket voucher requests beyond local maxDeposit', async () => {
|
|
2642
3043
|
const harness = await createManagedWsHarness({ maxDeposit: 1n })
|
|
2643
3044
|
harness.wsServer.on('connection', (socket: import('ws').WebSocket) => {
|
|
2644
|
-
void
|
|
3045
|
+
void harness.serveWebSocket({
|
|
2645
3046
|
socket,
|
|
2646
|
-
store: harness.rawStore,
|
|
2647
3047
|
url: `${harness.server.url}/ws`,
|
|
2648
3048
|
route: harness.route,
|
|
2649
3049
|
generate: async function* (stream: TempoWs.SessionController) {
|
|
@@ -2803,9 +3203,8 @@ describe('precompile server session unit guardrails', () => {
|
|
|
2803
3203
|
let serverSocket: import('ws').WebSocket | null = null
|
|
2804
3204
|
harness.wsServer.on('connection', (socket: import('ws').WebSocket) => {
|
|
2805
3205
|
serverSocket = socket
|
|
2806
|
-
void
|
|
3206
|
+
void harness.serveWebSocket({
|
|
2807
3207
|
socket,
|
|
2808
|
-
store: harness.rawStore,
|
|
2809
3208
|
url: `${harness.server.url}/ws`,
|
|
2810
3209
|
route: harness.route,
|
|
2811
3210
|
generate: async function* (stream: TempoWs.SessionController) {
|
|
@@ -3399,6 +3798,54 @@ describe('precompile server session unit guardrails', () => {
|
|
|
3399
3798
|
})
|
|
3400
3799
|
})
|
|
3401
3800
|
|
|
3801
|
+
describe('session settlement extensions', () => {
|
|
3802
|
+
test.each([
|
|
3803
|
+
['no schedule is configured', undefined],
|
|
3804
|
+
['the configured threshold is not due', { units: 11 }],
|
|
3805
|
+
] as const)('does not resolve a client when %s', async (_label, settlementSchedule) => {
|
|
3806
|
+
const rawStore = Store.memory()
|
|
3807
|
+
const store = channelStore(rawStore)
|
|
3808
|
+
const openPayload = await createOpenPayload()
|
|
3809
|
+
let clientResolutions = 0
|
|
3810
|
+
await persistPrecompileChannel(store, openPayload, {
|
|
3811
|
+
highestVoucherAmount: 500n,
|
|
3812
|
+
highestVoucher: {
|
|
3813
|
+
channelId: openPayload.channelId,
|
|
3814
|
+
cumulativeAmount: 500n,
|
|
3815
|
+
signature: '0x1234',
|
|
3816
|
+
},
|
|
3817
|
+
spent: 500n,
|
|
3818
|
+
units: 10,
|
|
3819
|
+
})
|
|
3820
|
+
|
|
3821
|
+
const payment = Mppx_server.create({
|
|
3822
|
+
methods: [
|
|
3823
|
+
tempo_server.session({
|
|
3824
|
+
account: payer,
|
|
3825
|
+
amount: '1',
|
|
3826
|
+
chainId,
|
|
3827
|
+
currency: token,
|
|
3828
|
+
decimals: 0,
|
|
3829
|
+
getClient() {
|
|
3830
|
+
clientResolutions++
|
|
3831
|
+
throw new Error('client should not be resolved')
|
|
3832
|
+
},
|
|
3833
|
+
recipient: payee,
|
|
3834
|
+
settlementSchedule,
|
|
3835
|
+
store: rawStore,
|
|
3836
|
+
unitType: 'token',
|
|
3837
|
+
}),
|
|
3838
|
+
],
|
|
3839
|
+
realm: 'api.example.com',
|
|
3840
|
+
secretKey: 'test-secret-key-test-secret-key-32',
|
|
3841
|
+
})
|
|
3842
|
+
const channel = await store.getChannel(openPayload.channelId)
|
|
3843
|
+
|
|
3844
|
+
await expect(payment.session.settleScheduled(channel!)).resolves.toBeUndefined()
|
|
3845
|
+
expect(clientResolutions).toBe(0)
|
|
3846
|
+
})
|
|
3847
|
+
})
|
|
3848
|
+
|
|
3402
3849
|
describe('onSessionSettlement', () => {
|
|
3403
3850
|
function createSettleClient(channelId: Hex, settledAmount: bigint) {
|
|
3404
3851
|
return createClient({
|