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
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { TempoAddress } from 'ox/tempo'
|
|
2
|
+
import { describe, expect, test } from 'vp/test'
|
|
3
|
+
|
|
4
|
+
import { isEqual } from './address.js'
|
|
5
|
+
|
|
6
|
+
const address = '0x742d35Cc6634C0532925a3b844Bc9e7595F2bD28'
|
|
7
|
+
const otherAddress = '0x52908400098527886E0F7030069857D2E4169EE7'
|
|
8
|
+
|
|
9
|
+
describe('isEqual', () => {
|
|
10
|
+
const representations = [
|
|
11
|
+
{ name: 'mixed-case hex', value: address },
|
|
12
|
+
{ name: 'lowercase hex', value: address.toLowerCase() as `0x${string}` },
|
|
13
|
+
{ name: 'Tempo-formatted', value: TempoAddress.format(address) },
|
|
14
|
+
] as const
|
|
15
|
+
|
|
16
|
+
const otherRepresentations = [
|
|
17
|
+
{ name: 'mixed-case hex', value: otherAddress },
|
|
18
|
+
{ name: 'lowercase hex', value: otherAddress.toLowerCase() as `0x${string}` },
|
|
19
|
+
{ name: 'Tempo-formatted', value: TempoAddress.format(otherAddress) },
|
|
20
|
+
] as const
|
|
21
|
+
|
|
22
|
+
test.each([
|
|
23
|
+
...representations.flatMap((a) =>
|
|
24
|
+
representations.map((b) => ({
|
|
25
|
+
a: a.value,
|
|
26
|
+
b: b.value,
|
|
27
|
+
expected: true,
|
|
28
|
+
name: `${a.name} and ${b.name} representations of the same address`,
|
|
29
|
+
})),
|
|
30
|
+
),
|
|
31
|
+
...representations.flatMap((a) =>
|
|
32
|
+
otherRepresentations.map((b) => ({
|
|
33
|
+
a: a.value,
|
|
34
|
+
b: b.value,
|
|
35
|
+
expected: false,
|
|
36
|
+
name: `${a.name} and ${b.name} representations of different addresses`,
|
|
37
|
+
})),
|
|
38
|
+
),
|
|
39
|
+
])('$name', ({ a, b, expected }) => {
|
|
40
|
+
expect(isEqual(a, b)).toBe(expected)
|
|
41
|
+
})
|
|
42
|
+
})
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
import type { TempoAddress } from 'ox/tempo'
|
|
1
|
+
import { TempoAddress } from 'ox/tempo'
|
|
3
2
|
|
|
3
|
+
/** Returns whether two hex or Tempo-formatted addresses resolve to the same address. */
|
|
4
4
|
export function isEqual(a: TempoAddress.Address, b: TempoAddress.Address) {
|
|
5
|
-
return a.toLowerCase() === b.toLowerCase()
|
|
5
|
+
return TempoAddress.resolve(a).toLowerCase() === TempoAddress.resolve(b).toLowerCase()
|
|
6
6
|
}
|
|
@@ -103,7 +103,7 @@ describe('resolve', () => {
|
|
|
103
103
|
})
|
|
104
104
|
|
|
105
105
|
describe('findCalls', () => {
|
|
106
|
-
test('
|
|
106
|
+
test('uses current viem Tempo call builder signatures', async () => {
|
|
107
107
|
vi.resetModules()
|
|
108
108
|
const account = '0x1111111111111111111111111111111111111111' as Address
|
|
109
109
|
const tokenOut = '0x2222222222222222222222222222222222222222' as Address
|
|
@@ -122,8 +122,8 @@ describe('findCalls', () => {
|
|
|
122
122
|
return { kind: 'approve' }
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
-
function buyCall(
|
|
126
|
-
builderCalls.push({ client, name: 'buy', parameters })
|
|
125
|
+
function buyCall(parameters: Record<string, unknown>) {
|
|
126
|
+
builderCalls.push({ client: undefined, name: 'buy', parameters })
|
|
127
127
|
return { kind: 'buy' }
|
|
128
128
|
}
|
|
129
129
|
|
|
@@ -158,7 +158,7 @@ describe('findCalls', () => {
|
|
|
158
158
|
})
|
|
159
159
|
|
|
160
160
|
expect(calls).toHaveLength(2)
|
|
161
|
-
expect(builderCalls.map((call) => call.client)).toEqual([client, client, client,
|
|
161
|
+
expect(builderCalls.map((call) => call.client)).toEqual([client, client, client, undefined])
|
|
162
162
|
expect(builderCalls.map((call) => call.name)).toEqual([
|
|
163
163
|
'getBalance',
|
|
164
164
|
'getBalance',
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { Address, Client } from 'viem'
|
|
2
2
|
import { readContract } from 'viem/actions'
|
|
3
3
|
import { Actions, Addresses } from 'viem/tempo'
|
|
4
|
-
import type { dex as viem_dex, token as viem_token } from 'viem/tempo/actions'
|
|
5
4
|
|
|
6
5
|
import * as TempoAddress from './address.js'
|
|
7
6
|
import * as defaults from './defaults.js'
|
|
@@ -15,51 +14,6 @@ export const defaultCurrencies: readonly Address[] = [
|
|
|
15
14
|
defaults.tokens.usdc as Address,
|
|
16
15
|
]
|
|
17
16
|
|
|
18
|
-
// TODO: Remove once the minimum viem version is >=2.54.0, which uses client-first Tempo call builders.
|
|
19
|
-
function getBalanceCall(
|
|
20
|
-
client: Client,
|
|
21
|
-
parameters: viem_token.getBalance.Args,
|
|
22
|
-
): ReturnType<typeof viem_token.getBalance.call> {
|
|
23
|
-
const call = Actions.token.getBalance.call as unknown as {
|
|
24
|
-
length: number
|
|
25
|
-
(parameters: viem_token.getBalance.Args): ReturnType<typeof viem_token.getBalance.call>
|
|
26
|
-
(
|
|
27
|
-
client: Client,
|
|
28
|
-
parameters: viem_token.getBalance.Args,
|
|
29
|
-
): ReturnType<typeof viem_token.getBalance.call>
|
|
30
|
-
}
|
|
31
|
-
return call.length >= 2 ? call(client, parameters) : call(parameters)
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// TODO: Remove once the minimum viem version is >=2.54.0, which uses client-first Tempo call builders.
|
|
35
|
-
function getApproveCall(
|
|
36
|
-
client: Client,
|
|
37
|
-
parameters: viem_token.approve.Args,
|
|
38
|
-
): ReturnType<typeof viem_token.approve.call> {
|
|
39
|
-
const call = Actions.token.approve.call as unknown as {
|
|
40
|
-
length: number
|
|
41
|
-
(parameters: viem_token.approve.Args): ReturnType<typeof viem_token.approve.call>
|
|
42
|
-
(
|
|
43
|
-
client: Client,
|
|
44
|
-
parameters: viem_token.approve.Args,
|
|
45
|
-
): ReturnType<typeof viem_token.approve.call>
|
|
46
|
-
}
|
|
47
|
-
return call.length >= 2 ? call(client, parameters) : call(parameters)
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// TODO: Remove once the minimum viem version is >=2.54.0, which uses client-first Tempo call builders.
|
|
51
|
-
function getBuyCall(
|
|
52
|
-
client: Client,
|
|
53
|
-
parameters: viem_dex.buy.Args,
|
|
54
|
-
): ReturnType<typeof viem_dex.buy.call> {
|
|
55
|
-
const call = Actions.dex.buy.call as unknown as {
|
|
56
|
-
length: number
|
|
57
|
-
(parameters: viem_dex.buy.Args): ReturnType<typeof viem_dex.buy.call>
|
|
58
|
-
(client: Client, parameters: viem_dex.buy.Args): ReturnType<typeof viem_dex.buy.call>
|
|
59
|
-
}
|
|
60
|
-
return call.length >= 2 ? call(client, parameters) : call(parameters)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
17
|
/**
|
|
64
18
|
* Finds the optimal swap calls to acquire `amountOut` of `tokenOut`,
|
|
65
19
|
* returning an approve + buy call sequence if a viable route is found.
|
|
@@ -76,9 +30,12 @@ export async function findCalls(
|
|
|
76
30
|
const candidates = tokenIn.filter((t) => !TempoAddress.isEqual(t, tokenOut))
|
|
77
31
|
|
|
78
32
|
const balanceResults = await Promise.allSettled([
|
|
79
|
-
readContract(
|
|
33
|
+
readContract(
|
|
34
|
+
client,
|
|
35
|
+
Actions.token.getBalance.call(client, { account, token: tokenOut }) as never,
|
|
36
|
+
),
|
|
80
37
|
...candidates.map((t) =>
|
|
81
|
-
readContract(client,
|
|
38
|
+
readContract(client, Actions.token.getBalance.call(client, { account, token: t }) as never),
|
|
82
39
|
),
|
|
83
40
|
])
|
|
84
41
|
|
|
@@ -108,12 +65,12 @@ export async function findCalls(
|
|
|
108
65
|
const maxAmountIn =
|
|
109
66
|
quotedAmountIn + (quotedAmountIn * BigInt(Math.round(slippage * 100))) / bps
|
|
110
67
|
return [
|
|
111
|
-
|
|
68
|
+
Actions.token.approve.call(client, {
|
|
112
69
|
amount: maxAmountIn,
|
|
113
70
|
spender: Addresses.stablecoinDex,
|
|
114
71
|
token: tokenIn,
|
|
115
72
|
}),
|
|
116
|
-
|
|
73
|
+
Actions.dex.buy.call({
|
|
117
74
|
tokenIn,
|
|
118
75
|
tokenOut,
|
|
119
76
|
amountOut,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# Tempo Legacy Session
|
|
2
2
|
|
|
3
|
-
This directory contains the legacy smart-contract-backed
|
|
4
|
-
implementation.
|
|
3
|
+
This directory contains the retained client for the legacy smart-contract-backed
|
|
4
|
+
`tempo/session` implementation.
|
|
5
5
|
|
|
6
6
|
The default `tempo.session` implementation is TIP-1034 precompile-backed and
|
|
7
|
-
lives under `src/tempo/session/precompile`.
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
lives under `src/tempo/session/precompile`. The legacy server implementation has
|
|
8
|
+
been removed, while legacy chain, channel, voucher, and client code remains here
|
|
9
|
+
for clients migrating existing sessions.
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
/** Legacy contract-backed session client surface. */
|
|
2
2
|
export * as Client from './client/index.js'
|
|
3
|
-
/** Legacy contract-backed session
|
|
4
|
-
export * as Server from './server/index.js'
|
|
5
|
-
/** Legacy contract-backed session channel primitives. */
|
|
3
|
+
/** Legacy contract-backed session channel primitives used by the client. */
|
|
6
4
|
export * as Session from './session/index.js'
|
|
@@ -19,6 +19,19 @@ test('tempo.charge store parameter requires AtomicStore', () => {
|
|
|
19
19
|
tempo.charge({ store: Store.memory() })
|
|
20
20
|
})
|
|
21
21
|
|
|
22
|
+
test('tempo.charge sponsor budget store requires AtomicStore', () => {
|
|
23
|
+
const nonAtomic = Store.from({
|
|
24
|
+
get: async () => null,
|
|
25
|
+
put: async () => {},
|
|
26
|
+
delete: async () => {},
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
tempo.charge({ sponsorBudget: false })
|
|
30
|
+
// @ts-expect-error — sponsor budget coordination requires AtomicStore
|
|
31
|
+
tempo.charge({ sponsorBudget: { store: nonAtomic } })
|
|
32
|
+
tempo.charge({ sponsorBudget: { store: Store.memory() } })
|
|
33
|
+
})
|
|
34
|
+
|
|
22
35
|
test('tempo.session store parameter requires AtomicStore', () => {
|
|
23
36
|
type SessionParameters = NonNullable<Parameters<typeof tempo.session>[0]>
|
|
24
37
|
expectTypeOf<SessionParameters['store']>().toEqualTypeOf<Store.AtomicStore | undefined>()
|
|
@@ -16,12 +16,6 @@ import { Abis, Account, Actions, Addresses, Secp256k1, Tick, Transaction } from
|
|
|
16
16
|
import type { token as viem_token } from 'viem/tempo/actions'
|
|
17
17
|
import { beforeAll, describe, expect, test } from 'vp/test'
|
|
18
18
|
import * as Http from '~test/Http.js'
|
|
19
|
-
import {
|
|
20
|
-
closeChannelOnChain,
|
|
21
|
-
deployEscrow,
|
|
22
|
-
openChannel,
|
|
23
|
-
signVoucher,
|
|
24
|
-
} from '~test/tempo/legacy/session.js'
|
|
25
19
|
import { accounts, asset, chain, client, fundAccount, http } from '~test/tempo/viem.js'
|
|
26
20
|
|
|
27
21
|
import * as Store from '../../Store.js'
|
|
@@ -58,18 +52,8 @@ function sponsoredFeeExposure(credential: string) {
|
|
|
58
52
|
return transaction.gas * transaction.maxFeePerGas
|
|
59
53
|
}
|
|
60
54
|
|
|
61
|
-
// TODO: Remove once the minimum viem version is >=2.54.0, which uses client-first Tempo call builders.
|
|
62
55
|
function tokenTransferCall(parameters: viem_token.transfer.Args) {
|
|
63
|
-
|
|
64
|
-
length: number
|
|
65
|
-
(parameters: viem_token.transfer.Args): ReturnType<typeof viem_token.transfer.call>
|
|
66
|
-
(
|
|
67
|
-
client: unknown,
|
|
68
|
-
parameters: viem_token.transfer.Args,
|
|
69
|
-
): ReturnType<typeof viem_token.transfer.call>
|
|
70
|
-
}
|
|
71
|
-
if (call.length >= 2) return call(client, parameters)
|
|
72
|
-
return call(parameters)
|
|
56
|
+
return Actions.token.transfer.call(client, parameters)
|
|
73
57
|
}
|
|
74
58
|
|
|
75
59
|
type ProofAccessKeyContext = {
|
|
@@ -92,6 +76,21 @@ const server = Mppx_server.create({
|
|
|
92
76
|
})
|
|
93
77
|
|
|
94
78
|
describe('tempo', () => {
|
|
79
|
+
describe('sponsor budget configuration', () => {
|
|
80
|
+
test('validates structured limits', () => {
|
|
81
|
+
expect(() => tempo_server.charge({ sponsorBudget: { maxInFlightReservations: 0 } })).toThrow(
|
|
82
|
+
'`sponsorBudget.maxInFlightReservations` must be a positive safe integer.',
|
|
83
|
+
)
|
|
84
|
+
expect(() => tempo_server.charge({ sponsorBudget: { maxInFlightTotalFee: 0n } })).toThrow(
|
|
85
|
+
'`sponsorBudget.maxInFlightTotalFee` must be greater than zero.',
|
|
86
|
+
)
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
test('allows aggregate exposure to be enforced externally', () => {
|
|
90
|
+
expect(() => tempo_server.charge({ sponsorBudget: false })).not.toThrow()
|
|
91
|
+
})
|
|
92
|
+
})
|
|
93
|
+
|
|
95
94
|
describe('intent: charge; type: hash', () => {
|
|
96
95
|
test('default', async () => {
|
|
97
96
|
const mppx = Mppx_client.create({
|
|
@@ -581,72 +580,6 @@ describe('tempo', () => {
|
|
|
581
580
|
httpServer.close()
|
|
582
581
|
})
|
|
583
582
|
|
|
584
|
-
test('behavior: rejects session settlement tx hash used as charge credential', async () => {
|
|
585
|
-
const chargeAmount = parseUnits('1', 6)
|
|
586
|
-
const recipient = accounts[0].address
|
|
587
|
-
const external = accounts[3]
|
|
588
|
-
|
|
589
|
-
const escrow = await deployEscrow()
|
|
590
|
-
|
|
591
|
-
await fundAccount({ address: external.address, token: Addresses.pathUsd })
|
|
592
|
-
await fundAccount({ address: external.address, token: asset })
|
|
593
|
-
|
|
594
|
-
const salt = '0x0000000000000000000000000000000000000000000000000000000000000001' as Hex.Hex
|
|
595
|
-
const { channelId } = await openChannel({
|
|
596
|
-
escrow,
|
|
597
|
-
payer: external,
|
|
598
|
-
payee: recipient,
|
|
599
|
-
token: asset,
|
|
600
|
-
deposit: chargeAmount,
|
|
601
|
-
salt,
|
|
602
|
-
})
|
|
603
|
-
|
|
604
|
-
const voucherSig = await signVoucher(
|
|
605
|
-
client,
|
|
606
|
-
external,
|
|
607
|
-
{ channelId, cumulativeAmount: chargeAmount },
|
|
608
|
-
escrow,
|
|
609
|
-
chain.id,
|
|
610
|
-
)
|
|
611
|
-
|
|
612
|
-
const { txHash: settleTxHash } = await closeChannelOnChain({
|
|
613
|
-
escrow,
|
|
614
|
-
payee: accounts[0],
|
|
615
|
-
channelId,
|
|
616
|
-
cumulativeAmount: chargeAmount,
|
|
617
|
-
signature: voucherSig,
|
|
618
|
-
})
|
|
619
|
-
|
|
620
|
-
const httpServer = await Http.createServer(async (req, res) => {
|
|
621
|
-
const result = await Mppx_server.toNodeListener(server.charge({ amount: '1' }))(req, res)
|
|
622
|
-
if (result.status === 402) return
|
|
623
|
-
res.end('OK')
|
|
624
|
-
})
|
|
625
|
-
|
|
626
|
-
const response = await fetch(httpServer.url)
|
|
627
|
-
expect(response.status).toBe(402)
|
|
628
|
-
|
|
629
|
-
const challenge = Challenge.fromResponse(response, {
|
|
630
|
-
methods: [tempo_client.charge()],
|
|
631
|
-
})
|
|
632
|
-
|
|
633
|
-
const credential = Credential.from({
|
|
634
|
-
challenge,
|
|
635
|
-
payload: { hash: settleTxHash, type: 'hash' as const },
|
|
636
|
-
})
|
|
637
|
-
|
|
638
|
-
{
|
|
639
|
-
const response = await fetch(httpServer.url, {
|
|
640
|
-
headers: { Authorization: Credential.serialize(credential) },
|
|
641
|
-
})
|
|
642
|
-
expect(response.status).toBe(402)
|
|
643
|
-
const body = (await response.json()) as { detail: string }
|
|
644
|
-
expect(body.detail).toContain('Payment verification failed: no matching transfer found.')
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
httpServer.close()
|
|
648
|
-
})
|
|
649
|
-
|
|
650
583
|
test('behavior: rejects replayed transaction hash', async () => {
|
|
651
584
|
const dedupServer = Mppx_server.create({
|
|
652
585
|
methods: [
|
|
@@ -1976,6 +1909,7 @@ describe('tempo', () => {
|
|
|
1976
1909
|
}),
|
|
1977
1910
|
})
|
|
1978
1911
|
|
|
1912
|
+
const replayStore = Store.memory()
|
|
1979
1913
|
const sponsoredStore = Store.memory()
|
|
1980
1914
|
const serverWithSlowSimulation = Mppx_server.create({
|
|
1981
1915
|
methods: [
|
|
@@ -1985,7 +1919,8 @@ describe('tempo', () => {
|
|
|
1985
1919
|
},
|
|
1986
1920
|
currency: asset,
|
|
1987
1921
|
account: accounts[0],
|
|
1988
|
-
store: sponsoredStore,
|
|
1922
|
+
sponsorBudget: { store: sponsoredStore },
|
|
1923
|
+
store: replayStore,
|
|
1989
1924
|
storeKeyPrefix: 'tenant:',
|
|
1990
1925
|
}),
|
|
1991
1926
|
],
|
|
@@ -67,6 +67,7 @@ export function charge<const parameters extends charge.Parameters>(
|
|
|
67
67
|
html,
|
|
68
68
|
memo,
|
|
69
69
|
relay,
|
|
70
|
+
sponsorBudget,
|
|
70
71
|
splits,
|
|
71
72
|
supportedModes,
|
|
72
73
|
validateSender,
|
|
@@ -75,21 +76,31 @@ export function charge<const parameters extends charge.Parameters>(
|
|
|
75
76
|
const storeKeyPrefix = parameters.storeKeyPrefix ?? ''
|
|
76
77
|
const rawStore = (parameters.store ?? Store.memory()) as Store.AtomicStore<charge.StoreItemMap>
|
|
77
78
|
const store = Store.from(rawStore, { keyPrefix: storeKeyPrefix })
|
|
78
|
-
// Aggregate exposure belongs to the actual sponsor, not a caller-specific
|
|
79
|
-
// replay namespace. Sharing the raw store gives every tenant/process the same
|
|
80
|
-
// atomic sponsor-wide budget.
|
|
81
|
-
const sponsorBudgetStore = Store.from(rawStore) as Store.AtomicStore<{
|
|
82
|
-
[key: `mppx:charge:sponsor-budget:${string}`]: SponsorBudget.State
|
|
83
|
-
}>
|
|
84
79
|
const {
|
|
85
|
-
maxInFlightReservations
|
|
86
|
-
maxInFlightTotalFee
|
|
80
|
+
maxInFlightReservations: legacyMaxInFlightReservations,
|
|
81
|
+
maxInFlightTotalFee: legacyMaxInFlightTotalFee,
|
|
87
82
|
...transactionFeePayerPolicy
|
|
88
83
|
} = feePayerPolicy ?? {}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
84
|
+
const sponsorBudgetConfig = sponsorBudget === false ? undefined : (sponsorBudget ?? {})
|
|
85
|
+
const maxInFlightReservations =
|
|
86
|
+
sponsorBudgetConfig?.maxInFlightReservations ?? legacyMaxInFlightReservations ?? 100
|
|
87
|
+
const maxInFlightTotalFee =
|
|
88
|
+
sponsorBudgetConfig?.maxInFlightTotalFee ??
|
|
89
|
+
legacyMaxInFlightTotalFee ??
|
|
90
|
+
(feePayerPolicy?.maxTotalFee ?? 50_000_000_000_000_000n) * 10n
|
|
91
|
+
if (sponsorBudgetConfig) {
|
|
92
|
+
if (!Number.isSafeInteger(maxInFlightReservations) || maxInFlightReservations <= 0)
|
|
93
|
+
throw new Error('`sponsorBudget.maxInFlightReservations` must be a positive safe integer.')
|
|
94
|
+
if (maxInFlightTotalFee <= 0n)
|
|
95
|
+
throw new Error('`sponsorBudget.maxInFlightTotalFee` must be greater than zero.')
|
|
96
|
+
}
|
|
97
|
+
// Aggregate exposure belongs to the actual sponsor, not a caller-specific replay namespace.
|
|
98
|
+
// Keep it unprefixed and shared across every tenant/process using the sponsor.
|
|
99
|
+
const sponsorBudgetStore = sponsorBudgetConfig
|
|
100
|
+
? (Store.from(sponsorBudgetConfig.store ?? rawStore) as Store.AtomicStore<{
|
|
101
|
+
[key: `mppx:charge:sponsor-budget:${string}`]: SponsorBudget.State
|
|
102
|
+
}>)
|
|
103
|
+
: undefined
|
|
93
104
|
const proofStore = parameters.store
|
|
94
105
|
? Store.from(parameters.store as Store.AtomicStore<charge.StoreItemMap>, {
|
|
95
106
|
keyPrefix: storeKeyPrefix,
|
|
@@ -360,6 +371,8 @@ export function charge<const parameters extends charge.Parameters>(
|
|
|
360
371
|
|
|
361
372
|
type Defaults = charge.DeriveDefaults<parameters>
|
|
362
373
|
const method = Method.toServer<typeof Methods.charge, Defaults>(Methods.charge, {
|
|
374
|
+
canOffer: parameters.canOffer,
|
|
375
|
+
onPaymentSuccess: parameters.onPaymentSuccess,
|
|
363
376
|
defaults: {
|
|
364
377
|
amount,
|
|
365
378
|
currency,
|
|
@@ -475,11 +488,13 @@ export function charge<const parameters extends charge.Parameters>(
|
|
|
475
488
|
: feePayer
|
|
476
489
|
: undefined
|
|
477
490
|
const expires = challenge.expires
|
|
491
|
+
Expires.assert(expires, challenge.id)
|
|
492
|
+
const replayExpires = Date.parse(expires)
|
|
478
493
|
|
|
479
494
|
switch (validated.type) {
|
|
480
495
|
case 'hash': {
|
|
481
496
|
const { hash, receipt } = validated
|
|
482
|
-
if (!(await
|
|
497
|
+
if (!(await tryClaimHash(store, hash, replayExpires))) {
|
|
483
498
|
throw new VerificationFailedError({
|
|
484
499
|
reason: 'Transaction hash has already been used',
|
|
485
500
|
})
|
|
@@ -488,7 +503,7 @@ export function charge<const parameters extends charge.Parameters>(
|
|
|
488
503
|
}
|
|
489
504
|
|
|
490
505
|
case 'proof': {
|
|
491
|
-
if (proofStore && !(await
|
|
506
|
+
if (proofStore && !(await tryClaimProof(proofStore, challenge.id, replayExpires))) {
|
|
492
507
|
throw new VerificationFailedError({
|
|
493
508
|
reason: 'Proof credential has already been used',
|
|
494
509
|
})
|
|
@@ -507,7 +522,7 @@ export function charge<const parameters extends charge.Parameters>(
|
|
|
507
522
|
|
|
508
523
|
// Pre-broadcast dedup: catch exact byte-for-byte replays early.
|
|
509
524
|
const hash = keccak256(serializedTransaction)
|
|
510
|
-
if (!(await
|
|
525
|
+
if (!(await tryClaimHash(store, hash, replayExpires))) {
|
|
511
526
|
throw new VerificationFailedError({
|
|
512
527
|
reason: 'Transaction hash has already been used',
|
|
513
528
|
})
|
|
@@ -589,7 +604,7 @@ export function charge<const parameters extends charge.Parameters>(
|
|
|
589
604
|
|
|
590
605
|
if (
|
|
591
606
|
finalHash.toLowerCase() !== hash.toLowerCase() &&
|
|
592
|
-
!(await
|
|
607
|
+
!(await tryClaimHash(store, finalHash, replayExpires))
|
|
593
608
|
)
|
|
594
609
|
throw new VerificationFailedError({
|
|
595
610
|
reason: 'Transaction hash has already been used',
|
|
@@ -614,20 +629,21 @@ export function charge<const parameters extends charge.Parameters>(
|
|
|
614
629
|
expiresAt,
|
|
615
630
|
expires ? Date.parse(expires) : Number.MAX_SAFE_INTEGER,
|
|
616
631
|
)
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
632
|
+
if (sponsorBudgetStore)
|
|
633
|
+
reservation = await SponsorBudget.reserve(sponsorBudgetStore, {
|
|
634
|
+
chainId: reservationChainId,
|
|
635
|
+
expiresAt,
|
|
636
|
+
fee: totalFee,
|
|
637
|
+
getReceipt: (transactionHash) =>
|
|
638
|
+
getTransactionReceipt(client, { hash: transactionHash }),
|
|
639
|
+
id: finalHash.toLowerCase(),
|
|
640
|
+
maxReservations: maxInFlightReservations,
|
|
641
|
+
maxTotalFee: maxInFlightTotalFee,
|
|
642
|
+
owner: globalThis.crypto.randomUUID(),
|
|
643
|
+
sponsor,
|
|
644
|
+
transactionHash: finalHash,
|
|
645
|
+
waitUntil,
|
|
646
|
+
})
|
|
631
647
|
Expires.assert(challenge.expires, challenge.id)
|
|
632
648
|
}
|
|
633
649
|
|
|
@@ -640,7 +656,7 @@ export function charge<const parameters extends charge.Parameters>(
|
|
|
640
656
|
|
|
641
657
|
if (
|
|
642
658
|
reservation &&
|
|
643
|
-
!(await SponsorBudget.transition(sponsorBudgetStore
|
|
659
|
+
!(await SponsorBudget.transition(sponsorBudgetStore!, reservation, 'broadcasting'))
|
|
644
660
|
)
|
|
645
661
|
throw new VerificationFailedError({
|
|
646
662
|
reason: 'Sponsor budget reservation ownership was lost before broadcast',
|
|
@@ -651,7 +667,7 @@ export function charge<const parameters extends charge.Parameters>(
|
|
|
651
667
|
const receipt = await sendRawTransactionSync(client, {
|
|
652
668
|
serializedTransaction: serializedTransaction_final,
|
|
653
669
|
})
|
|
654
|
-
if (reservation) await SponsorBudget.release(sponsorBudgetStore
|
|
670
|
+
if (reservation) await SponsorBudget.release(sponsorBudgetStore!, reservation)
|
|
655
671
|
const matchedLogs = await assertTransferLogs(receipt, {
|
|
656
672
|
currency,
|
|
657
673
|
sender: transaction.from! as `0x${string}`,
|
|
@@ -681,7 +697,7 @@ export function charge<const parameters extends charge.Parameters>(
|
|
|
681
697
|
})
|
|
682
698
|
if (
|
|
683
699
|
reservation &&
|
|
684
|
-
!(await SponsorBudget.transition(sponsorBudgetStore
|
|
700
|
+
!(await SponsorBudget.transition(sponsorBudgetStore!, reservation, 'pending'))
|
|
685
701
|
)
|
|
686
702
|
throw new VerificationFailedError({
|
|
687
703
|
reason: 'Sponsor budget reservation ownership was lost after broadcast',
|
|
@@ -694,7 +710,7 @@ export function charge<const parameters extends charge.Parameters>(
|
|
|
694
710
|
} as const
|
|
695
711
|
} catch (error) {
|
|
696
712
|
if (!broadcastAttempted) {
|
|
697
|
-
if (reservation) await SponsorBudget.release(sponsorBudgetStore
|
|
713
|
+
if (reservation) await SponsorBudget.release(sponsorBudgetStore!, reservation)
|
|
698
714
|
if (finalHash && finalHash.toLowerCase() !== hash.toLowerCase())
|
|
699
715
|
await releaseHashUse(store, finalHash)
|
|
700
716
|
await releaseHashUse(store, hash)
|
|
@@ -710,7 +726,7 @@ export function charge<const parameters extends charge.Parameters>(
|
|
|
710
726
|
|
|
711
727
|
export declare namespace charge {
|
|
712
728
|
type StoreItemMap = {
|
|
713
|
-
[key: `mppx:charge:${string}`]: number | SponsorBudget.State
|
|
729
|
+
[key: `mppx:charge:${string}`]: number | SponsorBudget.State | Store.ReplayMarker
|
|
714
730
|
}
|
|
715
731
|
|
|
716
732
|
type Defaults = LooseOmit<Method.RequestDefaults<typeof Methods.charge>, 'feePayer' | 'recipient'>
|
|
@@ -739,13 +755,8 @@ export declare namespace charge {
|
|
|
739
755
|
/**
|
|
740
756
|
* Override the fee-sponsor policy used when co-signing Tempo charge
|
|
741
757
|
* transactions. Defaults resolve per chain, including a higher
|
|
742
|
-
* priority-fee ceiling on Moderato
|
|
743
|
-
*
|
|
744
|
-
* atomically; independent expiring-nonce transactions run concurrently
|
|
745
|
-
* while capacity remains and wait for capacity when the budget is full.
|
|
746
|
-
*
|
|
747
|
-
* If you increase `maxGas`, `maxFeePerGas`, or `maxTotalFee`, you may also
|
|
748
|
-
* need to raise `maxInFlightTotalFee`.
|
|
758
|
+
* priority-fee ceiling on Moderato. Aggregate in-flight exposure is
|
|
759
|
+
* configured separately with `sponsorBudget`.
|
|
749
760
|
*/
|
|
750
761
|
feePayerPolicy?: FeePayerPolicy | undefined
|
|
751
762
|
/**
|
|
@@ -785,8 +796,24 @@ export declare namespace charge {
|
|
|
785
796
|
* By default, no prefix is applied.
|
|
786
797
|
*/
|
|
787
798
|
storeKeyPrefix?: string | undefined
|
|
788
|
-
/**
|
|
799
|
+
/**
|
|
800
|
+
* Delegates Tempo charge credential validation and broadcast to Tempo API
|
|
801
|
+
* or a compatible MPP relay.
|
|
802
|
+
*
|
|
803
|
+
* The adapter delegates finalization to the relay for both modes. The
|
|
804
|
+
* relay broadcasts pull credentials, while it recognizes a push
|
|
805
|
+
* credential as already broadcast and returns its receipt without sending
|
|
806
|
+
* it again.
|
|
807
|
+
*/
|
|
789
808
|
relay?: RelayOptions | undefined
|
|
809
|
+
/**
|
|
810
|
+
* Configures aggregate in-flight fee exposure for sponsored transactions.
|
|
811
|
+
*
|
|
812
|
+
* Set to `false` only when aggregate exposure is enforced outside mppx.
|
|
813
|
+
* The configured store must be shared by every process using the sponsor.
|
|
814
|
+
* @default `{}`
|
|
815
|
+
*/
|
|
816
|
+
sponsorBudget?: SponsorBudgetConfig | false | undefined
|
|
790
817
|
/**
|
|
791
818
|
* Whether to wait for the charge transaction to confirm on-chain before
|
|
792
819
|
* responding. @default true
|
|
@@ -801,7 +828,8 @@ export declare namespace charge {
|
|
|
801
828
|
waitForConfirmation?: boolean | undefined
|
|
802
829
|
} & Client.getResolver.Parameters &
|
|
803
830
|
Account.resolve.Parameters &
|
|
804
|
-
Defaults
|
|
831
|
+
Defaults &
|
|
832
|
+
Method.ComposableHooks<typeof Methods.charge>
|
|
805
833
|
|
|
806
834
|
type DeriveDefaults<parameters extends Parameters> = types.DeriveDefaults<
|
|
807
835
|
parameters,
|
|
@@ -813,16 +841,28 @@ export declare namespace charge {
|
|
|
813
841
|
>
|
|
814
842
|
|
|
815
843
|
type FeePayerPolicy = Partial<FeePayer.Policy> & {
|
|
816
|
-
/**
|
|
844
|
+
/**
|
|
845
|
+
* Maximum number of sponsored transactions awaiting a terminal receipt.
|
|
846
|
+
* @deprecated Use `sponsorBudget.maxInFlightReservations`.
|
|
847
|
+
*/
|
|
817
848
|
maxInFlightReservations?: number | undefined
|
|
818
849
|
/**
|
|
819
850
|
* Maximum aggregate declared fee exposure awaiting terminal receipts.
|
|
820
851
|
*
|
|
821
|
-
* @
|
|
852
|
+
* @deprecated Use `sponsorBudget.maxInFlightTotalFee`.
|
|
822
853
|
*/
|
|
823
854
|
maxInFlightTotalFee?: bigint | undefined
|
|
824
855
|
}
|
|
825
856
|
|
|
857
|
+
type SponsorBudgetConfig = {
|
|
858
|
+
/** Maximum number of sponsored transactions awaiting a terminal receipt. @default 100 */
|
|
859
|
+
maxInFlightReservations?: number | undefined
|
|
860
|
+
/** Maximum aggregate declared fee exposure. @default `feePayerPolicy.maxTotalFee * 10` */
|
|
861
|
+
maxInFlightTotalFee?: bigint | undefined
|
|
862
|
+
/** Atomic store shared by every process using the sponsor. Defaults to `store`. */
|
|
863
|
+
store?: Store.AtomicStore | undefined
|
|
864
|
+
}
|
|
865
|
+
|
|
826
866
|
/** Tempo API relay configuration for server-side charges. */
|
|
827
867
|
type RelayOptions = Relay.configure.Options
|
|
828
868
|
}
|
|
@@ -1165,14 +1205,12 @@ function getProofStoreKey(challengeId: string): `mppx:charge:${string}` {
|
|
|
1165
1205
|
return `mppx:charge:proof:${challengeId}`
|
|
1166
1206
|
}
|
|
1167
1207
|
|
|
1168
|
-
async function
|
|
1208
|
+
async function tryClaimHash(
|
|
1169
1209
|
store: Store.AtomicStore<charge.StoreItemMap>,
|
|
1170
1210
|
hash: `0x${string}`,
|
|
1211
|
+
expires: number,
|
|
1171
1212
|
): Promise<boolean> {
|
|
1172
|
-
return
|
|
1173
|
-
if (current !== null) return { op: 'noop', result: false }
|
|
1174
|
-
return { op: 'set', value: Date.now(), result: true }
|
|
1175
|
-
})
|
|
1213
|
+
return Store.tryClaim(store, getHashStoreKey(hash), expires)
|
|
1176
1214
|
}
|
|
1177
1215
|
|
|
1178
1216
|
/** @internal */
|
|
@@ -1199,14 +1237,12 @@ function parseHashCredentialSource(parameters: {
|
|
|
1199
1237
|
}
|
|
1200
1238
|
|
|
1201
1239
|
/** @internal */
|
|
1202
|
-
async function
|
|
1240
|
+
async function tryClaimProof(
|
|
1203
1241
|
store: Store.AtomicStore<charge.StoreItemMap>,
|
|
1204
1242
|
challengeId: string,
|
|
1243
|
+
expires: number,
|
|
1205
1244
|
): Promise<boolean> {
|
|
1206
|
-
return
|
|
1207
|
-
if (current !== null) return { op: 'noop', result: false }
|
|
1208
|
-
return { op: 'set', value: Date.now(), result: true }
|
|
1209
|
-
})
|
|
1245
|
+
return Store.tryClaim(store, getProofStoreKey(challengeId), expires)
|
|
1210
1246
|
}
|
|
1211
1247
|
|
|
1212
1248
|
function recoverAuthorizedProofSigner(parameters: {
|