mppx 0.0.1 → 0.1.0
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/LICENSE +21 -0
- package/README.md +195 -0
- package/dist/BodyDigest.d.ts +42 -0
- package/dist/BodyDigest.d.ts.map +1 -0
- package/dist/BodyDigest.js +40 -0
- package/dist/BodyDigest.js.map +1 -0
- package/dist/Challenge.d.ts +271 -0
- package/dist/Challenge.d.ts.map +1 -0
- package/dist/Challenge.js +291 -0
- package/dist/Challenge.js.map +1 -0
- package/dist/Credential.d.ts +91 -0
- package/dist/Credential.d.ts.map +1 -0
- package/dist/Credential.js +122 -0
- package/dist/Credential.js.map +1 -0
- package/dist/Errors.d.ts +243 -0
- package/dist/Errors.d.ts.map +1 -0
- package/dist/Errors.js +201 -0
- package/dist/Errors.js.map +1 -0
- package/dist/Expires.d.ts +15 -0
- package/dist/Expires.d.ts.map +1 -0
- package/dist/Expires.js +29 -0
- package/dist/Expires.js.map +1 -0
- package/dist/Intent.d.ts +101 -0
- package/dist/Intent.d.ts.map +1 -0
- package/dist/Intent.js +83 -0
- package/dist/Intent.js.map +1 -0
- package/dist/Mcp.d.ts +74 -0
- package/dist/Mcp.d.ts.map +1 -0
- package/dist/Mcp.js +9 -0
- package/dist/Mcp.js.map +1 -0
- package/dist/MethodIntent.d.ts +225 -0
- package/dist/MethodIntent.d.ts.map +1 -0
- package/dist/MethodIntent.js +156 -0
- package/dist/MethodIntent.js.map +1 -0
- package/dist/PaymentRequest.d.ts +88 -0
- package/dist/PaymentRequest.d.ts.map +1 -0
- package/dist/PaymentRequest.js +81 -0
- package/dist/PaymentRequest.js.map +1 -0
- package/dist/Receipt.d.ts +110 -0
- package/dist/Receipt.d.ts.map +1 -0
- package/dist/Receipt.js +105 -0
- package/dist/Receipt.js.map +1 -0
- package/dist/Store.d.ts +28 -0
- package/dist/Store.d.ts.map +1 -0
- package/dist/Store.js +61 -0
- package/dist/Store.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +1219 -0
- package/dist/cli.js.map +1 -0
- package/dist/client/Methods.d.ts +4 -0
- package/dist/client/Methods.d.ts.map +1 -0
- package/dist/client/Methods.js +4 -0
- package/dist/client/Methods.js.map +1 -0
- package/dist/client/Mppx.d.ts +84 -0
- package/dist/client/Mppx.d.ts.map +1 -0
- package/dist/client/Mppx.js +64 -0
- package/dist/client/Mppx.js.map +1 -0
- package/dist/client/Transport.d.ts +56 -0
- package/dist/client/Transport.d.ts.map +1 -0
- package/dist/client/Transport.js +81 -0
- package/dist/client/Transport.js.map +1 -0
- package/dist/client/index.d.ts +5 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +5 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/internal/Fetch.d.ts +85 -0
- package/dist/client/internal/Fetch.d.ts.map +1 -0
- package/dist/client/internal/Fetch.js +95 -0
- package/dist/client/internal/Fetch.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/types.d.ts +302 -0
- package/dist/internal/types.d.ts.map +1 -0
- package/dist/internal/types.js +2 -0
- package/dist/internal/types.js.map +1 -0
- package/dist/mcp-sdk/client/McpClient.d.ts +78 -0
- package/dist/mcp-sdk/client/McpClient.d.ts.map +1 -0
- package/dist/mcp-sdk/client/McpClient.js +98 -0
- package/dist/mcp-sdk/client/McpClient.js.map +1 -0
- package/dist/mcp-sdk/client/index.d.ts +3 -0
- package/dist/mcp-sdk/client/index.d.ts.map +1 -0
- package/dist/mcp-sdk/client/index.js +3 -0
- package/dist/mcp-sdk/client/index.js.map +1 -0
- package/dist/mcp-sdk/server/Transport.d.ts +43 -0
- package/dist/mcp-sdk/server/Transport.d.ts.map +1 -0
- package/dist/mcp-sdk/server/Transport.js +71 -0
- package/dist/mcp-sdk/server/Transport.js.map +1 -0
- package/dist/mcp-sdk/server/index.d.ts +2 -0
- package/dist/mcp-sdk/server/index.d.ts.map +1 -0
- package/dist/mcp-sdk/server/index.js +2 -0
- package/dist/mcp-sdk/server/index.js.map +1 -0
- package/dist/middlewares/elysia.d.ts +51 -0
- package/dist/middlewares/elysia.d.ts.map +1 -0
- package/dist/middlewares/elysia.js +59 -0
- package/dist/middlewares/elysia.js.map +1 -0
- package/dist/middlewares/express.d.ts +46 -0
- package/dist/middlewares/express.d.ts.map +1 -0
- package/dist/middlewares/express.js +69 -0
- package/dist/middlewares/express.js.map +1 -0
- package/dist/middlewares/hono.d.ts +46 -0
- package/dist/middlewares/hono.d.ts.map +1 -0
- package/dist/middlewares/hono.js +57 -0
- package/dist/middlewares/hono.js.map +1 -0
- package/dist/middlewares/internal/mppx.d.ts +16 -0
- package/dist/middlewares/internal/mppx.d.ts.map +1 -0
- package/dist/middlewares/internal/mppx.js +16 -0
- package/dist/middlewares/internal/mppx.js.map +1 -0
- package/dist/middlewares/nextjs.d.ts +45 -0
- package/dist/middlewares/nextjs.d.ts.map +1 -0
- package/dist/middlewares/nextjs.js +57 -0
- package/dist/middlewares/nextjs.js.map +1 -0
- package/dist/proxy/Proxy.d.ts +47 -0
- package/dist/proxy/Proxy.d.ts.map +1 -0
- package/dist/proxy/Proxy.js +126 -0
- package/dist/proxy/Proxy.js.map +1 -0
- package/dist/proxy/Service.d.ts +100 -0
- package/dist/proxy/Service.d.ts.map +1 -0
- package/dist/proxy/Service.js +147 -0
- package/dist/proxy/Service.js.map +1 -0
- package/dist/proxy/index.d.ts +7 -0
- package/dist/proxy/index.d.ts.map +1 -0
- package/dist/proxy/index.js +7 -0
- package/dist/proxy/index.js.map +1 -0
- package/dist/proxy/internal/Headers.d.ts +3 -0
- package/dist/proxy/internal/Headers.d.ts.map +1 -0
- package/dist/proxy/internal/Headers.js +41 -0
- package/dist/proxy/internal/Headers.js.map +1 -0
- package/dist/proxy/internal/Route.d.ts +14 -0
- package/dist/proxy/internal/Route.d.ts.map +1 -0
- package/dist/proxy/internal/Route.js +47 -0
- package/dist/proxy/internal/Route.js.map +1 -0
- package/dist/proxy/services/anthropic.d.ts +29 -0
- package/dist/proxy/services/anthropic.d.ts.map +1 -0
- package/dist/proxy/services/anthropic.js +30 -0
- package/dist/proxy/services/anthropic.js.map +1 -0
- package/dist/proxy/services/openai.d.ts +29 -0
- package/dist/proxy/services/openai.d.ts.map +1 -0
- package/dist/proxy/services/openai.js +30 -0
- package/dist/proxy/services/openai.js.map +1 -0
- package/dist/proxy/services/stripe.d.ts +29 -0
- package/dist/proxy/services/stripe.d.ts.map +1 -0
- package/dist/proxy/services/stripe.js +30 -0
- package/dist/proxy/services/stripe.js.map +1 -0
- package/dist/server/Methods.d.ts +3 -0
- package/dist/server/Methods.d.ts.map +1 -0
- package/dist/server/Methods.js +3 -0
- package/dist/server/Methods.js.map +1 -0
- package/dist/server/Mppx.d.ts +116 -0
- package/dist/server/Mppx.d.ts.map +1 -0
- package/dist/server/Mppx.js +207 -0
- package/dist/server/Mppx.js.map +1 -0
- package/dist/server/NodeListener.d.ts +3 -0
- package/dist/server/NodeListener.d.ts.map +1 -0
- package/dist/server/NodeListener.js +3 -0
- package/dist/server/NodeListener.js.map +1 -0
- package/dist/server/Request.d.ts +24 -0
- package/dist/server/Request.d.ts.map +1 -0
- package/dist/server/Request.js +26 -0
- package/dist/server/Request.js.map +1 -0
- package/dist/server/Response.d.ts +10 -0
- package/dist/server/Response.d.ts.map +1 -0
- package/dist/server/Response.js +15 -0
- package/dist/server/Response.js.map +1 -0
- package/dist/server/Transport.d.ts +93 -0
- package/dist/server/Transport.d.ts.map +1 -0
- package/dist/server/Transport.js +132 -0
- package/dist/server/Transport.js.map +1 -0
- package/dist/server/index.d.ts +9 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +9 -0
- package/dist/server/index.js.map +1 -0
- package/dist/stripe/Intents.d.ts +54 -0
- package/dist/stripe/Intents.d.ts.map +1 -0
- package/dist/stripe/Intents.js +27 -0
- package/dist/stripe/Intents.js.map +1 -0
- package/dist/stripe/client/Charge.d.ts +114 -0
- package/dist/stripe/client/Charge.d.ts.map +1 -0
- package/dist/stripe/client/Charge.js +77 -0
- package/dist/stripe/client/Charge.js.map +1 -0
- package/dist/stripe/client/MethodIntents.d.ts +80 -0
- package/dist/stripe/client/MethodIntents.d.ts.map +1 -0
- package/dist/stripe/client/MethodIntents.js +34 -0
- package/dist/stripe/client/MethodIntents.js.map +1 -0
- package/dist/stripe/client/index.d.ts +3 -0
- package/dist/stripe/client/index.d.ts.map +1 -0
- package/dist/stripe/client/index.js +3 -0
- package/dist/stripe/client/index.js.map +1 -0
- package/dist/stripe/index.d.ts +2 -0
- package/dist/stripe/index.d.ts.map +1 -0
- package/dist/stripe/index.js +2 -0
- package/dist/stripe/index.js.map +1 -0
- package/dist/stripe/server/Charge.d.ts +74 -0
- package/dist/stripe/server/Charge.d.ts.map +1 -0
- package/dist/stripe/server/Charge.js +79 -0
- package/dist/stripe/server/Charge.js.map +1 -0
- package/dist/stripe/server/MethodIntents.d.ts +65 -0
- package/dist/stripe/server/MethodIntents.d.ts.map +1 -0
- package/dist/stripe/server/MethodIntents.js +21 -0
- package/dist/stripe/server/MethodIntents.js.map +1 -0
- package/dist/stripe/server/index.d.ts +3 -0
- package/dist/stripe/server/index.d.ts.map +1 -0
- package/dist/stripe/server/index.js +3 -0
- package/dist/stripe/server/index.js.map +1 -0
- package/dist/tempo/Attribution.d.ts +101 -0
- package/dist/tempo/Attribution.d.ts.map +1 -0
- package/dist/tempo/Attribution.js +124 -0
- package/dist/tempo/Attribution.js.map +1 -0
- package/dist/tempo/Intents.d.ts +132 -0
- package/dist/tempo/Intents.d.ts.map +1 -0
- package/dist/tempo/Intents.js +81 -0
- package/dist/tempo/Intents.js.map +1 -0
- package/dist/tempo/client/ChannelOps.d.ts +54 -0
- package/dist/tempo/client/ChannelOps.d.ts.map +1 -0
- package/dist/tempo/client/ChannelOps.js +138 -0
- package/dist/tempo/client/ChannelOps.js.map +1 -0
- package/dist/tempo/client/Charge.d.ts +76 -0
- package/dist/tempo/client/Charge.d.ts.map +1 -0
- package/dist/tempo/client/Charge.js +69 -0
- package/dist/tempo/client/Charge.js.map +1 -0
- package/dist/tempo/client/MethodIntents.d.ts +157 -0
- package/dist/tempo/client/MethodIntents.d.ts.map +1 -0
- package/dist/tempo/client/MethodIntents.js +25 -0
- package/dist/tempo/client/MethodIntents.js.map +1 -0
- package/dist/tempo/client/Session.d.ts +159 -0
- package/dist/tempo/client/Session.d.ts.map +1 -0
- package/dist/tempo/client/Session.js +263 -0
- package/dist/tempo/client/Session.js.map +1 -0
- package/dist/tempo/client/SessionManager.d.ts +62 -0
- package/dist/tempo/client/SessionManager.d.ts.map +1 -0
- package/dist/tempo/client/SessionManager.js +196 -0
- package/dist/tempo/client/SessionManager.js.map +1 -0
- package/dist/tempo/client/index.d.ts +6 -0
- package/dist/tempo/client/index.d.ts.map +1 -0
- package/dist/tempo/client/index.js +5 -0
- package/dist/tempo/client/index.js.map +1 -0
- package/dist/tempo/index.d.ts +3 -0
- package/dist/tempo/index.d.ts.map +1 -0
- package/dist/tempo/index.js +3 -0
- package/dist/tempo/index.js.map +1 -0
- package/dist/tempo/internal/account.d.ts +32 -0
- package/dist/tempo/internal/account.d.ts.map +1 -0
- package/dist/tempo/internal/account.js +33 -0
- package/dist/tempo/internal/account.js.map +1 -0
- package/dist/tempo/internal/defaults.d.ts +18 -0
- package/dist/tempo/internal/defaults.d.ts.map +1 -0
- package/dist/tempo/internal/defaults.js +18 -0
- package/dist/tempo/internal/defaults.js.map +1 -0
- package/dist/tempo/internal/types.d.ts +11 -0
- package/dist/tempo/internal/types.d.ts.map +1 -0
- package/dist/tempo/internal/types.js +2 -0
- package/dist/tempo/internal/types.js.map +1 -0
- package/dist/tempo/server/Charge.d.ts +77 -0
- package/dist/tempo/server/Charge.d.ts.map +1 -0
- package/dist/tempo/server/Charge.js +228 -0
- package/dist/tempo/server/Charge.js.map +1 -0
- package/dist/tempo/server/MethodIntents.d.ts +140 -0
- package/dist/tempo/server/MethodIntents.d.ts.map +1 -0
- package/dist/tempo/server/MethodIntents.js +26 -0
- package/dist/tempo/server/MethodIntents.js.map +1 -0
- package/dist/tempo/server/Session.d.ts +148 -0
- package/dist/tempo/server/Session.d.ts.map +1 -0
- package/dist/tempo/server/Session.js +529 -0
- package/dist/tempo/server/Session.js.map +1 -0
- package/dist/tempo/server/internal/transport.d.ts +47 -0
- package/dist/tempo/server/internal/transport.d.ts.map +1 -0
- package/dist/tempo/server/internal/transport.js +118 -0
- package/dist/tempo/server/internal/transport.js.map +1 -0
- package/dist/tempo/stream/Chain.d.ts +52 -0
- package/dist/tempo/stream/Chain.d.ts.map +1 -0
- package/dist/tempo/stream/Chain.js +215 -0
- package/dist/tempo/stream/Chain.js.map +1 -0
- package/dist/tempo/stream/Channel.d.ts +26 -0
- package/dist/tempo/stream/Channel.d.ts.map +1 -0
- package/dist/tempo/stream/Channel.js +27 -0
- package/dist/tempo/stream/Channel.js.map +1 -0
- package/dist/tempo/stream/ChannelStore.d.ts +103 -0
- package/dist/tempo/stream/ChannelStore.d.ts.map +1 -0
- package/dist/tempo/stream/ChannelStore.js +100 -0
- package/dist/tempo/stream/ChannelStore.js.map +1 -0
- package/dist/tempo/stream/Receipt.d.ts +22 -0
- package/dist/tempo/stream/Receipt.d.ts.map +1 -0
- package/dist/tempo/stream/Receipt.js +34 -0
- package/dist/tempo/stream/Receipt.js.map +1 -0
- package/dist/tempo/stream/Sse.d.ts +134 -0
- package/dist/tempo/stream/Sse.d.ts.map +1 -0
- package/dist/tempo/stream/Sse.js +288 -0
- package/dist/tempo/stream/Sse.js.map +1 -0
- package/dist/tempo/stream/Types.d.ts +78 -0
- package/dist/tempo/stream/Types.d.ts.map +1 -0
- package/dist/tempo/stream/Types.js +2 -0
- package/dist/tempo/stream/Types.js.map +1 -0
- package/dist/tempo/stream/Voucher.d.ts +20 -0
- package/dist/tempo/stream/Voucher.d.ts.map +1 -0
- package/dist/tempo/stream/Voucher.js +98 -0
- package/dist/tempo/stream/Voucher.js.map +1 -0
- package/dist/tempo/stream/escrow.abi.d.ts +598 -0
- package/dist/tempo/stream/escrow.abi.d.ts.map +1 -0
- package/dist/tempo/stream/escrow.abi.js +760 -0
- package/dist/tempo/stream/escrow.abi.js.map +1 -0
- package/dist/tempo/stream/index.d.ts +8 -0
- package/dist/tempo/stream/index.d.ts.map +1 -0
- package/dist/tempo/stream/index.js +8 -0
- package/dist/tempo/stream/index.js.map +1 -0
- package/dist/viem/Account.d.ts +12 -0
- package/dist/viem/Account.d.ts.map +1 -0
- package/dist/viem/Account.js +14 -0
- package/dist/viem/Account.js.map +1 -0
- package/dist/viem/Client.d.ts +21 -0
- package/dist/viem/Client.d.ts.map +1 -0
- package/dist/viem/Client.js +19 -0
- package/dist/viem/Client.js.map +1 -0
- package/dist/zod.d.ts +17 -0
- package/dist/zod.d.ts.map +1 -0
- package/dist/zod.js +35 -0
- package/dist/zod.js.map +1 -0
- package/package.json +117 -4
- package/src/BodyDigest.test.ts +43 -0
- package/src/BodyDigest.ts +53 -0
- package/src/Challenge.test-d.ts +81 -0
- package/src/Challenge.test.ts +414 -0
- package/src/Challenge.ts +429 -0
- package/src/Credential.test.ts +227 -0
- package/src/Credential.ts +154 -0
- package/src/Errors.test.ts +402 -0
- package/src/Errors.ts +348 -0
- package/src/Expires.ts +34 -0
- package/src/Intent.test.ts +180 -0
- package/src/Intent.ts +109 -0
- package/src/Mcp.ts +81 -0
- package/src/MethodIntent.test.ts +303 -0
- package/src/MethodIntent.ts +388 -0
- package/src/PaymentRequest.test.ts +152 -0
- package/src/PaymentRequest.ts +107 -0
- package/src/Receipt.test.ts +98 -0
- package/src/Receipt.ts +129 -0
- package/src/Store.ts +84 -0
- package/src/cli.test.ts +542 -0
- package/src/cli.ts +1319 -0
- package/src/client/Methods.ts +3 -0
- package/src/client/Mppx.test-d.ts +90 -0
- package/src/client/Mppx.test.ts +468 -0
- package/src/client/Mppx.ts +149 -0
- package/src/client/Transport.test.ts +283 -0
- package/src/client/Transport.ts +115 -0
- package/src/client/index.ts +4 -0
- package/src/client/internal/Fetch.test-d.ts +57 -0
- package/src/client/internal/Fetch.test.ts +281 -0
- package/src/client/internal/Fetch.ts +157 -0
- package/src/env.d.ts +11 -0
- package/src/index.ts +12 -0
- package/src/internal/types.ts +403 -0
- package/src/mcp-sdk/client/McpClient.test-d.ts +109 -0
- package/src/mcp-sdk/client/McpClient.test.ts +219 -0
- package/src/mcp-sdk/client/McpClient.ts +187 -0
- package/src/mcp-sdk/client/index.ts +2 -0
- package/src/mcp-sdk/server/Transport.ts +94 -0
- package/src/mcp-sdk/server/index.ts +1 -0
- package/src/middlewares/elysia.ts +66 -0
- package/src/middlewares/express.test.ts +155 -0
- package/src/middlewares/express.ts +82 -0
- package/src/middlewares/hono.test.ts +148 -0
- package/src/middlewares/hono.ts +62 -0
- package/src/middlewares/internal/mppx.ts +30 -0
- package/src/middlewares/nextjs.test.ts +164 -0
- package/src/middlewares/nextjs.ts +66 -0
- package/src/proxy/Proxy.test.ts +472 -0
- package/src/proxy/Proxy.ts +175 -0
- package/src/proxy/Service.test.ts +125 -0
- package/src/proxy/Service.ts +227 -0
- package/src/proxy/index.ts +6 -0
- package/src/proxy/internal/Headers.test.ts +100 -0
- package/src/proxy/internal/Headers.ts +40 -0
- package/src/proxy/internal/Route.test.ts +143 -0
- package/src/proxy/internal/Route.ts +54 -0
- package/src/proxy/services/anthropic.ts +45 -0
- package/src/proxy/services/openai.test.ts +97 -0
- package/src/proxy/services/openai.ts +48 -0
- package/src/proxy/services/stripe.ts +49 -0
- package/src/server/Methods.ts +2 -0
- package/src/server/Mppx.test-d.ts +343 -0
- package/src/server/Mppx.test.ts +342 -0
- package/src/server/Mppx.ts +378 -0
- package/src/server/NodeListener.test.ts +188 -0
- package/src/server/NodeListener.ts +3 -0
- package/src/server/Request.test.ts +102 -0
- package/src/server/Request.ts +33 -0
- package/src/server/Response.test.ts +31 -0
- package/src/server/Response.ts +27 -0
- package/src/server/Transport.test.ts +294 -0
- package/src/server/Transport.ts +222 -0
- package/src/server/index.ts +8 -0
- package/src/stripe/Charge.integration.test.ts +326 -0
- package/src/stripe/Intents.test.ts +52 -0
- package/src/stripe/Intents.ts +27 -0
- package/src/stripe/client/Charge.ts +119 -0
- package/src/stripe/client/MethodIntents.ts +37 -0
- package/src/stripe/client/index.ts +2 -0
- package/src/stripe/index.ts +1 -0
- package/src/stripe/server/Charge.ts +121 -0
- package/src/stripe/server/MethodIntents.ts +24 -0
- package/src/stripe/server/index.ts +2 -0
- package/src/tempo/Attribution.test.ts +187 -0
- package/src/tempo/Attribution.ts +156 -0
- package/src/tempo/Intents.test.ts +84 -0
- package/src/tempo/Intents.ts +93 -0
- package/src/tempo/client/ChannelOps.ts +233 -0
- package/src/tempo/client/Charge.ts +84 -0
- package/src/tempo/client/MethodIntents.ts +28 -0
- package/src/tempo/client/Session.ts +369 -0
- package/src/tempo/client/SessionManager.test.ts +223 -0
- package/src/tempo/client/SessionManager.ts +270 -0
- package/src/tempo/client/index.ts +5 -0
- package/src/tempo/index.ts +2 -0
- package/src/tempo/internal/account.ts +47 -0
- package/src/tempo/internal/defaults.ts +20 -0
- package/src/tempo/internal/types.ts +8 -0
- package/src/tempo/server/Charge.test.ts +847 -0
- package/src/tempo/server/Charge.ts +309 -0
- package/src/tempo/server/MethodIntents.ts +29 -0
- package/src/tempo/server/Session.test.ts +1349 -0
- package/src/tempo/server/Session.ts +773 -0
- package/src/tempo/server/Sse.test.ts +289 -0
- package/src/tempo/server/index.ts +5 -0
- package/src/tempo/server/internal/transport.ts +153 -0
- package/src/tempo/stream/Chain.ts +333 -0
- package/src/tempo/stream/Channel.ts +50 -0
- package/src/tempo/stream/ChannelStore.test.ts +473 -0
- package/src/tempo/stream/ChannelStore.ts +202 -0
- package/src/tempo/stream/Receipt.test.ts +84 -0
- package/src/tempo/stream/Receipt.ts +45 -0
- package/src/tempo/stream/Sse.test.ts +401 -0
- package/src/tempo/stream/Sse.ts +375 -0
- package/src/tempo/stream/Types.ts +86 -0
- package/src/tempo/stream/Voucher.test.ts +134 -0
- package/src/tempo/stream/Voucher.ts +123 -0
- package/src/tempo/stream/escrow.abi.ts +759 -0
- package/src/tempo/stream/index.ts +7 -0
- package/src/tsconfig.json +10 -0
- package/src/viem/Account.test.ts +71 -0
- package/src/viem/Account.ts +30 -0
- package/src/viem/Client.test.ts +58 -0
- package/src/viem/Client.ts +33 -0
- package/src/zod.ts +47 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { IncomingMessage, RequestListener, ServerResponse } from 'node:http'
|
|
2
|
+
import * as FetchServer from '@remix-run/node-fetch-server'
|
|
3
|
+
|
|
4
|
+
export type FetchHandler = (request: Request) => Promise<Response> | Response
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Converts a Fetch API handler into a Node.js HTTP request listener.
|
|
8
|
+
*
|
|
9
|
+
* Uses [`@remix-run/node-fetch-server`](https://github.com/remix-run/remix/blob/main/packages/node-fetch-server/src/lib/request-listener.ts).
|
|
10
|
+
*
|
|
11
|
+
* @param handler - A Fetch API handler: `(request: Request) => Response`.
|
|
12
|
+
* @param options - Optional error handler.
|
|
13
|
+
* @returns A Node.js `(req, res)` listener.
|
|
14
|
+
*/
|
|
15
|
+
export function toNodeListener(
|
|
16
|
+
handler: FetchHandler,
|
|
17
|
+
options?: FetchServer.RequestListenerOptions | undefined,
|
|
18
|
+
): RequestListener {
|
|
19
|
+
return FetchServer.createRequestListener(handler, options) as never
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Converts a Node.js `IncomingMessage`/`ServerResponse` pair to a Fetch API `Request`.
|
|
24
|
+
*
|
|
25
|
+
* Uses [`@remix-run/node-fetch-server`](https://github.com/remix-run/remix/blob/main/packages/node-fetch-server/src/lib/request-listener.ts).
|
|
26
|
+
*
|
|
27
|
+
* @param req - The Node.js IncomingMessage.
|
|
28
|
+
* @param res - The Node.js ServerResponse (used for abort signal lifecycle).
|
|
29
|
+
* @returns A Fetch API Request.
|
|
30
|
+
*/
|
|
31
|
+
export function fromNodeListener(req: IncomingMessage, res: ServerResponse): Request {
|
|
32
|
+
return FetchServer.createRequest(req, res)
|
|
33
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Challenge } from 'mppx'
|
|
2
|
+
import { Response } from 'mppx/server'
|
|
3
|
+
import { describe, expect, test } from 'vitest'
|
|
4
|
+
import * as Errors from '../Errors.js'
|
|
5
|
+
|
|
6
|
+
const challenge = Challenge.from({
|
|
7
|
+
id: 'abc123',
|
|
8
|
+
intent: 'charge',
|
|
9
|
+
method: 'tempo',
|
|
10
|
+
realm: 'api.example.com',
|
|
11
|
+
request: { amount: '1000000' },
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
describe('requirePayment', () => {
|
|
15
|
+
test('returns 402 Response with WWW-Authenticate header', () => {
|
|
16
|
+
const response = Response.requirePayment({ challenge })
|
|
17
|
+
|
|
18
|
+
expect(response.status).toBe(402)
|
|
19
|
+
expect(response.headers.get('WWW-Authenticate')).toBe(Challenge.serialize(challenge))
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
test('includes problem details in body when error provided', async () => {
|
|
23
|
+
const error = new Errors.PaymentRequiredError()
|
|
24
|
+
|
|
25
|
+
const response = Response.requirePayment({ challenge, error })
|
|
26
|
+
|
|
27
|
+
expect(response.headers.get('Content-Type')).toBe('application/problem+json')
|
|
28
|
+
const body = await response.json()
|
|
29
|
+
expect(body).toEqual(error.toProblemDetails(challenge.id))
|
|
30
|
+
})
|
|
31
|
+
})
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as Challenge from '../Challenge.js'
|
|
2
|
+
import type * as Errors from '../Errors.js'
|
|
3
|
+
|
|
4
|
+
export function requirePayment(parameters: requirePayment.Parameters): Response {
|
|
5
|
+
const { challenge, error } = parameters
|
|
6
|
+
|
|
7
|
+
const headers: Record<string, string> = {
|
|
8
|
+
'WWW-Authenticate': Challenge.serialize(challenge),
|
|
9
|
+
'Cache-Control': 'no-store',
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
let body: string | null = null
|
|
13
|
+
|
|
14
|
+
if (error) {
|
|
15
|
+
headers['Content-Type'] = 'application/problem+json'
|
|
16
|
+
body = JSON.stringify(error.toProblemDetails(challenge.id))
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return new Response(body, { status: 402, headers })
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export declare namespace requirePayment {
|
|
23
|
+
type Parameters = {
|
|
24
|
+
challenge: Challenge.Challenge
|
|
25
|
+
error?: Errors.PaymentError | undefined
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import { Challenge, Credential, Mcp, Receipt } from 'mppx'
|
|
2
|
+
import { Transport } from 'mppx/server'
|
|
3
|
+
import { MethodIntents as Intents } from 'mppx/tempo'
|
|
4
|
+
import { describe, expect, test } from 'vitest'
|
|
5
|
+
import { BadRequestError, ChannelClosedError } from '../Errors.js'
|
|
6
|
+
|
|
7
|
+
const realm = 'api.example.com'
|
|
8
|
+
const secretKey = 'test-secret-key'
|
|
9
|
+
|
|
10
|
+
const challenge = Challenge.fromIntent(Intents.charge, {
|
|
11
|
+
realm,
|
|
12
|
+
secretKey,
|
|
13
|
+
request: {
|
|
14
|
+
amount: '1000',
|
|
15
|
+
currency: '0x20c0000000000000000000000000000000000001',
|
|
16
|
+
decimals: 6,
|
|
17
|
+
recipient: '0x742d35Cc6634C0532925a3b844Bc9e7595f8fE00',
|
|
18
|
+
expires: '2025-01-01T00:00:00.000Z',
|
|
19
|
+
},
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
const credential = Credential.from({
|
|
23
|
+
challenge,
|
|
24
|
+
payload: { signature: '0xabc123', type: 'transaction' },
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
const receipt = Receipt.from({
|
|
28
|
+
method: 'tempo',
|
|
29
|
+
status: 'success',
|
|
30
|
+
timestamp: '2025-01-01T00:00:00.000Z',
|
|
31
|
+
reference: '0xtxhash',
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
describe('http', () => {
|
|
35
|
+
describe('getCredential', () => {
|
|
36
|
+
test('returns credential from Authorization header', () => {
|
|
37
|
+
const transport = Transport.http()
|
|
38
|
+
const request = new Request('https://example.com', {
|
|
39
|
+
headers: { Authorization: Credential.serialize(credential) },
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
expect(transport.getCredential(request)).toMatchInlineSnapshot(`
|
|
43
|
+
{
|
|
44
|
+
"challenge": {
|
|
45
|
+
"expires": "2025-01-01T00:00:00.000Z",
|
|
46
|
+
"id": "jIuTUdphF_TyhJ-NT1lK2r5YzPXw4tuELfslOVa3nls",
|
|
47
|
+
"intent": "charge",
|
|
48
|
+
"method": "tempo",
|
|
49
|
+
"realm": "api.example.com",
|
|
50
|
+
"request": {
|
|
51
|
+
"amount": "1000000000",
|
|
52
|
+
"currency": "0x20c0000000000000000000000000000000000001",
|
|
53
|
+
"expires": "2025-01-01T00:00:00.000Z",
|
|
54
|
+
"recipient": "0x742d35Cc6634C0532925a3b844Bc9e7595f8fE00",
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
"payload": {
|
|
58
|
+
"signature": "0xabc123",
|
|
59
|
+
"type": "transaction",
|
|
60
|
+
},
|
|
61
|
+
}
|
|
62
|
+
`)
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
test('returns null when no Authorization header', () => {
|
|
66
|
+
const transport = Transport.http()
|
|
67
|
+
const request = new Request('https://example.com')
|
|
68
|
+
|
|
69
|
+
expect(transport.getCredential(request)).toBeNull()
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
test('returns null when no Payment scheme present', () => {
|
|
73
|
+
const transport = Transport.http()
|
|
74
|
+
const request = new Request('https://example.com', {
|
|
75
|
+
headers: { Authorization: 'Bearer invalid' },
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
expect(transport.getCredential(request)).toBeNull()
|
|
79
|
+
})
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
describe('respondChallenge', () => {
|
|
83
|
+
test('default', async () => {
|
|
84
|
+
const transport = Transport.http()
|
|
85
|
+
const request = new Request('https://example.com')
|
|
86
|
+
|
|
87
|
+
const response = await transport.respondChallenge({ challenge, input: request })
|
|
88
|
+
|
|
89
|
+
expect({
|
|
90
|
+
status: response.status,
|
|
91
|
+
headers: Object.fromEntries(response.headers),
|
|
92
|
+
}).toMatchInlineSnapshot(`
|
|
93
|
+
{
|
|
94
|
+
"headers": {
|
|
95
|
+
"cache-control": "no-store",
|
|
96
|
+
"www-authenticate": "Payment id="jIuTUdphF_TyhJ-NT1lK2r5YzPXw4tuELfslOVa3nls", realm="api.example.com", method="tempo", intent="charge", request="eyJjdXJyZW5jeSI6IjB4MjBjMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMSIsImV4cGlyZXMiOiIyMDI1LTAxLTAxVDAwOjAwOjAwLjAwMFoiLCJyZWNpcGllbnQiOiIweDc0MmQzNUNjNjYzNEMwNTMyOTI1YTNiODQ0QmM5ZTc1OTVmOGZFMDAiLCJhbW91bnQiOiIxMDAwMDAwMDAwIn0", expires="2025-01-01T00:00:00.000Z"",
|
|
97
|
+
},
|
|
98
|
+
"status": 402,
|
|
99
|
+
}
|
|
100
|
+
`)
|
|
101
|
+
})
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
describe('respondChallenge with error status codes', () => {
|
|
105
|
+
test('BadRequestError returns 400', async () => {
|
|
106
|
+
const transport = Transport.http()
|
|
107
|
+
const request = new Request('https://example.com')
|
|
108
|
+
const error = new BadRequestError({ reason: 'invalid parameters' })
|
|
109
|
+
|
|
110
|
+
const response = await transport.respondChallenge({ challenge, input: request, error })
|
|
111
|
+
|
|
112
|
+
expect(response.status).toBe(400)
|
|
113
|
+
const body = await response.json()
|
|
114
|
+
expect(body.type).toBe('https://tempoxyz.github.io/payment-auth-spec/problems/bad-request')
|
|
115
|
+
expect(body.status).toBe(400)
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
test('ChannelClosedError returns 410', async () => {
|
|
119
|
+
const transport = Transport.http()
|
|
120
|
+
const request = new Request('https://example.com')
|
|
121
|
+
const error = new ChannelClosedError({ reason: 'channel finalized' })
|
|
122
|
+
|
|
123
|
+
const response = await transport.respondChallenge({ challenge, input: request, error })
|
|
124
|
+
|
|
125
|
+
expect(response.status).toBe(410)
|
|
126
|
+
const body = await response.json()
|
|
127
|
+
expect(body.type).toBe('https://paymentauth.org/problems/stream/channel-finalized')
|
|
128
|
+
expect(body.status).toBe(410)
|
|
129
|
+
})
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
describe('respondReceipt', () => {
|
|
133
|
+
test('default', () => {
|
|
134
|
+
const transport = Transport.http()
|
|
135
|
+
const originalResponse = new Response('OK', { status: 200 })
|
|
136
|
+
|
|
137
|
+
const response = transport.respondReceipt({
|
|
138
|
+
receipt,
|
|
139
|
+
response: originalResponse,
|
|
140
|
+
challengeId: challenge.id,
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
expect({
|
|
144
|
+
status: response.status,
|
|
145
|
+
headers: Object.fromEntries(response.headers),
|
|
146
|
+
}).toMatchInlineSnapshot(`
|
|
147
|
+
{
|
|
148
|
+
"headers": {
|
|
149
|
+
"content-type": "text/plain;charset=UTF-8",
|
|
150
|
+
"payment-receipt": "eyJtZXRob2QiOiJ0ZW1wbyIsInJlZmVyZW5jZSI6IjB4dHhoYXNoIiwic3RhdHVzIjoic3VjY2VzcyIsInRpbWVzdGFtcCI6IjIwMjUtMDEtMDFUMDA6MDA6MDAuMDAwWiJ9",
|
|
151
|
+
},
|
|
152
|
+
"status": 200,
|
|
153
|
+
}
|
|
154
|
+
`)
|
|
155
|
+
})
|
|
156
|
+
})
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
describe('mcp', () => {
|
|
160
|
+
const mcpRequest: Mcp.JsonRpcRequest = {
|
|
161
|
+
jsonrpc: '2.0',
|
|
162
|
+
id: 1,
|
|
163
|
+
method: 'tools/call',
|
|
164
|
+
params: {
|
|
165
|
+
name: 'test-tool',
|
|
166
|
+
},
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
describe('getCredential', () => {
|
|
170
|
+
test('returns credential from _meta', () => {
|
|
171
|
+
const transport = Transport.mcp()
|
|
172
|
+
const request: Mcp.JsonRpcRequest = {
|
|
173
|
+
...mcpRequest,
|
|
174
|
+
params: {
|
|
175
|
+
...mcpRequest.params,
|
|
176
|
+
_meta: {
|
|
177
|
+
[Mcp.credentialMetaKey]: credential,
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
expect(transport.getCredential(request)).toMatchInlineSnapshot(`
|
|
183
|
+
{
|
|
184
|
+
"challenge": {
|
|
185
|
+
"expires": "2025-01-01T00:00:00.000Z",
|
|
186
|
+
"id": "jIuTUdphF_TyhJ-NT1lK2r5YzPXw4tuELfslOVa3nls",
|
|
187
|
+
"intent": "charge",
|
|
188
|
+
"method": "tempo",
|
|
189
|
+
"realm": "api.example.com",
|
|
190
|
+
"request": {
|
|
191
|
+
"amount": "1000000000",
|
|
192
|
+
"currency": "0x20c0000000000000000000000000000000000001",
|
|
193
|
+
"expires": "2025-01-01T00:00:00.000Z",
|
|
194
|
+
"recipient": "0x742d35Cc6634C0532925a3b844Bc9e7595f8fE00",
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
"payload": {
|
|
198
|
+
"signature": "0xabc123",
|
|
199
|
+
"type": "transaction",
|
|
200
|
+
},
|
|
201
|
+
}
|
|
202
|
+
`)
|
|
203
|
+
})
|
|
204
|
+
|
|
205
|
+
test('returns null when no credential in _meta', () => {
|
|
206
|
+
const transport = Transport.mcp()
|
|
207
|
+
|
|
208
|
+
expect(transport.getCredential(mcpRequest)).toBeNull()
|
|
209
|
+
})
|
|
210
|
+
})
|
|
211
|
+
|
|
212
|
+
describe('respondChallenge', () => {
|
|
213
|
+
test('default', () => {
|
|
214
|
+
const transport = Transport.mcp()
|
|
215
|
+
|
|
216
|
+
expect(transport.respondChallenge({ challenge, input: mcpRequest })).toMatchInlineSnapshot(`
|
|
217
|
+
{
|
|
218
|
+
"error": {
|
|
219
|
+
"code": -32042,
|
|
220
|
+
"data": {
|
|
221
|
+
"challenges": [
|
|
222
|
+
{
|
|
223
|
+
"expires": "2025-01-01T00:00:00.000Z",
|
|
224
|
+
"id": "jIuTUdphF_TyhJ-NT1lK2r5YzPXw4tuELfslOVa3nls",
|
|
225
|
+
"intent": "charge",
|
|
226
|
+
"method": "tempo",
|
|
227
|
+
"realm": "api.example.com",
|
|
228
|
+
"request": {
|
|
229
|
+
"amount": "1000000000",
|
|
230
|
+
"currency": "0x20c0000000000000000000000000000000000001",
|
|
231
|
+
"expires": "2025-01-01T00:00:00.000Z",
|
|
232
|
+
"recipient": "0x742d35Cc6634C0532925a3b844Bc9e7595f8fE00",
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
],
|
|
236
|
+
"httpStatus": 402,
|
|
237
|
+
},
|
|
238
|
+
"message": "Payment Required",
|
|
239
|
+
},
|
|
240
|
+
"id": 1,
|
|
241
|
+
"jsonrpc": "2.0",
|
|
242
|
+
}
|
|
243
|
+
`)
|
|
244
|
+
})
|
|
245
|
+
})
|
|
246
|
+
|
|
247
|
+
describe('respondReceipt', () => {
|
|
248
|
+
test('default', () => {
|
|
249
|
+
const transport = Transport.mcp()
|
|
250
|
+
const successResponse: Mcp.Response = {
|
|
251
|
+
jsonrpc: '2.0',
|
|
252
|
+
id: 1,
|
|
253
|
+
result: { content: [] },
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
expect(
|
|
257
|
+
transport.respondReceipt({ receipt, response: successResponse, challengeId: challenge.id }),
|
|
258
|
+
).toMatchInlineSnapshot(`
|
|
259
|
+
{
|
|
260
|
+
"id": 1,
|
|
261
|
+
"jsonrpc": "2.0",
|
|
262
|
+
"result": {
|
|
263
|
+
"_meta": {
|
|
264
|
+
"org.paymentauth/receipt": {
|
|
265
|
+
"challengeId": "jIuTUdphF_TyhJ-NT1lK2r5YzPXw4tuELfslOVa3nls",
|
|
266
|
+
"method": "tempo",
|
|
267
|
+
"reference": "0xtxhash",
|
|
268
|
+
"status": "success",
|
|
269
|
+
"timestamp": "2025-01-01T00:00:00.000Z",
|
|
270
|
+
},
|
|
271
|
+
},
|
|
272
|
+
"content": [],
|
|
273
|
+
},
|
|
274
|
+
}
|
|
275
|
+
`)
|
|
276
|
+
})
|
|
277
|
+
|
|
278
|
+
test('returns error response unchanged', () => {
|
|
279
|
+
const transport = Transport.mcp()
|
|
280
|
+
const errorResponse: Mcp.Response = {
|
|
281
|
+
jsonrpc: '2.0',
|
|
282
|
+
id: 1,
|
|
283
|
+
error: {
|
|
284
|
+
code: -32600,
|
|
285
|
+
message: 'Invalid Request',
|
|
286
|
+
},
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
expect(
|
|
290
|
+
transport.respondReceipt({ receipt, response: errorResponse, challengeId: challenge.id }),
|
|
291
|
+
).toBe(errorResponse)
|
|
292
|
+
})
|
|
293
|
+
})
|
|
294
|
+
})
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import * as Challenge from '../Challenge.js'
|
|
2
|
+
import * as Credential from '../Credential.js'
|
|
3
|
+
import * as Errors from '../Errors.js'
|
|
4
|
+
import type { Distribute, UnionToIntersection } from '../internal/types.js'
|
|
5
|
+
import * as core_Mcp from '../Mcp.js'
|
|
6
|
+
import * as Receipt from '../Receipt.js'
|
|
7
|
+
|
|
8
|
+
export { type McpSdk, mcpSdk } from '../mcp-sdk/server/Transport.js'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Server-side transport adapter.
|
|
12
|
+
*
|
|
13
|
+
* Abstracts how challenges are issued and credentials are received
|
|
14
|
+
* across different transport protocols (HTTP, MCP, etc.).
|
|
15
|
+
*/
|
|
16
|
+
export type Transport<
|
|
17
|
+
in out input = unknown,
|
|
18
|
+
in out challengeOutput = unknown,
|
|
19
|
+
in receiptResponse = challengeOutput,
|
|
20
|
+
out receiptOutput = receiptResponse,
|
|
21
|
+
> = {
|
|
22
|
+
/** Transport name for identification. */
|
|
23
|
+
name: string
|
|
24
|
+
/**
|
|
25
|
+
* Extracts credential from the transport input.
|
|
26
|
+
* Returns `null` if no credential was provided, or throws if malformed.
|
|
27
|
+
*/
|
|
28
|
+
getCredential: (input: input) => Credential.Credential | null
|
|
29
|
+
/** Creates a transport response for a payment challenge. */
|
|
30
|
+
respondChallenge: (options: {
|
|
31
|
+
challenge: Challenge.Challenge
|
|
32
|
+
error?: Errors.PaymentError | undefined
|
|
33
|
+
input: input
|
|
34
|
+
}) => challengeOutput | Promise<challengeOutput>
|
|
35
|
+
/** Attaches a receipt to a successful response. */
|
|
36
|
+
respondReceipt: (options: {
|
|
37
|
+
challengeId: string
|
|
38
|
+
receipt: Receipt.Receipt
|
|
39
|
+
response: receiptResponse
|
|
40
|
+
}) => receiptOutput
|
|
41
|
+
}
|
|
42
|
+
export type AnyTransport = Transport<any, any, any, any>
|
|
43
|
+
|
|
44
|
+
export type Http = Transport<Request, Response>
|
|
45
|
+
|
|
46
|
+
export type Mcp = Transport<core_Mcp.JsonRpcRequest, core_Mcp.Response>
|
|
47
|
+
|
|
48
|
+
export type Sse<stream = any> = Transport<
|
|
49
|
+
Request,
|
|
50
|
+
Response,
|
|
51
|
+
Response | AsyncIterable<string> | ((stream: stream) => AsyncIterable<string>),
|
|
52
|
+
Response
|
|
53
|
+
>
|
|
54
|
+
|
|
55
|
+
/** Extracts the input type from a transport. */
|
|
56
|
+
export type InputOf<transport extends AnyTransport = AnyTransport> =
|
|
57
|
+
transport extends Transport<infer input, any, any> ? input : never
|
|
58
|
+
|
|
59
|
+
/** Extracts the challenge output type from a transport. */
|
|
60
|
+
export type ChallengeOutputOf<transport extends AnyTransport = AnyTransport> =
|
|
61
|
+
transport extends Transport<any, infer challengeOutput, any> ? challengeOutput : never
|
|
62
|
+
|
|
63
|
+
/** Extracts the receipt output type from a transport. */
|
|
64
|
+
export type ReceiptResponseOf<transport extends AnyTransport = AnyTransport> =
|
|
65
|
+
transport extends Transport<any, any, infer response, any> ? response : never
|
|
66
|
+
|
|
67
|
+
/** Extracts the resolved receipt type (return type of respondReceipt). */
|
|
68
|
+
export type ReceiptOutputOf<transport extends AnyTransport = AnyTransport> =
|
|
69
|
+
transport extends Transport<any, any, any, infer output> ? output : never
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The `withReceipt` overload set for a given transport.
|
|
73
|
+
*
|
|
74
|
+
* Produces one overload per union member of `ReceiptOutputOf<transport>`,
|
|
75
|
+
* so TypeScript can contextually type generator function parameters.
|
|
76
|
+
*/
|
|
77
|
+
export type WithReceipt<transport extends AnyTransport = Http> = WithReceiptOverloads<transport>
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Creates a custom server-side transport.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```ts
|
|
84
|
+
* import { Transport } from 'mppx/server'
|
|
85
|
+
*
|
|
86
|
+
* const custom = Transport.from({
|
|
87
|
+
* name: 'custom',
|
|
88
|
+
* getCredential(input) { ... },
|
|
89
|
+
* respondChallenge({ challenge, input }) { ... },
|
|
90
|
+
* respondReceipt({ receipt, response, challengeId }) { ... },
|
|
91
|
+
* })
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
export function from<
|
|
95
|
+
input = unknown,
|
|
96
|
+
challengeOutput = unknown,
|
|
97
|
+
receiptOutput = challengeOutput,
|
|
98
|
+
receiptResolved = receiptOutput,
|
|
99
|
+
>(
|
|
100
|
+
transport: Transport<input, challengeOutput, receiptOutput, receiptResolved>,
|
|
101
|
+
): Transport<input, challengeOutput, receiptOutput, receiptResolved> {
|
|
102
|
+
return transport
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* HTTP transport for server-side payment handling.
|
|
107
|
+
*
|
|
108
|
+
* - Reads credentials from the `Authorization` header
|
|
109
|
+
* - Issues challenges via `WWW-Authenticate` header with 402 status
|
|
110
|
+
* - Attaches receipts via `Payment-Receipt` header
|
|
111
|
+
*/
|
|
112
|
+
export function http(): Http {
|
|
113
|
+
return from<Request, Response>({
|
|
114
|
+
name: 'http',
|
|
115
|
+
|
|
116
|
+
getCredential(request) {
|
|
117
|
+
const header = request.headers.get('Authorization')
|
|
118
|
+
if (!header) return null
|
|
119
|
+
const payment = Credential.extractPaymentScheme(header)
|
|
120
|
+
if (!payment) return null
|
|
121
|
+
return Credential.deserialize(payment)
|
|
122
|
+
},
|
|
123
|
+
|
|
124
|
+
respondChallenge({ challenge, error }) {
|
|
125
|
+
const headers: Record<string, string> = {
|
|
126
|
+
'WWW-Authenticate': Challenge.serialize(challenge),
|
|
127
|
+
'Cache-Control': 'no-store',
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
let body: string | null = null
|
|
131
|
+
if (error) {
|
|
132
|
+
headers['Content-Type'] = 'application/problem+json'
|
|
133
|
+
body = JSON.stringify(error.toProblemDetails(challenge.id))
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return new Response(body, { status: error?.status ?? 402, headers })
|
|
137
|
+
},
|
|
138
|
+
|
|
139
|
+
respondReceipt({ receipt, response }) {
|
|
140
|
+
const headers = new Headers(response.headers)
|
|
141
|
+
headers.set('Payment-Receipt', Receipt.serialize(receipt))
|
|
142
|
+
return new Response(response.body, {
|
|
143
|
+
status: response.status,
|
|
144
|
+
statusText: response.statusText,
|
|
145
|
+
headers,
|
|
146
|
+
})
|
|
147
|
+
},
|
|
148
|
+
})
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* MCP transport for server-side payment handling with raw JSON-RPC.
|
|
153
|
+
*
|
|
154
|
+
* - Reads credentials from `_meta["org.paymentauth/credential"]`
|
|
155
|
+
* - Issues challenges via JSON-RPC error with code -32042/-32043
|
|
156
|
+
* - Attaches receipts via `_meta["org.paymentauth/receipt"]`
|
|
157
|
+
*
|
|
158
|
+
* Use this transport when handling raw JSON-RPC messages directly.
|
|
159
|
+
* For use with `@modelcontextprotocol/sdk`, use `mcpSdk()` instead.
|
|
160
|
+
*/
|
|
161
|
+
export function mcp() {
|
|
162
|
+
return from<core_Mcp.JsonRpcRequest, core_Mcp.Response>({
|
|
163
|
+
name: 'mcp',
|
|
164
|
+
|
|
165
|
+
getCredential(request) {
|
|
166
|
+
const meta = request.params?._meta
|
|
167
|
+
const credential = meta?.[core_Mcp.credentialMetaKey]
|
|
168
|
+
if (!credential) return null
|
|
169
|
+
return credential
|
|
170
|
+
},
|
|
171
|
+
|
|
172
|
+
respondChallenge({ challenge, input, error }) {
|
|
173
|
+
return {
|
|
174
|
+
jsonrpc: '2.0',
|
|
175
|
+
id: input.id,
|
|
176
|
+
error: {
|
|
177
|
+
code: mcpErrorCode(error),
|
|
178
|
+
message: error?.message ?? 'Payment Required',
|
|
179
|
+
data: {
|
|
180
|
+
httpStatus: error?.status ?? 402,
|
|
181
|
+
challenges: [challenge],
|
|
182
|
+
...(error && { problem: error.toProblemDetails(challenge.id) }),
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
|
|
188
|
+
respondReceipt({ receipt, response, challengeId }) {
|
|
189
|
+
if ('error' in response) return response
|
|
190
|
+
|
|
191
|
+
const mcpReceipt: core_Mcp.Receipt = {
|
|
192
|
+
...receipt,
|
|
193
|
+
challengeId,
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return {
|
|
197
|
+
...response,
|
|
198
|
+
result: {
|
|
199
|
+
...response.result,
|
|
200
|
+
_meta: {
|
|
201
|
+
...response.result._meta,
|
|
202
|
+
[core_Mcp.receiptMetaKey]: mcpReceipt,
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
})
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/** @internal */
|
|
211
|
+
function mcpErrorCode(error?: Errors.PaymentError): number {
|
|
212
|
+
if (!error) return core_Mcp.paymentRequiredCode
|
|
213
|
+
if (error instanceof Errors.MalformedCredentialError) return -32602
|
|
214
|
+
if (error instanceof Errors.PaymentRequiredError) return core_Mcp.paymentRequiredCode
|
|
215
|
+
return core_Mcp.paymentVerificationFailedCode
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/** @internal Distributes over the receipt response union to create overloads. */
|
|
219
|
+
type WithReceiptOverloads<transport extends AnyTransport = Http> = {
|
|
220
|
+
// biome-ignore lint/style/useShorthandFunctionType: _
|
|
221
|
+
(): ReceiptOutputOf<transport>
|
|
222
|
+
} & UnionToIntersection<Distribute<ReceiptResponseOf<transport>, ReceiptOutputOf<transport>>>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * as Expires from '../Expires.js'
|
|
2
|
+
export * as Store from '../Store.js'
|
|
3
|
+
export { stripe, tempo } from './Methods.js'
|
|
4
|
+
export * as Mppx from './Mppx.js'
|
|
5
|
+
export * as NodeListener from './NodeListener.js'
|
|
6
|
+
export * as Request from './Request.js'
|
|
7
|
+
export * as Response from './Response.js'
|
|
8
|
+
export * as Transport from './Transport.js'
|