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,83 @@
|
|
|
1
|
+
import * as Attestation from 'mppx/attestation'
|
|
2
|
+
import * as Tap from 'mppx/attestation/tap'
|
|
3
|
+
import * as WebBotAuth from 'mppx/attestation/web-bot-auth'
|
|
4
|
+
import { expect, test } from 'vp/test'
|
|
5
|
+
import { jwkThumbprint, keyPair } from '~test/Attestation.js'
|
|
6
|
+
|
|
7
|
+
test('shares one immutable context and composes signature dictionaries', async () => {
|
|
8
|
+
const tapKeys = await keyPair()
|
|
9
|
+
const webBotAuthKeys = await keyPair()
|
|
10
|
+
const webBotAuthKeyId = await jwkThumbprint(webBotAuthKeys.publicKey)
|
|
11
|
+
const tapSigner = Tap.Client.signer({
|
|
12
|
+
intent: Tap.Constants.intents.payment,
|
|
13
|
+
key: tapKeys.privateKey,
|
|
14
|
+
keyId: 'tap-agent',
|
|
15
|
+
})
|
|
16
|
+
const webBotAuthSigner = WebBotAuth.Client.signer({
|
|
17
|
+
key: webBotAuthKeys.privateKey,
|
|
18
|
+
keyId: webBotAuthKeyId,
|
|
19
|
+
signatureAgent: 'https://agent.example',
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
for (const signers of [
|
|
23
|
+
[webBotAuthSigner, tapSigner],
|
|
24
|
+
[tapSigner, webBotAuthSigner],
|
|
25
|
+
] as const) {
|
|
26
|
+
const contexts: Attestation.SigningContext[] = []
|
|
27
|
+
const observingSigners = signers.map((signer) => ({
|
|
28
|
+
...signer,
|
|
29
|
+
sign(request: Request, context?: Attestation.SigningContext) {
|
|
30
|
+
if (context) contexts.push(context)
|
|
31
|
+
return signer.sign(request, context)
|
|
32
|
+
},
|
|
33
|
+
})) as [Attestation.Signer, Attestation.Signer]
|
|
34
|
+
const signed = await Attestation.Client.composeSigners(...observingSigners).sign(
|
|
35
|
+
new Request('https://merchant.example/resource'),
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
expect(contexts).toHaveLength(2)
|
|
39
|
+
expect(contexts[0]).toBe(contexts[1])
|
|
40
|
+
expect(Object.isFrozen(contexts[0])).toBe(true)
|
|
41
|
+
const input = signed.headers.get(Attestation.Headers.signatureInput) ?? ''
|
|
42
|
+
const signature = signed.headers.get(Attestation.Headers.signature) ?? ''
|
|
43
|
+
expect(input).toContain(`${WebBotAuth.Constants.label}=`)
|
|
44
|
+
expect(input).toContain(`${Tap.Constants.label}=`)
|
|
45
|
+
expect(signature).toContain(`${WebBotAuth.Constants.label}=`)
|
|
46
|
+
expect(signature).toContain(`${Tap.Constants.label}=`)
|
|
47
|
+
}
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
test('rejects duplicate and mismatched signature labels', async () => {
|
|
51
|
+
const tapKeys = await keyPair()
|
|
52
|
+
const webBotAuthKeys = await keyPair()
|
|
53
|
+
const webBotAuthKeyId = await jwkThumbprint(webBotAuthKeys.publicKey)
|
|
54
|
+
const signer = Attestation.Client.composeSigners(
|
|
55
|
+
WebBotAuth.Client.signer({
|
|
56
|
+
key: webBotAuthKeys.privateKey,
|
|
57
|
+
keyId: webBotAuthKeyId,
|
|
58
|
+
label: 'agent',
|
|
59
|
+
signatureAgent: 'https://agent.example',
|
|
60
|
+
}),
|
|
61
|
+
Tap.Client.signer({
|
|
62
|
+
intent: Tap.Constants.intents.payment,
|
|
63
|
+
key: tapKeys.privateKey,
|
|
64
|
+
keyId: 'tap-agent',
|
|
65
|
+
label: 'agent',
|
|
66
|
+
}),
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
await expect(signer.sign(new Request('https://merchant.example/resource'))).rejects.toThrow(
|
|
70
|
+
'HTTP message signature label "agent" already exists.',
|
|
71
|
+
)
|
|
72
|
+
await expect(
|
|
73
|
+
Tap.Client.signer({
|
|
74
|
+
intent: Tap.Constants.intents.payment,
|
|
75
|
+
key: tapKeys.privateKey,
|
|
76
|
+
keyId: 'tap-agent',
|
|
77
|
+
}).sign(
|
|
78
|
+
new Request('https://merchant.example/resource', {
|
|
79
|
+
headers: { [Attestation.Headers.signatureInput]: 'orphan=("@authority")' },
|
|
80
|
+
}),
|
|
81
|
+
),
|
|
82
|
+
).rejects.toThrow('Signature-Input and Signature must contain the same labels.')
|
|
83
|
+
})
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import * as SigningContext from './internal/SigningContext.js'
|
|
2
|
+
import type * as Types from './Types.js'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Combines request signers using one shared context per call.
|
|
6
|
+
*
|
|
7
|
+
* The returned signer creates a fresh context unless its caller supplies one,
|
|
8
|
+
* allowing every signature on one HTTP attempt to share a nonce and timestamp.
|
|
9
|
+
*/
|
|
10
|
+
export function composeSigners(
|
|
11
|
+
...signers: readonly [Types.Signer, ...Types.Signer[]]
|
|
12
|
+
): Types.Signer<'composed'> {
|
|
13
|
+
return {
|
|
14
|
+
protocol: 'composed',
|
|
15
|
+
async sign(request, context = SigningContext.create()) {
|
|
16
|
+
for (const signer of signers) request = await signer.sign(request, context)
|
|
17
|
+
return request
|
|
18
|
+
},
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Wraps a fetch implementation so every outbound request is attested.
|
|
24
|
+
*
|
|
25
|
+
* Configure this wrapper as the underlying `fetch` passed to `mppx/client`
|
|
26
|
+
* `Fetch.from()`. MPPX then uses it for both the initial request and its
|
|
27
|
+
* automatic request containing an `Authorization: Payment` credential.
|
|
28
|
+
*/
|
|
29
|
+
export function wrapFetch(
|
|
30
|
+
fetch: typeof globalThis.fetch,
|
|
31
|
+
signer: Types.Signer,
|
|
32
|
+
): typeof globalThis.fetch {
|
|
33
|
+
return async (input, init) => fetch(await signer.sign(new Request(input, init)))
|
|
34
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** RFC 9421 signature algorithms supported by request attestation. */
|
|
2
|
+
export const Algorithms = {
|
|
3
|
+
/** EdDSA using the Ed25519 curve. */
|
|
4
|
+
ed25519: 'ed25519',
|
|
5
|
+
/** RSASSA-PSS using SHA-512 and a 64-byte salt. */
|
|
6
|
+
rsaPssSha512: 'rsa-pss-sha512',
|
|
7
|
+
} as const
|
|
8
|
+
|
|
9
|
+
/** HTTP headers defined by RFC 9421 for request-attestation signatures. */
|
|
10
|
+
export const Headers = {
|
|
11
|
+
/** Carries the RFC 9421 signature bytes. */
|
|
12
|
+
signature: 'Signature',
|
|
13
|
+
/** Carries the RFC 9421 covered components and signature parameters. */
|
|
14
|
+
signatureInput: 'Signature-Input',
|
|
15
|
+
} as const
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import * as Attestation from 'mppx/attestation'
|
|
2
|
+
import * as Tap from 'mppx/attestation/tap'
|
|
3
|
+
import * as WebBotAuth from 'mppx/attestation/web-bot-auth'
|
|
4
|
+
import { expect, test } from 'vp/test'
|
|
5
|
+
import { jwkThumbprint, keyPair } from '~test/Attestation.js'
|
|
6
|
+
|
|
7
|
+
test('returns typed protocol outcomes and namespaces shared nonces', async () => {
|
|
8
|
+
const keys = await keyPair()
|
|
9
|
+
const keyId = await jwkThumbprint(keys.publicKey)
|
|
10
|
+
const signatureAgent = 'https://agent.example'
|
|
11
|
+
const signed = await Attestation.Client.composeSigners(
|
|
12
|
+
WebBotAuth.Client.signer({ key: keys.privateKey, keyId, signatureAgent }),
|
|
13
|
+
Tap.Client.signer({
|
|
14
|
+
intent: Tap.Constants.intents.payment,
|
|
15
|
+
key: keys.privateKey,
|
|
16
|
+
keyId,
|
|
17
|
+
}),
|
|
18
|
+
).sign(new Request('https://merchant.example/resource'))
|
|
19
|
+
const consumed = new Set<string>()
|
|
20
|
+
const backing = Attestation.Store.memory()
|
|
21
|
+
const nonceStore: Attestation.Store.AtomicStore = {
|
|
22
|
+
...backing,
|
|
23
|
+
tryClaim(key, expires) {
|
|
24
|
+
consumed.add(key)
|
|
25
|
+
return Attestation.Store.tryClaim(backing, key, expires)
|
|
26
|
+
},
|
|
27
|
+
}
|
|
28
|
+
const verifiers = {
|
|
29
|
+
tap: Tap.Server.verifier({
|
|
30
|
+
keyResolver: ({ keyId: candidate }) => (candidate === keyId ? keys.publicKey : undefined),
|
|
31
|
+
nonceStore,
|
|
32
|
+
}),
|
|
33
|
+
webBotAuth: WebBotAuth.Server.verifier({
|
|
34
|
+
keyResolver: ({ keyId: candidate, signatureAgent: candidateAgent }) =>
|
|
35
|
+
candidate === keyId && candidateAgent === signatureAgent ? keys.publicKey : undefined,
|
|
36
|
+
nonceStore,
|
|
37
|
+
}),
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const verified = await Attestation.Server.verify(signed, verifiers)
|
|
41
|
+
expect(verified.tap).toMatchObject({
|
|
42
|
+
status: 'verified',
|
|
43
|
+
value: { intent: Tap.Constants.intents.payment, keyId },
|
|
44
|
+
})
|
|
45
|
+
expect(verified.webBotAuth).toMatchObject({
|
|
46
|
+
status: 'verified',
|
|
47
|
+
value: { keyId, signatureAgent },
|
|
48
|
+
})
|
|
49
|
+
expect([...consumed].some((value) => value.startsWith(`${Tap.Constants.protocol}:`))).toBe(true)
|
|
50
|
+
expect([...consumed].some((value) => value.startsWith(`${WebBotAuth.Constants.protocol}:`))).toBe(
|
|
51
|
+
true,
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
const replay = await Attestation.Server.verify(signed, verifiers)
|
|
55
|
+
for (const outcome of Object.values(replay))
|
|
56
|
+
expect(outcome).toEqual({
|
|
57
|
+
reason: 'The signature nonce has already been used.',
|
|
58
|
+
status: 'invalid',
|
|
59
|
+
})
|
|
60
|
+
})
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type * as Types from './Types.js'
|
|
2
|
+
|
|
3
|
+
/** Verifies every configured request-attestation protocol. */
|
|
4
|
+
export async function verify<const verifiers extends Types.VerifierMap>(
|
|
5
|
+
request: Request,
|
|
6
|
+
verifiers: verifiers,
|
|
7
|
+
): Promise<Types.VerificationsFrom<verifiers>> {
|
|
8
|
+
const outcomes: Record<string, Types.Verification> = {}
|
|
9
|
+
for (const [name, verifier] of Object.entries(verifiers))
|
|
10
|
+
outcomes[name] = await verifier.verify(request)
|
|
11
|
+
return outcomes as Types.VerificationsFrom<verifiers>
|
|
12
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import * as Attestation from 'mppx/attestation'
|
|
2
|
+
import * as Tap from 'mppx/attestation/tap'
|
|
3
|
+
import { expectTypeOf, test } from 'vp/test'
|
|
4
|
+
|
|
5
|
+
test('types: request signers compose with an optional shared context', () => {
|
|
6
|
+
const first: Attestation.Signer<'first'> = {
|
|
7
|
+
protocol: 'first',
|
|
8
|
+
sign: (request) => request,
|
|
9
|
+
}
|
|
10
|
+
const second: Attestation.Signer<'second'> = {
|
|
11
|
+
protocol: 'second',
|
|
12
|
+
sign: (request) => request,
|
|
13
|
+
}
|
|
14
|
+
const signer = Attestation.Client.composeSigners(first, second)
|
|
15
|
+
|
|
16
|
+
expectTypeOf(signer).toMatchTypeOf<Attestation.Signer>()
|
|
17
|
+
expectTypeOf<Parameters<typeof signer.sign>[1]>().toEqualTypeOf<
|
|
18
|
+
Attestation.SigningContext | undefined
|
|
19
|
+
>()
|
|
20
|
+
|
|
21
|
+
// @ts-expect-error at least one signer is required
|
|
22
|
+
Attestation.Client.composeSigners()
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
test('types: server verification preserves each protocol value', () => {
|
|
26
|
+
const tapVerifier: Attestation.Verifier<Tap.VerifiedRequest> = {
|
|
27
|
+
verify: () => ({ status: 'absent' }),
|
|
28
|
+
}
|
|
29
|
+
const verifiers = { tap: tapVerifier } as const
|
|
30
|
+
const verification = Attestation.Server.verify(
|
|
31
|
+
new Request('https://merchant.example/resource'),
|
|
32
|
+
verifiers,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
expectTypeOf<Awaited<typeof verification>['tap']>().toEqualTypeOf<
|
|
36
|
+
Attestation.Verification<Tap.VerifiedRequest>
|
|
37
|
+
>()
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
test('types: server verifiers require explicit replay storage and expose the algorithm', () => {
|
|
41
|
+
const nonceStore = Attestation.Store.memory()
|
|
42
|
+
expectTypeOf(nonceStore).toEqualTypeOf<Attestation.Store.AtomicStore>()
|
|
43
|
+
|
|
44
|
+
Tap.Server.verifier({
|
|
45
|
+
keyResolver({ algorithm }) {
|
|
46
|
+
expectTypeOf(algorithm).toEqualTypeOf<Attestation.SignatureAlgorithm>()
|
|
47
|
+
return undefined
|
|
48
|
+
},
|
|
49
|
+
nonceStore,
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
// @ts-expect-error replay storage must be chosen explicitly
|
|
53
|
+
Tap.Server.verifier({ keyResolver: () => undefined })
|
|
54
|
+
})
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { MaybePromise } from '../internal/types.js'
|
|
2
|
+
import type { Algorithms } from './Constants.js'
|
|
3
|
+
|
|
4
|
+
/** RFC 9421 algorithms implemented by the request-attestation signer and verifier. */
|
|
5
|
+
export type SignatureAlgorithm = (typeof Algorithms)[keyof typeof Algorithms]
|
|
6
|
+
|
|
7
|
+
/** Resolves a trusted public key for a parsed request signature. */
|
|
8
|
+
export type KeyResolver = (parameters: {
|
|
9
|
+
/** RFC 9421 algorithm declared by the signature. */
|
|
10
|
+
algorithm: SignatureAlgorithm
|
|
11
|
+
/** Key identifier declared by the signature. */
|
|
12
|
+
keyId: string
|
|
13
|
+
/** Request carrying the signature. */
|
|
14
|
+
request: Request
|
|
15
|
+
}) => MaybePromise<CryptoKey | undefined>
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The complete outcome of attempting one protocol verifier.
|
|
19
|
+
*
|
|
20
|
+
* `absent` means the protocol did not appear on the request. `invalid` means
|
|
21
|
+
* it appeared but failed validation and must reject the request. `unverified`
|
|
22
|
+
* means key material or another required verification dependency was unavailable.
|
|
23
|
+
* `verified` carries protocol-specific data that is safe for callers to inspect.
|
|
24
|
+
*/
|
|
25
|
+
export type Verification<value = unknown> =
|
|
26
|
+
| { status: 'absent' }
|
|
27
|
+
| { status: 'invalid'; reason: string }
|
|
28
|
+
| { status: 'unverified'; reason: string }
|
|
29
|
+
| { status: 'verified'; value: value }
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Verifies one request-attestation protocol carried by an HTTP request.
|
|
33
|
+
*
|
|
34
|
+
* Verifiers are registered in a {@link VerifierMap}; each map key names the
|
|
35
|
+
* result returned to the caller.
|
|
36
|
+
*/
|
|
37
|
+
export type Verifier<value = unknown> = {
|
|
38
|
+
/** Validates the request and returns a complete protocol verification outcome. */
|
|
39
|
+
verify: (request: Request) => MaybePromise<Verification<value>>
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Maps each recognized protocol name to its verifier. */
|
|
43
|
+
export type VerifierMap = Readonly<Record<string, Verifier>>
|
|
44
|
+
|
|
45
|
+
/** Preserves each configured protocol's complete verification outcome. */
|
|
46
|
+
export type VerificationsFrom<verifiers extends VerifierMap> = {
|
|
47
|
+
readonly [protocol in keyof verifiers]: Awaited<ReturnType<verifiers[protocol]['verify']>>
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Values shared by every signer contributing to one HTTP request attempt.
|
|
52
|
+
*
|
|
53
|
+
* A caller may reuse this context across independent signature protocols so
|
|
54
|
+
* they describe the same attempt. A later network retry must use a new context.
|
|
55
|
+
*/
|
|
56
|
+
export type SigningContext = {
|
|
57
|
+
/** Unix timestamp, in seconds, at which the request attempt was created. */
|
|
58
|
+
readonly created: number
|
|
59
|
+
/** Base64url-encoded random value identifying this request attempt. */
|
|
60
|
+
readonly nonce: string
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Signs each outbound HTTP request, including MPP payment retries.
|
|
65
|
+
*
|
|
66
|
+
* The protocol type preserves which adapter produced the signer for diagnostics
|
|
67
|
+
* and composition, without asserting that the signer alone authorizes payment.
|
|
68
|
+
*/
|
|
69
|
+
export type Signer<protocol extends string = string> = {
|
|
70
|
+
/** Protocol identifier used for diagnostics. */
|
|
71
|
+
protocol: protocol
|
|
72
|
+
/** Returns a new request containing the protocol's signature material. */
|
|
73
|
+
sign: (request: Request, context?: SigningContext | undefined) => MaybePromise<Request>
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Maps application-defined names to request-attestation signers. */
|
|
77
|
+
export type SignerMap = Readonly<Record<string, Signer>>
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { describe, expect, test } from 'vp/test'
|
|
2
|
+
import { keyPair } from '~test/Attestation.js'
|
|
3
|
+
|
|
4
|
+
import * as Store from '../../Store.js'
|
|
5
|
+
import { Algorithms, Headers } from '../Constants.js'
|
|
6
|
+
import * as HttpMessageSignature from './HttpMessageSignature.js'
|
|
7
|
+
|
|
8
|
+
const signatureAgent = 'agent2="https://signature-agent.test"'
|
|
9
|
+
const maximumVectorLifetime = 3_153_600_000
|
|
10
|
+
|
|
11
|
+
describe('Web Bot Auth draft test vectors', () => {
|
|
12
|
+
test('verifies the Ed25519 Signature-Agent vector', async () => {
|
|
13
|
+
const key = await crypto.subtle.importKey(
|
|
14
|
+
'jwk',
|
|
15
|
+
{
|
|
16
|
+
crv: 'Ed25519',
|
|
17
|
+
kty: 'OKP',
|
|
18
|
+
x: 'JrQLj5P_89iXES9-vFgrIy29clF9CC_oPPsw3c5D0bs',
|
|
19
|
+
},
|
|
20
|
+
'Ed25519',
|
|
21
|
+
true,
|
|
22
|
+
['verify'],
|
|
23
|
+
)
|
|
24
|
+
const request = vectorRequest({
|
|
25
|
+
input:
|
|
26
|
+
'sig2=("@authority" "signature-agent";key="agent2");created=1735689600;keyid="poqkLGiymh_W0uP6PZFw-dvez3QJT5SolqXBCW38r0U";alg="ed25519";expires=4889289600;nonce="n9p433xm+NJ3ph3upfBIGmsuwHw387YV7Q/F+6BSpGCVjYCqQw6rznNA8PVVLySrAWsv0hQtFioQb6E1YsauiA==";tag="web-bot-auth"',
|
|
27
|
+
signature:
|
|
28
|
+
'sig2=:RdNFx5Bj6au3YgAMQL/RzmUlZE8QZLIaXGRpw985hWnwPfMxT228NMk6ehRS1PSl4e8PhbNZACSanGdhEwYCCg==:',
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
expect(await verifyVector(request, key)).toMatchObject({ status: 'verified' })
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
test('verifies the RSA-PSS SHA-512 Signature-Agent vector', async () => {
|
|
35
|
+
const spki = Buffer.from(
|
|
36
|
+
'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr4tmm3r20Wd/PbqvP1s2+QEtvpuRaV8Yq40gjUR8y2Rjxa6dpG2GXHbPfvMs8ct+Lh1GH45x28Rw3Ry53mm+oAXjyQ86OnDkZ5N8lYbggD4O3w6M6pAvLkhk95AndTrifbIFPNU8PPMO7OyrFAHqgDsznjPFmTOtCEcN2Z1FpWgchwuYLPL+Wokqltd11nqqzi+bJ9cvSKADYdUAAN5WUtzdpiy6LbTgSxP7ociU4Tn0g5I6aDZJ7A8Lzo0KSyZYoA485mqcO0GVAdVw9lq4aOT9v6d+nb4bnNkQVklLQ3fVAvJm+xdDOp9LCNCN48V2pnDOkFV6+U9nV5oyc6XI2wIDAQAB',
|
|
37
|
+
'base64',
|
|
38
|
+
)
|
|
39
|
+
const key = await crypto.subtle.importKey(
|
|
40
|
+
'spki',
|
|
41
|
+
new Uint8Array(spki),
|
|
42
|
+
{ hash: 'SHA-512', name: 'RSA-PSS' },
|
|
43
|
+
true,
|
|
44
|
+
['verify'],
|
|
45
|
+
)
|
|
46
|
+
const request = vectorRequest({
|
|
47
|
+
input:
|
|
48
|
+
'sig2=("@authority" "signature-agent";key="agent2");created=1735689600;keyid="oD0HwocPBSfpNy5W3bpJeyFGY_IQ_YpqxSjQ3Yd-CLA";alg="rsa-pss-sha512";expires=4889289600;nonce="wcfPQPh7SzkvrIVvhD00vNk9PkxJNY2NVbYl2PVBB4zmUoluSwE7W6bPtF60QA3k8g06FU7PPCD+J58YofY1zg==";tag="web-bot-auth"',
|
|
49
|
+
signature:
|
|
50
|
+
'sig2=:gHzpLNeHaHIO19NaJH9YMW5dcVSi2s0wOMBr6p18vcofS106sfC4KBIS0/szPlBBd1vIcyQ88B6CTEWIhRAiVrb9zfX0mx1aG12CSGWcYkSirHeyTxhbuJvXd27ed6skWoy4PjXItq38936ivUQjfdIwXh1aX6HxkAC3vRnEdSNfntkLWeEuIQ5BLIOBGE39fSwg27Qjq6OVWYas/9/aFUr3HA34MXWYdp+//cvlEKDp3kRoLOw9ro0AOr6srHrTeEtxon2afcws1aZVSlPdd2fZSEIGmw9HAHLDCEkFTERu1gH2k/zIEqgy7CAYXI9E5slog0cLg/Vc6+f8gih33g==:',
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
expect(await verifyVector(request, key)).toMatchObject({ status: 'verified' })
|
|
54
|
+
})
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
test('rejects non-ASCII signed HTTP header values', async () => {
|
|
58
|
+
const keys = await keyPair()
|
|
59
|
+
await expect(
|
|
60
|
+
HttpMessageSignature.sign(
|
|
61
|
+
new Request('https://example.com', { headers: { 'X-Example': 'café' } }),
|
|
62
|
+
{
|
|
63
|
+
components: ['x-example'],
|
|
64
|
+
key: keys.privateKey,
|
|
65
|
+
keyId: 'test-key',
|
|
66
|
+
label: 'test',
|
|
67
|
+
tag: 'test',
|
|
68
|
+
},
|
|
69
|
+
),
|
|
70
|
+
).rejects.toThrow('Signed HTTP header "x-example" is not ASCII.')
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
function vectorRequest(parameters: { input: string; signature: string }): Request {
|
|
74
|
+
return new Request('https://example.com/foo?param=Value&Pet=dog', {
|
|
75
|
+
headers: {
|
|
76
|
+
[Headers.signature]: parameters.signature,
|
|
77
|
+
[Headers.signatureInput]: parameters.input,
|
|
78
|
+
'Signature-Agent': signatureAgent,
|
|
79
|
+
},
|
|
80
|
+
method: 'POST',
|
|
81
|
+
})
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function verifyVector(request: Request, key: CryptoKey) {
|
|
85
|
+
return HttpMessageSignature.verify(request, {
|
|
86
|
+
keyResolver({ algorithm }) {
|
|
87
|
+
expect(algorithm).toBe(
|
|
88
|
+
key.algorithm.name === 'Ed25519' ? Algorithms.ed25519 : Algorithms.rsaPssSha512,
|
|
89
|
+
)
|
|
90
|
+
return key
|
|
91
|
+
},
|
|
92
|
+
maxAge: maximumVectorLifetime,
|
|
93
|
+
nonceNamespace: 'web-bot-auth',
|
|
94
|
+
nonceStore: Store.memory(),
|
|
95
|
+
requiredComponents: [
|
|
96
|
+
HttpMessageSignature.Constants.components.authority,
|
|
97
|
+
HttpMessageSignature.Constants.components.signatureAgent,
|
|
98
|
+
],
|
|
99
|
+
tag: 'web-bot-auth',
|
|
100
|
+
})
|
|
101
|
+
}
|