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,388 @@
|
|
|
1
|
+
import type * as Challenge from './Challenge.js'
|
|
2
|
+
import type * as Credential from './Credential.js'
|
|
3
|
+
import * as Intent from './Intent.js'
|
|
4
|
+
import type { ExactPartial, LooseOmit, MaybePromise } from './internal/types.js'
|
|
5
|
+
import type * as Receipt from './Receipt.js'
|
|
6
|
+
import type * as Transport from './server/Transport.js'
|
|
7
|
+
import * as z from './zod.js'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* A payment method-specific intent.
|
|
11
|
+
*/
|
|
12
|
+
export type MethodIntent<
|
|
13
|
+
intent extends Intent.Intent = Intent.Intent,
|
|
14
|
+
options extends fromIntent.Options<intent> = fromIntent.Options<intent>,
|
|
15
|
+
> = {
|
|
16
|
+
method: options['method']
|
|
17
|
+
name: intent['name']
|
|
18
|
+
schema: {
|
|
19
|
+
credential: {
|
|
20
|
+
payload: options['schema']['credential']['payload']
|
|
21
|
+
}
|
|
22
|
+
request: MergedRequestSchema<intent, options>
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export type AnyMethodIntent = MethodIntent<any, any>
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Creates a method-specific intent.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* import { z } from 'zod/mini'
|
|
33
|
+
* import { MethodIntent } from 'mppx'
|
|
34
|
+
*
|
|
35
|
+
* const tempoCharge = MethodIntent.from({
|
|
36
|
+
* method: 'tempo',
|
|
37
|
+
* name: 'charge',
|
|
38
|
+
* schema: {
|
|
39
|
+
* credential: {
|
|
40
|
+
* payload: z.object({
|
|
41
|
+
* signature: z.string(),
|
|
42
|
+
* type: z.literal('transaction'),
|
|
43
|
+
* }),
|
|
44
|
+
* },
|
|
45
|
+
* request: z.object({
|
|
46
|
+
* amount: z.string(),
|
|
47
|
+
* currency: z.string(),
|
|
48
|
+
* recipient: z.string(),
|
|
49
|
+
* }),
|
|
50
|
+
* },
|
|
51
|
+
* })
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export function from<const intent extends MethodIntent>(intent: intent): intent {
|
|
55
|
+
return intent
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Creates a method-specific intent from a base intent.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* import { z } from 'zod/mini'
|
|
64
|
+
* import { Intent, MethodIntent } from 'mppx'
|
|
65
|
+
*
|
|
66
|
+
* const tempoCharge = MethodIntent.fromIntent(Intent.charge, {
|
|
67
|
+
* method: 'tempo',
|
|
68
|
+
* schema: {
|
|
69
|
+
* credential: {
|
|
70
|
+
* payload: z.object({
|
|
71
|
+
* signature: z.string(),
|
|
72
|
+
* type: z.literal('transaction'),
|
|
73
|
+
* }),
|
|
74
|
+
* },
|
|
75
|
+
* request: {
|
|
76
|
+
* methodDetails: z.object({
|
|
77
|
+
* chainId: z.number(),
|
|
78
|
+
* }),
|
|
79
|
+
* requires: ['recipient'],
|
|
80
|
+
* },
|
|
81
|
+
* },
|
|
82
|
+
* })
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export function fromIntent<
|
|
86
|
+
const intent extends Intent.Intent,
|
|
87
|
+
const options extends fromIntent.Options<intent>,
|
|
88
|
+
>(intent: intent, options: options): MethodIntent<intent, options> {
|
|
89
|
+
const { name } = intent
|
|
90
|
+
const { method, schema } = options
|
|
91
|
+
|
|
92
|
+
const requestShape = Intent.shapeOf(intent) as Record<string, z.ZodMiniType>
|
|
93
|
+
|
|
94
|
+
const methodDetails = schema.request?.methodDetails
|
|
95
|
+
const requires = schema.request?.requires ?? []
|
|
96
|
+
|
|
97
|
+
const requestInputShape: Record<string, z.ZodMiniType> = {}
|
|
98
|
+
for (const [key, field] of Object.entries(requestShape)) {
|
|
99
|
+
if (requires.includes(key as never)) requestInputShape[key] = z.unwrapOptional(field)
|
|
100
|
+
else requestInputShape[key] = field
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const methodDetailsKeys: string[] = []
|
|
104
|
+
if (methodDetails)
|
|
105
|
+
for (const [key, field] of Object.entries(
|
|
106
|
+
methodDetails.shape as Record<string, z.ZodMiniType>,
|
|
107
|
+
)) {
|
|
108
|
+
requestInputShape[key] = field
|
|
109
|
+
methodDetailsKeys.push(key)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const intentRequest = intent.schema.request
|
|
113
|
+
const hasPipe = !('shape' in intentRequest)
|
|
114
|
+
|
|
115
|
+
const request = z.pipe(
|
|
116
|
+
z.object(requestInputShape),
|
|
117
|
+
z.transform((input: Record<string, unknown>) => {
|
|
118
|
+
const transformed = hasPipe ? (intentRequest as z.ZodMiniType).parse(input) : input
|
|
119
|
+
|
|
120
|
+
const result: Record<string, unknown> = {}
|
|
121
|
+
const details: Record<string, unknown> = {}
|
|
122
|
+
|
|
123
|
+
for (const [key, value] of Object.entries(transformed as Record<string, unknown>)) {
|
|
124
|
+
result[key] = value
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
for (const key of methodDetailsKeys) {
|
|
128
|
+
const value = input[key]
|
|
129
|
+
if (value !== undefined) details[key] = value
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (Object.keys(details).length > 0) result.methodDetails = details
|
|
133
|
+
return result
|
|
134
|
+
}),
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
return {
|
|
138
|
+
method,
|
|
139
|
+
name,
|
|
140
|
+
schema: {
|
|
141
|
+
credential: { payload: schema.credential.payload },
|
|
142
|
+
request,
|
|
143
|
+
},
|
|
144
|
+
} as unknown as MethodIntent<intent, options>
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export namespace fromIntent {
|
|
148
|
+
export type Options<intent extends Intent.Intent> = {
|
|
149
|
+
method: string
|
|
150
|
+
schema: {
|
|
151
|
+
credential: { payload: z.ZodMiniType }
|
|
152
|
+
request?:
|
|
153
|
+
| {
|
|
154
|
+
methodDetails?: z.ZodMiniObject | undefined
|
|
155
|
+
requires?: readonly (keyof Intent.ShapeOf<intent>)[] | undefined
|
|
156
|
+
}
|
|
157
|
+
| undefined
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/** @internal */
|
|
163
|
+
type RequiresKeys<
|
|
164
|
+
intent extends Intent.Intent,
|
|
165
|
+
options extends fromIntent.Options<intent>,
|
|
166
|
+
> = options['schema']['request'] extends { requires: readonly (infer key)[] } ? key : never
|
|
167
|
+
|
|
168
|
+
/** @internal */
|
|
169
|
+
type UnwrapOptional<schema> = schema extends z.ZodMiniOptional<infer inner> ? inner : schema
|
|
170
|
+
|
|
171
|
+
/** @internal */
|
|
172
|
+
type MethodDetailsShape<
|
|
173
|
+
intent extends Intent.Intent,
|
|
174
|
+
options extends fromIntent.Options<intent>,
|
|
175
|
+
> = options['schema']['request'] extends { methodDetails: infer details extends z.ZodMiniObject }
|
|
176
|
+
? details['shape']
|
|
177
|
+
: Record<never, never>
|
|
178
|
+
|
|
179
|
+
/** @internal */
|
|
180
|
+
type InputRequestShape<intent extends Intent.Intent, options extends fromIntent.Options<intent>> = {
|
|
181
|
+
[K in keyof Intent.ShapeOf<intent>]: K extends RequiresKeys<intent, options>
|
|
182
|
+
? UnwrapOptional<Intent.ShapeOf<intent>[K]>
|
|
183
|
+
: Intent.ShapeOf<intent>[K]
|
|
184
|
+
} & MethodDetailsShape<intent, options>
|
|
185
|
+
|
|
186
|
+
/** @internal */
|
|
187
|
+
type MethodDetailsOutput<
|
|
188
|
+
intent extends Intent.Intent,
|
|
189
|
+
options extends fromIntent.Options<intent>,
|
|
190
|
+
> = options['schema']['request'] extends { methodDetails: infer details extends z.ZodMiniObject }
|
|
191
|
+
? { methodDetails?: z.output<details> }
|
|
192
|
+
: Record<never, never>
|
|
193
|
+
|
|
194
|
+
/** @internal */
|
|
195
|
+
type OutputRequestType<intent extends Intent.Intent, options extends fromIntent.Options<intent>> = {
|
|
196
|
+
[K in keyof Intent.ShapeOf<intent>]: K extends RequiresKeys<intent, options>
|
|
197
|
+
? z.output<UnwrapOptional<Intent.ShapeOf<intent>[K]>>
|
|
198
|
+
: z.output<Intent.ShapeOf<intent>[K]>
|
|
199
|
+
} & MethodDetailsOutput<intent, options>
|
|
200
|
+
|
|
201
|
+
/** @internal */
|
|
202
|
+
type MergedRequestSchema<
|
|
203
|
+
intent extends Intent.Intent,
|
|
204
|
+
options extends fromIntent.Options<intent>,
|
|
205
|
+
> = z.ZodMiniType<
|
|
206
|
+
OutputRequestType<intent, options>,
|
|
207
|
+
z.input<z.ZodMiniObject<InputRequestShape<intent, options>>>
|
|
208
|
+
>
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* A client-side configured method intent with credential creation logic.
|
|
212
|
+
*/
|
|
213
|
+
export type Client<
|
|
214
|
+
intent extends AnyMethodIntent = MethodIntent,
|
|
215
|
+
context extends z.ZodMiniType | undefined = z.ZodMiniType | undefined,
|
|
216
|
+
> = intent & {
|
|
217
|
+
context?: context
|
|
218
|
+
createCredential: CreateCredentialFn<
|
|
219
|
+
intent,
|
|
220
|
+
context extends z.ZodMiniType ? z.output<context> : Record<never, never>
|
|
221
|
+
>
|
|
222
|
+
}
|
|
223
|
+
export type AnyClient = Client<any, any>
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* A server-side configured method intent with verification logic.
|
|
227
|
+
*/
|
|
228
|
+
export type Server<
|
|
229
|
+
intent extends AnyMethodIntent = MethodIntent,
|
|
230
|
+
defaults extends ExactPartial<z.input<intent['schema']['request']>> = {},
|
|
231
|
+
transportOverride = undefined,
|
|
232
|
+
> = intent & {
|
|
233
|
+
defaults?: defaults | undefined
|
|
234
|
+
request?: RequestFn<intent> | undefined
|
|
235
|
+
respond?: RespondFn<intent> | undefined
|
|
236
|
+
transport?: transportOverride | undefined
|
|
237
|
+
verify: VerifyFn<intent>
|
|
238
|
+
}
|
|
239
|
+
export type AnyServer = Server<any, any, any>
|
|
240
|
+
|
|
241
|
+
/** Credential creation function for a single intent. */
|
|
242
|
+
export type CreateCredentialFn<intent extends AnyMethodIntent, context = unknown> = (
|
|
243
|
+
parameters: {
|
|
244
|
+
challenge: Challenge.Challenge<
|
|
245
|
+
z.output<intent['schema']['request']>,
|
|
246
|
+
intent['name'],
|
|
247
|
+
intent['method']
|
|
248
|
+
>
|
|
249
|
+
} & ([keyof context] extends [never] ? unknown : { context: context }),
|
|
250
|
+
) => Promise<string>
|
|
251
|
+
|
|
252
|
+
/** Request transform function for a single intent. */
|
|
253
|
+
export type RequestFn<intent extends AnyMethodIntent> = (options: {
|
|
254
|
+
credential?: Credential.Credential | null | undefined
|
|
255
|
+
request: z.input<intent['schema']['request']>
|
|
256
|
+
}) => MaybePromise<z.input<intent['schema']['request']>>
|
|
257
|
+
|
|
258
|
+
/** Verification function for a single intent. */
|
|
259
|
+
export type VerifyFn<intent extends AnyMethodIntent> = (parameters: {
|
|
260
|
+
credential: Credential.Credential<
|
|
261
|
+
z.output<intent['schema']['credential']['payload']>,
|
|
262
|
+
Challenge.Challenge<z.output<intent['schema']['request']>, intent['name'], intent['method']>
|
|
263
|
+
>
|
|
264
|
+
request: z.input<intent['schema']['request']>
|
|
265
|
+
}) => Promise<Receipt.Receipt>
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Optional respond function for a server-side method intent.
|
|
269
|
+
*
|
|
270
|
+
* Called after `verify` succeeds. If it returns a `Response`, the library
|
|
271
|
+
* treats the request as fully handled (e.g. channel open/close) and
|
|
272
|
+
* `withReceipt()` will short-circuit — returning the management response
|
|
273
|
+
* with the receipt header attached without invoking any user-supplied
|
|
274
|
+
* response or generator. If it returns `undefined`, the server handler
|
|
275
|
+
* is expected to serve content via `withReceipt(response)`.
|
|
276
|
+
*
|
|
277
|
+
* **HTTP-only.** The `input` parameter is a `Request` object; MCP transports
|
|
278
|
+
* do not invoke this hook.
|
|
279
|
+
*/
|
|
280
|
+
export type RespondFn<intent extends AnyMethodIntent> = (parameters: {
|
|
281
|
+
credential: Credential.Credential<
|
|
282
|
+
z.output<intent['schema']['credential']['payload']>,
|
|
283
|
+
Challenge.Challenge<z.output<intent['schema']['request']>, intent['name'], intent['method']>
|
|
284
|
+
>
|
|
285
|
+
input: globalThis.Request
|
|
286
|
+
receipt: Receipt.Receipt
|
|
287
|
+
request: z.input<intent['schema']['request']>
|
|
288
|
+
}) => MaybePromise<globalThis.Response | undefined>
|
|
289
|
+
|
|
290
|
+
/** Partial request type for defaults. */
|
|
291
|
+
export type RequestDefaults<intent extends AnyMethodIntent> = ExactPartial<
|
|
292
|
+
z.input<intent['schema']['request']>
|
|
293
|
+
>
|
|
294
|
+
|
|
295
|
+
/** Makes fields optional if they exist in defaults. */
|
|
296
|
+
export type WithDefaults<request, defaults> = [keyof defaults] extends [never]
|
|
297
|
+
? request
|
|
298
|
+
: LooseOmit<request, keyof defaults & string> &
|
|
299
|
+
ExactPartial<Pick<request, keyof defaults & keyof request>>
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Extends a method intent with client-side credential creation logic.
|
|
303
|
+
*
|
|
304
|
+
* @example
|
|
305
|
+
* ```ts
|
|
306
|
+
* import { MethodIntent } from 'mppx'
|
|
307
|
+
* import { Intents } from 'mppx/tempo'
|
|
308
|
+
*
|
|
309
|
+
* const tempoCharge = MethodIntent.toClient(Intents.charge, {
|
|
310
|
+
* async createCredential({ challenge }) {
|
|
311
|
+
* return Credential.serialize({ challenge, payload: { ... } })
|
|
312
|
+
* },
|
|
313
|
+
* })
|
|
314
|
+
* ```
|
|
315
|
+
*/
|
|
316
|
+
export function toClient<
|
|
317
|
+
const intent extends AnyMethodIntent,
|
|
318
|
+
const context extends z.ZodMiniType | undefined = undefined,
|
|
319
|
+
>(intent: intent, options: toClient.Options<intent, context>): Client<intent, context> {
|
|
320
|
+
const { context, createCredential } = options
|
|
321
|
+
return {
|
|
322
|
+
...intent,
|
|
323
|
+
context,
|
|
324
|
+
createCredential,
|
|
325
|
+
} as Client<intent, context>
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
export declare namespace toClient {
|
|
329
|
+
type Options<
|
|
330
|
+
intent extends AnyMethodIntent,
|
|
331
|
+
context extends z.ZodMiniType | undefined = undefined,
|
|
332
|
+
> = {
|
|
333
|
+
context?: context
|
|
334
|
+
createCredential: CreateCredentialFn<
|
|
335
|
+
intent,
|
|
336
|
+
context extends z.ZodMiniType ? z.output<context> : Record<never, never>
|
|
337
|
+
>
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Extends a method intent with server-side verification logic.
|
|
343
|
+
*
|
|
344
|
+
* @example
|
|
345
|
+
* ```ts
|
|
346
|
+
* import { MethodIntent } from 'mppx'
|
|
347
|
+
* import { Intents } from 'mppx/tempo'
|
|
348
|
+
*
|
|
349
|
+
* const tempoCharge = MethodIntent.toServer(Intents.charge, {
|
|
350
|
+
* async verify({ credential }) {
|
|
351
|
+
* // verification logic
|
|
352
|
+
* return { status: 'success', ... }
|
|
353
|
+
* },
|
|
354
|
+
* })
|
|
355
|
+
* ```
|
|
356
|
+
*/
|
|
357
|
+
export function toServer<
|
|
358
|
+
const intent extends AnyMethodIntent,
|
|
359
|
+
const defaults extends RequestDefaults<intent> = {},
|
|
360
|
+
const transportOverride extends Transport.AnyTransport | undefined = undefined,
|
|
361
|
+
>(
|
|
362
|
+
intent: intent,
|
|
363
|
+
options: toServer.Options<intent, defaults, transportOverride>,
|
|
364
|
+
): Server<intent, defaults, transportOverride> {
|
|
365
|
+
const { defaults, request, respond, transport, verify } = options
|
|
366
|
+
return {
|
|
367
|
+
...intent,
|
|
368
|
+
defaults,
|
|
369
|
+
request,
|
|
370
|
+
respond,
|
|
371
|
+
transport,
|
|
372
|
+
verify,
|
|
373
|
+
} as Server<intent, defaults, transportOverride>
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
export declare namespace toServer {
|
|
377
|
+
type Options<
|
|
378
|
+
intent extends AnyMethodIntent,
|
|
379
|
+
defaults extends RequestDefaults<intent> = {},
|
|
380
|
+
transportOverride extends Transport.AnyTransport | undefined = undefined,
|
|
381
|
+
> = {
|
|
382
|
+
defaults?: defaults | undefined
|
|
383
|
+
request?: RequestFn<intent> | undefined
|
|
384
|
+
respond?: RespondFn<intent> | undefined
|
|
385
|
+
transport?: transportOverride | undefined
|
|
386
|
+
verify: VerifyFn<intent>
|
|
387
|
+
}
|
|
388
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { PaymentRequest } from 'mppx'
|
|
2
|
+
import { MethodIntents as Intents } from 'mppx/tempo'
|
|
3
|
+
import { describe, expect, test } from 'vitest'
|
|
4
|
+
|
|
5
|
+
describe('from', () => {
|
|
6
|
+
test('creates a request', () => {
|
|
7
|
+
const request = PaymentRequest.from({
|
|
8
|
+
amount: '1000000',
|
|
9
|
+
currency: 'USD',
|
|
10
|
+
recipient: '0x1234',
|
|
11
|
+
})
|
|
12
|
+
expect(request).toMatchInlineSnapshot(`
|
|
13
|
+
{
|
|
14
|
+
"amount": "1000000",
|
|
15
|
+
"currency": "USD",
|
|
16
|
+
"recipient": "0x1234",
|
|
17
|
+
}
|
|
18
|
+
`)
|
|
19
|
+
})
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
describe('fromIntent', () => {
|
|
23
|
+
test('creates a validated request from intent', () => {
|
|
24
|
+
const request = PaymentRequest.fromIntent(Intents.charge, {
|
|
25
|
+
amount: '1',
|
|
26
|
+
currency: '0x20c0000000000000000000000000000000000001',
|
|
27
|
+
decimals: 6,
|
|
28
|
+
recipient: '0x742d35Cc6634C0532925a3b844Bc9e7595f8fE00',
|
|
29
|
+
expires: '2025-01-06T12:00:00Z',
|
|
30
|
+
})
|
|
31
|
+
expect(request).toMatchInlineSnapshot(`
|
|
32
|
+
{
|
|
33
|
+
"amount": "1000000",
|
|
34
|
+
"currency": "0x20c0000000000000000000000000000000000001",
|
|
35
|
+
"expires": "2025-01-06T12:00:00Z",
|
|
36
|
+
"recipient": "0x742d35Cc6634C0532925a3b844Bc9e7595f8fE00",
|
|
37
|
+
}
|
|
38
|
+
`)
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
test('includes methodDetails fields', () => {
|
|
42
|
+
const request = PaymentRequest.fromIntent(Intents.charge, {
|
|
43
|
+
amount: '1',
|
|
44
|
+
currency: '0x20c0000000000000000000000000000000000001',
|
|
45
|
+
decimals: 6,
|
|
46
|
+
recipient: '0x742d35Cc6634C0532925a3b844Bc9e7595f8fE00',
|
|
47
|
+
expires: '2025-01-06T12:00:00Z',
|
|
48
|
+
chainId: 42431,
|
|
49
|
+
})
|
|
50
|
+
expect(request).toMatchInlineSnapshot(`
|
|
51
|
+
{
|
|
52
|
+
"amount": "1000000",
|
|
53
|
+
"currency": "0x20c0000000000000000000000000000000000001",
|
|
54
|
+
"expires": "2025-01-06T12:00:00Z",
|
|
55
|
+
"methodDetails": {
|
|
56
|
+
"chainId": 42431,
|
|
57
|
+
},
|
|
58
|
+
"recipient": "0x742d35Cc6634C0532925a3b844Bc9e7595f8fE00",
|
|
59
|
+
}
|
|
60
|
+
`)
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
test('throws on invalid request', () => {
|
|
64
|
+
expect(() =>
|
|
65
|
+
PaymentRequest.fromIntent(Intents.charge, {
|
|
66
|
+
amount: 123,
|
|
67
|
+
currency: '0x20c0000000000000000000000000000000000001',
|
|
68
|
+
recipient: '0x742d35Cc6634C0532925a3b844Bc9e7595f8fE00',
|
|
69
|
+
expires: '2025-01-06T12:00:00Z',
|
|
70
|
+
} as any),
|
|
71
|
+
).toThrowErrorMatchingInlineSnapshot(`
|
|
72
|
+
[$ZodError: [
|
|
73
|
+
{
|
|
74
|
+
"expected": "string",
|
|
75
|
+
"code": "invalid_type",
|
|
76
|
+
"path": [
|
|
77
|
+
"amount"
|
|
78
|
+
],
|
|
79
|
+
"message": "Invalid input"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"expected": "number",
|
|
83
|
+
"code": "invalid_type",
|
|
84
|
+
"path": [
|
|
85
|
+
"decimals"
|
|
86
|
+
],
|
|
87
|
+
"message": "Invalid input"
|
|
88
|
+
}
|
|
89
|
+
]]
|
|
90
|
+
`)
|
|
91
|
+
})
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
describe('serialize', () => {
|
|
95
|
+
test('serializes request to base64url', () => {
|
|
96
|
+
const request = PaymentRequest.from({
|
|
97
|
+
amount: '1000000',
|
|
98
|
+
currency: 'USD',
|
|
99
|
+
})
|
|
100
|
+
const serialized = PaymentRequest.serialize(request)
|
|
101
|
+
expect(serialized).toMatch(/^[A-Za-z0-9_-]+$/)
|
|
102
|
+
expect(serialized).not.toContain('=')
|
|
103
|
+
expect(serialized).not.toContain('+')
|
|
104
|
+
expect(serialized).not.toContain('/')
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
test('roundtrips correctly', () => {
|
|
108
|
+
const original = PaymentRequest.from({
|
|
109
|
+
amount: '1000000',
|
|
110
|
+
currency: 'USD',
|
|
111
|
+
recipient: '0x742d35Cc6634C0532925a3b844Bc9e7595f8fE00',
|
|
112
|
+
})
|
|
113
|
+
const serialized = PaymentRequest.serialize(original)
|
|
114
|
+
const deserialized = PaymentRequest.deserialize(serialized)
|
|
115
|
+
expect(deserialized).toMatchInlineSnapshot(`
|
|
116
|
+
{
|
|
117
|
+
"amount": "1000000",
|
|
118
|
+
"currency": "USD",
|
|
119
|
+
"recipient": "0x742d35Cc6634C0532925a3b844Bc9e7595f8fE00",
|
|
120
|
+
}
|
|
121
|
+
`)
|
|
122
|
+
})
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
describe('deserialize', () => {
|
|
126
|
+
test('deserializes base64url to request', () => {
|
|
127
|
+
const original = { amount: '500', currency: 'EUR' }
|
|
128
|
+
const serialized = PaymentRequest.serialize(original)
|
|
129
|
+
const result = PaymentRequest.deserialize(serialized)
|
|
130
|
+
expect(result).toMatchInlineSnapshot(`
|
|
131
|
+
{
|
|
132
|
+
"amount": "500",
|
|
133
|
+
"currency": "EUR",
|
|
134
|
+
}
|
|
135
|
+
`)
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
test('handles special characters in values', () => {
|
|
139
|
+
const original = {
|
|
140
|
+
amount: '1000000',
|
|
141
|
+
description: 'Payment for café & más',
|
|
142
|
+
}
|
|
143
|
+
const serialized = PaymentRequest.serialize(original)
|
|
144
|
+
const result = PaymentRequest.deserialize(serialized)
|
|
145
|
+
expect(result).toMatchInlineSnapshot(`
|
|
146
|
+
{
|
|
147
|
+
"amount": "1000000",
|
|
148
|
+
"description": "Payment for café & más",
|
|
149
|
+
}
|
|
150
|
+
`)
|
|
151
|
+
})
|
|
152
|
+
})
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { Base64 } from 'ox'
|
|
2
|
+
import type { Compute } from './internal/types.js'
|
|
3
|
+
import type * as MethodIntent from './MethodIntent.js'
|
|
4
|
+
import type * as z from './zod.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Intent-specific payment parameters.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { Request } from 'mppx'
|
|
12
|
+
*
|
|
13
|
+
* const request: Request.Request = {
|
|
14
|
+
* amount: '1000000',
|
|
15
|
+
* currency: '0x20c0000000000000000000000000000000000001',
|
|
16
|
+
* recipient: '0x742d35Cc6634C0532925a3b844Bc9e7595f8fE00',
|
|
17
|
+
* }
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export type Request<request extends Record<string, unknown> = Record<string, unknown>> =
|
|
21
|
+
Compute<request>
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Deserializes a base64url string to a request.
|
|
25
|
+
*
|
|
26
|
+
* @param encoded - The base64url-encoded string.
|
|
27
|
+
* @returns The deserialized request.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* import { Request } from 'mppx'
|
|
32
|
+
*
|
|
33
|
+
* const request = Request.deserialize(serialized)
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export function deserialize(encoded: string): Request {
|
|
37
|
+
const json = Base64.toString(encoded)
|
|
38
|
+
return JSON.parse(json)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Creates a request from the given parameters.
|
|
43
|
+
*
|
|
44
|
+
* @param request - Request parameters.
|
|
45
|
+
* @returns A request.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```ts
|
|
49
|
+
* import { Request } from 'mppx'
|
|
50
|
+
*
|
|
51
|
+
* const request = Request.from({
|
|
52
|
+
* amount: '1000000',
|
|
53
|
+
* currency: '0x20c0000000000000000000000000000000000001',
|
|
54
|
+
* recipient: '0x742d35Cc6634C0532925a3b844Bc9e7595f8fE00',
|
|
55
|
+
* })
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export function from<const request extends Request>(request: request): request {
|
|
59
|
+
return request
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Creates a validated request from a method intent.
|
|
64
|
+
*
|
|
65
|
+
* @param intent - The method intent to validate against.
|
|
66
|
+
* @param request - Request parameters.
|
|
67
|
+
* @returns A validated request.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```ts
|
|
71
|
+
* import { Request } from 'mppx'
|
|
72
|
+
* import { Intents } from 'mppx/tempo'
|
|
73
|
+
*
|
|
74
|
+
* const request = Request.fromIntent(Intents.charge, {
|
|
75
|
+
* amount: '1000000',
|
|
76
|
+
* currency: '0x20c0000000000000000000000000000000000001',
|
|
77
|
+
* recipient: '0x742d35Cc6634C0532925a3b844Bc9e7595f8fE00',
|
|
78
|
+
* expires: '2025-01-06T12:00:00Z',
|
|
79
|
+
* chainId: 42431,
|
|
80
|
+
* })
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
export function fromIntent<const intent extends MethodIntent.MethodIntent>(
|
|
84
|
+
intent: intent,
|
|
85
|
+
request: z.input<intent['schema']['request']>,
|
|
86
|
+
): Request<z.output<intent['schema']['request']>> {
|
|
87
|
+
return intent.schema.request.parse(request) as Request<z.output<intent['schema']['request']>>
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Serializes a request to a base64url string.
|
|
92
|
+
*
|
|
93
|
+
* @param request - The request to serialize.
|
|
94
|
+
* @returns A base64url-encoded string (no padding).
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```ts
|
|
98
|
+
* import { Request } from 'mppx'
|
|
99
|
+
*
|
|
100
|
+
* const serialized = Request.serialize(request)
|
|
101
|
+
* // => "eyJhbW91bnQiOiIxMDAwMDAwIiwiY3VycmVuY3kiOiIweC4uLiJ9"
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
export function serialize(request: Request): string {
|
|
105
|
+
const json = JSON.stringify(request)
|
|
106
|
+
return Base64.fromString(json, { pad: false, url: true })
|
|
107
|
+
}
|