mppx 0.4.8 → 0.4.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -3
- package/README.md +13 -13
- package/dist/BodyDigest.d.ts.map +1 -1
- package/dist/BodyDigest.js.map +1 -1
- package/dist/Challenge.d.ts.map +1 -1
- package/dist/Challenge.js.map +1 -1
- package/dist/Credential.d.ts.map +1 -1
- package/dist/Credential.js.map +1 -1
- package/dist/Errors.js +64 -67
- package/dist/Errors.js.map +1 -1
- package/dist/PaymentRequest.d.ts.map +1 -1
- package/dist/PaymentRequest.js.map +1 -1
- package/dist/Receipt.d.ts.map +1 -1
- package/dist/Receipt.js.map +1 -1
- package/dist/Store.d.ts +9 -0
- package/dist/Store.d.ts.map +1 -1
- package/dist/Store.js +17 -0
- package/dist/Store.js.map +1 -1
- package/dist/cli/account.d.ts.map +1 -1
- package/dist/cli/account.js +40 -5
- package/dist/cli/account.js.map +1 -1
- package/dist/cli/cli.d.ts.map +1 -1
- package/dist/cli/cli.js +2 -1
- package/dist/cli/cli.js.map +1 -1
- package/dist/cli/internal.d.ts.map +1 -1
- package/dist/cli/internal.js.map +1 -1
- package/dist/cli/plugins/stripe.d.ts.map +1 -1
- package/dist/cli/plugins/stripe.js.map +1 -1
- package/dist/cli/plugins/tempo.d.ts.map +1 -1
- package/dist/cli/plugins/tempo.js +2 -1
- package/dist/cli/plugins/tempo.js.map +1 -1
- package/dist/cli/utils.d.ts.map +1 -1
- package/dist/cli/utils.js.map +1 -1
- package/dist/client/internal/Fetch.d.ts +2 -0
- package/dist/client/internal/Fetch.d.ts.map +1 -1
- package/dist/client/internal/Fetch.js +1 -1
- package/dist/client/internal/Fetch.js.map +1 -1
- package/dist/internal/types.d.ts.map +1 -1
- package/dist/mcp-sdk/client/McpClient.d.ts.map +1 -1
- package/dist/mcp-sdk/client/McpClient.js +1 -1
- package/dist/mcp-sdk/client/McpClient.js.map +1 -1
- package/dist/mcp-sdk/server/Transport.d.ts.map +1 -1
- package/dist/mcp-sdk/server/Transport.js.map +1 -1
- package/dist/middlewares/elysia.d.ts.map +1 -1
- package/dist/middlewares/elysia.js.map +1 -1
- package/dist/middlewares/express.d.ts.map +1 -1
- package/dist/middlewares/express.js +5 -2
- package/dist/middlewares/express.js.map +1 -1
- package/dist/middlewares/hono.d.ts.map +1 -1
- package/dist/middlewares/hono.js.map +1 -1
- package/dist/proxy/Proxy.d.ts.map +1 -1
- package/dist/proxy/Proxy.js.map +1 -1
- package/dist/proxy/Service.js +1 -1
- package/dist/proxy/Service.js.map +1 -1
- package/dist/server/Mppx.d.ts.map +1 -1
- package/dist/server/Mppx.js +35 -17
- package/dist/server/Mppx.js.map +1 -1
- package/dist/server/Request.d.ts.map +1 -1
- package/dist/server/Request.js.map +1 -1
- package/dist/stripe/Methods.d.ts.map +1 -1
- package/dist/stripe/Methods.js.map +1 -1
- package/dist/tempo/Methods.d.ts.map +1 -1
- package/dist/tempo/Methods.js.map +1 -1
- package/dist/tempo/client/ChannelOps.d.ts.map +1 -1
- package/dist/tempo/client/ChannelOps.js.map +1 -1
- package/dist/tempo/client/Charge.d.ts.map +1 -1
- package/dist/tempo/client/Charge.js.map +1 -1
- package/dist/tempo/client/Session.d.ts.map +1 -1
- package/dist/tempo/client/Session.js.map +1 -1
- package/dist/tempo/client/SessionManager.d.ts.map +1 -1
- package/dist/tempo/client/SessionManager.js +1 -1
- package/dist/tempo/client/SessionManager.js.map +1 -1
- package/dist/tempo/internal/auto-swap.d.ts.map +1 -1
- package/dist/tempo/internal/auto-swap.js +1 -1
- package/dist/tempo/internal/auto-swap.js.map +1 -1
- package/dist/tempo/internal/fee-payer.d.ts.map +1 -1
- package/dist/tempo/internal/fee-payer.js +1 -1
- package/dist/tempo/internal/fee-payer.js.map +1 -1
- package/dist/tempo/server/Charge.d.ts.map +1 -1
- package/dist/tempo/server/Charge.js +1 -1
- package/dist/tempo/server/Charge.js.map +1 -1
- package/dist/tempo/server/Session.d.ts.map +1 -1
- package/dist/tempo/server/Session.js.map +1 -1
- package/dist/tempo/session/Chain.d.ts.map +1 -1
- package/dist/tempo/session/Chain.js.map +1 -1
- package/dist/tempo/session/ChannelStore.d.ts.map +1 -1
- package/dist/tempo/session/ChannelStore.js.map +1 -1
- package/dist/tempo/session/Receipt.d.ts.map +1 -1
- package/dist/tempo/session/Receipt.js.map +1 -1
- package/dist/tempo/session/Sse.d.ts.map +1 -1
- package/dist/tempo/session/Sse.js.map +1 -1
- package/dist/tempo/session/Voucher.d.ts.map +1 -1
- package/dist/tempo/session/Voucher.js.map +1 -1
- package/dist/viem/Client.d.ts.map +1 -1
- package/dist/viem/Client.js.map +1 -1
- package/package.json +1 -1
- package/src/BodyDigest.ts +1 -0
- package/src/Challenge.test-d.ts +1 -0
- package/src/Challenge.ts +1 -0
- package/src/Credential.ts +1 -0
- package/src/Errors.test.ts +27 -39
- package/src/Expires.test.ts +1 -0
- package/src/PaymentRequest.ts +1 -0
- package/src/Receipt.ts +1 -0
- package/src/Store.test-d.ts +1 -0
- package/src/Store.test.ts +56 -6
- package/src/Store.ts +25 -0
- package/src/cli/account.ts +65 -30
- package/src/cli/cli.test.ts +3 -1
- package/src/cli/cli.ts +4 -1
- package/src/cli/config.test.ts +1 -0
- package/src/cli/internal.ts +1 -0
- package/src/cli/plugins/stripe.ts +1 -0
- package/src/cli/plugins/tempo.ts +4 -1
- package/src/cli/utils.ts +1 -0
- package/src/client/Mppx.test-d.ts +1 -0
- package/src/client/internal/Fetch.browser.test.ts +1 -0
- package/src/client/internal/Fetch.test-d.ts +1 -0
- package/src/client/internal/Fetch.test.ts +1 -0
- package/src/client/internal/Fetch.ts +1 -1
- package/src/internal/constantTimeEqual.test.ts +1 -0
- package/src/internal/types.ts +1 -3
- package/src/mcp-sdk/client/McpClient.test-d.ts +1 -0
- package/src/mcp-sdk/client/McpClient.test.ts +1 -0
- package/src/mcp-sdk/client/McpClient.ts +2 -0
- package/src/mcp-sdk/server/Transport.test.ts +1 -0
- package/src/mcp-sdk/server/Transport.ts +1 -0
- package/src/middlewares/elysia.test.ts +1 -0
- package/src/middlewares/elysia.ts +1 -0
- package/src/middlewares/express.test.ts +62 -2
- package/src/middlewares/express.ts +6 -2
- package/src/middlewares/hono.ts +1 -0
- package/src/middlewares/internal/mppx.test.ts +1 -0
- package/src/middlewares/nextjs.test.ts +1 -0
- package/src/proxy/Proxy.test.ts +1 -0
- package/src/proxy/Proxy.ts +2 -0
- package/src/proxy/Service.test.ts +1 -0
- package/src/proxy/Service.ts +8 -2
- package/src/proxy/internal/Headers.test.ts +1 -0
- package/src/proxy/services/openai.test.ts +1 -0
- package/src/server/Mppx.test.ts +192 -0
- package/src/server/Mppx.ts +38 -19
- package/src/server/Request.test.ts +1 -0
- package/src/server/Request.ts +1 -0
- package/src/server/Response.test.ts +1 -0
- package/src/server/Transport.test.ts +1 -0
- package/src/stripe/Methods.ts +1 -0
- package/src/stripe/client/Charge.test.ts +1 -0
- package/src/stripe/server/Charge.test.ts +1 -0
- package/src/tempo/Attribution.test.ts +1 -0
- package/src/tempo/Methods.ts +1 -0
- package/src/tempo/client/ChannelOps.test.ts +1 -0
- package/src/tempo/client/ChannelOps.ts +1 -0
- package/src/tempo/client/Charge.ts +1 -0
- package/src/tempo/client/Session.test.ts +1 -0
- package/src/tempo/client/Session.ts +1 -0
- package/src/tempo/client/SessionManager.test.ts +28 -0
- package/src/tempo/client/SessionManager.ts +2 -1
- package/src/tempo/internal/auto-swap.test.ts +1 -0
- package/src/tempo/internal/auto-swap.ts +1 -0
- package/src/tempo/internal/defaults.test.ts +1 -0
- package/src/tempo/internal/fee-payer.test.ts +1 -0
- package/src/tempo/internal/fee-payer.ts +1 -0
- package/src/tempo/server/Charge.test.ts +1 -0
- package/src/tempo/server/Charge.ts +1 -0
- package/src/tempo/server/Session.test.ts +1 -0
- package/src/tempo/server/Session.ts +1 -0
- package/src/tempo/server/Sse.test.ts +1 -0
- package/src/tempo/server/internal/transport.test.ts +1 -0
- package/src/tempo/session/Chain.test.ts +1 -0
- package/src/tempo/session/Chain.ts +1 -0
- package/src/tempo/session/Channel.test.ts +1 -0
- package/src/tempo/session/ChannelStore.test.ts +1 -0
- package/src/tempo/session/ChannelStore.ts +1 -0
- package/src/tempo/session/Receipt.test.ts +1 -0
- package/src/tempo/session/Receipt.ts +1 -0
- package/src/tempo/session/Sse.test.ts +1 -0
- package/src/tempo/session/Sse.ts +1 -0
- package/src/tempo/session/Voucher.test.ts +1 -0
- package/src/tempo/session/Voucher.ts +1 -0
- package/src/viem/Account.test.ts +1 -0
- package/src/viem/Client.test.ts +1 -0
- package/src/viem/Client.ts +1 -0
package/dist/viem/Client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Client.js","sourceRoot":"","sources":["../../src/viem/Client.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,YAAY,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"Client.js","sourceRoot":"","sources":["../../src/viem/Client.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,YAAY,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAIzC,MAAM,UAAU,WAAW,CACzB,UAOC;IAED,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,UAAU,CAAA;IAE5D,IAAI,SAAS,EAAE,CAAC;QACd,+EAA+E;QAC/E,gFAAgF;QAChF,+EAA+E;QAC/E,kFAAkF;QAClF,IAAI,CAAC,KAAK,EAAE,WAAW,IAAI,CAAC,WAAW;YAAE,OAAO,SAAS,CAAA;QACzD,OAAO,KAAK,EAAE,MAAM,EAAE,EAAE;YACtB,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,CAAA;YAEtC,oFAAoF;YACpF,IAAI,WAAW,IAAI,MAAM,CAAC,SAAS,CAAC,GAAG,KAAK,UAAU,EAAE,CAAC;gBACvD,MAAM,GAAG,GAAI,MAAM,CAAC,SAA8B,CAAC,GAAG,CAAA;gBACtD,IAAI,GAAG,EAAE,CAAC;oBACR,MAAM,OAAO,GAAG,YAAY,CAAC;wBAC3B,KAAK,EAAE,MAAM,CAAC,KAAK;wBACnB,SAAS,EAAE,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;qBACtD,CAAC,CAAA;oBACF,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;gBACnF,CAAC;YACH,CAAC;YAED,IAAI,CAAC,KAAK,EAAE,WAAW,IAAI,MAAM,CAAC,KAAK,EAAE,WAAW,EAAE,WAAW;gBAAE,OAAO,MAAM,CAAA;YAChF,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE;gBAC/B,KAAK,EAAE;oBACL,GAAG,KAAK;oBACR,GAAG,MAAM,CAAC,KAAK;oBACf,UAAU,EAAE,MAAM,CAAC,KAAK,EAAE,UAAU,IAAI,KAAK,CAAC,UAAU;oBACxD,yBAAyB,EACvB,MAAM,CAAC,KAAK,EAAE,yBAAyB,IAAI,KAAK,CAAC,yBAAyB;oBAC5E,WAAW,EAAE,MAAM,CAAC,KAAK,EAAE,WAAW,EAAE,WAAW;wBACjD,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW;wBAC1B,CAAC,CAAC,KAAK,CAAC,WAAW;iBACC;aACzB,CAAC,CAAA;QACJ,CAAC,CAAA;IACH,CAAC;IAED,OAAO,CAAC,EAAE,OAAO,EAAoC,EAAE,EAAE;QACvD,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAA;QACrD,MAAM,eAAe,GAAG,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAE,CAAA;QAClE,MAAM,GAAG,GAAG,MAAM,CAAC,eAAsC,CAAC,CAAA;QAC1D,IAAI,CAAC,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,eAAe,IAAI,CAAC,CAAA;QAC3F,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACtF,OAAO,YAAY,CAAC;YAClB,KAAK,EAAE,EAAE,GAAG,KAAK,EAAE,EAAE,EAAE,eAAe,EAAW;YACjD,SAAS;SACV,CAAC,CAAA;IACJ,CAAC,CAAA;AACH,CAAC"}
|
package/package.json
CHANGED
package/src/BodyDigest.ts
CHANGED
package/src/Challenge.test-d.ts
CHANGED
package/src/Challenge.ts
CHANGED
package/src/Credential.ts
CHANGED
package/src/Errors.test.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { describe, expect, test } from 'vitest'
|
|
2
|
+
|
|
2
3
|
import {
|
|
3
4
|
AmountExceedsDepositError,
|
|
4
5
|
BadRequestError,
|
|
@@ -41,9 +42,8 @@ describe('MalformedCredentialError', () => {
|
|
|
41
42
|
})
|
|
42
43
|
|
|
43
44
|
test('with reason', () => {
|
|
44
|
-
expect(
|
|
45
|
-
|
|
46
|
-
).toMatchInlineSnapshot(`
|
|
45
|
+
expect(errorSnapshot(new MalformedCredentialError({ reason: 'invalid base64url' })))
|
|
46
|
+
.toMatchInlineSnapshot(`
|
|
47
47
|
{
|
|
48
48
|
"message": "Credential is malformed: invalid base64url.",
|
|
49
49
|
"name": "MalformedCredentialError",
|
|
@@ -89,9 +89,8 @@ describe('InvalidChallengeError', () => {
|
|
|
89
89
|
})
|
|
90
90
|
|
|
91
91
|
test('with id and reason', () => {
|
|
92
|
-
expect(
|
|
93
|
-
|
|
94
|
-
).toMatchInlineSnapshot(`
|
|
92
|
+
expect(errorSnapshot(new InvalidChallengeError({ id: 'abc123', reason: 'already used' })))
|
|
93
|
+
.toMatchInlineSnapshot(`
|
|
95
94
|
{
|
|
96
95
|
"message": "Challenge "abc123" is invalid: already used.",
|
|
97
96
|
"name": "InvalidChallengeError",
|
|
@@ -115,9 +114,8 @@ describe('VerificationFailedError', () => {
|
|
|
115
114
|
})
|
|
116
115
|
|
|
117
116
|
test('with reason', () => {
|
|
118
|
-
expect(
|
|
119
|
-
|
|
120
|
-
).toMatchInlineSnapshot(`
|
|
117
|
+
expect(errorSnapshot(new VerificationFailedError({ reason: 'invalid signature' })))
|
|
118
|
+
.toMatchInlineSnapshot(`
|
|
121
119
|
{
|
|
122
120
|
"message": "Payment verification failed: invalid signature.",
|
|
123
121
|
"name": "VerificationFailedError",
|
|
@@ -141,9 +139,8 @@ describe('PaymentExpiredError', () => {
|
|
|
141
139
|
})
|
|
142
140
|
|
|
143
141
|
test('with expires', () => {
|
|
144
|
-
expect(
|
|
145
|
-
|
|
146
|
-
).toMatchInlineSnapshot(`
|
|
142
|
+
expect(errorSnapshot(new PaymentExpiredError({ expires: '2025-01-26T12:00:00Z' })))
|
|
143
|
+
.toMatchInlineSnapshot(`
|
|
147
144
|
{
|
|
148
145
|
"message": "Payment expired at 2025-01-26T12:00:00Z.",
|
|
149
146
|
"name": "PaymentExpiredError",
|
|
@@ -167,9 +164,8 @@ describe('PaymentRequiredError', () => {
|
|
|
167
164
|
})
|
|
168
165
|
|
|
169
166
|
test('with description', () => {
|
|
170
|
-
expect(
|
|
171
|
-
|
|
172
|
-
).toMatchInlineSnapshot(`
|
|
167
|
+
expect(errorSnapshot(new PaymentRequiredError({ description: 'API access fee' })))
|
|
168
|
+
.toMatchInlineSnapshot(`
|
|
173
169
|
{
|
|
174
170
|
"message": "Payment is required (API access fee).",
|
|
175
171
|
"name": "PaymentRequiredError",
|
|
@@ -193,9 +189,8 @@ describe('InvalidPayloadError', () => {
|
|
|
193
189
|
})
|
|
194
190
|
|
|
195
191
|
test('with reason', () => {
|
|
196
|
-
expect(
|
|
197
|
-
|
|
198
|
-
).toMatchInlineSnapshot(`
|
|
192
|
+
expect(errorSnapshot(new InvalidPayloadError({ reason: 'missing signature field' })))
|
|
193
|
+
.toMatchInlineSnapshot(`
|
|
199
194
|
{
|
|
200
195
|
"message": "Credential payload is invalid: missing signature field.",
|
|
201
196
|
"name": "InvalidPayloadError",
|
|
@@ -219,9 +214,8 @@ describe('BadRequestError', () => {
|
|
|
219
214
|
})
|
|
220
215
|
|
|
221
216
|
test('with reason', () => {
|
|
222
|
-
expect(
|
|
223
|
-
|
|
224
|
-
).toMatchInlineSnapshot(`
|
|
217
|
+
expect(errorSnapshot(new BadRequestError({ reason: 'cannot combine hash type with feePayer' })))
|
|
218
|
+
.toMatchInlineSnapshot(`
|
|
225
219
|
{
|
|
226
220
|
"message": "Bad request: cannot combine hash type with feePayer.",
|
|
227
221
|
"name": "BadRequestError",
|
|
@@ -245,9 +239,8 @@ describe('PaymentInsufficientError', () => {
|
|
|
245
239
|
})
|
|
246
240
|
|
|
247
241
|
test('with reason', () => {
|
|
248
|
-
expect(
|
|
249
|
-
|
|
250
|
-
).toMatchInlineSnapshot(`
|
|
242
|
+
expect(errorSnapshot(new PaymentInsufficientError({ reason: 'expected 1000, received 500' })))
|
|
243
|
+
.toMatchInlineSnapshot(`
|
|
251
244
|
{
|
|
252
245
|
"message": "Payment insufficient: expected 1000, received 500.",
|
|
253
246
|
"name": "PaymentInsufficientError",
|
|
@@ -271,9 +264,8 @@ describe('PaymentMethodUnsupportedError', () => {
|
|
|
271
264
|
})
|
|
272
265
|
|
|
273
266
|
test('with method', () => {
|
|
274
|
-
expect(
|
|
275
|
-
|
|
276
|
-
).toMatchInlineSnapshot(`
|
|
267
|
+
expect(errorSnapshot(new PaymentMethodUnsupportedError({ method: 'bitcoin' })))
|
|
268
|
+
.toMatchInlineSnapshot(`
|
|
277
269
|
{
|
|
278
270
|
"message": "Payment method "bitcoin" is not supported.",
|
|
279
271
|
"name": "PaymentMethodUnsupportedError",
|
|
@@ -297,9 +289,8 @@ describe('InsufficientBalanceError', () => {
|
|
|
297
289
|
})
|
|
298
290
|
|
|
299
291
|
test('with reason', () => {
|
|
300
|
-
expect(
|
|
301
|
-
|
|
302
|
-
).toMatchInlineSnapshot(`
|
|
292
|
+
expect(errorSnapshot(new InsufficientBalanceError({ reason: 'requested 500, available 100' })))
|
|
293
|
+
.toMatchInlineSnapshot(`
|
|
303
294
|
{
|
|
304
295
|
"message": "Insufficient balance: requested 500, available 100.",
|
|
305
296
|
"name": "InsufficientBalanceError",
|
|
@@ -323,9 +314,8 @@ describe('InvalidSignatureError', () => {
|
|
|
323
314
|
})
|
|
324
315
|
|
|
325
316
|
test('with reason', () => {
|
|
326
|
-
expect(
|
|
327
|
-
|
|
328
|
-
).toMatchInlineSnapshot(`
|
|
317
|
+
expect(errorSnapshot(new InvalidSignatureError({ reason: 'ECDSA recovery failed' })))
|
|
318
|
+
.toMatchInlineSnapshot(`
|
|
329
319
|
{
|
|
330
320
|
"message": "Invalid signature: ECDSA recovery failed.",
|
|
331
321
|
"name": "InvalidSignatureError",
|
|
@@ -401,9 +391,8 @@ describe('ChannelClosedError', () => {
|
|
|
401
391
|
})
|
|
402
392
|
|
|
403
393
|
test('with reason', () => {
|
|
404
|
-
expect(
|
|
405
|
-
|
|
406
|
-
).toMatchInlineSnapshot(`
|
|
394
|
+
expect(errorSnapshot(new ChannelClosedError({ reason: 'channel is finalized on-chain' })))
|
|
395
|
+
.toMatchInlineSnapshot(`
|
|
407
396
|
{
|
|
408
397
|
"message": "Channel closed: channel is finalized on-chain.",
|
|
409
398
|
"name": "ChannelClosedError",
|
|
@@ -427,9 +416,8 @@ describe('PaymentActionRequiredError', () => {
|
|
|
427
416
|
})
|
|
428
417
|
|
|
429
418
|
test('with reason', () => {
|
|
430
|
-
expect(
|
|
431
|
-
|
|
432
|
-
).toMatchInlineSnapshot(`
|
|
419
|
+
expect(errorSnapshot(new PaymentActionRequiredError({ reason: 'requires_action' })))
|
|
420
|
+
.toMatchInlineSnapshot(`
|
|
433
421
|
{
|
|
434
422
|
"message": "Payment requires action: requires_action.",
|
|
435
423
|
"name": "PaymentActionRequiredError",
|
package/src/Expires.test.ts
CHANGED
package/src/PaymentRequest.ts
CHANGED
package/src/Receipt.ts
CHANGED
package/src/Store.test-d.ts
CHANGED
package/src/Store.test.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { describe, expect, test } from 'vitest'
|
|
2
|
+
|
|
2
3
|
import * as Store from './Store.js'
|
|
3
4
|
|
|
4
5
|
const nested = {
|
|
@@ -7,16 +8,16 @@ const nested = {
|
|
|
7
8
|
meta: { active: true, tags: ['a', 'b'] },
|
|
8
9
|
}
|
|
9
10
|
|
|
10
|
-
function fakeKv()
|
|
11
|
+
function fakeKv() {
|
|
11
12
|
const map = new Map<string, string>()
|
|
12
13
|
return {
|
|
13
|
-
async get(key) {
|
|
14
|
+
async get(key: string) {
|
|
14
15
|
return map.get(key) ?? null
|
|
15
16
|
},
|
|
16
|
-
async put(key, value) {
|
|
17
|
+
async put(key: string, value: string) {
|
|
17
18
|
map.set(key, value)
|
|
18
19
|
},
|
|
19
|
-
async delete(key) {
|
|
20
|
+
async delete(key: string) {
|
|
20
21
|
map.delete(key)
|
|
21
22
|
},
|
|
22
23
|
}
|
|
@@ -25,6 +26,17 @@ function fakeKv(): Store.cloudflare.Parameters {
|
|
|
25
26
|
describe.each([
|
|
26
27
|
{ label: 'memory', create: () => Store.memory() },
|
|
27
28
|
{ label: 'cloudflare', create: () => Store.cloudflare(fakeKv()) },
|
|
29
|
+
{
|
|
30
|
+
label: 'redis',
|
|
31
|
+
create: () => {
|
|
32
|
+
const kv = fakeKv()
|
|
33
|
+
return Store.redis({
|
|
34
|
+
get: kv.get,
|
|
35
|
+
set: kv.put,
|
|
36
|
+
del: (key) => kv.delete(key),
|
|
37
|
+
})
|
|
38
|
+
},
|
|
39
|
+
},
|
|
28
40
|
{
|
|
29
41
|
label: 'upstash',
|
|
30
42
|
create: () => {
|
|
@@ -64,6 +76,20 @@ describe.each([
|
|
|
64
76
|
})
|
|
65
77
|
|
|
66
78
|
describe('json roundtrip behavior', () => {
|
|
79
|
+
test('cloudflare json-roundtrips nested objects', async () => {
|
|
80
|
+
const store = Store.cloudflare(fakeKv())
|
|
81
|
+
const value = { a: [1, { b: 'c' }], d: null }
|
|
82
|
+
await store.put('k', value)
|
|
83
|
+
expect(await store.get('k')).toEqual(value)
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
test('cloudflare roundtrips BigInt values', async () => {
|
|
87
|
+
const store = Store.cloudflare(fakeKv())
|
|
88
|
+
const value = { amount: 1000000000000000000n, nested: { big: 42n } }
|
|
89
|
+
await store.put('k', value)
|
|
90
|
+
expect(await store.get('k')).toEqual(value)
|
|
91
|
+
})
|
|
92
|
+
|
|
67
93
|
test('memory json-roundtrips nested objects', async () => {
|
|
68
94
|
const store = Store.memory()
|
|
69
95
|
const value = { a: [1, { b: 'c' }], d: null }
|
|
@@ -71,13 +97,37 @@ describe('json roundtrip behavior', () => {
|
|
|
71
97
|
expect(await store.get('k')).toEqual(value)
|
|
72
98
|
})
|
|
73
99
|
|
|
74
|
-
test('
|
|
75
|
-
const store = Store.
|
|
100
|
+
test('memory roundtrips BigInt values', async () => {
|
|
101
|
+
const store = Store.memory()
|
|
102
|
+
const value = { amount: 1000000000000000000n, nested: { big: 42n } }
|
|
103
|
+
await store.put('k', value)
|
|
104
|
+
expect(await store.get('k')).toEqual(value)
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
test('redis json-roundtrips nested objects', async () => {
|
|
108
|
+
const kv = fakeKv()
|
|
109
|
+
const store = Store.redis({
|
|
110
|
+
get: kv.get,
|
|
111
|
+
set: kv.put,
|
|
112
|
+
del: (key) => kv.delete(key),
|
|
113
|
+
})
|
|
76
114
|
const value = { a: [1, { b: 'c' }], d: null }
|
|
77
115
|
await store.put('k', value)
|
|
78
116
|
expect(await store.get('k')).toEqual(value)
|
|
79
117
|
})
|
|
80
118
|
|
|
119
|
+
test('redis roundtrips BigInt values', async () => {
|
|
120
|
+
const kv = fakeKv()
|
|
121
|
+
const store = Store.redis({
|
|
122
|
+
get: kv.get,
|
|
123
|
+
set: kv.put,
|
|
124
|
+
del: (key) => kv.delete(key),
|
|
125
|
+
})
|
|
126
|
+
const value = { amount: 1000000000000000000n, nested: { big: 42n } }
|
|
127
|
+
await store.put('k', value)
|
|
128
|
+
expect(await store.get('k')).toEqual(value)
|
|
129
|
+
})
|
|
130
|
+
|
|
81
131
|
test('upstash passes values through without json serialization', async () => {
|
|
82
132
|
const kv = fakeKv()
|
|
83
133
|
const store = Store.upstash({
|
package/src/Store.ts
CHANGED
|
@@ -62,6 +62,31 @@ export function memory(): Store {
|
|
|
62
62
|
})
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
/** Wraps a standard Redis client (ioredis, node-redis, Valkey). */
|
|
66
|
+
export function redis(client: redis.Parameters): Store {
|
|
67
|
+
return from({
|
|
68
|
+
async get(key) {
|
|
69
|
+
const raw = await client.get(key)
|
|
70
|
+
if (raw == null) return null as any
|
|
71
|
+
return Json.parse(raw)
|
|
72
|
+
},
|
|
73
|
+
async put(key, value) {
|
|
74
|
+
await client.set(key, Json.stringify(value))
|
|
75
|
+
},
|
|
76
|
+
async delete(key) {
|
|
77
|
+
await client.del(key)
|
|
78
|
+
},
|
|
79
|
+
})
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export declare namespace redis {
|
|
83
|
+
export type Parameters = {
|
|
84
|
+
get: (key: string) => Promise<string | null>
|
|
85
|
+
set: (key: string, value: string) => Promise<unknown>
|
|
86
|
+
del: (key: string) => Promise<unknown>
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
65
90
|
/** Wraps an Upstash Redis instance (e.g. Vercel KV). */
|
|
66
91
|
export function upstash(redis: upstash.Parameters): Store {
|
|
67
92
|
return from({
|
package/src/cli/account.ts
CHANGED
|
@@ -55,50 +55,85 @@ export function createKeychain(account = 'main') {
|
|
|
55
55
|
async list(): Promise<string[]> {
|
|
56
56
|
const platform = os.platform()
|
|
57
57
|
if (platform === 'darwin') {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
58
|
+
const { stdout, error } = await execCommand('security', ['dump-keychain'])
|
|
59
|
+
if (error) return []
|
|
60
|
+
const accounts: string[] = []
|
|
61
|
+
const blocks = stdout.split('keychain:')
|
|
62
|
+
for (const block of blocks) {
|
|
63
|
+
const serviceMatch = block.match(/"svce"<blob>="([^"]*)"/)
|
|
64
|
+
const accountMatch = block.match(/"acct"<blob>="([^"]*)"/)
|
|
65
|
+
if (serviceMatch?.[1] === service && accountMatch?.[1]) accounts.push(accountMatch[1])
|
|
66
|
+
}
|
|
67
|
+
return accounts
|
|
68
68
|
}
|
|
69
69
|
if (platform === 'linux') {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
70
|
+
const { stdout, stderr, error } = await execCommand('secret-tool', [
|
|
71
|
+
'search',
|
|
72
|
+
'--all',
|
|
73
|
+
'--unlock',
|
|
74
|
+
'service',
|
|
75
|
+
service,
|
|
76
|
+
])
|
|
77
|
+
if (error) return []
|
|
78
|
+
const combined = `${stdout}\n${stderr}`
|
|
79
|
+
const accounts: string[] = []
|
|
80
|
+
const matches = combined.matchAll(/\baccount = (.+)/g)
|
|
81
|
+
for (const match of matches) if (match[1]) accounts.push(match[1])
|
|
82
|
+
return accounts
|
|
77
83
|
}
|
|
78
84
|
throw new Error(`Unsupported platform: ${platform}`)
|
|
79
85
|
},
|
|
80
86
|
async get(): Promise<string | undefined> {
|
|
81
87
|
const platform = os.platform()
|
|
82
88
|
if (platform === 'darwin') {
|
|
83
|
-
|
|
84
|
-
|
|
89
|
+
const { stdout, error } = await execCommand('security', [
|
|
90
|
+
'find-generic-password',
|
|
91
|
+
'-s',
|
|
92
|
+
service,
|
|
93
|
+
'-a',
|
|
94
|
+
account,
|
|
95
|
+
'-w',
|
|
96
|
+
])
|
|
97
|
+
return error ? undefined : stdout
|
|
85
98
|
}
|
|
86
99
|
if (platform === 'linux') {
|
|
87
|
-
|
|
88
|
-
|
|
100
|
+
const { stdout, error } = await execCommand('secret-tool', [
|
|
101
|
+
'lookup',
|
|
102
|
+
'service',
|
|
103
|
+
service,
|
|
104
|
+
'account',
|
|
105
|
+
account,
|
|
106
|
+
])
|
|
107
|
+
return error ? undefined : stdout || undefined
|
|
89
108
|
}
|
|
90
109
|
throw new Error(`Unsupported platform: ${platform}`)
|
|
91
110
|
},
|
|
92
111
|
async set(value: string): Promise<void> {
|
|
93
112
|
const platform = os.platform()
|
|
94
113
|
if (platform === 'darwin') {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
114
|
+
await execCommand('security', ['delete-generic-password', '-s', service, '-a', account])
|
|
115
|
+
const { error } = await execCommand('security', [
|
|
116
|
+
'add-generic-password',
|
|
117
|
+
'-s',
|
|
118
|
+
service,
|
|
119
|
+
'-a',
|
|
120
|
+
account,
|
|
121
|
+
'-w',
|
|
122
|
+
value,
|
|
123
|
+
])
|
|
124
|
+
if (error) throw error
|
|
125
|
+
return
|
|
99
126
|
}
|
|
100
127
|
if (platform === 'linux') {
|
|
101
|
-
const proc = child.execFile('secret-tool', [
|
|
128
|
+
const proc = child.execFile('secret-tool', [
|
|
129
|
+
'store',
|
|
130
|
+
'--label',
|
|
131
|
+
`${service} ${account}`,
|
|
132
|
+
'service',
|
|
133
|
+
service,
|
|
134
|
+
'account',
|
|
135
|
+
account,
|
|
136
|
+
])
|
|
102
137
|
proc.stdin?.write(value)
|
|
103
138
|
proc.stdin?.end()
|
|
104
139
|
return new Promise((resolve, reject) => {
|
|
@@ -114,12 +149,12 @@ export function createKeychain(account = 'main') {
|
|
|
114
149
|
async delete(): Promise<void> {
|
|
115
150
|
const platform = os.platform()
|
|
116
151
|
if (platform === 'darwin') {
|
|
117
|
-
|
|
118
|
-
|
|
152
|
+
await execCommand('security', ['delete-generic-password', '-s', service, '-a', account])
|
|
153
|
+
return
|
|
119
154
|
}
|
|
120
155
|
if (platform === 'linux') {
|
|
121
|
-
|
|
122
|
-
|
|
156
|
+
await execCommand('secret-tool', ['clear', 'service', service, 'account', account])
|
|
157
|
+
return
|
|
123
158
|
}
|
|
124
159
|
throw new Error(`Unsupported platform: ${platform}`)
|
|
125
160
|
},
|
package/src/cli/cli.test.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { spawnSync } from 'node:child_process'
|
|
|
2
2
|
import * as fs from 'node:fs'
|
|
3
3
|
import * as os from 'node:os'
|
|
4
4
|
import * as path from 'node:path'
|
|
5
|
+
|
|
5
6
|
import { parseUnits } from 'viem'
|
|
6
7
|
import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts'
|
|
7
8
|
import { Addresses } from 'viem/tempo'
|
|
@@ -10,10 +11,11 @@ import * as Http from '~test/Http.js'
|
|
|
10
11
|
import { rpcUrl } from '~test/tempo/prool.js'
|
|
11
12
|
import { deployEscrow } from '~test/tempo/session.js'
|
|
12
13
|
import { accounts, asset, client, fundAccount } from '~test/tempo/viem.js'
|
|
14
|
+
|
|
13
15
|
import * as Credential from '../Credential.js'
|
|
14
|
-
import * as Store from '../Store.js'
|
|
15
16
|
import * as Mppx_server from '../server/Mppx.js'
|
|
16
17
|
import { toNodeListener } from '../server/Mppx.js'
|
|
18
|
+
import * as Store from '../Store.js'
|
|
17
19
|
import { stripe as stripe_server } from '../stripe/server/Methods.js'
|
|
18
20
|
import { tempo } from '../tempo/server/Methods.js'
|
|
19
21
|
import type { SessionCredentialPayload } from '../tempo/session/Types.js'
|
package/src/cli/cli.ts
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import * as fs from 'node:fs'
|
|
2
2
|
import { createRequire } from 'node:module'
|
|
3
3
|
import * as path from 'node:path'
|
|
4
|
+
|
|
4
5
|
import { Cli, Errors, z } from 'incur'
|
|
5
6
|
import { Base64 } from 'ox'
|
|
6
7
|
import { type Address, createClient, http } from 'viem'
|
|
7
8
|
import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts'
|
|
8
9
|
import { tempo as tempoMainnet } from 'viem/chains'
|
|
10
|
+
|
|
9
11
|
import * as Challenge from '../Challenge.js'
|
|
12
|
+
import { normalizeHeaders } from '../client/internal/Fetch.js'
|
|
10
13
|
import * as Mppx from '../client/Mppx.js'
|
|
11
14
|
import { createDefaultStore, createKeychain, resolveAccountName } from './account.js'
|
|
12
15
|
import { loadConfig, resolvePlugin } from './internal.js'
|
|
@@ -312,7 +315,7 @@ const cli = Cli.create('mppx', {
|
|
|
312
315
|
|
|
313
316
|
// Send credential and get response
|
|
314
317
|
const credentialHeaders = {
|
|
315
|
-
...(init.headers
|
|
318
|
+
...normalizeHeaders(init.headers),
|
|
316
319
|
Authorization: credential,
|
|
317
320
|
}
|
|
318
321
|
plugin?.prepareCredentialRequest?.({ challenge, credential, headers: credentialHeaders })
|
package/src/cli/config.test.ts
CHANGED
package/src/cli/internal.ts
CHANGED
package/src/cli/plugins/tempo.ts
CHANGED
|
@@ -3,11 +3,14 @@ import * as fs from 'node:fs'
|
|
|
3
3
|
import { createRequire } from 'node:module'
|
|
4
4
|
import * as os from 'node:os'
|
|
5
5
|
import * as path from 'node:path'
|
|
6
|
+
|
|
6
7
|
import { Errors, z } from 'incur'
|
|
7
8
|
import { Base64 } from 'ox'
|
|
8
9
|
import type { Address } from 'viem'
|
|
9
10
|
import { createClient, http } from 'viem'
|
|
10
11
|
import { privateKeyToAccount } from 'viem/accounts'
|
|
12
|
+
|
|
13
|
+
import { normalizeHeaders } from '../../client/internal/Fetch.js'
|
|
11
14
|
import * as Credential from '../../Credential.js'
|
|
12
15
|
import { tempo as tempoMethods } from '../../tempo/client/index.js'
|
|
13
16
|
import type { SessionCredentialPayload } from '../../tempo/session/Types.js'
|
|
@@ -610,7 +613,7 @@ async function closeChannel(opts: {
|
|
|
610
613
|
const closeRes = await globalThis.fetch(opts.fetchUrl, {
|
|
611
614
|
...opts.fetchInit,
|
|
612
615
|
headers: {
|
|
613
|
-
...(opts.fetchInit.headers
|
|
616
|
+
...normalizeHeaders(opts.fetchInit.headers),
|
|
614
617
|
Authorization: closeCred,
|
|
615
618
|
},
|
|
616
619
|
})
|
package/src/cli/utils.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { describe, expect, test, vi } from 'vitest'
|
|
|
6
6
|
import * as Http from '~test/Http.js'
|
|
7
7
|
import { rpcUrl } from '~test/tempo/prool.js'
|
|
8
8
|
import { accounts, asset, chain, client, http } from '~test/tempo/viem.js'
|
|
9
|
+
|
|
9
10
|
import * as Fetch from './Fetch.js'
|
|
10
11
|
|
|
11
12
|
const realm = 'api.example.com'
|
|
@@ -193,7 +193,7 @@ export function restore(): void {
|
|
|
193
193
|
}
|
|
194
194
|
|
|
195
195
|
/** @internal Normalizes headers to a plain object for spreading. */
|
|
196
|
-
function normalizeHeaders(headers: unknown): Record<string, string> {
|
|
196
|
+
export function normalizeHeaders(headers: unknown): Record<string, string> {
|
|
197
197
|
if (!headers) return {}
|
|
198
198
|
if (headers instanceof Headers) {
|
|
199
199
|
const result: Record<string, string> = {}
|