mppx 0.8.15 → 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 +36 -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/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 +2 -6
- package/dist/client/internal/Fetch.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 +25 -11
- 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 +1 -1
- package/dist/tempo/server/Relay.d.ts.map +1 -1
- package/dist/tempo/server/Relay.js +2 -2
- package/dist/tempo/server/Relay.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.js.map +1 -1
- package/dist/tempo/session/client/SessionManager.js.map +1 -1
- package/dist/tempo/session/client/Transports.d.ts.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 +1 -0
- package/dist/tempo/session/server/Ws.js.map +1 -1
- package/dist/tempo/subscription/KeyAuthorization.d.ts +39 -39
- package/dist/tempo/subscription/KeyAuthorization.d.ts.map +1 -1
- package/dist/viem/Account.d.ts.map +1 -1
- package/dist/viem/Account.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 +19 -3
- 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/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.ts +2 -6
- 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 +83 -55
- package/src/tempo/server/Methods.ts +0 -20
- package/src/tempo/server/Relay.test.ts +5 -5
- package/src/tempo/server/Relay.ts +2 -2
- 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 +112 -0
- 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 +428 -43
- 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 +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
|
@@ -6,20 +6,22 @@ import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/
|
|
|
6
6
|
import { createMcpExpressApp } from '@modelcontextprotocol/sdk/server/express.js'
|
|
7
7
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
|
|
8
8
|
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'
|
|
9
|
-
import {
|
|
9
|
+
import { session as tempo_session_client, tempo as tempo_client } from 'mppx/client'
|
|
10
10
|
import { Mppx as Mppx_server, tempo as tempo_server } from 'mppx/server'
|
|
11
11
|
import type { Address } from 'viem'
|
|
12
12
|
import { readContract } from 'viem/actions'
|
|
13
13
|
import { Actions, Addresses } from 'viem/tempo'
|
|
14
14
|
import { beforeAll, describe, expect, test } from 'vp/test'
|
|
15
15
|
import { tempoNetwork } from '~test/config.js'
|
|
16
|
-
import { deployEscrow, signTopUpChannel } from '~test/tempo/legacy/session.js'
|
|
17
16
|
import { accounts, asset, client as testClient, fundAccount } from '~test/tempo/viem.js'
|
|
18
17
|
|
|
19
18
|
import * as Credential from '../../Credential.js'
|
|
20
19
|
import * as core_Mcp from '../../Mcp.js'
|
|
21
20
|
import * as Store from '../../Store.js'
|
|
22
|
-
import type {
|
|
21
|
+
import type {
|
|
22
|
+
SessionCredentialPayload,
|
|
23
|
+
SessionReceipt,
|
|
24
|
+
} from '../../tempo/session/precompile/Protocol.js'
|
|
23
25
|
import * as ChannelStore from '../../tempo/session/server/ChannelStore.js'
|
|
24
26
|
import * as McpServer_transport from '../server/Transport.js'
|
|
25
27
|
import * as McpClient from './McpClient.js'
|
|
@@ -31,21 +33,11 @@ const doubleSessionAmountRaw = chargeAmountRaw * 2n
|
|
|
31
33
|
const topUpAmountRaw = chargeAmountRaw * 3n
|
|
32
34
|
const isLocalnet = tempoNetwork === 'localnet'
|
|
33
35
|
|
|
34
|
-
let escrowContract: Address
|
|
35
|
-
|
|
36
|
-
// TODO: Remove once the minimum viem version is >=2.54.0, which uses client-first Tempo call builders.
|
|
37
36
|
function tokenGetBalanceCall(parameters: { account: Address; token: Address }) {
|
|
38
|
-
|
|
39
|
-
length: number
|
|
40
|
-
(parameters: { account: Address; token: Address }): unknown
|
|
41
|
-
(client: unknown, parameters: { account: Address; token: Address }): unknown
|
|
42
|
-
}
|
|
43
|
-
if (call.length >= 2) return call(testClient, parameters)
|
|
44
|
-
return call(parameters)
|
|
37
|
+
return Actions.token.getBalance.call(testClient, parameters)
|
|
45
38
|
}
|
|
46
39
|
|
|
47
40
|
beforeAll(async () => {
|
|
48
|
-
escrowContract = await deployEscrow()
|
|
49
41
|
await fundAccount({ address: accounts[4].address, token: Addresses.pathUsd })
|
|
50
42
|
await fundAccount({ address: accounts[4].address, token: asset })
|
|
51
43
|
await fundAccount({ address: accounts[2].address, token: Addresses.pathUsd })
|
|
@@ -171,6 +163,7 @@ describe.runIf(isLocalnet)('McpClient.wrap integration', () => {
|
|
|
171
163
|
action: 'voucher',
|
|
172
164
|
channelId: openReceipt!.channelId,
|
|
173
165
|
cumulativeAmountRaw: replayedCumulativeRaw,
|
|
166
|
+
descriptor: credentialDescriptor(openCredential),
|
|
174
167
|
},
|
|
175
168
|
})
|
|
176
169
|
const firstVoucher = await callToolWithCredential(
|
|
@@ -236,7 +229,7 @@ describe.runIf(isLocalnet)('McpClient.wrap integration', () => {
|
|
|
236
229
|
{
|
|
237
230
|
name: 'session intent can top up a live MCP channel and continue metering on the same channel',
|
|
238
231
|
sessionFeePayer: true,
|
|
239
|
-
sessionMaxDeposit: '
|
|
232
|
+
sessionMaxDeposit: '5',
|
|
240
233
|
async run(harness: Harness) {
|
|
241
234
|
const openChallenge = await getPaymentChallenge(harness.sdkClient, 'session_tool')
|
|
242
235
|
const openCredential = await harness.sessionMethod.createCredential({
|
|
@@ -269,14 +262,6 @@ describe.runIf(isLocalnet)('McpClient.wrap integration', () => {
|
|
|
269
262
|
expect(meteredReceipt?.channelId).toBe(openReceipt?.channelId)
|
|
270
263
|
expect(meteredReceipt?.acceptedCumulative).toBe((chargeAmountRaw * 2n).toString())
|
|
271
264
|
|
|
272
|
-
const { serializedTransaction } = await signTopUpChannel({
|
|
273
|
-
escrow: escrowContract,
|
|
274
|
-
feePayer: true,
|
|
275
|
-
payer: accounts[2],
|
|
276
|
-
channelId: openReceipt!.channelId,
|
|
277
|
-
token: asset,
|
|
278
|
-
amount: topUpAmountRaw,
|
|
279
|
-
})
|
|
280
265
|
const topUpChallenge = await getPaymentChallenge(harness.sdkClient, 'session_tool')
|
|
281
266
|
const topUpCredential = await harness.sessionMethod.createCredential({
|
|
282
267
|
challenge: topUpChallenge,
|
|
@@ -284,7 +269,7 @@ describe.runIf(isLocalnet)('McpClient.wrap integration', () => {
|
|
|
284
269
|
action: 'topUp',
|
|
285
270
|
additionalDepositRaw: topUpAmountRaw.toString(),
|
|
286
271
|
channelId: openReceipt!.channelId,
|
|
287
|
-
|
|
272
|
+
descriptor: credentialDescriptor(openCredential),
|
|
288
273
|
},
|
|
289
274
|
})
|
|
290
275
|
const toppedUp = await callToolWithCredential(
|
|
@@ -317,7 +302,7 @@ describe.runIf(isLocalnet)('McpClient.wrap integration', () => {
|
|
|
317
302
|
expect(resumedReceipt?.acceptedCumulative).toBe((chargeAmountRaw * 3n).toString())
|
|
318
303
|
|
|
319
304
|
const channel = await harness.sessionStore.getChannel(openReceipt!.channelId)
|
|
320
|
-
expect(channel?.deposit).toBe(chargeAmountRaw *
|
|
305
|
+
expect(channel?.deposit).toBe(chargeAmountRaw * 5n + topUpAmountRaw)
|
|
321
306
|
expect(channel?.highestVoucherAmount).toBe(chargeAmountRaw * 3n)
|
|
322
307
|
expect(channel?.spent).toBeGreaterThanOrEqual(BigInt(topUpReceipt!.spent))
|
|
323
308
|
expect(channel?.units).toBeGreaterThanOrEqual(topUpReceipt?.units ?? 0)
|
|
@@ -362,6 +347,7 @@ describe.runIf(isLocalnet)('McpClient.wrap integration', () => {
|
|
|
362
347
|
action: 'close',
|
|
363
348
|
channelId: openReceipt!.channelId,
|
|
364
349
|
cumulativeAmountRaw: (chargeAmountRaw * 2n).toString(),
|
|
350
|
+
descriptor: credentialDescriptor(openCredential),
|
|
365
351
|
},
|
|
366
352
|
})
|
|
367
353
|
const closed = await callToolWithCredential(
|
|
@@ -452,7 +438,6 @@ type Harness = {
|
|
|
452
438
|
|
|
453
439
|
async function createHarness(options?: {
|
|
454
440
|
sessionFeePayer?: boolean | undefined
|
|
455
|
-
sessionDeposit?: string | undefined
|
|
456
441
|
sessionMaxDeposit?: string | undefined
|
|
457
442
|
}): Promise<Harness> {
|
|
458
443
|
const sessionBackingStore = Store.memory()
|
|
@@ -463,11 +448,8 @@ async function createHarness(options?: {
|
|
|
463
448
|
})
|
|
464
449
|
const sessionMethod = tempo_session_client({
|
|
465
450
|
account: accounts[2],
|
|
466
|
-
escrowContract,
|
|
467
451
|
getClient: () => testClient,
|
|
468
|
-
...(options?.sessionMaxDeposit
|
|
469
|
-
? { maxDeposit: options.sessionMaxDeposit }
|
|
470
|
-
: { deposit: options?.sessionDeposit ?? '5' }),
|
|
452
|
+
...(options?.sessionMaxDeposit ? { maxDeposit: options.sessionMaxDeposit } : {}),
|
|
471
453
|
})
|
|
472
454
|
|
|
473
455
|
const payment = Mppx_server.create({
|
|
@@ -477,10 +459,9 @@ async function createHarness(options?: {
|
|
|
477
459
|
currency: asset,
|
|
478
460
|
getClient: () => testClient,
|
|
479
461
|
}),
|
|
480
|
-
tempo_server.
|
|
462
|
+
tempo_server.session({
|
|
481
463
|
account: accounts[0],
|
|
482
464
|
currency: asset,
|
|
483
|
-
escrowContract,
|
|
484
465
|
getClient: () => testClient,
|
|
485
466
|
store: sessionBackingStore,
|
|
486
467
|
...(options?.sessionFeePayer ? { feePayer: accounts[4] } : {}),
|
|
@@ -578,6 +559,12 @@ async function createHarness(options?: {
|
|
|
578
559
|
}
|
|
579
560
|
}
|
|
580
561
|
|
|
562
|
+
function credentialDescriptor(serializedCredential: string) {
|
|
563
|
+
const payload = Credential.deserialize<SessionCredentialPayload>(serializedCredential).payload
|
|
564
|
+
if (!payload.descriptor) throw new Error('Session credential is missing its channel descriptor.')
|
|
565
|
+
return payload.descriptor
|
|
566
|
+
}
|
|
567
|
+
|
|
581
568
|
async function getPaymentChallenge(client: Client, toolName: string): Promise<SessionChallenge> {
|
|
582
569
|
try {
|
|
583
570
|
await client.callTool({ name: toolName, arguments: {} })
|
|
@@ -2,18 +2,12 @@ import * as http from 'node:http'
|
|
|
2
2
|
|
|
3
3
|
import { Elysia } from 'elysia'
|
|
4
4
|
import { Receipt } from 'mppx'
|
|
5
|
-
import {
|
|
6
|
-
Mppx as Mppx_client,
|
|
7
|
-
sessionLegacy as sessionIntent,
|
|
8
|
-
tempo as tempo_client,
|
|
9
|
-
} from 'mppx/client'
|
|
5
|
+
import { Mppx as Mppx_client, session as sessionIntent, tempo as tempo_client } from 'mppx/client'
|
|
10
6
|
import { Mppx, discovery, payment } from 'mppx/elysia'
|
|
11
7
|
import { tempo as tempo_server } from 'mppx/server'
|
|
12
|
-
import type { Address } from 'viem'
|
|
13
8
|
import { Addresses } from 'viem/tempo'
|
|
14
9
|
import { beforeAll, describe, expect, test } from 'vp/test'
|
|
15
10
|
import * as TestHttp from '~test/Http.js'
|
|
16
|
-
import { deployEscrow } from '~test/tempo/legacy/session.js'
|
|
17
11
|
import { accounts, asset, client, fundAccount } from '~test/tempo/viem.js'
|
|
18
12
|
|
|
19
13
|
function createServer(app: Elysia<any, any, any, any, any, any, any>) {
|
|
@@ -201,16 +195,13 @@ describe('charge', () => {
|
|
|
201
195
|
})
|
|
202
196
|
|
|
203
197
|
describe('session', () => {
|
|
204
|
-
let escrowContract: Address
|
|
205
|
-
|
|
206
198
|
function createSessionHarness(feePayer: boolean) {
|
|
207
199
|
const mppx = Mppx.create({
|
|
208
200
|
methods: [
|
|
209
|
-
tempo_server.
|
|
201
|
+
tempo_server.session({
|
|
210
202
|
getClient: () => client,
|
|
211
203
|
account: accounts[0],
|
|
212
204
|
currency: asset,
|
|
213
|
-
escrowContract,
|
|
214
205
|
...(feePayer ? { feePayer: accounts[1] } : {}),
|
|
215
206
|
} as any),
|
|
216
207
|
],
|
|
@@ -232,7 +223,6 @@ describe('session', () => {
|
|
|
232
223
|
}
|
|
233
224
|
|
|
234
225
|
beforeAll(async () => {
|
|
235
|
-
escrowContract = await deployEscrow()
|
|
236
226
|
await fundAccount({ address: accounts[1].address, token: Addresses.pathUsd })
|
|
237
227
|
await fundAccount({ address: accounts[1].address, token: asset })
|
|
238
228
|
await fundAccount({ address: accounts[2].address, token: Addresses.pathUsd })
|
|
@@ -1,17 +1,11 @@
|
|
|
1
1
|
import express from 'express'
|
|
2
2
|
import { Receipt } from 'mppx'
|
|
3
|
-
import {
|
|
4
|
-
Mppx as Mppx_client,
|
|
5
|
-
sessionLegacy as sessionIntent,
|
|
6
|
-
tempo as tempo_client,
|
|
7
|
-
} from 'mppx/client'
|
|
3
|
+
import { Mppx as Mppx_client, session as sessionIntent, tempo as tempo_client } from 'mppx/client'
|
|
8
4
|
import { Mppx, discovery, payment } from 'mppx/express'
|
|
9
5
|
import { Mppx as Mppx_server, tempo as tempo_server } from 'mppx/server'
|
|
10
|
-
import type { Address } from 'viem'
|
|
11
6
|
import { Addresses } from 'viem/tempo'
|
|
12
7
|
import { beforeAll, describe, expect, test } from 'vp/test'
|
|
13
8
|
import * as Http from '~test/Http.js'
|
|
14
|
-
import { deployEscrow } from '~test/tempo/legacy/session.js'
|
|
15
9
|
import { accounts, asset, client, fundAccount } from '~test/tempo/viem.js'
|
|
16
10
|
|
|
17
11
|
function createServer(app: express.Express) {
|
|
@@ -195,16 +189,13 @@ describe('payment', () => {
|
|
|
195
189
|
})
|
|
196
190
|
|
|
197
191
|
describe('session', () => {
|
|
198
|
-
let escrowContract: Address
|
|
199
|
-
|
|
200
192
|
function createSessionHarness(feePayer: boolean) {
|
|
201
193
|
const mppx = Mppx.create({
|
|
202
194
|
methods: [
|
|
203
|
-
tempo_server.
|
|
195
|
+
tempo_server.session({
|
|
204
196
|
getClient: () => client,
|
|
205
197
|
account: accounts[0],
|
|
206
198
|
currency: asset,
|
|
207
|
-
escrowContract,
|
|
208
199
|
...(feePayer ? { feePayer: accounts[1] } : {}),
|
|
209
200
|
} as any),
|
|
210
201
|
],
|
|
@@ -226,7 +217,6 @@ describe('session', () => {
|
|
|
226
217
|
}
|
|
227
218
|
|
|
228
219
|
beforeAll(async () => {
|
|
229
|
-
escrowContract = await deployEscrow()
|
|
230
220
|
await fundAccount({ address: accounts[1].address, token: Addresses.pathUsd })
|
|
231
221
|
await fundAccount({ address: accounts[1].address, token: asset })
|
|
232
222
|
await fundAccount({ address: accounts[2].address, token: Addresses.pathUsd })
|
|
@@ -4,7 +4,7 @@ import { Challenge, Credential, Method, Receipt, z } from 'mppx'
|
|
|
4
4
|
import {
|
|
5
5
|
evm as evm_client,
|
|
6
6
|
Mppx as Mppx_client,
|
|
7
|
-
|
|
7
|
+
session as sessionIntent,
|
|
8
8
|
tempo as tempo_client,
|
|
9
9
|
} from 'mppx/client'
|
|
10
10
|
import { Mppx, discovery, payment } from 'mppx/hono'
|
|
@@ -15,11 +15,9 @@ import {
|
|
|
15
15
|
paymentSignatureHeader,
|
|
16
16
|
type PaymentPayload,
|
|
17
17
|
} from 'mppx/x402'
|
|
18
|
-
import type { Address } from 'viem'
|
|
19
18
|
import { Addresses } from 'viem/tempo'
|
|
20
19
|
import { beforeAll, describe, expect, test } from 'vp/test'
|
|
21
20
|
import * as Http from '~test/Http.js'
|
|
22
|
-
import { deployEscrow } from '~test/tempo/legacy/session.js'
|
|
23
21
|
import { accounts, asset, client, fundAccount } from '~test/tempo/viem.js'
|
|
24
22
|
|
|
25
23
|
function createServer(app: Hono) {
|
|
@@ -203,7 +201,9 @@ describe('charge', () => {
|
|
|
203
201
|
const { mppx } = createChargeHarness(false)
|
|
204
202
|
|
|
205
203
|
const app = new Hono()
|
|
206
|
-
app.get('/', mppx.charge({ amount: '1'
|
|
204
|
+
app.get('/', mppx.charge({ amount: '1', description: 'Daily fortune' }), (c) =>
|
|
205
|
+
c.json({ fortune: 'You will be rich' }),
|
|
206
|
+
)
|
|
207
207
|
discovery(app, mppx, { auto: true, info: { title: 'Auto API', version: '2.0.0' } })
|
|
208
208
|
|
|
209
209
|
const server = await createServer(app)
|
|
@@ -216,6 +216,7 @@ describe('charge', () => {
|
|
|
216
216
|
expect(body.paths['/'].get['x-payment-info'].offers[0]).toMatchObject({
|
|
217
217
|
amount: '1000000',
|
|
218
218
|
currency: asset,
|
|
219
|
+
description: 'Daily fortune',
|
|
219
220
|
intent: 'charge',
|
|
220
221
|
method: 'tempo',
|
|
221
222
|
})
|
|
@@ -386,16 +387,13 @@ describe('scope binding', () => {
|
|
|
386
387
|
})
|
|
387
388
|
|
|
388
389
|
describe('session', () => {
|
|
389
|
-
let escrowContract: Address
|
|
390
|
-
|
|
391
390
|
function createSessionHarness(feePayer: boolean) {
|
|
392
391
|
const mppx = Mppx.create({
|
|
393
392
|
methods: [
|
|
394
|
-
tempo_server.
|
|
393
|
+
tempo_server.session({
|
|
395
394
|
getClient: () => client,
|
|
396
395
|
account: accounts[0],
|
|
397
396
|
currency: asset,
|
|
398
|
-
escrowContract,
|
|
399
397
|
...(feePayer ? { feePayer: accounts[1] } : {}),
|
|
400
398
|
} as any),
|
|
401
399
|
],
|
|
@@ -417,7 +415,6 @@ describe('session', () => {
|
|
|
417
415
|
}
|
|
418
416
|
|
|
419
417
|
beforeAll(async () => {
|
|
420
|
-
escrowContract = await deployEscrow()
|
|
421
418
|
await fundAccount({ address: accounts[1].address, token: Addresses.pathUsd })
|
|
422
419
|
await fundAccount({ address: accounts[1].address, token: asset })
|
|
423
420
|
await fundAccount({ address: accounts[2].address, token: Addresses.pathUsd })
|
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
import * as http from 'node:http'
|
|
2
2
|
|
|
3
3
|
import { Challenge, Credential, Receipt } from 'mppx'
|
|
4
|
-
import {
|
|
5
|
-
Mppx as Mppx_client,
|
|
6
|
-
sessionLegacy as sessionIntent,
|
|
7
|
-
tempo as tempo_client,
|
|
8
|
-
} from 'mppx/client'
|
|
4
|
+
import { Mppx as Mppx_client, session as sessionIntent, tempo as tempo_client } from 'mppx/client'
|
|
9
5
|
import { Mppx, discovery, payment } from 'mppx/nextjs'
|
|
10
6
|
import { tempo as tempo_server } from 'mppx/server'
|
|
11
|
-
import type { Address } from 'viem'
|
|
12
7
|
import { Addresses } from 'viem/tempo'
|
|
13
8
|
import { beforeAll, describe, expect, test } from 'vp/test'
|
|
14
9
|
import * as TestHttp from '~test/Http.js'
|
|
15
|
-
import { deployEscrow } from '~test/tempo/legacy/session.js'
|
|
16
10
|
import { accounts, asset, chain, client, fundAccount } from '~test/tempo/viem.js'
|
|
17
11
|
|
|
18
12
|
function createServer(handler: (request: Request) => Promise<Response> | Response) {
|
|
@@ -278,16 +272,13 @@ describe('charge', () => {
|
|
|
278
272
|
})
|
|
279
273
|
|
|
280
274
|
describe('session', () => {
|
|
281
|
-
let escrowContract: Address
|
|
282
|
-
|
|
283
275
|
function createSessionHarness(feePayer: boolean) {
|
|
284
276
|
const mppx = Mppx.create({
|
|
285
277
|
methods: [
|
|
286
|
-
tempo_server.
|
|
278
|
+
tempo_server.session({
|
|
287
279
|
getClient: () => client,
|
|
288
280
|
account: accounts[0],
|
|
289
281
|
currency: asset,
|
|
290
|
-
escrowContract,
|
|
291
282
|
...(feePayer ? { feePayer: accounts[1] } : {}),
|
|
292
283
|
} as any),
|
|
293
284
|
],
|
|
@@ -309,7 +300,6 @@ describe('session', () => {
|
|
|
309
300
|
}
|
|
310
301
|
|
|
311
302
|
beforeAll(async () => {
|
|
312
|
-
escrowContract = await deployEscrow()
|
|
313
303
|
await fundAccount({ address: accounts[1].address, token: Addresses.pathUsd })
|
|
314
304
|
await fundAccount({ address: accounts[1].address, token: asset })
|
|
315
305
|
await fundAccount({ address: accounts[2].address, token: Addresses.pathUsd })
|
package/src/proxy/Proxy.test.ts
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import { Challenge, Credential, Method, Receipt, z } from 'mppx'
|
|
2
2
|
import { Mppx as Mppx_client, tempo as tempo_client } from 'mppx/client'
|
|
3
3
|
import { Mppx as Mppx_server, tempo as tempo_server } from 'mppx/server'
|
|
4
|
-
import
|
|
5
|
-
import { afterEach, beforeAll, describe, expect, test } from 'vp/test'
|
|
4
|
+
import { afterEach, describe, expect, test } from 'vp/test'
|
|
6
5
|
import { tempoNetwork } from '~test/config.js'
|
|
7
6
|
import * as Http from '~test/Http.js'
|
|
8
|
-
import { deployEscrow } from '~test/tempo/legacy/session.js'
|
|
9
7
|
import { accounts, asset, client } from '~test/tempo/viem.js'
|
|
10
8
|
|
|
11
|
-
import { sessionManager } from '../tempo/
|
|
9
|
+
import { sessionManager } from '../tempo/session/client/SessionManager.js'
|
|
12
10
|
import { deserializeSessionReceipt } from '../tempo/session/precompile/Protocol.js'
|
|
13
11
|
import * as ApiProxy from './Proxy.js'
|
|
14
12
|
import * as Service from './Service.js'
|
|
@@ -76,13 +74,6 @@ const mppx_client = Mppx_client.create({
|
|
|
76
74
|
|
|
77
75
|
let upstream: Awaited<ReturnType<typeof Http.createServer>> | undefined
|
|
78
76
|
let proxyServer: Awaited<ReturnType<typeof Http.createServer>> | undefined
|
|
79
|
-
let sessionEscrow: Address
|
|
80
|
-
|
|
81
|
-
beforeAll(async () => {
|
|
82
|
-
if (!isLocalnet) return
|
|
83
|
-
sessionEscrow = await deployEscrow()
|
|
84
|
-
})
|
|
85
|
-
|
|
86
77
|
afterEach(() => {
|
|
87
78
|
upstream?.close()
|
|
88
79
|
proxyServer?.close()
|
|
@@ -181,6 +172,7 @@ describe('create', () => {
|
|
|
181
172
|
})
|
|
182
173
|
|
|
183
174
|
test('behavior: GET /openapi.json returns discovery JSON', async () => {
|
|
175
|
+
const alternateAsset = '0x20c0000000000000000000000000000000000002'
|
|
184
176
|
const proxy = ApiProxy.create({
|
|
185
177
|
categories: ['gateway'],
|
|
186
178
|
docs: {
|
|
@@ -196,6 +188,10 @@ describe('create', () => {
|
|
|
196
188
|
routes: {
|
|
197
189
|
'GET /v1/models': true,
|
|
198
190
|
'POST /v1/generate': mppx_server.charge({ amount: '1', description: 'Generate text' }),
|
|
191
|
+
'POST /v1/multi': mppx_server.compose(
|
|
192
|
+
['tempo/charge', { amount: '1', currency: asset, decimals: 6 }],
|
|
193
|
+
['tempo/charge', { amount: '2', currency: alternateAsset, decimals: 6 }],
|
|
194
|
+
),
|
|
199
195
|
'POST /v1/stream': mppx_server.session({
|
|
200
196
|
amount: '1',
|
|
201
197
|
description: 'Stream text',
|
|
@@ -231,6 +227,20 @@ describe('create', () => {
|
|
|
231
227
|
intent: 'charge',
|
|
232
228
|
method: 'tempo',
|
|
233
229
|
})
|
|
230
|
+
expect(body.paths['/api/v1/multi'].post['x-payment-info'].offers).toEqual([
|
|
231
|
+
expect.objectContaining({
|
|
232
|
+
amount: '1000000',
|
|
233
|
+
currency: asset,
|
|
234
|
+
intent: 'charge',
|
|
235
|
+
method: 'tempo',
|
|
236
|
+
}),
|
|
237
|
+
expect.objectContaining({
|
|
238
|
+
amount: '2000000',
|
|
239
|
+
currency: alternateAsset,
|
|
240
|
+
intent: 'charge',
|
|
241
|
+
method: 'tempo',
|
|
242
|
+
}),
|
|
243
|
+
])
|
|
234
244
|
expect(body.paths['/api/v1/stream'].post['x-payment-info'].offers[0]).toMatchObject({
|
|
235
245
|
amount: '1000000',
|
|
236
246
|
currency: asset,
|
|
@@ -576,7 +586,7 @@ describe('create', () => {
|
|
|
576
586
|
expect(res.status).toBe(402)
|
|
577
587
|
})
|
|
578
588
|
|
|
579
|
-
test('behavior: management POST uses credential
|
|
589
|
+
test('behavior: management POST uses composed credential binding to disambiguate same-path paid routes', async () => {
|
|
580
590
|
const alpha = Method.from({
|
|
581
591
|
name: 'alpha',
|
|
582
592
|
intent: 'charge',
|
|
@@ -631,7 +641,7 @@ describe('create', () => {
|
|
|
631
641
|
Service.from('api', {
|
|
632
642
|
baseUrl: 'https://example.com',
|
|
633
643
|
routes: {
|
|
634
|
-
'GET /v1/stream': handler['alpha/charge'
|
|
644
|
+
'GET /v1/stream': handler.compose(['alpha/charge', { amount: '1' }]),
|
|
635
645
|
'PATCH /v1/stream': handler['beta/charge']({ amount: '1' }),
|
|
636
646
|
},
|
|
637
647
|
}),
|
|
@@ -907,10 +917,9 @@ describe.runIf(isLocalnet)('plain HTTP session proxy', () => {
|
|
|
907
917
|
|
|
908
918
|
const sessionHandler = Mppx_server.create({
|
|
909
919
|
methods: [
|
|
910
|
-
tempo_server.
|
|
920
|
+
tempo_server.session({
|
|
911
921
|
account: accounts[0],
|
|
912
922
|
currency: asset,
|
|
913
|
-
escrowContract: sessionEscrow,
|
|
914
923
|
getClient: () => client,
|
|
915
924
|
chainId: client.chain!.id,
|
|
916
925
|
}),
|
|
@@ -937,7 +946,6 @@ describe.runIf(isLocalnet)('plain HTTP session proxy', () => {
|
|
|
937
946
|
const manager = sessionManager({
|
|
938
947
|
account: accounts[1],
|
|
939
948
|
client,
|
|
940
|
-
escrowContract: sessionEscrow,
|
|
941
949
|
fetch: globalThis.fetch,
|
|
942
950
|
maxDeposit: '3',
|
|
943
951
|
})
|
|
@@ -967,10 +975,9 @@ describe.runIf(isLocalnet)('plain HTTP session proxy', () => {
|
|
|
967
975
|
|
|
968
976
|
const sessionHandler = Mppx_server.create({
|
|
969
977
|
methods: [
|
|
970
|
-
tempo_server.
|
|
978
|
+
tempo_server.session({
|
|
971
979
|
account: accounts[0],
|
|
972
980
|
currency: asset,
|
|
973
|
-
escrowContract: sessionEscrow,
|
|
974
981
|
getClient: () => client,
|
|
975
982
|
chainId: client.chain!.id,
|
|
976
983
|
}),
|
|
@@ -997,7 +1004,7 @@ describe.runIf(isLocalnet)('plain HTTP session proxy', () => {
|
|
|
997
1004
|
const sessionClient = Mppx_client.create({
|
|
998
1005
|
polyfill: false,
|
|
999
1006
|
methods: [
|
|
1000
|
-
tempo_client.
|
|
1007
|
+
tempo_client.session({
|
|
1001
1008
|
account: accounts[1],
|
|
1002
1009
|
getClient: () => client,
|
|
1003
1010
|
maxDeposit: '2',
|
package/src/proxy/Proxy.ts
CHANGED
|
@@ -128,7 +128,14 @@ export function create(config: create.Config): Proxy {
|
|
|
128
128
|
const endpoint = matched.value as Service.Endpoint
|
|
129
129
|
const ctx: Service.Context = { request, service, upstreamPath }
|
|
130
130
|
|
|
131
|
-
if (endpoint === true)
|
|
131
|
+
if (endpoint === true)
|
|
132
|
+
return proxyUpstream({
|
|
133
|
+
request,
|
|
134
|
+
service,
|
|
135
|
+
ctx,
|
|
136
|
+
proxy,
|
|
137
|
+
onUpstreamError: service.onUpstreamError ?? config.onUpstreamError,
|
|
138
|
+
})
|
|
132
139
|
|
|
133
140
|
const handler = typeof endpoint === 'function' ? endpoint : endpoint.pay
|
|
134
141
|
const scope =
|
|
@@ -161,6 +168,7 @@ export function create(config: create.Config): Proxy {
|
|
|
161
168
|
service,
|
|
162
169
|
ctx: { ...ctx, ...options },
|
|
163
170
|
proxy,
|
|
171
|
+
onUpstreamError: service.onUpstreamError ?? config.onUpstreamError,
|
|
164
172
|
})
|
|
165
173
|
return result.withReceipt(upstreamRes)
|
|
166
174
|
}
|
|
@@ -183,6 +191,8 @@ export declare namespace create {
|
|
|
183
191
|
docs?: Service.Docs | undefined
|
|
184
192
|
/** Custom `fetch` implementation. Defaults to `globalThis.fetch`. */
|
|
185
193
|
fetch?: typeof globalThis.fetch | undefined
|
|
194
|
+
/** Default handler for failed upstream attempts. Services may override it. */
|
|
195
|
+
onUpstreamError?: Service.UpstreamErrorHandler | undefined
|
|
186
196
|
/** Services to proxy. Each service is mounted at `/{serviceId}/`. */
|
|
187
197
|
services: Service.Service[]
|
|
188
198
|
/** Human-readable title for the proxy shown in `llms.txt`. */
|
|
@@ -195,6 +205,7 @@ export declare namespace create {
|
|
|
195
205
|
declare namespace proxyUpstream {
|
|
196
206
|
type Options = {
|
|
197
207
|
ctx: Service.Context
|
|
208
|
+
onUpstreamError?: Service.UpstreamErrorHandler | undefined
|
|
198
209
|
proxy: (input: URL | RequestInfo, init?: RequestInit) => Promise<Response>
|
|
199
210
|
request: globalThis.Request
|
|
200
211
|
service: Service.Service
|
|
@@ -203,7 +214,7 @@ declare namespace proxyUpstream {
|
|
|
203
214
|
|
|
204
215
|
/** @internal */
|
|
205
216
|
async function proxyUpstream(options: proxyUpstream.Options): Promise<Response> {
|
|
206
|
-
const { request, service, ctx, proxy } = options
|
|
217
|
+
const { request, service, ctx, proxy, onUpstreamError } = options
|
|
207
218
|
const url = ctx.upstreamPath + new URL(request.url).search
|
|
208
219
|
const headers = Headers.scrub(request.headers)
|
|
209
220
|
|
|
@@ -221,17 +232,137 @@ async function proxyUpstream(options: proxyUpstream.Options): Promise<Response>
|
|
|
221
232
|
init.duplex = 'half'
|
|
222
233
|
}
|
|
223
234
|
|
|
224
|
-
|
|
235
|
+
const upstreamRequest = new globalThis.Request(
|
|
236
|
+
new URL(url, new URL(service.baseUrl).origin),
|
|
237
|
+
init,
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
if (!onUpstreamError)
|
|
241
|
+
return proxyUpstreamOnce({
|
|
242
|
+
ctx,
|
|
243
|
+
proxy,
|
|
244
|
+
service,
|
|
245
|
+
upstreamRequest,
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
for (let attempt = 1; ; attempt++) {
|
|
249
|
+
const outcome = await proxyUpstreamAttempt({
|
|
250
|
+
ctx,
|
|
251
|
+
proxy,
|
|
252
|
+
service,
|
|
253
|
+
upstreamRequest,
|
|
254
|
+
})
|
|
255
|
+
|
|
256
|
+
let response = outcome.response
|
|
257
|
+
if (response && service.rewriteResponse) response = await service.rewriteResponse(response, ctx)
|
|
258
|
+
if (response?.ok) return response
|
|
259
|
+
|
|
260
|
+
const handlerResponse = response?.clone()
|
|
225
261
|
|
|
226
|
-
|
|
262
|
+
const action = await onUpstreamError({
|
|
263
|
+
...ctx,
|
|
264
|
+
attempt,
|
|
265
|
+
error: outcome.error,
|
|
266
|
+
response: handlerResponse,
|
|
267
|
+
upstreamRequest: outcome.upstreamRequest,
|
|
268
|
+
})
|
|
269
|
+
|
|
270
|
+
if (!action.retry) {
|
|
271
|
+
if (action.response) {
|
|
272
|
+
if (response) void cancelResponseBody(response)
|
|
273
|
+
return action.response
|
|
274
|
+
}
|
|
275
|
+
if (response) {
|
|
276
|
+
if (handlerResponse) void cancelResponseBody(handlerResponse)
|
|
277
|
+
return response
|
|
278
|
+
}
|
|
279
|
+
throw outcome.error
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
for (const failedResponse of [response, handlerResponse])
|
|
283
|
+
if (failedResponse) void cancelResponseBody(failedResponse)
|
|
284
|
+
await waitForRetry(action.delay, request.signal)
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/** Proxies one request without retaining a replay copy of its body. */
|
|
289
|
+
async function proxyUpstreamOnce(options: proxyUpstreamAttempt.Options): Promise<Response> {
|
|
290
|
+
const { ctx, proxy, service } = options
|
|
291
|
+
let upstreamRequest = options.upstreamRequest
|
|
227
292
|
|
|
228
|
-
|
|
293
|
+
if (service.rewriteRequest) upstreamRequest = await service.rewriteRequest(upstreamRequest, ctx)
|
|
229
294
|
|
|
230
|
-
|
|
295
|
+
let response = await proxy(upstreamRequest)
|
|
296
|
+
response = Headers.scrubResponse(response)
|
|
231
297
|
|
|
232
|
-
if (service.rewriteResponse)
|
|
298
|
+
if (service.rewriteResponse) response = await service.rewriteResponse(response, ctx)
|
|
233
299
|
|
|
234
|
-
return
|
|
300
|
+
return response
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
declare namespace proxyUpstreamAttempt {
|
|
304
|
+
type Options = {
|
|
305
|
+
ctx: Service.Context
|
|
306
|
+
proxy: (input: URL | RequestInfo, init?: RequestInit) => Promise<Response>
|
|
307
|
+
service: Service.Service
|
|
308
|
+
upstreamRequest: Request
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
type Result = {
|
|
312
|
+
error: unknown | undefined
|
|
313
|
+
response: Response | undefined
|
|
314
|
+
upstreamRequest: Request
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/** Performs one independently replayable upstream request attempt. */
|
|
319
|
+
async function proxyUpstreamAttempt(
|
|
320
|
+
options: proxyUpstreamAttempt.Options,
|
|
321
|
+
): Promise<proxyUpstreamAttempt.Result> {
|
|
322
|
+
const { ctx, proxy, service } = options
|
|
323
|
+
let upstreamRequest = options.upstreamRequest.clone()
|
|
324
|
+
|
|
325
|
+
try {
|
|
326
|
+
if (service.rewriteRequest) upstreamRequest = await service.rewriteRequest(upstreamRequest, ctx)
|
|
327
|
+
|
|
328
|
+
let response = await proxy(upstreamRequest)
|
|
329
|
+
response = Headers.scrubResponse(response)
|
|
330
|
+
|
|
331
|
+
return { error: undefined, response, upstreamRequest }
|
|
332
|
+
} catch (error) {
|
|
333
|
+
return { error, response: undefined, upstreamRequest }
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/** Cancels an unused failed response body before a retry. */
|
|
338
|
+
async function cancelResponseBody(response: Response): Promise<void> {
|
|
339
|
+
if (!response.body || response.bodyUsed) return
|
|
340
|
+
try {
|
|
341
|
+
await response.body.cancel()
|
|
342
|
+
} catch {
|
|
343
|
+
return
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/** Waits for a retry delay while respecting request cancellation. */
|
|
348
|
+
async function waitForRetry(delay = 0, signal: AbortSignal): Promise<void> {
|
|
349
|
+
if (signal.aborted)
|
|
350
|
+
throw signal.reason ?? new DOMException('The operation was aborted.', 'AbortError')
|
|
351
|
+
if (!Number.isFinite(delay) || delay <= 0) return
|
|
352
|
+
|
|
353
|
+
await new Promise<void>((resolve, reject) => {
|
|
354
|
+
const onAbort = () => {
|
|
355
|
+
clearTimeout(timeout)
|
|
356
|
+
signal.removeEventListener('abort', onAbort)
|
|
357
|
+
reject(signal.reason ?? new DOMException('The operation was aborted.', 'AbortError'))
|
|
358
|
+
}
|
|
359
|
+
const timeout = setTimeout(() => {
|
|
360
|
+
signal.removeEventListener('abort', onAbort)
|
|
361
|
+
resolve()
|
|
362
|
+
}, delay)
|
|
363
|
+
signal.addEventListener('abort', onAbort, { once: true })
|
|
364
|
+
if (signal.aborted) onAbort()
|
|
365
|
+
})
|
|
235
366
|
}
|
|
236
367
|
|
|
237
368
|
function buildDiscoveryRoutes(services: Service.Service[]) {
|
|
@@ -310,7 +441,14 @@ function matchesPaymentBinding(endpoint: unknown, binding: PaymentBinding | null
|
|
|
310
441
|
if (!binding) return true
|
|
311
442
|
const payment = Service.paymentOf(endpoint as Exclude<Service.Endpoint, true>)
|
|
312
443
|
if (!payment) return true
|
|
313
|
-
|
|
444
|
+
const offers = Array.isArray(payment.offers) ? payment.offers : [payment]
|
|
445
|
+
return offers.some(
|
|
446
|
+
(offer) =>
|
|
447
|
+
typeof offer === 'object' &&
|
|
448
|
+
offer !== null &&
|
|
449
|
+
offer.method === binding.method &&
|
|
450
|
+
offer.intent === binding.intent,
|
|
451
|
+
)
|
|
314
452
|
}
|
|
315
453
|
|
|
316
454
|
function createFetchProxy(
|