mppx 0.0.1 → 0.1.1
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 +89 -0
- package/dist/client/Mppx.d.ts.map +1 -0
- package/dist/client/Mppx.js +69 -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 +87 -0
- package/dist/client/internal/Fetch.d.ts.map +1 -0
- package/dist/client/internal/Fetch.js +99 -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 +105 -0
- package/dist/stripe/client/Charge.d.ts.map +1 -0
- package/dist/stripe/client/Charge.js +74 -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 +201 -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 +119 -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 +165 -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 +315 -0
- package/src/client/internal/Fetch.ts +169 -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 +329 -0
- package/src/stripe/Intents.test.ts +52 -0
- package/src/stripe/Intents.ts +27 -0
- package/src/stripe/client/Charge.ts +115 -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 +276 -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 +154 -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,155 @@
|
|
|
1
|
+
import express from 'express'
|
|
2
|
+
import { Receipt } from 'mppx'
|
|
3
|
+
import { Mppx as Mppx_client, session as sessionIntent, tempo as tempo_client } from 'mppx/client'
|
|
4
|
+
import { Mppx } from 'mppx/express'
|
|
5
|
+
import { tempo as tempo_server } from 'mppx/server'
|
|
6
|
+
import type { Address } from 'viem'
|
|
7
|
+
import { Addresses } from 'viem/tempo'
|
|
8
|
+
import { beforeAll, describe, expect, test } from 'vitest'
|
|
9
|
+
import { deployEscrow } from '~test/tempo/stream.js'
|
|
10
|
+
import { accounts, asset, client, fundAccount } from '~test/tempo/viem.js'
|
|
11
|
+
|
|
12
|
+
function createServer(app: express.Express) {
|
|
13
|
+
return new Promise<{ url: string; close: () => void }>((resolve) => {
|
|
14
|
+
const server = app.listen(0, () => {
|
|
15
|
+
const { port } = server.address() as { port: number }
|
|
16
|
+
resolve({
|
|
17
|
+
url: `http://localhost:${port}`,
|
|
18
|
+
close: () => server.close(),
|
|
19
|
+
})
|
|
20
|
+
})
|
|
21
|
+
})
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
describe('charge', () => {
|
|
25
|
+
const mppx = Mppx.create({
|
|
26
|
+
methods: [
|
|
27
|
+
tempo_server({
|
|
28
|
+
getClient: () => client,
|
|
29
|
+
currency: asset,
|
|
30
|
+
recipient: accounts[0].address,
|
|
31
|
+
}),
|
|
32
|
+
],
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
const { fetch } = Mppx_client.create({
|
|
36
|
+
polyfill: false,
|
|
37
|
+
methods: [
|
|
38
|
+
tempo_client({
|
|
39
|
+
account: accounts[1],
|
|
40
|
+
getClient: () => client,
|
|
41
|
+
}),
|
|
42
|
+
],
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
test('returns 402 when no credential', async () => {
|
|
46
|
+
const app = express()
|
|
47
|
+
app.get('/', mppx.charge({ amount: '1' }), (_req, res) => {
|
|
48
|
+
res.json({ fortune: 'You will be rich' })
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
const server = await createServer(app)
|
|
52
|
+
const response = await globalThis.fetch(server.url)
|
|
53
|
+
expect(response.status).toBe(402)
|
|
54
|
+
expect(response.headers.get('WWW-Authenticate')).toContain('Payment')
|
|
55
|
+
|
|
56
|
+
server.close()
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
test('returns 200 with receipt on valid payment', async () => {
|
|
60
|
+
const app = express()
|
|
61
|
+
app.get('/', mppx.charge({ amount: '1' }), (_req, res) => {
|
|
62
|
+
res.json({ fortune: 'You will be rich' })
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
const server = await createServer(app)
|
|
66
|
+
const response = await fetch(server.url)
|
|
67
|
+
expect(response.status).toBe(200)
|
|
68
|
+
|
|
69
|
+
const body = await response.json()
|
|
70
|
+
expect(body).toEqual({ fortune: 'You will be rich' })
|
|
71
|
+
|
|
72
|
+
const receiptHeader = response.headers.get('Payment-Receipt')
|
|
73
|
+
expect(receiptHeader).toBeTruthy()
|
|
74
|
+
|
|
75
|
+
const receipt = Receipt.fromResponse(response)
|
|
76
|
+
expect(receipt.status).toBe('success')
|
|
77
|
+
expect(receipt.method).toBe('tempo')
|
|
78
|
+
|
|
79
|
+
server.close()
|
|
80
|
+
})
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
describe('session', () => {
|
|
84
|
+
let escrowContract: Address
|
|
85
|
+
|
|
86
|
+
beforeAll(async () => {
|
|
87
|
+
escrowContract = await deployEscrow()
|
|
88
|
+
await fundAccount({ address: accounts[2].address, token: Addresses.pathUsd })
|
|
89
|
+
await fundAccount({ address: accounts[2].address, token: asset })
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
test('returns 402 when no credential', async () => {
|
|
93
|
+
const mppx = Mppx.create({
|
|
94
|
+
methods: [
|
|
95
|
+
tempo_server.session({
|
|
96
|
+
getClient: () => client,
|
|
97
|
+
recipient: accounts[0].address,
|
|
98
|
+
currency: asset,
|
|
99
|
+
escrowContract,
|
|
100
|
+
}),
|
|
101
|
+
],
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
const app = express()
|
|
105
|
+
app.get('/', mppx.session({ amount: '1', unitType: 'token' }), (_req, res) => {
|
|
106
|
+
res.json({ data: 'streamed' })
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
const server = await createServer(app)
|
|
110
|
+
const response = await globalThis.fetch(server.url)
|
|
111
|
+
expect(response.status).toBe(402)
|
|
112
|
+
expect(response.headers.get('WWW-Authenticate')).toContain('Payment')
|
|
113
|
+
|
|
114
|
+
server.close()
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
test('returns 200 with receipt on valid payment', async () => {
|
|
118
|
+
const mppx = Mppx.create({
|
|
119
|
+
methods: [
|
|
120
|
+
tempo_server.session({
|
|
121
|
+
getClient: () => client,
|
|
122
|
+
recipient: accounts[0].address,
|
|
123
|
+
currency: asset,
|
|
124
|
+
escrowContract,
|
|
125
|
+
feePayer: accounts[0],
|
|
126
|
+
}),
|
|
127
|
+
],
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
const { fetch } = Mppx_client.create({
|
|
131
|
+
polyfill: false,
|
|
132
|
+
methods: [
|
|
133
|
+
sessionIntent({
|
|
134
|
+
account: accounts[2],
|
|
135
|
+
deposit: '10',
|
|
136
|
+
getClient: () => client,
|
|
137
|
+
}),
|
|
138
|
+
],
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
const app = express()
|
|
142
|
+
app.get('/', mppx.session({ amount: '1', unitType: 'token' }), (_req, res) => {
|
|
143
|
+
res.json({ data: 'streamed' })
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
const server = await createServer(app)
|
|
147
|
+
const response = await fetch(server.url)
|
|
148
|
+
expect(response.status).toBe(200)
|
|
149
|
+
|
|
150
|
+
const body = await response.json()
|
|
151
|
+
expect(body).toEqual({ data: 'streamed' })
|
|
152
|
+
|
|
153
|
+
server.close()
|
|
154
|
+
})
|
|
155
|
+
})
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Request as ExpressRequest,
|
|
3
|
+
Response as ExpressResponse,
|
|
4
|
+
NextFunction,
|
|
5
|
+
RequestHandler,
|
|
6
|
+
} from 'express'
|
|
7
|
+
import * as Mppx_core from '../server/Mppx.js'
|
|
8
|
+
import * as Request from '../server/Request.js'
|
|
9
|
+
import * as Mppx_internal from './internal/mppx.js'
|
|
10
|
+
|
|
11
|
+
export * from '../server/Methods.js'
|
|
12
|
+
|
|
13
|
+
export namespace Mppx {
|
|
14
|
+
/**
|
|
15
|
+
* Creates an Express-aware payment handler where each intent
|
|
16
|
+
* returns an Express `RequestHandler`.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* import express from 'express'
|
|
21
|
+
* import { Mppx, tempo } from 'mppx/express'
|
|
22
|
+
*
|
|
23
|
+
* const app = express()
|
|
24
|
+
* const mppx = Mppx.create({ methods: [tempo()] })
|
|
25
|
+
*
|
|
26
|
+
* app.get('/premium', mppx.charge({ amount: '1' }), (req, res) => {
|
|
27
|
+
* res.json({ data: 'paid content' })
|
|
28
|
+
* })
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export function create<const methods extends Mppx_core.Methods>(
|
|
32
|
+
config: Mppx_core.create.Config<methods>,
|
|
33
|
+
): Mppx_internal.Wrap<Mppx_core.Mppx<methods>, RequestHandler> {
|
|
34
|
+
return Mppx_internal.wrap(Mppx_core.create(config), payment)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Express middleware that gates a route behind a payment intent.
|
|
40
|
+
*
|
|
41
|
+
* Returns a 402 challenge if no valid credential is provided,
|
|
42
|
+
* otherwise attaches a `Payment-Receipt` header to the response.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```ts
|
|
46
|
+
* import express from 'express'
|
|
47
|
+
* import { Mppx } from 'mppx/server'
|
|
48
|
+
* import { payment } from 'mppx/express'
|
|
49
|
+
*
|
|
50
|
+
* const mppx = Mppx.create({ methods: [tempo()] })
|
|
51
|
+
*
|
|
52
|
+
* const app = express()
|
|
53
|
+
* app.get('/premium', payment(mppx.charge, { amount: '1' }), (req, res) => {
|
|
54
|
+
* res.json({ data: 'paid content' })
|
|
55
|
+
* })
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export function payment<const intent extends Mppx_internal.AnyIntentFn>(
|
|
59
|
+
intent: intent,
|
|
60
|
+
options: intent extends (options: infer options) => any ? options : never,
|
|
61
|
+
): RequestHandler {
|
|
62
|
+
return async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
63
|
+
const result = await intent(options)(Request.fromNodeListener(req, res))
|
|
64
|
+
|
|
65
|
+
if (result.status === 402) {
|
|
66
|
+
const challenge = result.challenge as Response
|
|
67
|
+
res.status(challenge.status)
|
|
68
|
+
for (const [key, value] of challenge.headers) res.setHeader(key, value)
|
|
69
|
+
res.send(await challenge.text())
|
|
70
|
+
return
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const originalJson = res.json.bind(res)
|
|
74
|
+
res.json = (body: any) => {
|
|
75
|
+
const wrapped = result.withReceipt(Response.json(body))
|
|
76
|
+
res.setHeader('Payment-Receipt', wrapped.headers.get('Payment-Receipt')!)
|
|
77
|
+
return originalJson(body)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
next()
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { serve } from '@hono/node-server'
|
|
2
|
+
import { Hono } from 'hono'
|
|
3
|
+
import { Receipt } from 'mppx'
|
|
4
|
+
import { Mppx as Mppx_client, session as sessionIntent, tempo as tempo_client } from 'mppx/client'
|
|
5
|
+
import { Mppx } from 'mppx/hono'
|
|
6
|
+
import { tempo as tempo_server } from 'mppx/server'
|
|
7
|
+
import type { Address } from 'viem'
|
|
8
|
+
import { Addresses } from 'viem/tempo'
|
|
9
|
+
import { beforeAll, describe, expect, test } from 'vitest'
|
|
10
|
+
import { deployEscrow } from '~test/tempo/stream.js'
|
|
11
|
+
import { accounts, asset, client, fundAccount } from '~test/tempo/viem.js'
|
|
12
|
+
|
|
13
|
+
function createServer(app: Hono) {
|
|
14
|
+
return new Promise<{ url: string; close: () => void }>((resolve) => {
|
|
15
|
+
const server = serve({ fetch: app.fetch, port: 0 }, (info) => {
|
|
16
|
+
resolve({
|
|
17
|
+
url: `http://localhost:${info.port}`,
|
|
18
|
+
close: () => server.close(),
|
|
19
|
+
})
|
|
20
|
+
})
|
|
21
|
+
})
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
describe('charge', () => {
|
|
25
|
+
const mppx = Mppx.create({
|
|
26
|
+
methods: [
|
|
27
|
+
tempo_server.charge({
|
|
28
|
+
getClient: () => client,
|
|
29
|
+
currency: asset,
|
|
30
|
+
recipient: accounts[0].address,
|
|
31
|
+
}),
|
|
32
|
+
],
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
const { fetch } = Mppx_client.create({
|
|
36
|
+
polyfill: false,
|
|
37
|
+
methods: [
|
|
38
|
+
tempo_client.charge({
|
|
39
|
+
account: accounts[1],
|
|
40
|
+
getClient: () => client,
|
|
41
|
+
}),
|
|
42
|
+
],
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
test('returns 402 when no credential', async () => {
|
|
46
|
+
const app = new Hono()
|
|
47
|
+
app.get('/', mppx.charge({ amount: '1' }), (c) => c.json({ fortune: 'You will be rich' }))
|
|
48
|
+
|
|
49
|
+
const server = await createServer(app)
|
|
50
|
+
const response = await globalThis.fetch(server.url)
|
|
51
|
+
expect(response.status).toBe(402)
|
|
52
|
+
expect(response.headers.get('WWW-Authenticate')).toContain('Payment')
|
|
53
|
+
|
|
54
|
+
server.close()
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
test('returns 200 with receipt on valid payment', async () => {
|
|
58
|
+
const app = new Hono()
|
|
59
|
+
app.get('/', mppx.charge({ amount: '1' }), (c) => c.json({ fortune: 'You will be rich' }))
|
|
60
|
+
|
|
61
|
+
const server = await createServer(app)
|
|
62
|
+
const response = await fetch(server.url)
|
|
63
|
+
expect(response.status).toBe(200)
|
|
64
|
+
|
|
65
|
+
const body = await response.json()
|
|
66
|
+
expect(body).toEqual({ fortune: 'You will be rich' })
|
|
67
|
+
|
|
68
|
+
const receipt = Receipt.fromResponse(response)
|
|
69
|
+
expect(receipt.status).toBe('success')
|
|
70
|
+
expect(receipt.method).toBe('tempo')
|
|
71
|
+
|
|
72
|
+
server.close()
|
|
73
|
+
})
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
describe('session', () => {
|
|
77
|
+
let escrowContract: Address
|
|
78
|
+
|
|
79
|
+
beforeAll(async () => {
|
|
80
|
+
escrowContract = await deployEscrow()
|
|
81
|
+
await fundAccount({ address: accounts[2].address, token: Addresses.pathUsd })
|
|
82
|
+
await fundAccount({ address: accounts[2].address, token: asset })
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
test('returns 402 when no credential', async () => {
|
|
86
|
+
const mppx = Mppx.create({
|
|
87
|
+
methods: [
|
|
88
|
+
tempo_server.session({
|
|
89
|
+
getClient: () => client,
|
|
90
|
+
recipient: accounts[0].address,
|
|
91
|
+
currency: asset,
|
|
92
|
+
escrowContract,
|
|
93
|
+
}),
|
|
94
|
+
],
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
const app = new Hono()
|
|
98
|
+
app.get('/', mppx.session({ amount: '1', unitType: 'token' }), (c) =>
|
|
99
|
+
c.json({ data: 'streamed' }),
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
const server = await createServer(app)
|
|
103
|
+
const response = await globalThis.fetch(server.url)
|
|
104
|
+
expect(response.status).toBe(402)
|
|
105
|
+
expect(response.headers.get('WWW-Authenticate')).toContain('Payment')
|
|
106
|
+
|
|
107
|
+
server.close()
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
test('returns 200 with receipt on valid payment', async () => {
|
|
111
|
+
const mppx = Mppx.create({
|
|
112
|
+
methods: [
|
|
113
|
+
tempo_server.session({
|
|
114
|
+
getClient: () => client,
|
|
115
|
+
recipient: accounts[0].address,
|
|
116
|
+
currency: asset,
|
|
117
|
+
escrowContract,
|
|
118
|
+
feePayer: accounts[0],
|
|
119
|
+
}),
|
|
120
|
+
],
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
const { fetch } = Mppx_client.create({
|
|
124
|
+
polyfill: false,
|
|
125
|
+
methods: [
|
|
126
|
+
sessionIntent({
|
|
127
|
+
account: accounts[2],
|
|
128
|
+
deposit: '10',
|
|
129
|
+
getClient: () => client,
|
|
130
|
+
}),
|
|
131
|
+
],
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
const app = new Hono()
|
|
135
|
+
app.get('/', mppx.session({ amount: '1', unitType: 'token' }), (c) =>
|
|
136
|
+
c.json({ data: 'streamed' }),
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
const server = await createServer(app)
|
|
140
|
+
const response = await fetch(server.url)
|
|
141
|
+
expect(response.status).toBe(200)
|
|
142
|
+
|
|
143
|
+
const body = await response.json()
|
|
144
|
+
expect(body).toEqual({ data: 'streamed' })
|
|
145
|
+
|
|
146
|
+
server.close()
|
|
147
|
+
})
|
|
148
|
+
})
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { MiddlewareHandler } from 'hono'
|
|
2
|
+
import * as Mppx_core from '../server/Mppx.js'
|
|
3
|
+
import * as Mppx_internal from './internal/mppx.js'
|
|
4
|
+
|
|
5
|
+
export * from '../server/Methods.js'
|
|
6
|
+
|
|
7
|
+
export namespace Mppx {
|
|
8
|
+
/**
|
|
9
|
+
* Creates a Hono-aware payment handler where each intent
|
|
10
|
+
* returns a Hono `MiddlewareHandler`.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* import { Hono } from 'hono'
|
|
15
|
+
* import { Mppx, tempo } from 'mppx/hono'
|
|
16
|
+
*
|
|
17
|
+
* const app = new Hono()
|
|
18
|
+
* const mppx = Mppx.create({ methods: [tempo()] })
|
|
19
|
+
*
|
|
20
|
+
* app.get('/premium', mppx.charge({ amount: '1' }), (c) =>
|
|
21
|
+
* c.json({ data: 'paid content' }),
|
|
22
|
+
* )
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export function create<const methods extends Mppx_core.Methods>(
|
|
26
|
+
config: Mppx_core.create.Config<methods>,
|
|
27
|
+
): Mppx_internal.Wrap<Mppx_core.Mppx<methods>, MiddlewareHandler> {
|
|
28
|
+
return Mppx_internal.wrap(Mppx_core.create(config), payment)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Hono middleware that gates a route behind a payment intent.
|
|
34
|
+
*
|
|
35
|
+
* Returns a 402 challenge if no valid credential is provided,
|
|
36
|
+
* otherwise attaches a `Payment-Receipt` header to the response.
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```ts
|
|
40
|
+
* import { Hono } from 'hono'
|
|
41
|
+
* import { Mppx } from 'mppx/server'
|
|
42
|
+
* import { payment } from 'mppx/hono'
|
|
43
|
+
*
|
|
44
|
+
* const mppx = Mppx.create({ methods: [tempo()] })
|
|
45
|
+
*
|
|
46
|
+
* const app = new Hono()
|
|
47
|
+
* app.get('/premium', payment(mppx.charge, { amount: '1' }), (c) =>
|
|
48
|
+
* c.json({ data: 'paid content' }),
|
|
49
|
+
* )
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export function payment<const intent extends Mppx_internal.AnyIntentFn>(
|
|
53
|
+
intent: intent,
|
|
54
|
+
options: intent extends (options: infer options) => any ? options : never,
|
|
55
|
+
): MiddlewareHandler {
|
|
56
|
+
return async (c, next) => {
|
|
57
|
+
const result = await intent(options)(c.req.raw)
|
|
58
|
+
if (result.status === 402) return result.challenge
|
|
59
|
+
await next()
|
|
60
|
+
c.res = result.withReceipt(c.res)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type * as MethodIntent from '../../MethodIntent.js'
|
|
2
|
+
import type * as Mppx from '../../server/Mppx.js'
|
|
3
|
+
|
|
4
|
+
export type AnyIntentFn = Mppx.AnyIntentFn
|
|
5
|
+
export type AnyServer = MethodIntent.AnyServer
|
|
6
|
+
|
|
7
|
+
export type Wrap<mppx, handler> = {
|
|
8
|
+
[key in keyof mppx]: mppx[key] extends (options: infer options) => any
|
|
9
|
+
? (o: options) => handler
|
|
10
|
+
: mppx[key]
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Wraps a payment handler so each intent returns a framework-specific
|
|
15
|
+
* handler instead of the raw intent response.
|
|
16
|
+
*
|
|
17
|
+
* @param mppx - The payment handler created by `Mppx.create`.
|
|
18
|
+
* @param wrapper - A function that adapts an intent function into a framework handler.
|
|
19
|
+
*/
|
|
20
|
+
export function wrap<mppx extends Mppx.Mppx<any, any>, handler>(
|
|
21
|
+
mppx: mppx,
|
|
22
|
+
wrapper: (intent: AnyIntentFn, options: any) => handler,
|
|
23
|
+
): Wrap<mppx, handler> {
|
|
24
|
+
const result: Record<string, unknown> = { ...mppx }
|
|
25
|
+
for (const mi of mppx.methods as readonly MethodIntent.AnyServer[]) {
|
|
26
|
+
const intentFn = (mppx as any)[mi.name]
|
|
27
|
+
result[mi.name] = (options: any) => wrapper(intentFn, options)
|
|
28
|
+
}
|
|
29
|
+
return result as never
|
|
30
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import * as http from 'node:http'
|
|
2
|
+
import { Receipt } from 'mppx'
|
|
3
|
+
import { Mppx as Mppx_client, session as sessionIntent, tempo as tempo_client } from 'mppx/client'
|
|
4
|
+
import { Mppx } from 'mppx/nextjs'
|
|
5
|
+
import { tempo as tempo_server } from 'mppx/server'
|
|
6
|
+
import type { Address } from 'viem'
|
|
7
|
+
import { Addresses } from 'viem/tempo'
|
|
8
|
+
import { beforeAll, describe, expect, test } from 'vitest'
|
|
9
|
+
import { deployEscrow } from '~test/tempo/stream.js'
|
|
10
|
+
import { accounts, asset, client, fundAccount } from '~test/tempo/viem.js'
|
|
11
|
+
|
|
12
|
+
function createServer(handler: (request: Request) => Promise<Response> | Response) {
|
|
13
|
+
return new Promise<{ url: string; close: () => void }>((resolve) => {
|
|
14
|
+
const server = http.createServer(async (req, res) => {
|
|
15
|
+
const url = `http://localhost${req.url}`
|
|
16
|
+
const headers = new Headers()
|
|
17
|
+
for (let i = 0; i < req.rawHeaders.length; i += 2)
|
|
18
|
+
headers.append(req.rawHeaders[i]!, req.rawHeaders[i + 1]!)
|
|
19
|
+
const request = new Request(url, { method: req.method!, headers })
|
|
20
|
+
const response = await handler(request)
|
|
21
|
+
res.writeHead(response.status, Object.fromEntries(response.headers))
|
|
22
|
+
const body = await response.text()
|
|
23
|
+
if (body) res.write(body)
|
|
24
|
+
res.end()
|
|
25
|
+
})
|
|
26
|
+
server.listen(0, () => {
|
|
27
|
+
const { port } = server.address() as { port: number }
|
|
28
|
+
resolve({
|
|
29
|
+
url: `http://localhost:${port}`,
|
|
30
|
+
close: () => server.close(),
|
|
31
|
+
})
|
|
32
|
+
})
|
|
33
|
+
})
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
describe('charge', () => {
|
|
37
|
+
const mppx = Mppx.create({
|
|
38
|
+
methods: [
|
|
39
|
+
tempo_server.charge({
|
|
40
|
+
getClient: () => client,
|
|
41
|
+
currency: asset,
|
|
42
|
+
recipient: accounts[0].address,
|
|
43
|
+
}),
|
|
44
|
+
],
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
const { fetch } = Mppx_client.create({
|
|
48
|
+
polyfill: false,
|
|
49
|
+
methods: [
|
|
50
|
+
tempo_client.charge({
|
|
51
|
+
account: accounts[1],
|
|
52
|
+
getClient: () => client,
|
|
53
|
+
}),
|
|
54
|
+
],
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
test('returns 402 when no credential', async () => {
|
|
58
|
+
const handler = mppx.charge({ amount: '1' })(() =>
|
|
59
|
+
Response.json({ fortune: 'You will be rich' }),
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
const server = await createServer(handler)
|
|
63
|
+
const response = await globalThis.fetch(server.url)
|
|
64
|
+
expect(response.status).toBe(402)
|
|
65
|
+
expect(response.headers.get('WWW-Authenticate')).toContain('Payment')
|
|
66
|
+
|
|
67
|
+
server.close()
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
test('returns 200 with receipt on valid payment', async () => {
|
|
71
|
+
const handler = mppx.charge({ amount: '1' })(() =>
|
|
72
|
+
Response.json({ fortune: 'You will be rich' }),
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
const server = await createServer(handler)
|
|
76
|
+
const response = await fetch(server.url)
|
|
77
|
+
expect(response.status).toBe(200)
|
|
78
|
+
|
|
79
|
+
const body = await response.json()
|
|
80
|
+
expect(body).toEqual({ fortune: 'You will be rich' })
|
|
81
|
+
|
|
82
|
+
const receipt = Receipt.fromResponse(response)
|
|
83
|
+
expect(receipt.status).toBe('success')
|
|
84
|
+
expect(receipt.method).toBe('tempo')
|
|
85
|
+
|
|
86
|
+
server.close()
|
|
87
|
+
})
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
describe('session', () => {
|
|
91
|
+
let escrowContract: Address
|
|
92
|
+
|
|
93
|
+
beforeAll(async () => {
|
|
94
|
+
escrowContract = await deployEscrow()
|
|
95
|
+
await fundAccount({ address: accounts[2].address, token: Addresses.pathUsd })
|
|
96
|
+
await fundAccount({ address: accounts[2].address, token: asset })
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
test('returns 402 when no credential', async () => {
|
|
100
|
+
const mppx = Mppx.create({
|
|
101
|
+
methods: [
|
|
102
|
+
tempo_server.session({
|
|
103
|
+
getClient: () => client,
|
|
104
|
+
recipient: accounts[0].address,
|
|
105
|
+
currency: asset,
|
|
106
|
+
escrowContract,
|
|
107
|
+
}),
|
|
108
|
+
],
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
const handler = mppx.session({ amount: '1', unitType: 'token' })(() =>
|
|
112
|
+
Response.json({ data: 'streamed' }),
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
const server = await createServer(handler)
|
|
116
|
+
const response = await globalThis.fetch(server.url)
|
|
117
|
+
expect(response.status).toBe(402)
|
|
118
|
+
expect(response.headers.get('WWW-Authenticate')).toContain('Payment')
|
|
119
|
+
|
|
120
|
+
server.close()
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
test('returns 200 with receipt on valid payment', async () => {
|
|
124
|
+
const mppx = Mppx.create({
|
|
125
|
+
methods: [
|
|
126
|
+
tempo_server.session({
|
|
127
|
+
getClient: () => client,
|
|
128
|
+
recipient: accounts[0].address,
|
|
129
|
+
currency: asset,
|
|
130
|
+
escrowContract,
|
|
131
|
+
feePayer: accounts[0],
|
|
132
|
+
}),
|
|
133
|
+
],
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
const { fetch } = Mppx_client.create({
|
|
137
|
+
polyfill: false,
|
|
138
|
+
methods: [
|
|
139
|
+
sessionIntent({
|
|
140
|
+
account: accounts[2],
|
|
141
|
+
deposit: '10',
|
|
142
|
+
getClient: () => client,
|
|
143
|
+
}),
|
|
144
|
+
],
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
const handler = mppx.session({ amount: '1', unitType: 'token' })(() =>
|
|
148
|
+
Response.json({ data: 'streamed' }),
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
const server = await createServer(handler)
|
|
152
|
+
const response = await fetch(server.url)
|
|
153
|
+
expect(response.status).toBe(200)
|
|
154
|
+
|
|
155
|
+
const body = await response.json()
|
|
156
|
+
expect(body).toEqual({ data: 'streamed' })
|
|
157
|
+
|
|
158
|
+
const receipt = Receipt.fromResponse(response)
|
|
159
|
+
expect(receipt.status).toBe('success')
|
|
160
|
+
expect(receipt.method).toBe('tempo')
|
|
161
|
+
|
|
162
|
+
server.close()
|
|
163
|
+
})
|
|
164
|
+
})
|