mppx 0.8.17 → 0.8.18
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 +55 -0
- package/README.md +15 -0
- package/dist/Challenge.js +21 -4
- package/dist/bin.js +3 -3
- package/dist/cli/THIRD-PARTY-LICENSES.txt +328 -0
- package/dist/cli/cli.js +253 -1505
- package/dist/cli/plugins/index.js +19 -5
- package/dist/cli/plugins/tempo.js +7 -3
- package/dist/cli/sessions/Manager.js +7 -4
- package/dist/cli/sessions/request.d.ts +2 -0
- package/dist/cli/sessions/request.js +18 -0
- package/dist/cli/sessions/store.js +28 -14
- package/dist/discovery/Discovery.js +2 -1
- package/dist/evm/client/Charge.js +8 -0
- package/dist/server/core.d.ts +9 -0
- package/dist/server/core.js +9 -0
- package/dist/stripe/server/Charge.js +2 -4
- package/dist/stripe/server/Methods.d.ts +2 -2
- package/dist/stripe/server/Methods.js +17 -11
- package/dist/stripe/server/internal/html.gen.d.ts +1 -1
- package/dist/stripe/server/internal/html.gen.js +1 -1
- package/dist/stripe/server/spt.d.ts +8 -0
- package/dist/stripe/server/spt.js +8 -0
- package/dist/tempo/Methods.d.ts +13 -0
- package/dist/tempo/Methods.js +14 -3
- package/dist/tempo/client/Charge.d.ts +3 -0
- package/dist/tempo/client/Charge.js +31 -9
- package/dist/tempo/client/Methods.d.ts +13 -0
- package/dist/tempo/internal/defaults.d.ts +11 -0
- package/dist/tempo/internal/defaults.js +11 -0
- package/dist/tempo/internal/machine-token-charge.d.ts +51 -0
- package/dist/tempo/internal/machine-token-charge.js +113 -0
- package/dist/tempo/internal/machine-token-session.d.ts +88 -0
- package/dist/tempo/internal/machine-token-session.js +173 -0
- package/dist/tempo/internal/signature-envelope.d.ts +14 -0
- package/dist/tempo/internal/signature-envelope.js +28 -0
- package/dist/tempo/legacy/client/ChannelOps.d.ts +2 -2
- package/dist/tempo/legacy/client/ChannelOps.js +11 -5
- package/dist/tempo/legacy/client/Session.d.ts +13 -1
- package/dist/tempo/legacy/client/Session.js +3 -3
- package/dist/tempo/legacy/client/SessionManager.d.ts +3 -1
- package/dist/tempo/legacy/client/SessionManager.js +2 -0
- package/dist/tempo/server/Charge.d.ts +3 -0
- package/dist/tempo/server/Charge.js +58 -17
- package/dist/tempo/server/Methods.d.ts +21 -4
- package/dist/tempo/server/Methods.js +8 -4
- package/dist/tempo/server/internal/html.gen.d.ts +1 -1
- package/dist/tempo/server/internal/html.gen.js +1 -1
- package/dist/tempo/session/client/ChannelOps.d.ts +18 -3
- package/dist/tempo/session/client/ChannelOps.js +35 -6
- package/dist/tempo/session/client/ChannelStore.d.ts +0 -5
- package/dist/tempo/session/client/ChannelStore.js +2 -2
- package/dist/tempo/session/client/CredentialState.d.ts +17 -2
- package/dist/tempo/session/client/CredentialState.js +77 -76
- package/dist/tempo/session/client/Runtime.d.ts +4 -2
- package/dist/tempo/session/client/Runtime.js +21 -5
- package/dist/tempo/session/client/Session.d.ts +15 -3
- package/dist/tempo/session/client/Session.js +186 -63
- package/dist/tempo/session/client/SessionManager.d.ts +3 -1
- package/dist/tempo/session/client/SessionManager.js +35 -11
- package/dist/tempo/session/client/Transports.d.ts +2 -0
- package/dist/tempo/session/client/Transports.js +12 -2
- package/dist/tempo/session/precompile/Chain.d.ts +10 -2
- package/dist/tempo/session/precompile/Chain.js +50 -10
- package/dist/tempo/session/precompile/Protocol.d.ts +15 -0
- package/dist/tempo/session/precompile/Protocol.js +7 -0
- package/dist/tempo/session/precompile/Voucher.d.ts +3 -1
- package/dist/tempo/session/precompile/Voucher.js +6 -12
- package/dist/tempo/session/server/ChannelStore.d.ts +6 -0
- package/dist/tempo/session/server/ChannelStore.js +11 -4
- package/dist/tempo/session/server/CredentialVerification.d.ts +11 -9
- package/dist/tempo/session/server/CredentialVerification.js +185 -109
- package/dist/tempo/session/server/MeteredStream.d.ts +1 -1
- package/dist/tempo/session/server/MeteredStream.js +5 -4
- package/dist/tempo/session/server/RequestState.d.ts +19 -0
- package/dist/tempo/session/server/RequestState.js +61 -15
- package/dist/tempo/session/server/Session.d.ts +14 -2
- package/dist/tempo/session/server/Session.js +37 -6
- package/dist/tempo/session/server/Settlement.d.ts +11 -4
- package/dist/tempo/session/server/Settlement.js +53 -21
- package/dist/x402/client/Exact.d.ts +8 -0
- package/dist/x402/client/Exact.js +40 -10
- package/dist/x402/server/EvmCharge.d.ts +22 -0
- package/dist/x402/server/EvmCharge.js +23 -1
- package/package.json +15 -37
- package/dist/BodyDigest.d.ts.map +0 -1
- package/dist/BodyDigest.js.map +0 -1
- package/dist/Challenge.d.ts.map +0 -1
- package/dist/Challenge.js.map +0 -1
- package/dist/Constants.d.ts.map +0 -1
- package/dist/Constants.js.map +0 -1
- package/dist/Credential.d.ts.map +0 -1
- package/dist/Credential.js.map +0 -1
- package/dist/Errors.d.ts.map +0 -1
- package/dist/Errors.js.map +0 -1
- package/dist/Expires.d.ts.map +0 -1
- package/dist/Expires.js.map +0 -1
- package/dist/Html.d.ts.map +0 -1
- package/dist/Html.js.map +0 -1
- package/dist/Mcp.d.ts.map +0 -1
- package/dist/Mcp.js.map +0 -1
- package/dist/Method.d.ts.map +0 -1
- package/dist/Method.js.map +0 -1
- package/dist/PaymentRequest.d.ts.map +0 -1
- package/dist/PaymentRequest.js.map +0 -1
- package/dist/Receipt.d.ts.map +0 -1
- package/dist/Receipt.js.map +0 -1
- package/dist/Store.d.ts.map +0 -1
- package/dist/Store.js.map +0 -1
- package/dist/attestation/Client.d.ts.map +0 -1
- package/dist/attestation/Client.js.map +0 -1
- package/dist/attestation/Constants.d.ts.map +0 -1
- package/dist/attestation/Constants.js.map +0 -1
- package/dist/attestation/Server.d.ts.map +0 -1
- package/dist/attestation/Server.js.map +0 -1
- package/dist/attestation/Types.d.ts.map +0 -1
- package/dist/attestation/Types.js.map +0 -1
- package/dist/attestation/index.d.ts.map +0 -1
- package/dist/attestation/index.js.map +0 -1
- package/dist/attestation/internal/HttpMessageSignature.d.ts.map +0 -1
- package/dist/attestation/internal/HttpMessageSignature.js.map +0 -1
- package/dist/attestation/internal/SigningContext.d.ts.map +0 -1
- package/dist/attestation/internal/SigningContext.js.map +0 -1
- package/dist/bin.d.ts.map +0 -1
- package/dist/bin.js.map +0 -1
- package/dist/cli/account.d.ts.map +0 -1
- package/dist/cli/account.js.map +0 -1
- package/dist/cli/cli.d.ts.map +0 -1
- package/dist/cli/cli.js.map +0 -1
- package/dist/cli/config.d.ts.map +0 -1
- package/dist/cli/config.js.map +0 -1
- package/dist/cli/internal.d.ts.map +0 -1
- package/dist/cli/internal.js.map +0 -1
- package/dist/cli/plugins/evm.d.ts.map +0 -1
- package/dist/cli/plugins/evm.js.map +0 -1
- package/dist/cli/plugins/index.d.ts.map +0 -1
- package/dist/cli/plugins/index.js.map +0 -1
- package/dist/cli/plugins/plugin.d.ts.map +0 -1
- package/dist/cli/plugins/plugin.js.map +0 -1
- package/dist/cli/plugins/stripe.d.ts.map +0 -1
- package/dist/cli/plugins/stripe.js.map +0 -1
- package/dist/cli/plugins/tempo.d.ts.map +0 -1
- package/dist/cli/plugins/tempo.js.map +0 -1
- package/dist/cli/sessions/Manager.d.ts.map +0 -1
- package/dist/cli/sessions/Manager.js.map +0 -1
- package/dist/cli/sessions/commands.d.ts.map +0 -1
- package/dist/cli/sessions/commands.js.map +0 -1
- package/dist/cli/sessions/request.d.ts.map +0 -1
- package/dist/cli/sessions/request.js.map +0 -1
- package/dist/cli/sessions/store.d.ts.map +0 -1
- package/dist/cli/sessions/store.js.map +0 -1
- package/dist/cli/utils.d.ts.map +0 -1
- package/dist/cli/utils.js.map +0 -1
- package/dist/cli/validate/challenge.d.ts.map +0 -1
- package/dist/cli/validate/challenge.js.map +0 -1
- package/dist/cli/validate/discovery.d.ts.map +0 -1
- package/dist/cli/validate/discovery.js.map +0 -1
- package/dist/cli/validate/helpers.d.ts.map +0 -1
- package/dist/cli/validate/helpers.js.map +0 -1
- package/dist/cli/validate/index.d.ts.map +0 -1
- package/dist/cli/validate/index.js.map +0 -1
- package/dist/cli/validate/messages.d.ts.map +0 -1
- package/dist/cli/validate/messages.js.map +0 -1
- package/dist/cli/validate/payment.d.ts.map +0 -1
- package/dist/cli/validate/payment.js.map +0 -1
- package/dist/client/Methods.d.ts.map +0 -1
- package/dist/client/Methods.js.map +0 -1
- package/dist/client/Mppx.d.ts.map +0 -1
- package/dist/client/Mppx.js.map +0 -1
- package/dist/client/Transport.d.ts.map +0 -1
- package/dist/client/Transport.js.map +0 -1
- package/dist/client/index.d.ts.map +0 -1
- package/dist/client/index.js.map +0 -1
- package/dist/client/internal/Fetch.d.ts.map +0 -1
- package/dist/client/internal/Fetch.js.map +0 -1
- package/dist/client/internal/MethodChallenge.d.ts.map +0 -1
- package/dist/client/internal/MethodChallenge.js.map +0 -1
- package/dist/client/internal/MethodResponse.d.ts.map +0 -1
- package/dist/client/internal/MethodResponse.js.map +0 -1
- package/dist/client/internal/protocols/Mcp.d.ts.map +0 -1
- package/dist/client/internal/protocols/Mcp.js.map +0 -1
- package/dist/client/internal/protocols/Mpp.d.ts.map +0 -1
- package/dist/client/internal/protocols/Mpp.js.map +0 -1
- package/dist/client/internal/protocols/Protocol.d.ts.map +0 -1
- package/dist/client/internal/protocols/Protocol.js.map +0 -1
- package/dist/client/internal/protocols/Shared.d.ts.map +0 -1
- package/dist/client/internal/protocols/Shared.js.map +0 -1
- package/dist/client/internal/protocols/X402.d.ts.map +0 -1
- package/dist/client/internal/protocols/X402.js.map +0 -1
- package/dist/client/node.d.ts.map +0 -1
- package/dist/client/node.js.map +0 -1
- package/dist/discovery/Discovery.d.ts.map +0 -1
- package/dist/discovery/Discovery.js.map +0 -1
- package/dist/discovery/OpenApi.d.ts.map +0 -1
- package/dist/discovery/OpenApi.js.map +0 -1
- package/dist/discovery/Validate.d.ts.map +0 -1
- package/dist/discovery/Validate.js.map +0 -1
- package/dist/discovery/index.d.ts.map +0 -1
- package/dist/discovery/index.js.map +0 -1
- package/dist/discovery/internal/Metadata.d.ts.map +0 -1
- package/dist/discovery/internal/Metadata.js.map +0 -1
- package/dist/evm/Assets.d.ts.map +0 -1
- package/dist/evm/Assets.js.map +0 -1
- package/dist/evm/Chains.d.ts.map +0 -1
- package/dist/evm/Chains.js.map +0 -1
- package/dist/evm/Methods.d.ts.map +0 -1
- package/dist/evm/Methods.js.map +0 -1
- package/dist/evm/Types.d.ts.map +0 -1
- package/dist/evm/Types.js.map +0 -1
- package/dist/evm/client/Charge.d.ts.map +0 -1
- package/dist/evm/client/Charge.js.map +0 -1
- package/dist/evm/client/Methods.d.ts.map +0 -1
- package/dist/evm/client/Methods.js.map +0 -1
- package/dist/evm/client/index.d.ts.map +0 -1
- package/dist/evm/client/index.js.map +0 -1
- package/dist/evm/index.d.ts.map +0 -1
- package/dist/evm/index.js.map +0 -1
- package/dist/evm/server/Charge.d.ts.map +0 -1
- package/dist/evm/server/Charge.js.map +0 -1
- package/dist/evm/server/Methods.d.ts.map +0 -1
- package/dist/evm/server/Methods.js.map +0 -1
- package/dist/evm/server/index.d.ts.map +0 -1
- package/dist/evm/server/index.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/internal/AcceptPayment.d.ts.map +0 -1
- package/dist/internal/AcceptPayment.js.map +0 -1
- package/dist/internal/HeaderCodec.d.ts.map +0 -1
- package/dist/internal/HeaderCodec.js.map +0 -1
- package/dist/internal/constantTimeEqual.d.ts.map +0 -1
- package/dist/internal/constantTimeEqual.js.map +0 -1
- package/dist/internal/env.d.ts.map +0 -1
- package/dist/internal/env.js.map +0 -1
- package/dist/internal/types.d.ts.map +0 -1
- package/dist/internal/types.js.map +0 -1
- package/dist/mcp/client/McpClient.d.ts.map +0 -1
- package/dist/mcp/client/McpClient.js.map +0 -1
- package/dist/mcp/client/index.d.ts.map +0 -1
- package/dist/mcp/client/index.js.map +0 -1
- package/dist/mcp/server/Transport.d.ts.map +0 -1
- package/dist/mcp/server/Transport.js.map +0 -1
- package/dist/mcp/server/index.d.ts.map +0 -1
- package/dist/mcp/server/index.js.map +0 -1
- package/dist/middlewares/elysia.d.ts.map +0 -1
- package/dist/middlewares/elysia.js.map +0 -1
- package/dist/middlewares/express.d.ts.map +0 -1
- package/dist/middlewares/express.js.map +0 -1
- package/dist/middlewares/hono.d.ts.map +0 -1
- package/dist/middlewares/hono.js.map +0 -1
- package/dist/middlewares/internal/mppx.d.ts.map +0 -1
- package/dist/middlewares/internal/mppx.js.map +0 -1
- package/dist/middlewares/nextjs.d.ts.map +0 -1
- package/dist/middlewares/nextjs.js.map +0 -1
- package/dist/proxy/Proxy.d.ts.map +0 -1
- package/dist/proxy/Proxy.js.map +0 -1
- package/dist/proxy/Service.d.ts.map +0 -1
- package/dist/proxy/Service.js.map +0 -1
- package/dist/proxy/index.d.ts.map +0 -1
- package/dist/proxy/index.js.map +0 -1
- package/dist/proxy/internal/Headers.d.ts.map +0 -1
- package/dist/proxy/internal/Headers.js.map +0 -1
- package/dist/proxy/internal/Route.d.ts.map +0 -1
- package/dist/proxy/internal/Route.js.map +0 -1
- package/dist/proxy/services/anthropic.d.ts.map +0 -1
- package/dist/proxy/services/anthropic.js.map +0 -1
- package/dist/proxy/services/openai.d.ts.map +0 -1
- package/dist/proxy/services/openai.js.map +0 -1
- package/dist/proxy/services/stripe.d.ts.map +0 -1
- package/dist/proxy/services/stripe.js.map +0 -1
- package/dist/server/Methods.d.ts.map +0 -1
- package/dist/server/Methods.js.map +0 -1
- package/dist/server/Mppx.d.ts.map +0 -1
- package/dist/server/Mppx.js.map +0 -1
- package/dist/server/NodeListener.d.ts.map +0 -1
- package/dist/server/NodeListener.js.map +0 -1
- package/dist/server/Request.d.ts.map +0 -1
- package/dist/server/Request.js.map +0 -1
- package/dist/server/Response.d.ts.map +0 -1
- package/dist/server/Response.js.map +0 -1
- package/dist/server/Transport.d.ts.map +0 -1
- package/dist/server/Transport.js.map +0 -1
- package/dist/server/index.d.ts.map +0 -1
- package/dist/server/index.js.map +0 -1
- package/dist/server/internal/html/compose.main.gen.d.ts.map +0 -1
- package/dist/server/internal/html/compose.main.gen.js.map +0 -1
- package/dist/server/internal/html/config.d.ts.map +0 -1
- package/dist/server/internal/html/config.js.map +0 -1
- package/dist/server/internal/html/constants.d.ts.map +0 -1
- package/dist/server/internal/html/constants.js.map +0 -1
- package/dist/server/internal/html/serviceWorker.client.d.ts.map +0 -1
- package/dist/server/internal/html/serviceWorker.client.js.map +0 -1
- package/dist/server/internal/html/serviceWorker.gen.d.ts.map +0 -1
- package/dist/server/internal/html/serviceWorker.gen.js.map +0 -1
- package/dist/server/internal/scope.d.ts.map +0 -1
- package/dist/server/internal/scope.js.map +0 -1
- package/dist/stripe/Methods.d.ts.map +0 -1
- package/dist/stripe/Methods.js.map +0 -1
- package/dist/stripe/client/Charge.d.ts.map +0 -1
- package/dist/stripe/client/Charge.js.map +0 -1
- package/dist/stripe/client/Methods.d.ts.map +0 -1
- package/dist/stripe/client/Methods.js.map +0 -1
- package/dist/stripe/client/index.d.ts.map +0 -1
- package/dist/stripe/client/index.js.map +0 -1
- package/dist/stripe/index.d.ts.map +0 -1
- package/dist/stripe/index.js.map +0 -1
- package/dist/stripe/internal/constants.d.ts.map +0 -1
- package/dist/stripe/internal/constants.js.map +0 -1
- package/dist/stripe/internal/types.d.ts.map +0 -1
- package/dist/stripe/internal/types.js.map +0 -1
- package/dist/stripe/server/Charge.d.ts.map +0 -1
- package/dist/stripe/server/Charge.js.map +0 -1
- package/dist/stripe/server/Methods.d.ts.map +0 -1
- package/dist/stripe/server/Methods.js.map +0 -1
- package/dist/stripe/server/index.d.ts.map +0 -1
- package/dist/stripe/server/index.js.map +0 -1
- package/dist/stripe/server/internal/deposit-address.d.ts.map +0 -1
- package/dist/stripe/server/internal/deposit-address.js.map +0 -1
- package/dist/stripe/server/internal/html/types.d.ts.map +0 -1
- package/dist/stripe/server/internal/html/types.js.map +0 -1
- package/dist/stripe/server/internal/html.gen.d.ts.map +0 -1
- package/dist/stripe/server/internal/html.gen.js.map +0 -1
- package/dist/stripe/server/internal/record-payment.d.ts.map +0 -1
- package/dist/stripe/server/internal/record-payment.js.map +0 -1
- package/dist/stripe/server/internal/request.d.ts.map +0 -1
- package/dist/stripe/server/internal/request.js.map +0 -1
- package/dist/tap/Constants.d.ts.map +0 -1
- package/dist/tap/Constants.js.map +0 -1
- package/dist/tap/Types.d.ts.map +0 -1
- package/dist/tap/Types.js.map +0 -1
- package/dist/tap/client/index.d.ts.map +0 -1
- package/dist/tap/client/index.js.map +0 -1
- package/dist/tap/index.d.ts.map +0 -1
- package/dist/tap/index.js.map +0 -1
- package/dist/tap/server/index.d.ts.map +0 -1
- package/dist/tap/server/index.js.map +0 -1
- package/dist/tempo/Attribution.d.ts.map +0 -1
- package/dist/tempo/Attribution.js.map +0 -1
- package/dist/tempo/Methods.d.ts.map +0 -1
- package/dist/tempo/Methods.js.map +0 -1
- package/dist/tempo/Proof.d.ts.map +0 -1
- package/dist/tempo/Proof.js.map +0 -1
- package/dist/tempo/client/Charge.d.ts.map +0 -1
- package/dist/tempo/client/Charge.js.map +0 -1
- package/dist/tempo/client/Methods.d.ts.map +0 -1
- package/dist/tempo/client/Methods.js.map +0 -1
- package/dist/tempo/client/ResolveAccount.d.ts.map +0 -1
- package/dist/tempo/client/ResolveAccount.js.map +0 -1
- package/dist/tempo/client/Subscription.d.ts.map +0 -1
- package/dist/tempo/client/Subscription.js.map +0 -1
- package/dist/tempo/client/index.d.ts.map +0 -1
- package/dist/tempo/client/index.js.map +0 -1
- package/dist/tempo/index.d.ts.map +0 -1
- package/dist/tempo/index.js.map +0 -1
- package/dist/tempo/internal/account.d.ts.map +0 -1
- package/dist/tempo/internal/account.js.map +0 -1
- package/dist/tempo/internal/address.d.ts.map +0 -1
- package/dist/tempo/internal/address.js.map +0 -1
- package/dist/tempo/internal/auto-swap.d.ts.map +0 -1
- package/dist/tempo/internal/auto-swap.js.map +0 -1
- package/dist/tempo/internal/charge.d.ts.map +0 -1
- package/dist/tempo/internal/charge.js.map +0 -1
- package/dist/tempo/internal/defaults.d.ts.map +0 -1
- package/dist/tempo/internal/defaults.js.map +0 -1
- package/dist/tempo/internal/fee-payer.d.ts.map +0 -1
- package/dist/tempo/internal/fee-payer.js.map +0 -1
- package/dist/tempo/internal/fee-token.d.ts.map +0 -1
- package/dist/tempo/internal/fee-token.js.map +0 -1
- package/dist/tempo/internal/proof.d.ts.map +0 -1
- package/dist/tempo/internal/proof.js.map +0 -1
- package/dist/tempo/internal/selectors.d.ts.map +0 -1
- package/dist/tempo/internal/selectors.js.map +0 -1
- package/dist/tempo/internal/types.d.ts.map +0 -1
- package/dist/tempo/internal/types.js.map +0 -1
- package/dist/tempo/legacy/client/ChannelOps.d.ts.map +0 -1
- package/dist/tempo/legacy/client/ChannelOps.js.map +0 -1
- package/dist/tempo/legacy/client/Session.d.ts.map +0 -1
- package/dist/tempo/legacy/client/Session.js.map +0 -1
- package/dist/tempo/legacy/client/SessionManager.d.ts.map +0 -1
- package/dist/tempo/legacy/client/SessionManager.js.map +0 -1
- package/dist/tempo/legacy/client/index.d.ts.map +0 -1
- package/dist/tempo/legacy/client/index.js.map +0 -1
- package/dist/tempo/legacy/index.d.ts.map +0 -1
- package/dist/tempo/legacy/index.js.map +0 -1
- package/dist/tempo/legacy/session/Chain.d.ts.map +0 -1
- package/dist/tempo/legacy/session/Chain.js.map +0 -1
- package/dist/tempo/legacy/session/Channel.d.ts.map +0 -1
- package/dist/tempo/legacy/session/Channel.js.map +0 -1
- package/dist/tempo/legacy/session/Types.d.ts.map +0 -1
- package/dist/tempo/legacy/session/Types.js.map +0 -1
- package/dist/tempo/legacy/session/Voucher.d.ts.map +0 -1
- package/dist/tempo/legacy/session/Voucher.js.map +0 -1
- package/dist/tempo/legacy/session/escrow.abi.d.ts.map +0 -1
- package/dist/tempo/legacy/session/escrow.abi.js.map +0 -1
- package/dist/tempo/legacy/session/index.d.ts.map +0 -1
- package/dist/tempo/legacy/session/index.js.map +0 -1
- package/dist/tempo/server/Charge.d.ts.map +0 -1
- package/dist/tempo/server/Charge.js.map +0 -1
- package/dist/tempo/server/Methods.d.ts.map +0 -1
- package/dist/tempo/server/Methods.js.map +0 -1
- package/dist/tempo/server/Relay.d.ts.map +0 -1
- package/dist/tempo/server/Relay.js.map +0 -1
- package/dist/tempo/server/SponsorBudget.d.ts.map +0 -1
- package/dist/tempo/server/SponsorBudget.js.map +0 -1
- package/dist/tempo/server/Subscription.d.ts.map +0 -1
- package/dist/tempo/server/Subscription.js.map +0 -1
- package/dist/tempo/server/index.d.ts.map +0 -1
- package/dist/tempo/server/index.js.map +0 -1
- package/dist/tempo/server/internal/html.gen.d.ts.map +0 -1
- package/dist/tempo/server/internal/html.gen.js.map +0 -1
- package/dist/tempo/server/internal/request-body.d.ts.map +0 -1
- package/dist/tempo/server/internal/request-body.js.map +0 -1
- package/dist/tempo/server/internal/transport.d.ts.map +0 -1
- package/dist/tempo/server/internal/transport.js.map +0 -1
- package/dist/tempo/session/Snapshot.d.ts.map +0 -1
- package/dist/tempo/session/Snapshot.js.map +0 -1
- package/dist/tempo/session/client/ChannelOps.d.ts.map +0 -1
- package/dist/tempo/session/client/ChannelOps.js.map +0 -1
- package/dist/tempo/session/client/ChannelStore.d.ts.map +0 -1
- package/dist/tempo/session/client/ChannelStore.js.map +0 -1
- package/dist/tempo/session/client/CredentialState.d.ts.map +0 -1
- package/dist/tempo/session/client/CredentialState.js.map +0 -1
- package/dist/tempo/session/client/ReceiptCoordinator.d.ts.map +0 -1
- package/dist/tempo/session/client/ReceiptCoordinator.js.map +0 -1
- package/dist/tempo/session/client/Runtime.d.ts.map +0 -1
- package/dist/tempo/session/client/Runtime.js.map +0 -1
- package/dist/tempo/session/client/Session.d.ts.map +0 -1
- package/dist/tempo/session/client/Session.js.map +0 -1
- package/dist/tempo/session/client/SessionManager.d.ts.map +0 -1
- package/dist/tempo/session/client/SessionManager.js.map +0 -1
- package/dist/tempo/session/client/Transports.d.ts.map +0 -1
- package/dist/tempo/session/client/Transports.js.map +0 -1
- package/dist/tempo/session/client/index.d.ts.map +0 -1
- package/dist/tempo/session/client/index.js.map +0 -1
- package/dist/tempo/session/client/internal/SessionManager.d.ts.map +0 -1
- package/dist/tempo/session/client/internal/SessionManager.js.map +0 -1
- package/dist/tempo/session/index.d.ts.map +0 -1
- package/dist/tempo/session/index.js.map +0 -1
- package/dist/tempo/session/precompile/Chain.d.ts.map +0 -1
- package/dist/tempo/session/precompile/Chain.js.map +0 -1
- package/dist/tempo/session/precompile/Channel.d.ts.map +0 -1
- package/dist/tempo/session/precompile/Channel.js.map +0 -1
- package/dist/tempo/session/precompile/Protocol.d.ts.map +0 -1
- package/dist/tempo/session/precompile/Protocol.js.map +0 -1
- package/dist/tempo/session/precompile/Voucher.d.ts.map +0 -1
- package/dist/tempo/session/precompile/Voucher.js.map +0 -1
- package/dist/tempo/session/precompile/escrow.abi.d.ts.map +0 -1
- package/dist/tempo/session/precompile/escrow.abi.js.map +0 -1
- package/dist/tempo/session/precompile/index.d.ts.map +0 -1
- package/dist/tempo/session/precompile/index.js.map +0 -1
- package/dist/tempo/session/server/ChannelOps.d.ts.map +0 -1
- package/dist/tempo/session/server/ChannelOps.js.map +0 -1
- package/dist/tempo/session/server/ChannelStore.d.ts.map +0 -1
- package/dist/tempo/session/server/ChannelStore.js.map +0 -1
- package/dist/tempo/session/server/CredentialVerification.d.ts.map +0 -1
- package/dist/tempo/session/server/CredentialVerification.js.map +0 -1
- package/dist/tempo/session/server/MeteredStream.d.ts.map +0 -1
- package/dist/tempo/session/server/MeteredStream.js.map +0 -1
- package/dist/tempo/session/server/RequestState.d.ts.map +0 -1
- package/dist/tempo/session/server/RequestState.js.map +0 -1
- package/dist/tempo/session/server/Session.d.ts.map +0 -1
- package/dist/tempo/session/server/Session.js.map +0 -1
- package/dist/tempo/session/server/Settlement.d.ts.map +0 -1
- package/dist/tempo/session/server/Settlement.js.map +0 -1
- package/dist/tempo/session/server/Sse.d.ts.map +0 -1
- package/dist/tempo/session/server/Sse.js.map +0 -1
- package/dist/tempo/session/server/Transports.d.ts.map +0 -1
- package/dist/tempo/session/server/Transports.js.map +0 -1
- package/dist/tempo/session/server/Ws.d.ts.map +0 -1
- package/dist/tempo/session/server/Ws.js.map +0 -1
- package/dist/tempo/session/server/index.d.ts.map +0 -1
- package/dist/tempo/session/server/index.js.map +0 -1
- package/dist/tempo/subscription/KeyAuthorization.d.ts.map +0 -1
- package/dist/tempo/subscription/KeyAuthorization.js.map +0 -1
- package/dist/tempo/subscription/Receipt.d.ts.map +0 -1
- package/dist/tempo/subscription/Receipt.js.map +0 -1
- package/dist/tempo/subscription/Store.d.ts.map +0 -1
- package/dist/tempo/subscription/Store.js.map +0 -1
- package/dist/tempo/subscription/Types.d.ts.map +0 -1
- package/dist/tempo/subscription/Types.js.map +0 -1
- package/dist/tempo/subscription/index.d.ts.map +0 -1
- package/dist/tempo/subscription/index.js.map +0 -1
- package/dist/validation/core.d.ts.map +0 -1
- package/dist/validation/core.js.map +0 -1
- package/dist/validation/index.d.ts.map +0 -1
- package/dist/validation/index.js.map +0 -1
- package/dist/viem/Account.d.ts.map +0 -1
- package/dist/viem/Account.js.map +0 -1
- package/dist/viem/Client.d.ts.map +0 -1
- package/dist/viem/Client.js.map +0 -1
- package/dist/web-bot-auth/Constants.d.ts.map +0 -1
- package/dist/web-bot-auth/Constants.js.map +0 -1
- package/dist/web-bot-auth/Types.d.ts.map +0 -1
- package/dist/web-bot-auth/Types.js.map +0 -1
- package/dist/web-bot-auth/client/index.d.ts.map +0 -1
- package/dist/web-bot-auth/client/index.js.map +0 -1
- package/dist/web-bot-auth/index.d.ts.map +0 -1
- package/dist/web-bot-auth/index.js.map +0 -1
- package/dist/web-bot-auth/internal/JwkThumbprint.d.ts.map +0 -1
- package/dist/web-bot-auth/internal/JwkThumbprint.js.map +0 -1
- package/dist/web-bot-auth/internal/SignatureAgent.d.ts.map +0 -1
- package/dist/web-bot-auth/internal/SignatureAgent.js.map +0 -1
- package/dist/web-bot-auth/server/index.d.ts.map +0 -1
- package/dist/web-bot-auth/server/index.js.map +0 -1
- package/dist/x402/Assets.d.ts.map +0 -1
- package/dist/x402/Assets.js.map +0 -1
- package/dist/x402/Header.d.ts.map +0 -1
- package/dist/x402/Header.js.map +0 -1
- package/dist/x402/Types.d.ts.map +0 -1
- package/dist/x402/Types.js.map +0 -1
- package/dist/x402/client/Exact.d.ts.map +0 -1
- package/dist/x402/client/Exact.js.map +0 -1
- package/dist/x402/index.d.ts.map +0 -1
- package/dist/x402/index.js.map +0 -1
- package/dist/x402/internal/ChallengeBrand.d.ts.map +0 -1
- package/dist/x402/internal/ChallengeBrand.js.map +0 -1
- package/dist/x402/internal/RouteBinding.d.ts.map +0 -1
- package/dist/x402/internal/RouteBinding.js.map +0 -1
- package/dist/x402/server/EvmCharge.d.ts.map +0 -1
- package/dist/x402/server/EvmCharge.js.map +0 -1
- package/dist/x402/server/Facilitator.d.ts.map +0 -1
- package/dist/x402/server/Facilitator.js.map +0 -1
- package/dist/zod.d.ts.map +0 -1
- package/dist/zod.js.map +0 -1
- package/src/BodyDigest.test.ts +0 -43
- package/src/BodyDigest.ts +0 -55
- package/src/Challenge.fuzz.test.ts +0 -154
- package/src/Challenge.test-d.ts +0 -82
- package/src/Challenge.test.ts +0 -1060
- package/src/Challenge.ts +0 -687
- package/src/Constants.ts +0 -58
- package/src/Credential.fuzz.test.ts +0 -62
- package/src/Credential.test.ts +0 -378
- package/src/Credential.ts +0 -217
- package/src/Errors.test.ts +0 -520
- package/src/Errors.ts +0 -448
- package/src/Expires.test.ts +0 -112
- package/src/Expires.ts +0 -59
- package/src/Html.ts +0 -67
- package/src/Mcp.ts +0 -85
- package/src/Method.test.ts +0 -177
- package/src/Method.ts +0 -631
- package/src/PaymentRequest.test.ts +0 -147
- package/src/PaymentRequest.ts +0 -108
- package/src/Receipt.test.ts +0 -151
- package/src/Receipt.ts +0 -146
- package/src/Store.test-d.ts +0 -211
- package/src/Store.test.ts +0 -407
- package/src/Store.ts +0 -397
- package/src/attestation/Attestation.integration.test.ts +0 -208
- package/src/attestation/Client.test.ts +0 -83
- package/src/attestation/Client.ts +0 -34
- package/src/attestation/Constants.ts +0 -15
- package/src/attestation/Server.test.ts +0 -60
- package/src/attestation/Server.ts +0 -12
- package/src/attestation/Types.test-d.ts +0 -54
- package/src/attestation/Types.ts +0 -77
- package/src/attestation/index.ts +0 -5
- package/src/attestation/internal/HttpMessageSignature.test.ts +0 -101
- package/src/attestation/internal/HttpMessageSignature.ts +0 -429
- package/src/attestation/internal/SigningContext.ts +0 -13
- package/src/bin.js +0 -2
- package/src/bin.ts +0 -4
- package/src/cli/account.ts +0 -269
- package/src/cli/cli.test.ts +0 -2221
- package/src/cli/cli.ts +0 -1650
- package/src/cli/config.test.ts +0 -89
- package/src/cli/config.ts +0 -50
- package/src/cli/internal.ts +0 -114
- package/src/cli/mcp.test.ts +0 -262
- package/src/cli/plugins/evm.ts +0 -55
- package/src/cli/plugins/index.ts +0 -4
- package/src/cli/plugins/plugin.ts +0 -84
- package/src/cli/plugins/stripe.ts +0 -174
- package/src/cli/plugins/tempo.ts +0 -1102
- package/src/cli/sessions/Manager.test.ts +0 -249
- package/src/cli/sessions/Manager.ts +0 -93
- package/src/cli/sessions/commands.ts +0 -444
- package/src/cli/sessions/request.test.ts +0 -51
- package/src/cli/sessions/request.ts +0 -353
- package/src/cli/sessions/store.test.ts +0 -581
- package/src/cli/sessions/store.ts +0 -940
- package/src/cli/utils.test.ts +0 -156
- package/src/cli/utils.ts +0 -394
- package/src/cli/validate/challenge.ts +0 -565
- package/src/cli/validate/discovery.test.ts +0 -435
- package/src/cli/validate/discovery.ts +0 -221
- package/src/cli/validate/helpers.ts +0 -166
- package/src/cli/validate/index.ts +0 -229
- package/src/cli/validate/messages.ts +0 -7
- package/src/cli/validate/payment.ts +0 -774
- package/src/cli/validate.test.ts +0 -843
- package/src/client/Methods.ts +0 -8
- package/src/client/Mppx.test-d.ts +0 -287
- package/src/client/Mppx.test.ts +0 -1065
- package/src/client/Mppx.ts +0 -487
- package/src/client/Transport.test.ts +0 -586
- package/src/client/Transport.ts +0 -170
- package/src/client/index.ts +0 -29
- package/src/client/internal/Fetch.browser.test.ts +0 -197
- package/src/client/internal/Fetch.test-d.ts +0 -109
- package/src/client/internal/Fetch.test.ts +0 -2336
- package/src/client/internal/Fetch.ts +0 -1075
- package/src/client/internal/MethodChallenge.ts +0 -35
- package/src/client/internal/MethodResponse.ts +0 -67
- package/src/client/internal/protocols/Mcp.test.ts +0 -220
- package/src/client/internal/protocols/Mcp.ts +0 -186
- package/src/client/internal/protocols/Mpp.ts +0 -21
- package/src/client/internal/protocols/Protocol.ts +0 -10
- package/src/client/internal/protocols/Shared.ts +0 -25
- package/src/client/internal/protocols/X402.ts +0 -46
- package/src/client/node.test.ts +0 -115
- package/src/client/node.ts +0 -247
- package/src/discovery/Discovery.test.ts +0 -214
- package/src/discovery/Discovery.ts +0 -105
- package/src/discovery/OpenApi.test.ts +0 -623
- package/src/discovery/OpenApi.ts +0 -192
- package/src/discovery/Validate.test.ts +0 -305
- package/src/discovery/Validate.ts +0 -77
- package/src/discovery/index.ts +0 -3
- package/src/discovery/internal/Metadata.ts +0 -51
- package/src/env.d.ts +0 -12
- package/src/evm/Assets.ts +0 -1
- package/src/evm/Chains.ts +0 -11
- package/src/evm/Methods.ts +0 -44
- package/src/evm/PublicInterface.test-d.ts +0 -134
- package/src/evm/Types.ts +0 -140
- package/src/evm/client/Charge.test.ts +0 -347
- package/src/evm/client/Charge.ts +0 -187
- package/src/evm/client/Methods.ts +0 -19
- package/src/evm/client/index.ts +0 -6
- package/src/evm/index.ts +0 -16
- package/src/evm/server/Charge.test.ts +0 -339
- package/src/evm/server/Charge.ts +0 -295
- package/src/evm/server/Methods.ts +0 -22
- package/src/evm/server/index.ts +0 -6
- package/src/index.ts +0 -14
- package/src/internal/AcceptPayment.test.ts +0 -347
- package/src/internal/AcceptPayment.ts +0 -366
- package/src/internal/HeaderCodec.ts +0 -36
- package/src/internal/changeset.test.ts +0 -106
- package/src/internal/constantTimeEqual.test.ts +0 -47
- package/src/internal/constantTimeEqual.ts +0 -10
- package/src/internal/env.test.ts +0 -42
- package/src/internal/env.ts +0 -49
- package/src/internal/types.test-d.ts +0 -21
- package/src/internal/types.ts +0 -479
- package/src/mcp/client/McpClient.integration.test.ts +0 -639
- package/src/mcp/client/McpClient.test-d.ts +0 -144
- package/src/mcp/client/McpClient.test.ts +0 -463
- package/src/mcp/client/McpClient.ts +0 -307
- package/src/mcp/client/McpClient.unit.test.ts +0 -135
- package/src/mcp/client/index.ts +0 -2
- package/src/mcp/server/Transport.test.ts +0 -191
- package/src/mcp/server/Transport.ts +0 -111
- package/src/mcp/server/index.ts +0 -1
- package/src/middlewares/elysia.test.ts +0 -285
- package/src/middlewares/elysia.ts +0 -116
- package/src/middlewares/express.test.ts +0 -361
- package/src/middlewares/express.ts +0 -140
- package/src/middlewares/hono.test.ts +0 -473
- package/src/middlewares/hono.ts +0 -153
- package/src/middlewares/internal/mppx.test.ts +0 -177
- package/src/middlewares/internal/mppx.ts +0 -67
- package/src/middlewares/nextjs.test.ts +0 -359
- package/src/middlewares/nextjs.ts +0 -107
- package/src/proxy/Proxy.test.ts +0 -1038
- package/src/proxy/Proxy.ts +0 -483
- package/src/proxy/Proxy.upstreamError.test.ts +0 -364
- package/src/proxy/Service.test.ts +0 -252
- package/src/proxy/Service.ts +0 -280
- package/src/proxy/index.ts +0 -6
- package/src/proxy/internal/Headers.test.ts +0 -139
- package/src/proxy/internal/Headers.ts +0 -66
- package/src/proxy/internal/Route.test.ts +0 -217
- package/src/proxy/internal/Route.ts +0 -64
- package/src/proxy/services/anthropic.test.ts +0 -132
- package/src/proxy/services/anthropic.ts +0 -53
- package/src/proxy/services/hooks.test-d.ts +0 -14
- package/src/proxy/services/hooks.test.ts +0 -44
- package/src/proxy/services/openai.test.ts +0 -157
- package/src/proxy/services/openai.ts +0 -60
- package/src/proxy/services/stripe.test.ts +0 -175
- package/src/proxy/services/stripe.ts +0 -59
- package/src/server/Methods.test-d.ts +0 -88
- package/src/server/Methods.test.ts +0 -69
- package/src/server/Methods.ts +0 -3
- package/src/server/Mppx.authorize.test.ts +0 -210
- package/src/server/Mppx.test-d.ts +0 -494
- package/src/server/Mppx.test.ts +0 -6711
- package/src/server/Mppx.ts +0 -2919
- package/src/server/NodeListener.test.ts +0 -293
- package/src/server/NodeListener.ts +0 -45
- package/src/server/Request.test.ts +0 -255
- package/src/server/Request.ts +0 -155
- package/src/server/Response.test.ts +0 -32
- package/src/server/Response.ts +0 -45
- package/src/server/Transport.test.ts +0 -598
- package/src/server/Transport.ts +0 -320
- package/src/server/index.ts +0 -9
- package/src/server/internal/html/compose.main.gen.ts +0 -2
- package/src/server/internal/html/compose.main.ts +0 -88
- package/src/server/internal/html/config.ts +0 -672
- package/src/server/internal/html/constants.ts +0 -28
- package/src/server/internal/html/serviceWorker.client.ts +0 -28
- package/src/server/internal/html/serviceWorker.gen.ts +0 -2
- package/src/server/internal/html/serviceWorker.ts +0 -27
- package/src/server/internal/html/tsconfig.compose.json +0 -8
- package/src/server/internal/html/tsconfig.worker.client.json +0 -8
- package/src/server/internal/html/tsconfig.worker.json +0 -8
- package/src/server/internal/scope.ts +0 -43
- package/src/stripe/Charge.integration.test.ts +0 -329
- package/src/stripe/Methods.test.ts +0 -62
- package/src/stripe/Methods.ts +0 -44
- package/src/stripe/client/Charge.test.ts +0 -205
- package/src/stripe/client/Charge.ts +0 -132
- package/src/stripe/client/Methods.ts +0 -37
- package/src/stripe/client/index.ts +0 -2
- package/src/stripe/index.ts +0 -1
- package/src/stripe/internal/constants.ts +0 -7
- package/src/stripe/internal/types.ts +0 -47
- package/src/stripe/server/Charge.test-d.ts +0 -81
- package/src/stripe/server/Charge.test.ts +0 -700
- package/src/stripe/server/Charge.ts +0 -487
- package/src/stripe/server/Methods.test-d.ts +0 -157
- package/src/stripe/server/Methods.test.ts +0 -403
- package/src/stripe/server/Methods.ts +0 -441
- package/src/stripe/server/index.ts +0 -2
- package/src/stripe/server/internal/deposit-address.ts +0 -57
- package/src/stripe/server/internal/html/main.ts +0 -165
- package/src/stripe/server/internal/html/node_modules/.bin/mppx +0 -22
- package/src/stripe/server/internal/html/node_modules/.bin/mppx.src +0 -22
- package/src/stripe/server/internal/html/package.json +0 -9
- package/src/stripe/server/internal/html/stripe-js-pure.d.ts +0 -7
- package/src/stripe/server/internal/html/tsconfig.json +0 -8
- package/src/stripe/server/internal/html/types.ts +0 -5
- package/src/stripe/server/internal/html.gen.ts +0 -2
- package/src/stripe/server/internal/record-payment.ts +0 -66
- package/src/stripe/server/internal/request.ts +0 -49
- package/src/tap/Constants.ts +0 -32
- package/src/tap/Tap.test.ts +0 -125
- package/src/tap/Types.ts +0 -11
- package/src/tap/client/index.ts +0 -54
- package/src/tap/index.ts +0 -4
- package/src/tap/server/index.ts +0 -48
- package/src/tempo/AccessKeyAuthorization.test.ts +0 -141
- package/src/tempo/Attribution.test.ts +0 -294
- package/src/tempo/Attribution.ts +0 -185
- package/src/tempo/Methods.test.ts +0 -425
- package/src/tempo/Methods.ts +0 -367
- package/src/tempo/Proof.conformance.test.ts +0 -146
- package/src/tempo/Proof.test-d.ts +0 -32
- package/src/tempo/Proof.test.ts +0 -40
- package/src/tempo/Proof.ts +0 -69
- package/src/tempo/PublicExports.test-d.ts +0 -130
- package/src/tempo/Subscription.integration.test.ts +0 -591
- package/src/tempo/client/Charge.test.ts +0 -501
- package/src/tempo/client/Charge.ts +0 -271
- package/src/tempo/client/Methods.ts +0 -45
- package/src/tempo/client/ResolveAccount.ts +0 -46
- package/src/tempo/client/Subscription.test.ts +0 -180
- package/src/tempo/client/Subscription.ts +0 -156
- package/src/tempo/client/index.ts +0 -17
- package/src/tempo/index.ts +0 -5
- package/src/tempo/internal/account.ts +0 -56
- package/src/tempo/internal/address.test.ts +0 -42
- package/src/tempo/internal/address.ts +0 -6
- package/src/tempo/internal/auto-swap.test.ts +0 -198
- package/src/tempo/internal/auto-swap.ts +0 -145
- package/src/tempo/internal/charge.test.ts +0 -66
- package/src/tempo/internal/charge.ts +0 -43
- package/src/tempo/internal/defaults.test.ts +0 -95
- package/src/tempo/internal/defaults.ts +0 -53
- package/src/tempo/internal/fee-payer.test.ts +0 -1177
- package/src/tempo/internal/fee-payer.ts +0 -808
- package/src/tempo/internal/fee-token.test.ts +0 -165
- package/src/tempo/internal/fee-token.ts +0 -72
- package/src/tempo/internal/proof.test.ts +0 -97
- package/src/tempo/internal/proof.ts +0 -87
- package/src/tempo/internal/selectors.ts +0 -10
- package/src/tempo/internal/types.ts +0 -19
- package/src/tempo/legacy/AccessKeyAuthorization.test.ts +0 -162
- package/src/tempo/legacy/README.md +0 -9
- package/src/tempo/legacy/client/ChannelOps.test.ts +0 -379
- package/src/tempo/legacy/client/ChannelOps.ts +0 -271
- package/src/tempo/legacy/client/Session.test.ts +0 -800
- package/src/tempo/legacy/client/Session.ts +0 -397
- package/src/tempo/legacy/client/SessionManager.test.ts +0 -468
- package/src/tempo/legacy/client/SessionManager.ts +0 -909
- package/src/tempo/legacy/client/index.ts +0 -6
- package/src/tempo/legacy/index.ts +0 -4
- package/src/tempo/legacy/session/Chain.test.ts +0 -1349
- package/src/tempo/legacy/session/Chain.ts +0 -830
- package/src/tempo/legacy/session/Channel.test.ts +0 -109
- package/src/tempo/legacy/session/Channel.ts +0 -51
- package/src/tempo/legacy/session/Types.ts +0 -91
- package/src/tempo/legacy/session/Voucher.test.ts +0 -410
- package/src/tempo/legacy/session/Voucher.ts +0 -183
- package/src/tempo/legacy/session/escrow.abi.ts +0 -760
- package/src/tempo/legacy/session/index.ts +0 -8
- package/src/tempo/server/AtomicStore.test-d.ts +0 -63
- package/src/tempo/server/Charge.test.ts +0 -6056
- package/src/tempo/server/Charge.ts +0 -1379
- package/src/tempo/server/Methods.ts +0 -86
- package/src/tempo/server/Relay.test.ts +0 -677
- package/src/tempo/server/Relay.ts +0 -297
- package/src/tempo/server/SponsorBudget.test.ts +0 -154
- package/src/tempo/server/SponsorBudget.ts +0 -219
- package/src/tempo/server/Sse.test.ts +0 -321
- package/src/tempo/server/Subscription.test.ts +0 -1944
- package/src/tempo/server/Subscription.ts +0 -1336
- package/src/tempo/server/index.ts +0 -12
- package/src/tempo/server/internal/html/main.ts +0 -115
- package/src/tempo/server/internal/html/node_modules/.bin/mppx +0 -22
- package/src/tempo/server/internal/html/node_modules/.bin/mppx.src +0 -22
- package/src/tempo/server/internal/html/package.json +0 -10
- package/src/tempo/server/internal/html/tsconfig.json +0 -8
- package/src/tempo/server/internal/html.gen.ts +0 -2
- package/src/tempo/server/internal/request-body.test.ts +0 -210
- package/src/tempo/server/internal/request-body.ts +0 -61
- package/src/tempo/server/internal/transport.test.ts +0 -922
- package/src/tempo/server/internal/transport.ts +0 -322
- package/src/tempo/session/README.md +0 -320
- package/src/tempo/session/Snapshot.test.ts +0 -41
- package/src/tempo/session/Snapshot.ts +0 -95
- package/src/tempo/session/client/ChannelOps.test.ts +0 -218
- package/src/tempo/session/client/ChannelOps.ts +0 -348
- package/src/tempo/session/client/ChannelStore.ts +0 -111
- package/src/tempo/session/client/CredentialState.test.ts +0 -789
- package/src/tempo/session/client/CredentialState.ts +0 -942
- package/src/tempo/session/client/ReceiptCoordinator.ts +0 -95
- package/src/tempo/session/client/Runtime.test.ts +0 -1104
- package/src/tempo/session/client/Runtime.ts +0 -1008
- package/src/tempo/session/client/Session.test.ts +0 -1355
- package/src/tempo/session/client/Session.ts +0 -420
- package/src/tempo/session/client/SessionManager.test.ts +0 -1899
- package/src/tempo/session/client/SessionManager.ts +0 -996
- package/src/tempo/session/client/Transports.test.ts +0 -1141
- package/src/tempo/session/client/Transports.ts +0 -1534
- package/src/tempo/session/client/index.ts +0 -40
- package/src/tempo/session/client/internal/SessionManager.ts +0 -36
- package/src/tempo/session/index.ts +0 -7
- package/src/tempo/session/precompile/Chain.integration.test.ts +0 -339
- package/src/tempo/session/precompile/Chain.test.ts +0 -1641
- package/src/tempo/session/precompile/Chain.ts +0 -1269
- package/src/tempo/session/precompile/Channel.test.ts +0 -147
- package/src/tempo/session/precompile/Channel.ts +0 -108
- package/src/tempo/session/precompile/Protocol.test.ts +0 -358
- package/src/tempo/session/precompile/Protocol.ts +0 -520
- package/src/tempo/session/precompile/Voucher.test.ts +0 -354
- package/src/tempo/session/precompile/Voucher.ts +0 -162
- package/src/tempo/session/precompile/escrow.abi.ts +0 -226
- package/src/tempo/session/precompile/index.ts +0 -33
- package/src/tempo/session/server/ChannelOps.test.ts +0 -129
- package/src/tempo/session/server/ChannelOps.ts +0 -157
- package/src/tempo/session/server/ChannelStore.test.ts +0 -1093
- package/src/tempo/session/server/ChannelStore.ts +0 -856
- package/src/tempo/session/server/CredentialVerification.test.ts +0 -299
- package/src/tempo/session/server/CredentialVerification.ts +0 -1087
- package/src/tempo/session/server/MeteredStream.ts +0 -99
- package/src/tempo/session/server/RequestState.test.ts +0 -574
- package/src/tempo/session/server/RequestState.ts +0 -507
- package/src/tempo/session/server/Session.integration.test.ts +0 -449
- package/src/tempo/session/server/Session.test.ts +0 -4247
- package/src/tempo/session/server/Session.ts +0 -669
- package/src/tempo/session/server/Settlement.test.ts +0 -345
- package/src/tempo/session/server/Settlement.ts +0 -527
- package/src/tempo/session/server/Sse.fuzz.test.ts +0 -138
- package/src/tempo/session/server/Sse.test.ts +0 -634
- package/src/tempo/session/server/Sse.ts +0 -261
- package/src/tempo/session/server/Transports.test.ts +0 -346
- package/src/tempo/session/server/Transports.ts +0 -256
- package/src/tempo/session/server/Ws.test.ts +0 -765
- package/src/tempo/session/server/Ws.ts +0 -391
- package/src/tempo/session/server/index.ts +0 -12
- package/src/tempo/subscription/KeyAuthorization.test.ts +0 -282
- package/src/tempo/subscription/KeyAuthorization.ts +0 -396
- package/src/tempo/subscription/Receipt.ts +0 -28
- package/src/tempo/subscription/Store.test.ts +0 -609
- package/src/tempo/subscription/Store.ts +0 -449
- package/src/tempo/subscription/Types.ts +0 -68
- package/src/tempo/subscription/index.ts +0 -23
- package/src/tsconfig.json +0 -10
- package/src/validation/core.ts +0 -386
- package/src/validation/index.ts +0 -11
- package/src/viem/Account.test.ts +0 -72
- package/src/viem/Account.ts +0 -30
- package/src/viem/Client.test.ts +0 -366
- package/src/viem/Client.ts +0 -93
- package/src/web-bot-auth/Constants.ts +0 -24
- package/src/web-bot-auth/Types.ts +0 -9
- package/src/web-bot-auth/WebBotAuth.test.ts +0 -182
- package/src/web-bot-auth/client/index.ts +0 -84
- package/src/web-bot-auth/index.ts +0 -6
- package/src/web-bot-auth/internal/JwkThumbprint.ts +0 -21
- package/src/web-bot-auth/internal/SignatureAgent.ts +0 -18
- package/src/web-bot-auth/server/index.ts +0 -113
- package/src/x402/Assets.test.ts +0 -253
- package/src/x402/Assets.ts +0 -221
- package/src/x402/Exact.e2e.test.ts +0 -488
- package/src/x402/Exact.localnet.test.ts +0 -475
- package/src/x402/Header.test.ts +0 -73
- package/src/x402/Header.ts +0 -79
- package/src/x402/PublicInterface.test-d.ts +0 -39
- package/src/x402/Types.ts +0 -248
- package/src/x402/client/Exact.test.ts +0 -309
- package/src/x402/client/Exact.ts +0 -186
- package/src/x402/index.ts +0 -6
- package/src/x402/internal/ChallengeBrand.ts +0 -14
- package/src/x402/internal/RouteBinding.ts +0 -18
- package/src/x402/server/EvmCharge.ts +0 -410
- package/src/x402/server/Facilitator.test.ts +0 -111
- package/src/x402/server/Facilitator.ts +0 -56
- package/src/zod.test.ts +0 -169
- package/src/zod.ts +0 -71
package/src/cli/cli.ts
DELETED
|
@@ -1,1650 +0,0 @@
|
|
|
1
|
-
import * as fs from 'node:fs'
|
|
2
|
-
import { createRequire } from 'node:module'
|
|
3
|
-
import * as path from 'node:path'
|
|
4
|
-
|
|
5
|
-
import { Cli, Errors, z } from 'incur'
|
|
6
|
-
import { Base64 } from 'ox'
|
|
7
|
-
import { type Address, createClient, http } from 'viem'
|
|
8
|
-
import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts'
|
|
9
|
-
import { tempo as tempoMainnet } from 'viem/tempo/chains'
|
|
10
|
-
|
|
11
|
-
import * as Challenge from '../Challenge.js'
|
|
12
|
-
import { normalizeHeaders } from '../client/internal/Fetch.js'
|
|
13
|
-
import * as Mppx from '../client/Mppx.js'
|
|
14
|
-
import * as Constants from '../Constants.js'
|
|
15
|
-
import { validate as validateDiscovery } from '../discovery/Validate.js'
|
|
16
|
-
import { isTempoSessionChallenge } from '../tempo/session/client/Transports.js'
|
|
17
|
-
import { createDefaultStore, createKeychain, resolveAccountName } from './account.js'
|
|
18
|
-
import { loadConfig, resolveAcceptPayment, selectChallenge } from './internal.js'
|
|
19
|
-
import type { Plugin } from './plugins/plugin.js'
|
|
20
|
-
import {
|
|
21
|
-
orderTempoChargeChallengesByBalance,
|
|
22
|
-
readTempoKeystore,
|
|
23
|
-
resolveTempoAccount,
|
|
24
|
-
} from './plugins/tempo.js'
|
|
25
|
-
import sessions, { sessionCommandError } from './sessions/commands.js'
|
|
26
|
-
import { runPersistentSessionRequest } from './sessions/request.js'
|
|
27
|
-
import { createSessionRegistry } from './sessions/store.js'
|
|
28
|
-
import {
|
|
29
|
-
chainName,
|
|
30
|
-
confirm,
|
|
31
|
-
decodeMemo,
|
|
32
|
-
fetchBalanceLines,
|
|
33
|
-
fmtBalance,
|
|
34
|
-
fmtChallengeValue,
|
|
35
|
-
fmtRequestValue,
|
|
36
|
-
isTempoAccount,
|
|
37
|
-
link,
|
|
38
|
-
parseMethodOpts,
|
|
39
|
-
pc,
|
|
40
|
-
printRequestHeaders,
|
|
41
|
-
printResponseHeaders,
|
|
42
|
-
prompt,
|
|
43
|
-
resolveChain,
|
|
44
|
-
resolveFundingNetwork,
|
|
45
|
-
resolveRpcUrl,
|
|
46
|
-
} from './utils.js'
|
|
47
|
-
import validate from './validate/index.js'
|
|
48
|
-
|
|
49
|
-
const packageJson = createRequire(import.meta.url)('../../package.json') as {
|
|
50
|
-
name: string
|
|
51
|
-
version: string
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const accountSummarySchema = z.object({
|
|
55
|
-
address: z.string(),
|
|
56
|
-
isDefault: z.boolean().optional(),
|
|
57
|
-
name: z.string(),
|
|
58
|
-
source: z.string().optional(),
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
const accountViewSchema = z.object({
|
|
62
|
-
address: z.string(),
|
|
63
|
-
balances: z.array(z.string()).optional(),
|
|
64
|
-
name: z.string(),
|
|
65
|
-
type: z.string().optional(),
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
const discoveryIssueSchema = z.object({
|
|
69
|
-
message: z.string(),
|
|
70
|
-
path: z.string(),
|
|
71
|
-
severity: z.string(),
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
const serviceSummarySchema = z.object({
|
|
75
|
-
description: z.string().optional(),
|
|
76
|
-
id: z.string(),
|
|
77
|
-
name: z.string().optional(),
|
|
78
|
-
paidEndpoints: z.number(),
|
|
79
|
-
status: z.string().optional(),
|
|
80
|
-
url: z.string().optional(),
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
const serviceEndpointSchema = z.object({
|
|
84
|
-
description: z.string().optional(),
|
|
85
|
-
method: z.string(),
|
|
86
|
-
path: z.string(),
|
|
87
|
-
payment: z.unknown().optional(),
|
|
88
|
-
})
|
|
89
|
-
|
|
90
|
-
const servicesRegistryUrl = 'https://mpp.dev/api/services'
|
|
91
|
-
|
|
92
|
-
function shouldReturnStructured(c: { format: string; formatExplicit: boolean }) {
|
|
93
|
-
return c.format === 'json' && c.formatExplicit
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
function outputResult<Data>(
|
|
97
|
-
c: { format: string; formatExplicit: boolean; ok: (data: Data) => never },
|
|
98
|
-
data: Data,
|
|
99
|
-
print: () => void,
|
|
100
|
-
): Data {
|
|
101
|
-
if (shouldReturnStructured(c)) return c.ok(data)
|
|
102
|
-
print()
|
|
103
|
-
return undefined as unknown as Data
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
async function writeResponseBody(response: Response) {
|
|
107
|
-
process.stdout.write(Buffer.from(await response.arrayBuffer()))
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
function canReadCommandStdin() {
|
|
111
|
-
if (process.stdin.isTTY !== false) return false
|
|
112
|
-
return process.stdin.listenerCount('data') === 0 && process.stdin.listenerCount('readable') === 0
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
type ServiceRegistryService = Record<string, unknown>
|
|
116
|
-
type ServiceRegistryEndpoint = Record<string, unknown>
|
|
117
|
-
|
|
118
|
-
function getString(value: unknown): string | undefined {
|
|
119
|
-
return typeof value === 'string' ? value : undefined
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
function getEndpoints(service: ServiceRegistryService): ServiceRegistryEndpoint[] {
|
|
123
|
-
return Array.isArray(service.endpoints)
|
|
124
|
-
? service.endpoints.filter(
|
|
125
|
-
(endpoint): endpoint is ServiceRegistryEndpoint =>
|
|
126
|
-
typeof endpoint === 'object' && endpoint !== null,
|
|
127
|
-
)
|
|
128
|
-
: []
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
function summarizeService(service: ServiceRegistryService) {
|
|
132
|
-
const endpoints = getEndpoints(service)
|
|
133
|
-
return {
|
|
134
|
-
...(getString(service.description) ? { description: getString(service.description) } : {}),
|
|
135
|
-
id: getString(service.id) ?? getString(service.name) ?? 'unknown',
|
|
136
|
-
...(getString(service.name) ? { name: getString(service.name) } : {}),
|
|
137
|
-
paidEndpoints: endpoints.filter((endpoint) => endpoint.payment).length,
|
|
138
|
-
...(getString(service.status) ? { status: getString(service.status) } : {}),
|
|
139
|
-
...(getString(service.serviceUrl) || getString(service.url)
|
|
140
|
-
? { url: getString(service.serviceUrl) ?? getString(service.url) }
|
|
141
|
-
: {}),
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
function summarizeEndpoint(endpoint: ServiceRegistryEndpoint) {
|
|
146
|
-
return {
|
|
147
|
-
...(getString(endpoint.description) ? { description: getString(endpoint.description) } : {}),
|
|
148
|
-
method: getString(endpoint.method) ?? 'GET',
|
|
149
|
-
path: getString(endpoint.path) ?? '/',
|
|
150
|
-
...(endpoint.payment !== undefined ? { payment: endpoint.payment } : {}),
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
function formatPayment(payment: unknown): string {
|
|
155
|
-
if (!payment) return 'free'
|
|
156
|
-
if (typeof payment !== 'object') return String(payment)
|
|
157
|
-
const p = payment as Record<string, unknown>
|
|
158
|
-
const amount = getString(p.amount)
|
|
159
|
-
const currency = getString(p.currency)
|
|
160
|
-
const method = getString(p.method)
|
|
161
|
-
const intent = getString(p.intent)
|
|
162
|
-
return [amount, currency, method && intent ? `${method}/${intent}` : (method ?? intent)]
|
|
163
|
-
.filter(Boolean)
|
|
164
|
-
.join(' ')
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
function filterChallengesByCurrency(
|
|
168
|
-
challenges: readonly Challenge.Challenge[],
|
|
169
|
-
currency: string | undefined,
|
|
170
|
-
): Challenge.Challenge[] {
|
|
171
|
-
if (!currency) return [...challenges]
|
|
172
|
-
const normalized = currency.toLowerCase()
|
|
173
|
-
return challenges.filter((challenge) => {
|
|
174
|
-
const offered = challenge.request.currency
|
|
175
|
-
return typeof offered === 'string' && offered.toLowerCase() === normalized
|
|
176
|
-
})
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
async function fetchServicesRegistry(): Promise<ServiceRegistryService[]> {
|
|
180
|
-
const url = process.env.MPPX_SERVICES_URL ?? servicesRegistryUrl
|
|
181
|
-
const response = await globalThis.fetch(url)
|
|
182
|
-
if (!response.ok)
|
|
183
|
-
throw new Errors.IncurError({
|
|
184
|
-
code: 'SERVICES_FETCH_FAILED',
|
|
185
|
-
message: `Failed to fetch services registry: HTTP ${response.status}`,
|
|
186
|
-
exitCode: 1,
|
|
187
|
-
})
|
|
188
|
-
const json = (await response.json()) as unknown
|
|
189
|
-
if (
|
|
190
|
-
!json ||
|
|
191
|
-
typeof json !== 'object' ||
|
|
192
|
-
!Array.isArray((json as { services?: unknown }).services)
|
|
193
|
-
)
|
|
194
|
-
throw new Errors.IncurError({
|
|
195
|
-
code: 'SERVICES_INVALID',
|
|
196
|
-
message: 'Services registry response did not contain a services array.',
|
|
197
|
-
exitCode: 1,
|
|
198
|
-
})
|
|
199
|
-
return (json as { services: ServiceRegistryService[] }).services
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
function findService(
|
|
203
|
-
services: ServiceRegistryService[],
|
|
204
|
-
id: string,
|
|
205
|
-
): ServiceRegistryService | undefined {
|
|
206
|
-
const needle = id.toLowerCase()
|
|
207
|
-
return services.find((service) => {
|
|
208
|
-
const serviceId = getString(service.id)?.toLowerCase()
|
|
209
|
-
const serviceName = getString(service.name)?.toLowerCase()
|
|
210
|
-
return serviceId === needle || serviceName === needle
|
|
211
|
-
})
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
const cli = Cli.create('mppx', {
|
|
215
|
-
mcp: { tools: { discovery: 'direct' } },
|
|
216
|
-
version: packageJson.version,
|
|
217
|
-
description: 'Make HTTP requests with automatic payment handling',
|
|
218
|
-
usage: [{ suffix: '<url> [options]' }],
|
|
219
|
-
args: z.object({
|
|
220
|
-
url: z.string().describe('URL to make request to'),
|
|
221
|
-
}),
|
|
222
|
-
options: z.object({
|
|
223
|
-
account: z.string().optional().describe('Account name (env: MPPX_ACCOUNT)'),
|
|
224
|
-
autoSwap: z.boolean().optional().describe('Auto-swap source tokens into payment currency'),
|
|
225
|
-
config: z.string().optional().describe('Path to config file'),
|
|
226
|
-
confirm: z.boolean().optional().default(false).describe('Show confirmation prompts'),
|
|
227
|
-
currency: z.string().optional().describe('Payment currency/token address to select'),
|
|
228
|
-
data: z.string().optional().describe('Send request body (implies POST unless -X is set)'),
|
|
229
|
-
fail: z.boolean().optional().describe('Fail silently on HTTP errors (exit 22)'),
|
|
230
|
-
header: z.array(z.string()).optional().describe('Add header (repeatable)'),
|
|
231
|
-
include: z.boolean().optional().describe('Include response headers in output'),
|
|
232
|
-
insecure: z
|
|
233
|
-
.boolean()
|
|
234
|
-
.optional()
|
|
235
|
-
.describe('Skip TLS certificate verification (true for localhost/.local)'),
|
|
236
|
-
jsonBody: z
|
|
237
|
-
.string()
|
|
238
|
-
.optional()
|
|
239
|
-
.describe('Send JSON body (sets Content-Type and Accept, implies POST)'),
|
|
240
|
-
location: z.boolean().optional().describe('Follow redirects'),
|
|
241
|
-
method: z.string().optional().describe('HTTP method'),
|
|
242
|
-
methodOpt: z
|
|
243
|
-
.array(z.string())
|
|
244
|
-
.optional()
|
|
245
|
-
.describe('Method-specific option (key=value, repeatable)'),
|
|
246
|
-
network: z.enum(['mainnet', 'testnet']).optional().describe('Tempo network'),
|
|
247
|
-
payWith: z.string().optional().describe('Source token for Tempo auto-swap'),
|
|
248
|
-
rpcUrl: z
|
|
249
|
-
.string()
|
|
250
|
-
.optional()
|
|
251
|
-
.describe('RPC endpoint, defaults to public RPC for chain (env: MPPX_RPC_URL)'),
|
|
252
|
-
session: z
|
|
253
|
-
.string()
|
|
254
|
-
.optional()
|
|
255
|
-
.default('auto')
|
|
256
|
-
.refine(
|
|
257
|
-
(value) => value === 'auto' || value === 'new' || /^0x[0-9a-fA-F]{64}$/.test(value),
|
|
258
|
-
'Expected auto, new, or a 32-byte channel ID',
|
|
259
|
-
)
|
|
260
|
-
.describe('Session selection: auto, new, or channel ID'),
|
|
261
|
-
silent: z.boolean().default(false).describe('Silent mode (suppress progress and info)'),
|
|
262
|
-
slippage: z.number().optional().describe('Tempo auto-swap max slippage percentage'),
|
|
263
|
-
userAgent: z
|
|
264
|
-
.string()
|
|
265
|
-
.optional()
|
|
266
|
-
.default(`${packageJson.name}/${packageJson.version}`)
|
|
267
|
-
.describe('Set User-Agent header'),
|
|
268
|
-
verbose: z
|
|
269
|
-
.number()
|
|
270
|
-
.default(0)
|
|
271
|
-
.meta({ count: true })
|
|
272
|
-
.describe('Verbosity (-v details, -vv headers)'),
|
|
273
|
-
}),
|
|
274
|
-
alias: {
|
|
275
|
-
account: 'a',
|
|
276
|
-
config: 'c',
|
|
277
|
-
data: 'd',
|
|
278
|
-
fail: 'f',
|
|
279
|
-
header: 'H',
|
|
280
|
-
include: 'i',
|
|
281
|
-
insecure: 'k',
|
|
282
|
-
jsonBody: 'J',
|
|
283
|
-
location: 'L',
|
|
284
|
-
method: 'X',
|
|
285
|
-
methodOpt: 'M',
|
|
286
|
-
rpcUrl: 'r',
|
|
287
|
-
silent: 's',
|
|
288
|
-
userAgent: 'A',
|
|
289
|
-
verbose: 'v',
|
|
290
|
-
},
|
|
291
|
-
examples: [{ args: { url: 'mpp.dev/api/ping/paid' }, description: 'Make a payment request' }],
|
|
292
|
-
async run(c) {
|
|
293
|
-
const info = c.options.silent
|
|
294
|
-
? (_msg: string) => {}
|
|
295
|
-
: (msg: string) => process.stderr.write(msg)
|
|
296
|
-
|
|
297
|
-
const loaded = await loadConfig(c.options.config)
|
|
298
|
-
if (loaded && c.options.verbose >= 1)
|
|
299
|
-
info(`${pc.dim('Using config')} ${pc.blue(path.relative(process.cwd(), loaded.path))}\n`)
|
|
300
|
-
|
|
301
|
-
const headers: Record<string, string> = {
|
|
302
|
-
'User-Agent': c.options.userAgent,
|
|
303
|
-
}
|
|
304
|
-
if (c.options.header) {
|
|
305
|
-
for (const header of c.options.header) {
|
|
306
|
-
const index = header.indexOf(':')
|
|
307
|
-
if (index === -1) {
|
|
308
|
-
return c.error({
|
|
309
|
-
code: 'INVALID_HEADER',
|
|
310
|
-
message: `Invalid header format: ${header}`,
|
|
311
|
-
exitCode: 2,
|
|
312
|
-
})
|
|
313
|
-
}
|
|
314
|
-
headers[header.slice(0, index).trim()] = header.slice(index + 1).trim()
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
const acceptPayment = resolveAcceptPayment(loaded?.config)
|
|
318
|
-
if (
|
|
319
|
-
acceptPayment &&
|
|
320
|
-
!Object.keys(headers).some((key) => key.toLowerCase() === 'accept-payment')
|
|
321
|
-
) {
|
|
322
|
-
headers['Accept-Payment'] = acceptPayment
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
const url = (() => {
|
|
326
|
-
const hasProtocol = /^https?:\/\//.test(c.args.url)
|
|
327
|
-
const isLocal = /^(localhost|.*\.localhost|127\.0\.0\.1|\[::1\])(:\d+)?/.test(c.args.url)
|
|
328
|
-
return hasProtocol ? c.args.url : `${isLocal ? 'http' : 'https'}://${c.args.url}`
|
|
329
|
-
})()
|
|
330
|
-
const { hostname } = new URL(url)
|
|
331
|
-
const insecure =
|
|
332
|
-
c.options.insecure ||
|
|
333
|
-
hostname === 'localhost' ||
|
|
334
|
-
hostname.endsWith('.localhost') ||
|
|
335
|
-
hostname.endsWith('.local')
|
|
336
|
-
|
|
337
|
-
// Scoped fetch that temporarily disables TLS verification only for
|
|
338
|
-
// the target connection when `insecure` is true, then restores
|
|
339
|
-
// the original value so other HTTPS connections are unaffected.
|
|
340
|
-
const targetFetch: typeof globalThis.fetch = insecure
|
|
341
|
-
? async (input, init) => {
|
|
342
|
-
const orig = process.env.NODE_TLS_REJECT_UNAUTHORIZED
|
|
343
|
-
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'
|
|
344
|
-
try {
|
|
345
|
-
return await globalThis.fetch(input, init)
|
|
346
|
-
} finally {
|
|
347
|
-
if (orig === undefined) delete process.env.NODE_TLS_REJECT_UNAUTHORIZED
|
|
348
|
-
else process.env.NODE_TLS_REJECT_UNAUTHORIZED = orig
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
: globalThis.fetch
|
|
352
|
-
|
|
353
|
-
// Node.js doesn't resolve *.localhost subdomains to loopback (unlike
|
|
354
|
-
// browsers per RFC 6761). Rewrite the URL to 127.0.0.1 and set the
|
|
355
|
-
// Host header so reverse proxies can route correctly.
|
|
356
|
-
const isSubLocalhost = hostname.endsWith('.localhost') && hostname !== 'localhost'
|
|
357
|
-
const fetchUrl = isSubLocalhost ? url.replace(hostname, '127.0.0.1') : url
|
|
358
|
-
if (isSubLocalhost) {
|
|
359
|
-
const { host } = new URL(url)
|
|
360
|
-
headers.Host = host
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
try {
|
|
364
|
-
const methodOpts = parseMethodOpts(c.options.methodOpt)
|
|
365
|
-
const sessionRegistry = createSessionRegistry()
|
|
366
|
-
|
|
367
|
-
const init: RequestInit = { redirect: c.options.location ? 'follow' : 'manual' }
|
|
368
|
-
if (c.options.jsonBody) {
|
|
369
|
-
init.body = c.options.jsonBody
|
|
370
|
-
headers['Content-Type'] ??= 'application/json'
|
|
371
|
-
headers.Accept ??= 'application/json'
|
|
372
|
-
} else if (c.options.data) {
|
|
373
|
-
init.body = c.options.data
|
|
374
|
-
}
|
|
375
|
-
if (c.options.method) init.method = c.options.method.toUpperCase()
|
|
376
|
-
else if (init.body) init.method = 'POST'
|
|
377
|
-
if (Object.keys(headers).length > 0) init.headers = headers
|
|
378
|
-
|
|
379
|
-
const headerOpts = {
|
|
380
|
-
include: c.options.include ?? false,
|
|
381
|
-
verbose: c.options.verbose,
|
|
382
|
-
silent: c.options.silent,
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
if (c.options.verbose >= 2) printRequestHeaders(url, init, info)
|
|
386
|
-
const challengeResponse = await targetFetch(fetchUrl, init)
|
|
387
|
-
if (challengeResponse.status !== 402) {
|
|
388
|
-
if (c.options.session !== 'auto')
|
|
389
|
-
return c.error({
|
|
390
|
-
code: 'UNSUPPORTED_SESSION',
|
|
391
|
-
message: '--session requires a tempo/session payment challenge.',
|
|
392
|
-
exitCode: 2,
|
|
393
|
-
})
|
|
394
|
-
if (c.options.fail && challengeResponse.status >= 400)
|
|
395
|
-
return c.error({
|
|
396
|
-
code: 'HTTP_ERROR',
|
|
397
|
-
message: `HTTP error ${challengeResponse.status}`,
|
|
398
|
-
exitCode: 22,
|
|
399
|
-
})
|
|
400
|
-
printResponseHeaders(challengeResponse, headerOpts)
|
|
401
|
-
await writeResponseBody(challengeResponse)
|
|
402
|
-
return
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
const offeredChallenges = Challenge.fromResponseList(challengeResponse)
|
|
406
|
-
const currencyChallenges = filterChallengesByCurrency(offeredChallenges, c.options.currency)
|
|
407
|
-
if (c.options.currency && currencyChallenges.length === 0) {
|
|
408
|
-
const offers = offeredChallenges
|
|
409
|
-
.map((challenge) => challenge.request.currency)
|
|
410
|
-
.filter((currency): currency is string => typeof currency === 'string')
|
|
411
|
-
.join(', ')
|
|
412
|
-
return c.error({
|
|
413
|
-
code: 'UNSUPPORTED_CURRENCY',
|
|
414
|
-
message: `Server did not offer payment currency ${c.options.currency}.${offers ? ` Offered currencies: ${offers}.` : ''}`,
|
|
415
|
-
exitCode: 2,
|
|
416
|
-
})
|
|
417
|
-
}
|
|
418
|
-
const challenges = await orderTempoChargeChallengesByBalance(currencyChallenges, {
|
|
419
|
-
options: {
|
|
420
|
-
account: c.options.account,
|
|
421
|
-
network: c.options.network,
|
|
422
|
-
rpcUrl: c.options.rpcUrl,
|
|
423
|
-
},
|
|
424
|
-
})
|
|
425
|
-
|
|
426
|
-
const selected = selectChallenge(challenges, loaded?.config)
|
|
427
|
-
if (!selected) {
|
|
428
|
-
const offers = challenges
|
|
429
|
-
.map((challenge) => `${challenge.method}/${challenge.intent}`)
|
|
430
|
-
.join(', ')
|
|
431
|
-
return c.error({
|
|
432
|
-
code: 'UNSUPPORTED_METHOD',
|
|
433
|
-
message: `Unsupported payment method. Server offers: ${offers}. Add it to mppx.config.ts using defineConfig().`,
|
|
434
|
-
exitCode: 2,
|
|
435
|
-
})
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
const { challenge, plugin, method: configMethod } = selected
|
|
439
|
-
const selectedChallengeResponse = new Response(null, {
|
|
440
|
-
status: 402,
|
|
441
|
-
headers: { [Constants.Headers.wwwAuthenticate]: Challenge.serialize(challenge) },
|
|
442
|
-
})
|
|
443
|
-
|
|
444
|
-
let tokenSymbol = (challenge.request.currency as string | undefined) ?? ''
|
|
445
|
-
let tokenDecimals = (challenge.request.decimals as number | undefined) ?? 6
|
|
446
|
-
let explorerUrl: string | undefined
|
|
447
|
-
let pluginResult: Awaited<ReturnType<Plugin['setup']>> | undefined
|
|
448
|
-
if (plugin) {
|
|
449
|
-
pluginResult = await plugin.setup({
|
|
450
|
-
challenge,
|
|
451
|
-
options: {
|
|
452
|
-
account: c.options.account,
|
|
453
|
-
autoSwap: c.options.autoSwap,
|
|
454
|
-
network: c.options.network,
|
|
455
|
-
payWith: c.options.payWith,
|
|
456
|
-
rpcUrl: c.options.rpcUrl,
|
|
457
|
-
slippage: c.options.slippage,
|
|
458
|
-
},
|
|
459
|
-
methodOpts,
|
|
460
|
-
})
|
|
461
|
-
tokenSymbol = pluginResult.tokenSymbol
|
|
462
|
-
tokenDecimals = pluginResult.tokenDecimals
|
|
463
|
-
explorerUrl = pluginResult.explorerUrl
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
const confirmEnabled = c.options.silent ? false : c.options.confirm
|
|
467
|
-
|
|
468
|
-
// Display challenge
|
|
469
|
-
const shownKeys = new Set<string>()
|
|
470
|
-
{
|
|
471
|
-
printResponseHeaders(
|
|
472
|
-
challengeResponse,
|
|
473
|
-
challenge.method === 'tempo' && challenge.intent === 'session' && c.options.include
|
|
474
|
-
? { ...headerOpts, include: false, verbose: Math.max(headerOpts.verbose, 2) }
|
|
475
|
-
: headerOpts,
|
|
476
|
-
)
|
|
477
|
-
|
|
478
|
-
const challengeRows = (() => {
|
|
479
|
-
const skip = new Set(['id', 'request'])
|
|
480
|
-
const rows: [string, string][] = []
|
|
481
|
-
for (const [key, value] of Object.entries(challenge)) {
|
|
482
|
-
if (skip.has(key) || value === undefined) continue
|
|
483
|
-
rows.push([key, fmtChallengeValue(key, value)])
|
|
484
|
-
}
|
|
485
|
-
return rows.sort(([a], [b]) => a.localeCompare(b))
|
|
486
|
-
})()
|
|
487
|
-
|
|
488
|
-
const fmtCtx = { tokenSymbol, tokenDecimals, explorerUrl }
|
|
489
|
-
const requestRows = (() => {
|
|
490
|
-
const skip = new Set(['decimals', 'currency', 'methodDetails'])
|
|
491
|
-
const rows: [string, string][] = []
|
|
492
|
-
for (const [key, value] of Object.entries(challenge.request)) {
|
|
493
|
-
if (skip.has(key) || value === undefined) continue
|
|
494
|
-
rows.push([key, fmtRequestValue(key, value, fmtCtx)])
|
|
495
|
-
}
|
|
496
|
-
return rows.sort(([a], [b]) => a.localeCompare(b))
|
|
497
|
-
})()
|
|
498
|
-
|
|
499
|
-
const detailRows = (() => {
|
|
500
|
-
const methodDetails = challenge.request.methodDetails as
|
|
501
|
-
| Record<string, unknown>
|
|
502
|
-
| undefined
|
|
503
|
-
if (!methodDetails) return []
|
|
504
|
-
const rows: [string, string][] = []
|
|
505
|
-
for (const [key, value] of Object.entries(methodDetails)) {
|
|
506
|
-
if (value === undefined) continue
|
|
507
|
-
if (key === 'memo' && typeof value === 'string') {
|
|
508
|
-
const decoded = decodeMemo(value)
|
|
509
|
-
rows.push([key, decoded ? `${decoded}\n${pc.dim(value)}` : value])
|
|
510
|
-
} else {
|
|
511
|
-
rows.push([key, fmtRequestValue(key, value, fmtCtx)])
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
return rows.sort(([a], [b]) => a.localeCompare(b))
|
|
515
|
-
})()
|
|
516
|
-
|
|
517
|
-
const sections: [string, [string, string][]][] = [
|
|
518
|
-
['Challenge', challengeRows],
|
|
519
|
-
['Request', requestRows],
|
|
520
|
-
...(detailRows.length ? [['Details', detailRows] as [string, [string, string][]]] : []),
|
|
521
|
-
]
|
|
522
|
-
for (const [, rows] of sections) for (const [key] of rows) shownKeys.add(key)
|
|
523
|
-
const pad = Math.max(...sections.flatMap(([, rows]) => rows.map(([k]) => k.length)))
|
|
524
|
-
const indent = ` ${''.padEnd(pad)} `
|
|
525
|
-
|
|
526
|
-
if (c.options.verbose >= 1 || confirmEnabled) {
|
|
527
|
-
info(`${pc.bold(pc.yellow('Payment Required'))}\n`)
|
|
528
|
-
for (const [title, rows] of sections) {
|
|
529
|
-
info(`${pc.bold(title)}\n`)
|
|
530
|
-
for (const [label, value] of rows) {
|
|
531
|
-
const [first, ...rest] = value.split('\n')
|
|
532
|
-
info(` ${pc.dim(label.padEnd(pad))} ${first}\n`)
|
|
533
|
-
for (const line of rest) info(`${indent}${line}\n`)
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
if (confirmEnabled) {
|
|
538
|
-
info('\n')
|
|
539
|
-
const ok = await confirm(`Proceed with ${challenge.intent}?`, true)
|
|
540
|
-
if (!ok) {
|
|
541
|
-
info('Aborted.\n')
|
|
542
|
-
return
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
const persistentSessionAccount =
|
|
548
|
-
process.env.MPPX_PRIVATE_KEY?.trim() ||
|
|
549
|
-
!isTempoAccount(resolveAccountName(c.options.account))
|
|
550
|
-
if (isTempoSessionChallenge(challenge) && persistentSessionAccount) {
|
|
551
|
-
try {
|
|
552
|
-
await runPersistentSessionRequest({
|
|
553
|
-
challenge,
|
|
554
|
-
challengeResponse: selectedChallengeResponse,
|
|
555
|
-
endpoint: url,
|
|
556
|
-
fetch: targetFetch,
|
|
557
|
-
fetchInput: fetchUrl,
|
|
558
|
-
init,
|
|
559
|
-
info,
|
|
560
|
-
methodOptions: methodOpts,
|
|
561
|
-
options: {
|
|
562
|
-
account: c.options.account,
|
|
563
|
-
fail: c.options.fail,
|
|
564
|
-
include: c.options.include,
|
|
565
|
-
network: c.options.network,
|
|
566
|
-
rpcUrl: c.options.rpcUrl,
|
|
567
|
-
session: c.options.session,
|
|
568
|
-
silent: c.options.silent,
|
|
569
|
-
verbose: c.options.verbose,
|
|
570
|
-
},
|
|
571
|
-
registry: sessionRegistry,
|
|
572
|
-
})
|
|
573
|
-
} catch (error) {
|
|
574
|
-
return sessionCommandError(error, 'SESSION_REQUEST_FAILED')
|
|
575
|
-
}
|
|
576
|
-
return
|
|
577
|
-
}
|
|
578
|
-
if (c.options.session !== 'auto')
|
|
579
|
-
return c.error({
|
|
580
|
-
code: 'UNSUPPORTED_SESSION',
|
|
581
|
-
message: '--session requires a tempo/session payment challenge.',
|
|
582
|
-
exitCode: 2,
|
|
583
|
-
})
|
|
584
|
-
|
|
585
|
-
// Create credential
|
|
586
|
-
let credential: string
|
|
587
|
-
if (pluginResult?.createCredential)
|
|
588
|
-
credential = await pluginResult.createCredential(selectedChallengeResponse)
|
|
589
|
-
else if (pluginResult) {
|
|
590
|
-
const mppx = Mppx.create({ methods: pluginResult.methods, polyfill: false })
|
|
591
|
-
credential = await mppx.createCredential(
|
|
592
|
-
selectedChallengeResponse,
|
|
593
|
-
pluginResult.credentialContext as undefined,
|
|
594
|
-
)
|
|
595
|
-
} else if (configMethod) {
|
|
596
|
-
const mppx = Mppx.create({ methods: [configMethod], polyfill: false })
|
|
597
|
-
credential = await mppx.createCredential(selectedChallengeResponse)
|
|
598
|
-
} else throw new Error('unreachable')
|
|
599
|
-
|
|
600
|
-
// Send credential and get response
|
|
601
|
-
const credentialHeaders = {
|
|
602
|
-
...normalizeHeaders(init.headers),
|
|
603
|
-
Authorization: credential,
|
|
604
|
-
}
|
|
605
|
-
plugin?.prepareCredentialRequest?.({ challenge, credential, headers: credentialHeaders })
|
|
606
|
-
|
|
607
|
-
const credentialFetchInit = { ...init, headers: credentialHeaders }
|
|
608
|
-
if (c.options.verbose >= 2) printRequestHeaders(url, credentialFetchInit, info)
|
|
609
|
-
const credentialResponse = await targetFetch(fetchUrl, credentialFetchInit)
|
|
610
|
-
|
|
611
|
-
if (c.options.fail && credentialResponse.status >= 400)
|
|
612
|
-
return c.error({
|
|
613
|
-
code: 'HTTP_ERROR',
|
|
614
|
-
message: `HTTP error ${credentialResponse.status}`,
|
|
615
|
-
exitCode: 22,
|
|
616
|
-
})
|
|
617
|
-
|
|
618
|
-
if (credentialResponse.status === 402) {
|
|
619
|
-
const body = await credentialResponse.text()
|
|
620
|
-
info(`${pc.bold(pc.red('Payment Rejected'))}\n`)
|
|
621
|
-
try {
|
|
622
|
-
const problem = JSON.parse(body) as Record<string, unknown>
|
|
623
|
-
const rows: [string, string][] = []
|
|
624
|
-
for (const [key, value] of Object.entries(problem)) {
|
|
625
|
-
if (value === undefined) continue
|
|
626
|
-
rows.push([key, String(value)])
|
|
627
|
-
}
|
|
628
|
-
rows.sort(([a], [b]) => a.localeCompare(b))
|
|
629
|
-
const pad = Math.max(...rows.map(([k]) => k.length))
|
|
630
|
-
for (const [label, value] of rows) info(` ${pc.dim(label.padEnd(pad))} ${value}\n`)
|
|
631
|
-
} catch {
|
|
632
|
-
if (body) info(` ${body}\n`)
|
|
633
|
-
}
|
|
634
|
-
return c.error({ code: 'PAYMENT_REJECTED', message: 'Payment rejected', exitCode: 75 })
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
printResponseHeaders(credentialResponse, headerOpts)
|
|
638
|
-
|
|
639
|
-
// Let plugin own the response lifecycle if it wants to
|
|
640
|
-
const handled = await plugin?.handleResponse?.({
|
|
641
|
-
challenge,
|
|
642
|
-
credential,
|
|
643
|
-
response: credentialResponse,
|
|
644
|
-
fetchUrl,
|
|
645
|
-
fetchInit: init,
|
|
646
|
-
silent: c.options.silent,
|
|
647
|
-
verbose: c.options.verbose,
|
|
648
|
-
confirmEnabled,
|
|
649
|
-
confirm,
|
|
650
|
-
tokenSymbol,
|
|
651
|
-
tokenDecimals,
|
|
652
|
-
explorerUrl,
|
|
653
|
-
shownKeys,
|
|
654
|
-
})
|
|
655
|
-
|
|
656
|
-
if (!handled) {
|
|
657
|
-
// Default: print receipt + body
|
|
658
|
-
const receiptHeader = credentialResponse.headers.get(Constants.Headers.paymentReceipt)
|
|
659
|
-
if (receiptHeader && c.options.verbose >= 1) {
|
|
660
|
-
try {
|
|
661
|
-
const receiptJson = JSON.parse(Base64.toString(receiptHeader)) as Record<
|
|
662
|
-
string,
|
|
663
|
-
unknown
|
|
664
|
-
>
|
|
665
|
-
info(`\n${pc.bold(pc.green('Payment Receipt'))}\n`)
|
|
666
|
-
const rows: [string, string][] = []
|
|
667
|
-
const channelId = receiptJson.channelId
|
|
668
|
-
const reference = receiptJson.reference
|
|
669
|
-
const skipReference = channelId && reference && channelId === reference
|
|
670
|
-
const receiptBalanceKeys = new Set(['acceptedCumulative', 'spent'])
|
|
671
|
-
for (const [key, value] of Object.entries(receiptJson)) {
|
|
672
|
-
if (value === undefined || shownKeys.has(key)) continue
|
|
673
|
-
if (key === 'reference' && skipReference) continue
|
|
674
|
-
const formatted = plugin?.formatReceiptField?.(key, value)
|
|
675
|
-
if (formatted !== undefined) {
|
|
676
|
-
rows.push([key, formatted])
|
|
677
|
-
} else if (receiptBalanceKeys.has(key) && typeof value === 'string') {
|
|
678
|
-
rows.push([
|
|
679
|
-
key,
|
|
680
|
-
`${value} ${pc.dim(`(${fmtBalance(BigInt(value), tokenSymbol, tokenDecimals)})`)}`,
|
|
681
|
-
])
|
|
682
|
-
} else if (
|
|
683
|
-
(key === 'reference' || key === 'txHash') &&
|
|
684
|
-
typeof value === 'string' &&
|
|
685
|
-
explorerUrl
|
|
686
|
-
) {
|
|
687
|
-
rows.push([key, link(`${explorerUrl}/tx/${value}`, value)])
|
|
688
|
-
} else rows.push([key, String(value)])
|
|
689
|
-
}
|
|
690
|
-
rows.sort(([a], [b]) => a.localeCompare(b))
|
|
691
|
-
const pad = Math.max(...rows.map(([k]) => k.length))
|
|
692
|
-
for (const [label, value] of rows) info(` ${pc.dim(label.padEnd(pad))} ${value}\n`)
|
|
693
|
-
info('\n')
|
|
694
|
-
} catch {}
|
|
695
|
-
}
|
|
696
|
-
|
|
697
|
-
await writeResponseBody(credentialResponse)
|
|
698
|
-
}
|
|
699
|
-
} catch (err) {
|
|
700
|
-
// Re-throw IncurError so incur's error handler formats it properly
|
|
701
|
-
if (err instanceof Errors.IncurError) throw err
|
|
702
|
-
|
|
703
|
-
// TODO: revert cast when https://github.com/wevm/zile/pull/26 is merged
|
|
704
|
-
const errCause =
|
|
705
|
-
err instanceof Error ? (err as unknown as Record<string, unknown>).cause : undefined
|
|
706
|
-
const cause = errCause instanceof Error ? errCause : undefined
|
|
707
|
-
|
|
708
|
-
if (cause && 'code' in cause) {
|
|
709
|
-
const code = cause.code as string
|
|
710
|
-
if (code === 'ENOTFOUND')
|
|
711
|
-
return c.error({
|
|
712
|
-
code: 'DNS_ERROR',
|
|
713
|
-
message: `Could not resolve host "${hostname}". Check the URL and try again.`,
|
|
714
|
-
exitCode: 6,
|
|
715
|
-
})
|
|
716
|
-
else if (code === 'ECONNREFUSED')
|
|
717
|
-
return c.error({
|
|
718
|
-
code: 'CONNECTION_REFUSED',
|
|
719
|
-
message: `Connection refused by "${hostname}". Is the server running?`,
|
|
720
|
-
retryable: true,
|
|
721
|
-
exitCode: 7,
|
|
722
|
-
})
|
|
723
|
-
else if (code === 'ECONNRESET')
|
|
724
|
-
return c.error({
|
|
725
|
-
code: 'CONNECTION_RESET',
|
|
726
|
-
message: `Connection to "${hostname}" was reset.`,
|
|
727
|
-
retryable: true,
|
|
728
|
-
exitCode: 56,
|
|
729
|
-
})
|
|
730
|
-
else if (code === 'ETIMEDOUT')
|
|
731
|
-
return c.error({
|
|
732
|
-
code: 'CONNECTION_TIMEOUT',
|
|
733
|
-
message: `Connection to "${hostname}" timed out.`,
|
|
734
|
-
retryable: true,
|
|
735
|
-
exitCode: 28,
|
|
736
|
-
})
|
|
737
|
-
else if (code === 'CERT_HAS_EXPIRED' || code === 'UNABLE_TO_VERIFY_LEAF_SIGNATURE')
|
|
738
|
-
return c.error({
|
|
739
|
-
code: 'TLS_ERROR',
|
|
740
|
-
message: `TLS certificate error for "${hostname}". Use --insecure to skip verification.`,
|
|
741
|
-
exitCode: 60,
|
|
742
|
-
})
|
|
743
|
-
else
|
|
744
|
-
return c.error({
|
|
745
|
-
code: 'REQUEST_FAILED',
|
|
746
|
-
message: `Request to "${hostname}" failed: ${cause.message}`,
|
|
747
|
-
})
|
|
748
|
-
} else {
|
|
749
|
-
const msg = err instanceof Error ? err.message : String(err)
|
|
750
|
-
return c.error({
|
|
751
|
-
code: 'REQUEST_FAILED',
|
|
752
|
-
message: cause
|
|
753
|
-
? `Request failed: ${msg} (Cause: ${cause.message})`
|
|
754
|
-
: `Request failed: ${msg}`,
|
|
755
|
-
})
|
|
756
|
-
}
|
|
757
|
-
}
|
|
758
|
-
},
|
|
759
|
-
})
|
|
760
|
-
|
|
761
|
-
const account = Cli.create('account', {
|
|
762
|
-
description: 'Manage accounts (create, default, delete, export, fund, list, view)',
|
|
763
|
-
})
|
|
764
|
-
.command('create', {
|
|
765
|
-
description: 'Create new account',
|
|
766
|
-
options: z.object({
|
|
767
|
-
account: z.string().optional().describe('Account name (env: MPPX_ACCOUNT)'),
|
|
768
|
-
network: z.enum(['mainnet', 'testnet']).optional().describe('Tempo network'),
|
|
769
|
-
rpcUrl: z.string().optional().describe('RPC endpoint (env: MPPX_RPC_URL)'),
|
|
770
|
-
}),
|
|
771
|
-
output: z.object({ address: z.string(), name: z.string() }),
|
|
772
|
-
alias: { account: 'a', rpcUrl: 'r' },
|
|
773
|
-
async run(c) {
|
|
774
|
-
const structured = shouldReturnStructured(c)
|
|
775
|
-
let resolvedName = c.options.account
|
|
776
|
-
if (!resolvedName) {
|
|
777
|
-
const existing = await createKeychain().list()
|
|
778
|
-
if (existing.length === 0) resolvedName = 'main'
|
|
779
|
-
else {
|
|
780
|
-
if (structured)
|
|
781
|
-
return c.error({
|
|
782
|
-
code: 'ACCOUNT_REQUIRED',
|
|
783
|
-
message: 'Account name is required in structured mode.',
|
|
784
|
-
exitCode: 2,
|
|
785
|
-
})
|
|
786
|
-
const input = await prompt('Account name')
|
|
787
|
-
if (!input) return undefined as never
|
|
788
|
-
resolvedName = input
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
let keychain = createKeychain(resolvedName)
|
|
792
|
-
while (await keychain.get()) {
|
|
793
|
-
if (structured)
|
|
794
|
-
return c.error({
|
|
795
|
-
code: 'ACCOUNT_EXISTS',
|
|
796
|
-
message: `Account "${resolvedName}" already exists.`,
|
|
797
|
-
exitCode: 1,
|
|
798
|
-
})
|
|
799
|
-
process.stderr.write(`${pc.dim(`Account "${resolvedName}" already exists.`)}\n\n`)
|
|
800
|
-
const input = await prompt('Enter different name')
|
|
801
|
-
if (!input) return undefined as never
|
|
802
|
-
resolvedName = input
|
|
803
|
-
keychain = createKeychain(resolvedName)
|
|
804
|
-
}
|
|
805
|
-
const privateKey = generatePrivateKey()
|
|
806
|
-
const acct = privateKeyToAccount(privateKey)
|
|
807
|
-
await keychain.set(privateKey)
|
|
808
|
-
const accounts = await createKeychain().list()
|
|
809
|
-
if (accounts.length === 1) createDefaultStore().set(resolvedName)
|
|
810
|
-
const explorerUrl = tempoMainnet.blockExplorers?.default?.url
|
|
811
|
-
const addrDisplay = explorerUrl
|
|
812
|
-
? link(`${explorerUrl}/address/${acct.address}`, acct.address)
|
|
813
|
-
: acct.address
|
|
814
|
-
const fundingNetwork = resolveFundingNetwork(c.options)
|
|
815
|
-
const rpcUrl = resolveRpcUrl(c.options.rpcUrl, { network: fundingNetwork })
|
|
816
|
-
resolveChain({ network: fundingNetwork, rpcUrl })
|
|
817
|
-
.then((chain) => createClient({ chain, transport: http(rpcUrl) }))
|
|
818
|
-
.then((client) =>
|
|
819
|
-
import('viem/tempo').then(({ Actions }) =>
|
|
820
|
-
Actions.faucet.fund(client, { account: acct }).catch(() => {}),
|
|
821
|
-
),
|
|
822
|
-
)
|
|
823
|
-
return outputResult(c, { address: acct.address, name: resolvedName }, () => {
|
|
824
|
-
console.log(`Account "${resolvedName}" saved to keychain.`)
|
|
825
|
-
console.log(pc.dim(`Address ${addrDisplay}`))
|
|
826
|
-
console.log(
|
|
827
|
-
pc.dim(
|
|
828
|
-
`Fund testnet tokens: mppx account fund --account ${resolvedName} --network testnet`,
|
|
829
|
-
),
|
|
830
|
-
)
|
|
831
|
-
})
|
|
832
|
-
},
|
|
833
|
-
})
|
|
834
|
-
.command('default', {
|
|
835
|
-
description: 'Set default account',
|
|
836
|
-
options: z.object({
|
|
837
|
-
account: z.string().describe('Account name'),
|
|
838
|
-
}),
|
|
839
|
-
output: z.object({ name: z.string() }),
|
|
840
|
-
alias: { account: 'a' },
|
|
841
|
-
async run(c) {
|
|
842
|
-
const accountName = c.options.account
|
|
843
|
-
if (isTempoAccount(accountName)) {
|
|
844
|
-
const tempoEntry = resolveTempoAccount(accountName)
|
|
845
|
-
if (!tempoEntry) {
|
|
846
|
-
return c.error({
|
|
847
|
-
code: 'ACCOUNT_NOT_FOUND',
|
|
848
|
-
message: `Account "${accountName}" not found. Is Tempo wallet configured?`,
|
|
849
|
-
exitCode: 69,
|
|
850
|
-
})
|
|
851
|
-
}
|
|
852
|
-
createDefaultStore().set(accountName)
|
|
853
|
-
return outputResult(c, { name: accountName }, () => {
|
|
854
|
-
console.log(`Default account set to "${accountName}"`)
|
|
855
|
-
})
|
|
856
|
-
}
|
|
857
|
-
const key = await createKeychain(accountName).get()
|
|
858
|
-
if (!key) {
|
|
859
|
-
return c.error({
|
|
860
|
-
code: 'ACCOUNT_NOT_FOUND',
|
|
861
|
-
message: `Account "${accountName}" not found.`,
|
|
862
|
-
exitCode: 69,
|
|
863
|
-
})
|
|
864
|
-
}
|
|
865
|
-
createDefaultStore().set(accountName)
|
|
866
|
-
return outputResult(c, { name: accountName }, () => {
|
|
867
|
-
console.log(`Default account set to "${accountName}"`)
|
|
868
|
-
})
|
|
869
|
-
},
|
|
870
|
-
})
|
|
871
|
-
.command('delete', {
|
|
872
|
-
description: 'Delete account',
|
|
873
|
-
options: z.object({
|
|
874
|
-
account: z.string().describe('Account name'),
|
|
875
|
-
yes: z.boolean().optional().describe('DANGER!! Skip confirmation prompts'),
|
|
876
|
-
}),
|
|
877
|
-
output: z.object({ defaultAccount: z.string().optional(), name: z.string() }),
|
|
878
|
-
alias: { account: 'a' },
|
|
879
|
-
async run(c) {
|
|
880
|
-
const keychain = createKeychain(c.options.account)
|
|
881
|
-
const key = await keychain.get()
|
|
882
|
-
if (!key) {
|
|
883
|
-
return c.error({
|
|
884
|
-
code: 'ACCOUNT_NOT_FOUND',
|
|
885
|
-
message: `Account "${c.options.account}" not found.`,
|
|
886
|
-
exitCode: 69,
|
|
887
|
-
})
|
|
888
|
-
}
|
|
889
|
-
const acct = privateKeyToAccount(key as `0x${string}`)
|
|
890
|
-
const balanceLines = await fetchBalanceLines(acct.address, { includeTestnet: false })
|
|
891
|
-
if (!c.options.yes) {
|
|
892
|
-
if (shouldReturnStructured(c))
|
|
893
|
-
return c.error({
|
|
894
|
-
code: 'CONFIRMATION_REQUIRED',
|
|
895
|
-
message: 'Pass --yes to delete an account in structured mode.',
|
|
896
|
-
exitCode: 2,
|
|
897
|
-
})
|
|
898
|
-
const explorerUrl = tempoMainnet.blockExplorers?.default?.url
|
|
899
|
-
const addrDisplay = explorerUrl
|
|
900
|
-
? link(`${explorerUrl}/address/${acct.address}`, acct.address)
|
|
901
|
-
: acct.address
|
|
902
|
-
process.stderr.write(pc.dim(`Delete account "${c.options.account}"\n`))
|
|
903
|
-
process.stderr.write(pc.dim(` Address ${addrDisplay}\n`))
|
|
904
|
-
for (let i = 0; i < balanceLines.length; i++)
|
|
905
|
-
process.stderr.write(pc.dim(` ${i === 0 ? 'Balance' : ' '} ${balanceLines[i]}\n`))
|
|
906
|
-
process.stderr.write(pc.dim('This action cannot be undone\n\n'))
|
|
907
|
-
const confirmed = await confirm('Confirm delete?')
|
|
908
|
-
if (!confirmed) {
|
|
909
|
-
console.log('Canceled')
|
|
910
|
-
return undefined as never
|
|
911
|
-
}
|
|
912
|
-
}
|
|
913
|
-
await keychain.delete()
|
|
914
|
-
const currentDefault = createDefaultStore().get()
|
|
915
|
-
let defaultAccount: string | undefined
|
|
916
|
-
if (currentDefault === c.options.account) {
|
|
917
|
-
const remaining = await createKeychain().list()
|
|
918
|
-
if (remaining.length > 0) {
|
|
919
|
-
defaultAccount = remaining[0]!
|
|
920
|
-
createDefaultStore().set(defaultAccount)
|
|
921
|
-
} else {
|
|
922
|
-
createDefaultStore().clear()
|
|
923
|
-
}
|
|
924
|
-
}
|
|
925
|
-
return outputResult(c, { defaultAccount, name: c.options.account }, () => {
|
|
926
|
-
if (defaultAccount) console.log(`Default account set to "${defaultAccount}"`)
|
|
927
|
-
console.log(`Account "${c.options.account}" deleted`)
|
|
928
|
-
})
|
|
929
|
-
},
|
|
930
|
-
})
|
|
931
|
-
.command('fund', {
|
|
932
|
-
description: 'Fund account with testnet tokens',
|
|
933
|
-
options: z.object({
|
|
934
|
-
account: z.string().optional().describe('Account name (env: MPPX_ACCOUNT)'),
|
|
935
|
-
network: z.enum(['testnet']).optional().describe('Tempo network'),
|
|
936
|
-
rpcUrl: z.string().optional().describe('RPC endpoint (env: MPPX_RPC_URL)'),
|
|
937
|
-
}),
|
|
938
|
-
output: z.object({ account: z.string(), chain: z.string(), transactions: z.array(z.string()) }),
|
|
939
|
-
alias: { account: 'a', rpcUrl: 'r' },
|
|
940
|
-
async run(c) {
|
|
941
|
-
const structured = shouldReturnStructured(c)
|
|
942
|
-
const accountName = resolveAccountName(c.options.account)
|
|
943
|
-
const keychain = createKeychain(accountName)
|
|
944
|
-
const key = await keychain.get()
|
|
945
|
-
if (!key) {
|
|
946
|
-
if (c.options.account)
|
|
947
|
-
return c.error({
|
|
948
|
-
code: 'ACCOUNT_NOT_FOUND',
|
|
949
|
-
message: `Account "${accountName}" not found.`,
|
|
950
|
-
exitCode: 69,
|
|
951
|
-
})
|
|
952
|
-
else
|
|
953
|
-
return c.error({ code: 'ACCOUNT_NOT_FOUND', message: 'No account found.', exitCode: 69 })
|
|
954
|
-
}
|
|
955
|
-
const acct = privateKeyToAccount(key as `0x${string}`)
|
|
956
|
-
const fundingNetwork = resolveFundingNetwork(c.options)
|
|
957
|
-
const rpcUrl = resolveRpcUrl(c.options.rpcUrl, { network: fundingNetwork })
|
|
958
|
-
const chain = await resolveChain({ network: fundingNetwork, rpcUrl })
|
|
959
|
-
const client = createClient({ chain, transport: http(rpcUrl) })
|
|
960
|
-
if (!structured) console.log(`Funding "${accountName}" on ${chainName(chain)}`)
|
|
961
|
-
try {
|
|
962
|
-
const { Actions } = await import('viem/tempo')
|
|
963
|
-
const hashes = await Actions.faucet.fund(client, { account: acct })
|
|
964
|
-
const explorerUrl = chain.blockExplorers?.default?.url
|
|
965
|
-
if (!structured) {
|
|
966
|
-
for (const hash of hashes) {
|
|
967
|
-
const label = explorerUrl ? link(`${explorerUrl}/tx/${hash}`, pc.gray(hash)) : hash
|
|
968
|
-
console.log(` ${label}`)
|
|
969
|
-
}
|
|
970
|
-
}
|
|
971
|
-
const { waitForTransactionReceipt } = await import('viem/actions')
|
|
972
|
-
await Promise.all(hashes.map((hash) => waitForTransactionReceipt(client, { hash })))
|
|
973
|
-
return outputResult(
|
|
974
|
-
c,
|
|
975
|
-
{ account: accountName, chain: chainName(chain), transactions: [...hashes] },
|
|
976
|
-
() => {
|
|
977
|
-
console.log('Funded successfully')
|
|
978
|
-
},
|
|
979
|
-
)
|
|
980
|
-
} catch (err) {
|
|
981
|
-
const message = err instanceof Error ? err.message : String(err)
|
|
982
|
-
if (structured)
|
|
983
|
-
return c.error({
|
|
984
|
-
code: 'FUNDING_FAILED',
|
|
985
|
-
message,
|
|
986
|
-
exitCode: 1,
|
|
987
|
-
})
|
|
988
|
-
return c.error({
|
|
989
|
-
code: 'FUNDING_FAILED',
|
|
990
|
-
message: `Funding failed: ${message}`,
|
|
991
|
-
exitCode: 1,
|
|
992
|
-
})
|
|
993
|
-
}
|
|
994
|
-
},
|
|
995
|
-
})
|
|
996
|
-
.command('list', {
|
|
997
|
-
description: 'List all accounts',
|
|
998
|
-
output: z.object({ accounts: z.array(accountSummarySchema) }),
|
|
999
|
-
async run(c) {
|
|
1000
|
-
const currentDefault = createDefaultStore().get()
|
|
1001
|
-
const accounts = (await createKeychain().list()).sort()
|
|
1002
|
-
const resolved: { name: string; address: string; source?: string }[] = []
|
|
1003
|
-
for (const accountName of accounts) {
|
|
1004
|
-
const key = await createKeychain(accountName).get()
|
|
1005
|
-
if (!key) continue
|
|
1006
|
-
resolved.push({
|
|
1007
|
-
name: accountName,
|
|
1008
|
-
address: privateKeyToAccount(key as `0x${string}`).address,
|
|
1009
|
-
})
|
|
1010
|
-
}
|
|
1011
|
-
const tempoEntries = readTempoKeystore()
|
|
1012
|
-
for (let i = 0; i < tempoEntries.length; i++) {
|
|
1013
|
-
const entry = tempoEntries[i]!
|
|
1014
|
-
const tempoName = i === 0 ? 'tempo:default' : `tempo:${i}`
|
|
1015
|
-
if (entry.wallet_address)
|
|
1016
|
-
resolved.push({ name: tempoName, address: entry.wallet_address, source: 'tempo wallet' })
|
|
1017
|
-
}
|
|
1018
|
-
if (resolved.length === 0) {
|
|
1019
|
-
return outputResult(c, { accounts: [] }, () => {
|
|
1020
|
-
console.log(`No accounts found.`)
|
|
1021
|
-
})
|
|
1022
|
-
}
|
|
1023
|
-
const explorerUrl = tempoMainnet.blockExplorers?.default?.url
|
|
1024
|
-
const maxWidth = Math.max(
|
|
1025
|
-
...resolved.map((e) => e.name.length + (e.name === currentDefault ? 1 : 0)),
|
|
1026
|
-
)
|
|
1027
|
-
return outputResult(
|
|
1028
|
-
c,
|
|
1029
|
-
{
|
|
1030
|
-
accounts: resolved.map((entry) => ({
|
|
1031
|
-
...entry,
|
|
1032
|
-
...(entry.name === currentDefault ? { isDefault: true } : undefined),
|
|
1033
|
-
})),
|
|
1034
|
-
},
|
|
1035
|
-
() => {
|
|
1036
|
-
for (const entry of resolved) {
|
|
1037
|
-
const isDefault = entry.name === currentDefault
|
|
1038
|
-
const label = isDefault ? `${entry.name}${pc.dim('*')}` : entry.name
|
|
1039
|
-
const width = entry.name.length + (isDefault ? 1 : 0)
|
|
1040
|
-
const addrDisplay = explorerUrl
|
|
1041
|
-
? link(`${explorerUrl}/address/${entry.address}`, entry.address)
|
|
1042
|
-
: entry.address
|
|
1043
|
-
const sourceLabel = entry.source ? ` ${pc.dim(`(${entry.source})`)}` : ''
|
|
1044
|
-
console.log(
|
|
1045
|
-
`${label}${' '.repeat(maxWidth - width + 2)}${pc.dim(addrDisplay)}${sourceLabel}`,
|
|
1046
|
-
)
|
|
1047
|
-
}
|
|
1048
|
-
},
|
|
1049
|
-
)
|
|
1050
|
-
},
|
|
1051
|
-
})
|
|
1052
|
-
.command('export', {
|
|
1053
|
-
description: 'Export the private key for a local account',
|
|
1054
|
-
options: z.object({
|
|
1055
|
-
account: z.string().optional().describe('Account name (env: MPPX_ACCOUNT)'),
|
|
1056
|
-
}),
|
|
1057
|
-
output: z.object({ privateKey: z.string() }),
|
|
1058
|
-
alias: { account: 'a' },
|
|
1059
|
-
async run(c) {
|
|
1060
|
-
const accountName = resolveAccountName(c.options.account)
|
|
1061
|
-
|
|
1062
|
-
if (isTempoAccount(accountName)) {
|
|
1063
|
-
return c.error({
|
|
1064
|
-
code: 'UNSUPPORTED_ACCOUNT',
|
|
1065
|
-
message: `Account "${accountName}" is managed by Tempo wallet and does not expose a private key via mppx.`,
|
|
1066
|
-
exitCode: 2,
|
|
1067
|
-
})
|
|
1068
|
-
}
|
|
1069
|
-
|
|
1070
|
-
const key = await createKeychain(accountName).get()
|
|
1071
|
-
if (!key) {
|
|
1072
|
-
if (c.options.account)
|
|
1073
|
-
return c.error({
|
|
1074
|
-
code: 'ACCOUNT_NOT_FOUND',
|
|
1075
|
-
message: `Account "${accountName}" not found.`,
|
|
1076
|
-
exitCode: 69,
|
|
1077
|
-
})
|
|
1078
|
-
else
|
|
1079
|
-
return c.error({ code: 'ACCOUNT_NOT_FOUND', message: 'No account found.', exitCode: 69 })
|
|
1080
|
-
}
|
|
1081
|
-
|
|
1082
|
-
return outputResult(c, { privateKey: key }, () => {
|
|
1083
|
-
console.log(key)
|
|
1084
|
-
})
|
|
1085
|
-
},
|
|
1086
|
-
})
|
|
1087
|
-
.command('view', {
|
|
1088
|
-
description: 'View account address',
|
|
1089
|
-
options: z.object({
|
|
1090
|
-
account: z.string().optional().describe('Account name (env: MPPX_ACCOUNT)'),
|
|
1091
|
-
network: z.enum(['mainnet', 'testnet']).optional().describe('Tempo network'),
|
|
1092
|
-
rpcUrl: z.string().optional().describe('RPC endpoint (env: MPPX_RPC_URL)'),
|
|
1093
|
-
}),
|
|
1094
|
-
output: accountViewSchema,
|
|
1095
|
-
alias: { account: 'a', rpcUrl: 'r' },
|
|
1096
|
-
async run(c) {
|
|
1097
|
-
const accountName = resolveAccountName(c.options.account)
|
|
1098
|
-
|
|
1099
|
-
if (isTempoAccount(accountName)) {
|
|
1100
|
-
const tempoEntry = resolveTempoAccount(accountName)
|
|
1101
|
-
if (!tempoEntry) {
|
|
1102
|
-
return c.error({
|
|
1103
|
-
code: 'ACCOUNT_NOT_FOUND',
|
|
1104
|
-
message: `Account "${accountName}" not found. Is Tempo wallet configured?`,
|
|
1105
|
-
exitCode: 69,
|
|
1106
|
-
})
|
|
1107
|
-
}
|
|
1108
|
-
const address = tempoEntry.wallet_address as Address
|
|
1109
|
-
const rpcUrl = resolveRpcUrl(c.options.rpcUrl, { network: c.options.network })
|
|
1110
|
-
const chain = await resolveChain({ network: c.options.network, rpcUrl })
|
|
1111
|
-
const explorerUrl = chain.blockExplorers?.default?.url
|
|
1112
|
-
const addrDisplay = explorerUrl
|
|
1113
|
-
? link(`${explorerUrl}/address/${address}`, address)
|
|
1114
|
-
: address
|
|
1115
|
-
|
|
1116
|
-
const balanceLines = await fetchBalanceLines(
|
|
1117
|
-
address,
|
|
1118
|
-
chain && rpcUrl ? { chain, rpcUrl } : undefined,
|
|
1119
|
-
)
|
|
1120
|
-
return outputResult(
|
|
1121
|
-
c,
|
|
1122
|
-
{
|
|
1123
|
-
address,
|
|
1124
|
-
balances: balanceLines,
|
|
1125
|
-
name: accountName,
|
|
1126
|
-
type: `${tempoEntry.wallet_type} (tempo wallet)`,
|
|
1127
|
-
},
|
|
1128
|
-
() => {
|
|
1129
|
-
console.log(`${pc.dim('Address')} ${addrDisplay}`)
|
|
1130
|
-
for (let i = 0; i < balanceLines.length; i++)
|
|
1131
|
-
console.log(`${pc.dim(i === 0 ? 'Balance' : ' ')} ${balanceLines[i]}`)
|
|
1132
|
-
console.log(`${pc.dim('Name')} ${accountName}`)
|
|
1133
|
-
console.log(
|
|
1134
|
-
`${pc.dim('Type')} ${tempoEntry.wallet_type} ${pc.dim('(tempo wallet)')}`,
|
|
1135
|
-
)
|
|
1136
|
-
},
|
|
1137
|
-
)
|
|
1138
|
-
}
|
|
1139
|
-
|
|
1140
|
-
const keychain = createKeychain(accountName)
|
|
1141
|
-
const key = await keychain.get()
|
|
1142
|
-
if (!key) {
|
|
1143
|
-
if (c.options.account)
|
|
1144
|
-
return c.error({
|
|
1145
|
-
code: 'ACCOUNT_NOT_FOUND',
|
|
1146
|
-
message: `Account "${accountName}" not found.`,
|
|
1147
|
-
exitCode: 69,
|
|
1148
|
-
})
|
|
1149
|
-
else
|
|
1150
|
-
return c.error({ code: 'ACCOUNT_NOT_FOUND', message: 'No account found.', exitCode: 69 })
|
|
1151
|
-
}
|
|
1152
|
-
const acct = privateKeyToAccount(key as `0x${string}`)
|
|
1153
|
-
const rpcUrl = resolveRpcUrl(c.options.rpcUrl, { network: c.options.network })
|
|
1154
|
-
const chain = await resolveChain({ network: c.options.network, rpcUrl })
|
|
1155
|
-
const explorerUrl = chain.blockExplorers?.default?.url
|
|
1156
|
-
const addrDisplay = explorerUrl
|
|
1157
|
-
? link(`${explorerUrl}/address/${acct.address}`, acct.address)
|
|
1158
|
-
: acct.address
|
|
1159
|
-
|
|
1160
|
-
const balanceLines = await fetchBalanceLines(
|
|
1161
|
-
acct.address,
|
|
1162
|
-
chain && rpcUrl ? { chain, rpcUrl } : undefined,
|
|
1163
|
-
)
|
|
1164
|
-
return outputResult(
|
|
1165
|
-
c,
|
|
1166
|
-
{ address: acct.address, balances: balanceLines, name: accountName },
|
|
1167
|
-
() => {
|
|
1168
|
-
console.log(`${pc.dim('Address')} ${addrDisplay}`)
|
|
1169
|
-
for (let i = 0; i < balanceLines.length; i++)
|
|
1170
|
-
console.log(`${pc.dim(i === 0 ? 'Balance' : ' ')} ${balanceLines[i]}`)
|
|
1171
|
-
console.log(`${pc.dim('Name')} ${accountName}`)
|
|
1172
|
-
},
|
|
1173
|
-
)
|
|
1174
|
-
},
|
|
1175
|
-
})
|
|
1176
|
-
|
|
1177
|
-
const sign = Cli.create('sign', {
|
|
1178
|
-
description: 'Sign a payment challenge and output the Authorization header',
|
|
1179
|
-
usage: [
|
|
1180
|
-
{ suffix: '--challenge <value> [options]' },
|
|
1181
|
-
{ prefix: 'echo <challenge> |', suffix: '[options]' },
|
|
1182
|
-
],
|
|
1183
|
-
options: z.object({
|
|
1184
|
-
account: z.string().optional().describe('Account name (env: MPPX_ACCOUNT)'),
|
|
1185
|
-
challenge: z.string().optional().describe('WWW-Authenticate challenge value'),
|
|
1186
|
-
config: z.string().optional().describe('Path to config file'),
|
|
1187
|
-
dryRun: z.boolean().optional().describe('Validate and parse the challenge without signing'),
|
|
1188
|
-
autoSwap: z.boolean().optional().describe('Auto-swap source tokens into payment currency'),
|
|
1189
|
-
methodOpt: z
|
|
1190
|
-
.array(z.string())
|
|
1191
|
-
.optional()
|
|
1192
|
-
.describe('Method-specific option (key=value, repeatable)'),
|
|
1193
|
-
network: z.enum(['mainnet', 'testnet']).optional().describe('Tempo network'),
|
|
1194
|
-
payWith: z.string().optional().describe('Source token for Tempo auto-swap'),
|
|
1195
|
-
rpcUrl: z
|
|
1196
|
-
.string()
|
|
1197
|
-
.optional()
|
|
1198
|
-
.describe('RPC endpoint, defaults to public RPC for chain (env: MPPX_RPC_URL)'),
|
|
1199
|
-
slippage: z.number().optional().describe('Tempo auto-swap max slippage percentage'),
|
|
1200
|
-
}),
|
|
1201
|
-
output: z.object({ authorization: z.string() }),
|
|
1202
|
-
alias: {
|
|
1203
|
-
account: 'a',
|
|
1204
|
-
challenge: 'C',
|
|
1205
|
-
config: 'c',
|
|
1206
|
-
methodOpt: 'M',
|
|
1207
|
-
rpcUrl: 'r',
|
|
1208
|
-
},
|
|
1209
|
-
async run(c) {
|
|
1210
|
-
const raw =
|
|
1211
|
-
c.options.challenge ||
|
|
1212
|
-
(canReadCommandStdin()
|
|
1213
|
-
? await new Promise<string>((resolve, reject) => {
|
|
1214
|
-
let data = ''
|
|
1215
|
-
process.stdin.setEncoding('utf-8')
|
|
1216
|
-
process.stdin.on('data', (chunk) => {
|
|
1217
|
-
data += chunk
|
|
1218
|
-
})
|
|
1219
|
-
process.stdin.on('end', () => resolve(data.trim()))
|
|
1220
|
-
process.stdin.on('error', reject)
|
|
1221
|
-
})
|
|
1222
|
-
: undefined)
|
|
1223
|
-
if (!raw) {
|
|
1224
|
-
return c.error({
|
|
1225
|
-
code: 'NO_CHALLENGE',
|
|
1226
|
-
message: 'No challenge provided. Use --challenge or pipe via stdin.',
|
|
1227
|
-
exitCode: 2,
|
|
1228
|
-
})
|
|
1229
|
-
}
|
|
1230
|
-
|
|
1231
|
-
let challenges: Challenge.Challenge[]
|
|
1232
|
-
try {
|
|
1233
|
-
challenges = Challenge.deserializeList(raw)
|
|
1234
|
-
} catch (err) {
|
|
1235
|
-
return c.error({
|
|
1236
|
-
code: 'INVALID_CHALLENGE',
|
|
1237
|
-
message: `Failed to parse challenge: ${err instanceof Error ? err.message : err}`,
|
|
1238
|
-
exitCode: 2,
|
|
1239
|
-
})
|
|
1240
|
-
}
|
|
1241
|
-
|
|
1242
|
-
if (c.options.dryRun) {
|
|
1243
|
-
process.stderr.write('Challenge is valid.\n')
|
|
1244
|
-
return undefined as never
|
|
1245
|
-
}
|
|
1246
|
-
|
|
1247
|
-
const loaded = await loadConfig(c.options.config)
|
|
1248
|
-
const selected = selectChallenge(challenges, loaded?.config)
|
|
1249
|
-
if (!selected) {
|
|
1250
|
-
const offers = challenges
|
|
1251
|
-
.map((challenge) => `${challenge.method}/${challenge.intent}`)
|
|
1252
|
-
.join(', ')
|
|
1253
|
-
return c.error({
|
|
1254
|
-
code: 'UNSUPPORTED_METHOD',
|
|
1255
|
-
message: `Unsupported payment method. Server offers: ${offers}. Add it to mppx.config.ts using defineConfig().`,
|
|
1256
|
-
exitCode: 2,
|
|
1257
|
-
})
|
|
1258
|
-
}
|
|
1259
|
-
|
|
1260
|
-
const { challenge, plugin, method: configMethod } = selected
|
|
1261
|
-
const methodOpts = parseMethodOpts(c.options.methodOpt)
|
|
1262
|
-
|
|
1263
|
-
const wwwAuth = Challenge.serialize(challenge)
|
|
1264
|
-
const fakeResponse = new Response(null, {
|
|
1265
|
-
status: 402,
|
|
1266
|
-
headers: { [Constants.Headers.wwwAuthenticate]: wwwAuth },
|
|
1267
|
-
})
|
|
1268
|
-
|
|
1269
|
-
let credential: string
|
|
1270
|
-
if (plugin) {
|
|
1271
|
-
const result = await plugin.setup({
|
|
1272
|
-
challenge,
|
|
1273
|
-
options: {
|
|
1274
|
-
account: c.options.account,
|
|
1275
|
-
autoSwap: c.options.autoSwap,
|
|
1276
|
-
network: c.options.network,
|
|
1277
|
-
payWith: c.options.payWith,
|
|
1278
|
-
rpcUrl: c.options.rpcUrl,
|
|
1279
|
-
slippage: c.options.slippage,
|
|
1280
|
-
},
|
|
1281
|
-
methodOpts,
|
|
1282
|
-
})
|
|
1283
|
-
if (result.createCredential) {
|
|
1284
|
-
credential = await result.createCredential(fakeResponse)
|
|
1285
|
-
} else {
|
|
1286
|
-
const mppx = Mppx.create({ methods: result.methods, polyfill: false })
|
|
1287
|
-
credential = await mppx.createCredential(
|
|
1288
|
-
fakeResponse,
|
|
1289
|
-
result.credentialContext as undefined,
|
|
1290
|
-
)
|
|
1291
|
-
}
|
|
1292
|
-
} else if (configMethod) {
|
|
1293
|
-
const mppx = Mppx.create({ methods: [configMethod], polyfill: false })
|
|
1294
|
-
credential = await mppx.createCredential(fakeResponse)
|
|
1295
|
-
} else {
|
|
1296
|
-
return c.error({
|
|
1297
|
-
code: 'UNSUPPORTED_METHOD',
|
|
1298
|
-
message: `Unsupported payment method: ${challenge.method}/${challenge.intent}. Add it to mppx.config.ts using defineConfig().`,
|
|
1299
|
-
exitCode: 2,
|
|
1300
|
-
})
|
|
1301
|
-
}
|
|
1302
|
-
|
|
1303
|
-
return outputResult(c, { authorization: credential }, () => {
|
|
1304
|
-
console.log(credential)
|
|
1305
|
-
})
|
|
1306
|
-
},
|
|
1307
|
-
})
|
|
1308
|
-
|
|
1309
|
-
const init = Cli.create('init', {
|
|
1310
|
-
description: 'Create an mppx.config.ts file in the current directory',
|
|
1311
|
-
options: z.object({
|
|
1312
|
-
force: z.boolean().optional().describe('Overwrite existing config file'),
|
|
1313
|
-
}),
|
|
1314
|
-
output: z.object({ file: z.string() }),
|
|
1315
|
-
alias: { force: 'f' },
|
|
1316
|
-
async run(c) {
|
|
1317
|
-
const cwd = process.cwd()
|
|
1318
|
-
|
|
1319
|
-
// Determine file extension: .ts if tsconfig exists, .mjs if type:module, else .js
|
|
1320
|
-
const ext = (() => {
|
|
1321
|
-
if (fs.existsSync(path.join(cwd, 'tsconfig.json'))) return '.ts'
|
|
1322
|
-
try {
|
|
1323
|
-
const pkg = JSON.parse(fs.readFileSync(path.join(cwd, 'package.json'), 'utf-8'))
|
|
1324
|
-
if (pkg.type === 'module') return '.mjs'
|
|
1325
|
-
} catch {}
|
|
1326
|
-
return '.js'
|
|
1327
|
-
})()
|
|
1328
|
-
|
|
1329
|
-
const filename = `mppx.config${ext}`
|
|
1330
|
-
const dest = path.join(cwd, filename)
|
|
1331
|
-
|
|
1332
|
-
if (fs.existsSync(dest) && !c.options.force) {
|
|
1333
|
-
return c.error({
|
|
1334
|
-
code: 'CONFIG_EXISTS',
|
|
1335
|
-
message: `${filename} already exists. Use --force to overwrite.`,
|
|
1336
|
-
exitCode: 1,
|
|
1337
|
-
})
|
|
1338
|
-
}
|
|
1339
|
-
|
|
1340
|
-
const template = `import { defineConfig } from 'mppx/cli'
|
|
1341
|
-
|
|
1342
|
-
export default defineConfig({
|
|
1343
|
-
methods: [],
|
|
1344
|
-
plugins: [],
|
|
1345
|
-
})
|
|
1346
|
-
`
|
|
1347
|
-
|
|
1348
|
-
fs.writeFileSync(dest, template)
|
|
1349
|
-
return outputResult(c, { file: dest }, () => {
|
|
1350
|
-
console.log(`Created ${filename}`)
|
|
1351
|
-
})
|
|
1352
|
-
},
|
|
1353
|
-
})
|
|
1354
|
-
|
|
1355
|
-
const services = Cli.create('services', {
|
|
1356
|
-
description: 'Browse the MPP services registry',
|
|
1357
|
-
})
|
|
1358
|
-
.command('list', {
|
|
1359
|
-
description: 'List registered MPP services',
|
|
1360
|
-
options: z.object({
|
|
1361
|
-
query: z.string().optional().describe('Filter by id, name, category, tag, or description'),
|
|
1362
|
-
}),
|
|
1363
|
-
output: z.object({ services: z.array(serviceSummarySchema) }),
|
|
1364
|
-
alias: { query: 'q' },
|
|
1365
|
-
async run(c) {
|
|
1366
|
-
const query = c.options.query?.toLowerCase()
|
|
1367
|
-
const registry = await fetchServicesRegistry()
|
|
1368
|
-
const filtered = query
|
|
1369
|
-
? registry.filter((service) =>
|
|
1370
|
-
[
|
|
1371
|
-
service.id,
|
|
1372
|
-
service.name,
|
|
1373
|
-
service.description,
|
|
1374
|
-
...(Array.isArray(service.categories) ? service.categories : []),
|
|
1375
|
-
...(Array.isArray(service.tags) ? service.tags : []),
|
|
1376
|
-
]
|
|
1377
|
-
.filter((value): value is string => typeof value === 'string')
|
|
1378
|
-
.some((value) => value.toLowerCase().includes(query)),
|
|
1379
|
-
)
|
|
1380
|
-
: registry
|
|
1381
|
-
const summaries = filtered.map(summarizeService).sort((a, b) => a.id.localeCompare(b.id))
|
|
1382
|
-
return outputResult(c, { services: summaries }, () => {
|
|
1383
|
-
if (summaries.length === 0) {
|
|
1384
|
-
console.log('No services found.')
|
|
1385
|
-
return
|
|
1386
|
-
}
|
|
1387
|
-
const idWidth = Math.max(...summaries.map((service) => service.id.length))
|
|
1388
|
-
const paidWidth = Math.max(
|
|
1389
|
-
...summaries.map((service) => String(service.paidEndpoints).length),
|
|
1390
|
-
)
|
|
1391
|
-
for (const service of summaries) {
|
|
1392
|
-
const name = service.name && service.name !== service.id ? ` ${service.name}` : ''
|
|
1393
|
-
const url = service.url ? ` ${pc.dim(service.url)}` : ''
|
|
1394
|
-
console.log(
|
|
1395
|
-
`${service.id.padEnd(idWidth)} ${String(service.paidEndpoints).padStart(paidWidth)} paid${name}${url}`,
|
|
1396
|
-
)
|
|
1397
|
-
}
|
|
1398
|
-
})
|
|
1399
|
-
},
|
|
1400
|
-
})
|
|
1401
|
-
.command('show', {
|
|
1402
|
-
description: 'Show one registered MPP service',
|
|
1403
|
-
args: z.object({
|
|
1404
|
-
service: z.string().describe('Service id or name'),
|
|
1405
|
-
}),
|
|
1406
|
-
output: z.object({ service: z.record(z.string(), z.unknown()) }),
|
|
1407
|
-
async run(c) {
|
|
1408
|
-
const registry = await fetchServicesRegistry()
|
|
1409
|
-
const service = findService(registry, c.args.service)
|
|
1410
|
-
if (!service)
|
|
1411
|
-
return c.error({
|
|
1412
|
-
code: 'SERVICE_NOT_FOUND',
|
|
1413
|
-
message: `Service not found: ${c.args.service}`,
|
|
1414
|
-
exitCode: 1,
|
|
1415
|
-
})
|
|
1416
|
-
const summary = summarizeService(service)
|
|
1417
|
-
const endpoints = getEndpoints(service)
|
|
1418
|
-
return outputResult(c, { service }, () => {
|
|
1419
|
-
console.log(`${summary.name ?? summary.id} ${pc.dim(`(${summary.id})`)}`)
|
|
1420
|
-
if (summary.description) console.log(summary.description)
|
|
1421
|
-
if (summary.url) console.log(`${pc.dim('URL')} ${link(summary.url, summary.url)}`)
|
|
1422
|
-
if (summary.status) console.log(`${pc.dim('Status')} ${summary.status}`)
|
|
1423
|
-
console.log(`${pc.dim('Endpoints')} ${endpoints.length} (${summary.paidEndpoints} paid)`)
|
|
1424
|
-
const docs = service.docs as Record<string, unknown> | undefined
|
|
1425
|
-
const homepage = docs && getString(docs.homepage)
|
|
1426
|
-
if (homepage) console.log(`${pc.dim('Docs')} ${link(homepage, homepage)}`)
|
|
1427
|
-
})
|
|
1428
|
-
},
|
|
1429
|
-
})
|
|
1430
|
-
.command('endpoints', {
|
|
1431
|
-
description: 'List endpoints for a registered MPP service',
|
|
1432
|
-
args: z.object({
|
|
1433
|
-
service: z.string().describe('Service id or name'),
|
|
1434
|
-
}),
|
|
1435
|
-
output: z.object({
|
|
1436
|
-
endpoints: z.array(serviceEndpointSchema),
|
|
1437
|
-
service: serviceSummarySchema,
|
|
1438
|
-
}),
|
|
1439
|
-
async run(c) {
|
|
1440
|
-
const registry = await fetchServicesRegistry()
|
|
1441
|
-
const service = findService(registry, c.args.service)
|
|
1442
|
-
if (!service)
|
|
1443
|
-
return c.error({
|
|
1444
|
-
code: 'SERVICE_NOT_FOUND',
|
|
1445
|
-
message: `Service not found: ${c.args.service}`,
|
|
1446
|
-
exitCode: 1,
|
|
1447
|
-
})
|
|
1448
|
-
const summary = summarizeService(service)
|
|
1449
|
-
const endpoints = getEndpoints(service).map(summarizeEndpoint)
|
|
1450
|
-
return outputResult(c, { endpoints, service: summary }, () => {
|
|
1451
|
-
if (endpoints.length === 0) {
|
|
1452
|
-
console.log(`No endpoints found for ${summary.id}.`)
|
|
1453
|
-
return
|
|
1454
|
-
}
|
|
1455
|
-
const methodWidth = Math.max(...endpoints.map((endpoint) => endpoint.method.length))
|
|
1456
|
-
const pathWidth = Math.max(...endpoints.map((endpoint) => endpoint.path.length))
|
|
1457
|
-
for (const endpoint of endpoints) {
|
|
1458
|
-
const payment = formatPayment(endpoint.payment)
|
|
1459
|
-
const description = endpoint.description ? ` ${pc.dim(endpoint.description)}` : ''
|
|
1460
|
-
console.log(
|
|
1461
|
-
`${endpoint.method.padEnd(methodWidth)} ${endpoint.path.padEnd(pathWidth)} ${payment}${description}`,
|
|
1462
|
-
)
|
|
1463
|
-
}
|
|
1464
|
-
})
|
|
1465
|
-
},
|
|
1466
|
-
})
|
|
1467
|
-
|
|
1468
|
-
const discover = Cli.create('discover', {
|
|
1469
|
-
description: 'Discovery tooling',
|
|
1470
|
-
})
|
|
1471
|
-
.command('generate', {
|
|
1472
|
-
description: 'Generate a static OpenAPI discovery document from a module',
|
|
1473
|
-
args: z.object({
|
|
1474
|
-
module: z.string().describe('Path to a module that default-exports a discovery config'),
|
|
1475
|
-
}),
|
|
1476
|
-
options: z.object({
|
|
1477
|
-
output: z.string().optional().describe('Write output to a file instead of stdout'),
|
|
1478
|
-
}),
|
|
1479
|
-
output: z.record(z.string(), z.unknown()),
|
|
1480
|
-
alias: { output: 'o' },
|
|
1481
|
-
async run(c) {
|
|
1482
|
-
const modulePath = path.resolve(c.args.module)
|
|
1483
|
-
if (!fs.existsSync(modulePath)) {
|
|
1484
|
-
return c.error({
|
|
1485
|
-
code: 'MODULE_NOT_FOUND',
|
|
1486
|
-
message: `Module not found: ${modulePath}`,
|
|
1487
|
-
exitCode: 1,
|
|
1488
|
-
})
|
|
1489
|
-
}
|
|
1490
|
-
|
|
1491
|
-
let mod: Record<string, unknown>
|
|
1492
|
-
try {
|
|
1493
|
-
mod = await import(modulePath)
|
|
1494
|
-
} catch (error) {
|
|
1495
|
-
return c.error({
|
|
1496
|
-
code: 'MODULE_IMPORT_FAILED',
|
|
1497
|
-
message: `Failed to import module: ${(error as Error).message}`,
|
|
1498
|
-
exitCode: 1,
|
|
1499
|
-
})
|
|
1500
|
-
}
|
|
1501
|
-
|
|
1502
|
-
const exported = (mod.default ?? mod) as Record<string, unknown>
|
|
1503
|
-
|
|
1504
|
-
// If the export is already a plain OpenAPI doc (has `openapi` key), use it directly.
|
|
1505
|
-
// Otherwise, expect { mppx, ...GenerateConfig } and call generate().
|
|
1506
|
-
let doc: Record<string, unknown>
|
|
1507
|
-
if (typeof exported.openapi === 'string') {
|
|
1508
|
-
doc = exported
|
|
1509
|
-
} else {
|
|
1510
|
-
const { generate } = await import('../discovery/OpenApi.js')
|
|
1511
|
-
const mppx = exported.mppx as { methods: readonly any[]; realm: string }
|
|
1512
|
-
if (!mppx) {
|
|
1513
|
-
return c.error({
|
|
1514
|
-
code: 'INVALID_MODULE',
|
|
1515
|
-
message:
|
|
1516
|
-
'Module must default-export an OpenAPI document (with `openapi` key) or an object with `mppx` (server instance) and `routes`.',
|
|
1517
|
-
exitCode: 1,
|
|
1518
|
-
})
|
|
1519
|
-
}
|
|
1520
|
-
doc = generate(mppx, exported as any)
|
|
1521
|
-
}
|
|
1522
|
-
|
|
1523
|
-
const json = JSON.stringify(doc, null, 2)
|
|
1524
|
-
if (c.options.output) {
|
|
1525
|
-
const outPath = path.resolve(c.options.output)
|
|
1526
|
-
fs.writeFileSync(outPath, `${json}\n`)
|
|
1527
|
-
process.stderr.write(`Wrote ${outPath}\n`)
|
|
1528
|
-
return outputResult(c, doc, () => {})
|
|
1529
|
-
} else {
|
|
1530
|
-
return outputResult(c, doc, () => {
|
|
1531
|
-
console.log(json)
|
|
1532
|
-
})
|
|
1533
|
-
}
|
|
1534
|
-
},
|
|
1535
|
-
})
|
|
1536
|
-
.command('validate', {
|
|
1537
|
-
description: 'Validate an OpenAPI discovery document from a file or URL',
|
|
1538
|
-
args: z.object({
|
|
1539
|
-
input: z.string().describe('Path or URL to a discovery document'),
|
|
1540
|
-
}),
|
|
1541
|
-
output: z.object({
|
|
1542
|
-
errorCount: z.number(),
|
|
1543
|
-
issues: z.array(discoveryIssueSchema),
|
|
1544
|
-
valid: z.boolean(),
|
|
1545
|
-
warningCount: z.number(),
|
|
1546
|
-
}),
|
|
1547
|
-
async run(c) {
|
|
1548
|
-
const input = c.args.input
|
|
1549
|
-
let raw: string
|
|
1550
|
-
if (/^https?:\/\//.test(input)) {
|
|
1551
|
-
const controller = new AbortController()
|
|
1552
|
-
const timeout = setTimeout(() => controller.abort(), 30_000)
|
|
1553
|
-
let response: Response
|
|
1554
|
-
try {
|
|
1555
|
-
response = await globalThis.fetch(input, { signal: controller.signal })
|
|
1556
|
-
} catch (error) {
|
|
1557
|
-
clearTimeout(timeout)
|
|
1558
|
-
const msg =
|
|
1559
|
-
error instanceof DOMException && error.name === 'AbortError'
|
|
1560
|
-
? 'Request timed out after 30s'
|
|
1561
|
-
: (error as Error).message
|
|
1562
|
-
return c.error({
|
|
1563
|
-
code: 'DISCOVERY_FETCH_FAILED',
|
|
1564
|
-
message: `Failed to fetch discovery document: ${msg}`,
|
|
1565
|
-
exitCode: 1,
|
|
1566
|
-
})
|
|
1567
|
-
}
|
|
1568
|
-
clearTimeout(timeout)
|
|
1569
|
-
if (!response.ok) {
|
|
1570
|
-
return c.error({
|
|
1571
|
-
code: 'DISCOVERY_FETCH_FAILED',
|
|
1572
|
-
message: `Failed to fetch discovery document: HTTP ${response.status}`,
|
|
1573
|
-
exitCode: 1,
|
|
1574
|
-
})
|
|
1575
|
-
}
|
|
1576
|
-
const maxSize = 10 * 1024 * 1024 // 10 MB
|
|
1577
|
-
const contentLength = response.headers.get('content-length')
|
|
1578
|
-
if (contentLength && Number(contentLength) > maxSize) {
|
|
1579
|
-
return c.error({
|
|
1580
|
-
code: 'DISCOVERY_TOO_LARGE',
|
|
1581
|
-
message: `Discovery document exceeds 10 MB limit`,
|
|
1582
|
-
exitCode: 1,
|
|
1583
|
-
})
|
|
1584
|
-
}
|
|
1585
|
-
raw = await response.text()
|
|
1586
|
-
if (raw.length > maxSize) {
|
|
1587
|
-
return c.error({
|
|
1588
|
-
code: 'DISCOVERY_TOO_LARGE',
|
|
1589
|
-
message: `Discovery document exceeds 10 MB limit`,
|
|
1590
|
-
exitCode: 1,
|
|
1591
|
-
})
|
|
1592
|
-
}
|
|
1593
|
-
} else {
|
|
1594
|
-
const resolved = path.resolve(input)
|
|
1595
|
-
if (!fs.existsSync(resolved)) {
|
|
1596
|
-
return c.error({
|
|
1597
|
-
code: 'DISCOVERY_NOT_FOUND',
|
|
1598
|
-
message: `Discovery document not found: ${resolved}`,
|
|
1599
|
-
exitCode: 1,
|
|
1600
|
-
})
|
|
1601
|
-
}
|
|
1602
|
-
raw = fs.readFileSync(resolved, 'utf-8')
|
|
1603
|
-
}
|
|
1604
|
-
|
|
1605
|
-
let doc: unknown
|
|
1606
|
-
try {
|
|
1607
|
-
doc = JSON.parse(raw)
|
|
1608
|
-
} catch (error) {
|
|
1609
|
-
return c.error({
|
|
1610
|
-
code: 'DISCOVERY_INVALID_JSON',
|
|
1611
|
-
message: `Invalid discovery JSON: ${(error as Error).message}`,
|
|
1612
|
-
exitCode: 1,
|
|
1613
|
-
})
|
|
1614
|
-
}
|
|
1615
|
-
|
|
1616
|
-
const issues = validateDiscovery(doc)
|
|
1617
|
-
if (!shouldReturnStructured(c))
|
|
1618
|
-
for (const issue of issues)
|
|
1619
|
-
console.log(`[${issue.severity}] ${issue.path}: ${issue.message}`)
|
|
1620
|
-
|
|
1621
|
-
const errorCount = issues.filter((issue) => issue.severity === 'error').length
|
|
1622
|
-
const warningCount = issues.filter((issue) => issue.severity === 'warning').length
|
|
1623
|
-
|
|
1624
|
-
if (errorCount > 0) {
|
|
1625
|
-
return c.error({
|
|
1626
|
-
code: 'DISCOVERY_INVALID',
|
|
1627
|
-
message: `Discovery document has ${errorCount} error(s) and ${warningCount} warning(s).`,
|
|
1628
|
-
exitCode: 1,
|
|
1629
|
-
})
|
|
1630
|
-
}
|
|
1631
|
-
|
|
1632
|
-
return outputResult(c, { errorCount, issues, valid: true, warningCount }, () => {
|
|
1633
|
-
console.log(
|
|
1634
|
-
warningCount > 0
|
|
1635
|
-
? `Discovery document is valid with ${warningCount} warning(s).`
|
|
1636
|
-
: 'Discovery document is valid.',
|
|
1637
|
-
)
|
|
1638
|
-
})
|
|
1639
|
-
},
|
|
1640
|
-
})
|
|
1641
|
-
|
|
1642
|
-
cli.command(account)
|
|
1643
|
-
cli.command(discover)
|
|
1644
|
-
cli.command(init)
|
|
1645
|
-
cli.command(services)
|
|
1646
|
-
cli.command(sessions)
|
|
1647
|
-
cli.command(sign)
|
|
1648
|
-
cli.command(validate)
|
|
1649
|
-
|
|
1650
|
-
export default cli
|