mppx 0.1.0 → 0.2.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/README.md +1 -1
- package/dist/Challenge.d.ts +18 -18
- package/dist/Challenge.d.ts.map +1 -1
- package/dist/Challenge.js +8 -8
- package/dist/Challenge.js.map +1 -1
- package/dist/Errors.d.ts +58 -8
- package/dist/Errors.d.ts.map +1 -1
- package/dist/Errors.js +51 -9
- package/dist/Errors.js.map +1 -1
- package/dist/Method.d.ts +154 -0
- package/dist/Method.d.ts.map +1 -0
- package/dist/Method.js +81 -0
- package/dist/Method.js.map +1 -0
- package/dist/PaymentRequest.d.ts +5 -5
- package/dist/PaymentRequest.d.ts.map +1 -1
- package/dist/PaymentRequest.js +5 -5
- package/dist/cli.js +67 -18
- package/dist/cli.js.map +1 -1
- package/dist/client/Methods.d.ts +2 -2
- package/dist/client/Methods.d.ts.map +1 -1
- package/dist/client/Methods.js +2 -2
- package/dist/client/Methods.js.map +1 -1
- package/dist/client/Mppx.d.ts +12 -7
- package/dist/client/Mppx.d.ts.map +1 -1
- package/dist/client/Mppx.js +10 -5
- package/dist/client/Mppx.js.map +1 -1
- package/dist/client/internal/Fetch.d.ts +13 -11
- package/dist/client/internal/Fetch.d.ts.map +1 -1
- package/dist/client/internal/Fetch.js +8 -4
- package/dist/client/internal/Fetch.js.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/dist/mcp-sdk/client/McpClient.d.ts +6 -6
- package/dist/mcp-sdk/client/McpClient.d.ts.map +1 -1
- package/dist/mcp-sdk/client/McpClient.js +4 -4
- package/dist/mcp-sdk/client/McpClient.js.map +1 -1
- package/dist/middlewares/elysia.d.ts +1 -1
- package/dist/middlewares/express.d.ts +1 -1
- package/dist/middlewares/hono.d.ts +1 -1
- package/dist/middlewares/internal/mppx.d.ts +7 -7
- package/dist/middlewares/internal/mppx.d.ts.map +1 -1
- package/dist/middlewares/internal/mppx.js +5 -5
- package/dist/middlewares/internal/mppx.js.map +1 -1
- package/dist/middlewares/nextjs.d.ts +1 -1
- package/dist/proxy/Service.js +2 -2
- package/dist/proxy/Service.js.map +1 -1
- package/dist/server/Methods.d.ts +2 -2
- package/dist/server/Methods.d.ts.map +1 -1
- package/dist/server/Methods.js +2 -2
- package/dist/server/Methods.js.map +1 -1
- package/dist/server/Mppx.d.ts +17 -17
- package/dist/server/Mppx.d.ts.map +1 -1
- package/dist/server/Mppx.js +9 -9
- package/dist/server/Mppx.js.map +1 -1
- package/dist/stripe/{Intents.d.ts → Methods.d.ts} +22 -22
- package/dist/stripe/Methods.d.ts.map +1 -0
- package/dist/stripe/Methods.js +42 -0
- package/dist/stripe/Methods.js.map +1 -0
- package/dist/stripe/client/Charge.d.ts +48 -44
- package/dist/stripe/client/Charge.d.ts.map +1 -1
- package/dist/stripe/client/Charge.js +22 -17
- package/dist/stripe/client/Charge.js.map +1 -1
- package/dist/stripe/client/{MethodIntents.d.ts → Methods.d.ts} +25 -24
- package/dist/stripe/client/Methods.d.ts.map +1 -0
- package/dist/stripe/client/{MethodIntents.js → Methods.js} +4 -4
- package/dist/stripe/client/Methods.js.map +1 -0
- package/dist/stripe/client/index.d.ts +1 -1
- package/dist/stripe/client/index.d.ts.map +1 -1
- package/dist/stripe/client/index.js +1 -1
- package/dist/stripe/client/index.js.map +1 -1
- package/dist/stripe/index.d.ts +1 -1
- package/dist/stripe/index.d.ts.map +1 -1
- package/dist/stripe/index.js +1 -1
- package/dist/stripe/index.js.map +1 -1
- package/dist/stripe/internal/types.d.ts +25 -0
- package/dist/stripe/internal/types.d.ts.map +1 -0
- package/dist/stripe/internal/types.js +2 -0
- package/dist/stripe/internal/types.js.map +1 -0
- package/dist/stripe/server/Charge.d.ts +47 -28
- package/dist/stripe/server/Charge.d.ts.map +1 -1
- package/dist/stripe/server/Charge.js +90 -32
- package/dist/stripe/server/Charge.js.map +1 -1
- package/dist/stripe/server/{MethodIntents.d.ts → Methods.d.ts} +24 -23
- package/dist/stripe/server/Methods.d.ts.map +1 -0
- package/dist/stripe/server/{MethodIntents.js → Methods.js} +3 -3
- package/dist/stripe/server/Methods.js.map +1 -0
- package/dist/stripe/server/index.d.ts +1 -1
- package/dist/stripe/server/index.d.ts.map +1 -1
- package/dist/stripe/server/index.js +1 -1
- package/dist/stripe/server/index.js.map +1 -1
- package/dist/tempo/{Intents.d.ts → Methods.d.ts} +72 -69
- package/dist/tempo/Methods.d.ts.map +1 -0
- package/dist/tempo/Methods.js +118 -0
- package/dist/tempo/Methods.js.map +1 -0
- package/dist/tempo/client/ChannelOps.d.ts +1 -1
- package/dist/tempo/client/ChannelOps.js +1 -1
- package/dist/tempo/client/Charge.d.ts +25 -25
- package/dist/tempo/client/Charge.d.ts.map +1 -1
- package/dist/tempo/client/Charge.js +3 -3
- package/dist/tempo/client/Charge.js.map +1 -1
- package/dist/tempo/client/{MethodIntents.d.ts → Methods.d.ts} +74 -70
- package/dist/tempo/client/Methods.d.ts.map +1 -0
- package/dist/tempo/client/{MethodIntents.js → Methods.js} +3 -3
- package/dist/tempo/client/Methods.js.map +1 -0
- package/dist/tempo/client/Session.d.ts +49 -45
- package/dist/tempo/client/Session.d.ts.map +1 -1
- package/dist/tempo/client/Session.js +4 -4
- package/dist/tempo/client/Session.js.map +1 -1
- package/dist/tempo/client/SessionManager.d.ts +1 -1
- package/dist/tempo/client/SessionManager.d.ts.map +1 -1
- package/dist/tempo/client/SessionManager.js +10 -5
- package/dist/tempo/client/SessionManager.js.map +1 -1
- package/dist/tempo/client/index.d.ts +1 -1
- package/dist/tempo/client/index.d.ts.map +1 -1
- package/dist/tempo/client/index.js +1 -1
- package/dist/tempo/client/index.js.map +1 -1
- package/dist/tempo/index.d.ts +1 -1
- package/dist/tempo/index.d.ts.map +1 -1
- package/dist/tempo/index.js +1 -1
- package/dist/tempo/index.js.map +1 -1
- package/dist/tempo/internal/defaults.d.ts +1 -1
- package/dist/tempo/internal/defaults.js +1 -1
- package/dist/tempo/server/Charge.d.ts +27 -27
- package/dist/tempo/server/Charge.d.ts.map +1 -1
- package/dist/tempo/server/Charge.js +3 -3
- package/dist/tempo/server/Charge.js.map +1 -1
- package/dist/tempo/server/{MethodIntents.d.ts → Methods.d.ts} +73 -69
- package/dist/tempo/server/Methods.d.ts.map +1 -0
- package/dist/tempo/server/{MethodIntents.js → Methods.js} +4 -4
- package/dist/tempo/server/Methods.js.map +1 -0
- package/dist/tempo/server/Session.d.ts +51 -47
- package/dist/tempo/server/Session.d.ts.map +1 -1
- package/dist/tempo/server/Session.js +4 -4
- package/dist/tempo/server/Session.js.map +1 -1
- package/dist/tempo/server/index.d.ts +6 -0
- package/dist/tempo/server/index.d.ts.map +1 -0
- package/dist/tempo/server/index.js +6 -0
- package/dist/tempo/server/index.js.map +1 -0
- package/dist/tempo/server/internal/transport.d.ts.map +1 -1
- package/dist/tempo/server/internal/transport.js +2 -1
- package/dist/tempo/server/internal/transport.js.map +1 -1
- package/package.json +1 -1
- package/src/Challenge.test-d.ts +3 -3
- package/src/Challenge.test.ts +6 -6
- package/src/Challenge.ts +34 -34
- package/src/Errors.test.ts +75 -21
- package/src/Errors.ts +74 -9
- package/src/Method.test.ts +76 -0
- package/src/Method.ts +228 -0
- package/src/PaymentRequest.test.ts +4 -4
- package/src/PaymentRequest.ts +9 -9
- package/src/cli.test.ts +12 -22
- package/src/cli.ts +74 -21
- package/src/client/Methods.ts +2 -2
- package/src/client/Mppx.test-d.ts +6 -6
- package/src/client/Mppx.test.ts +26 -22
- package/src/client/Mppx.ts +29 -13
- package/src/client/Transport.test.ts +2 -2
- package/src/client/internal/Fetch.test.ts +35 -1
- package/src/client/internal/Fetch.ts +36 -27
- package/src/index.ts +1 -2
- package/src/mcp-sdk/client/McpClient.ts +11 -13
- package/src/middlewares/elysia.ts +1 -1
- package/src/middlewares/express.ts +1 -1
- package/src/middlewares/hono.ts +1 -1
- package/src/middlewares/internal/mppx.ts +10 -10
- package/src/middlewares/nextjs.ts +1 -1
- package/src/proxy/Service.ts +2 -2
- package/src/server/Methods.ts +2 -2
- package/src/server/Mppx.test-d.ts +27 -29
- package/src/server/Mppx.test.ts +23 -19
- package/src/server/Mppx.ts +43 -43
- package/src/server/Transport.test.ts +3 -3
- package/src/stripe/Charge.integration.test.ts +4 -1
- package/src/stripe/{Intents.test.ts → Methods.test.ts} +12 -12
- package/src/stripe/Methods.ts +45 -0
- package/src/stripe/client/Charge.test.ts +189 -0
- package/src/stripe/client/Charge.ts +40 -31
- package/src/stripe/client/{MethodIntents.ts → Methods.ts} +3 -3
- package/src/stripe/client/index.ts +1 -1
- package/src/stripe/index.ts +1 -1
- package/src/stripe/internal/types.ts +22 -0
- package/src/stripe/server/Charge.test.ts +241 -0
- package/src/stripe/server/Charge.ts +124 -38
- package/src/stripe/server/{MethodIntents.ts → Methods.ts} +2 -2
- package/src/stripe/server/index.ts +1 -1
- package/src/tempo/{Intents.test.ts → Methods.test.ts} +15 -15
- package/src/tempo/{Intents.ts → Methods.ts} +77 -22
- package/src/tempo/client/ChannelOps.ts +1 -1
- package/src/tempo/client/Charge.ts +3 -3
- package/src/tempo/client/{MethodIntents.ts → Methods.ts} +2 -2
- package/src/tempo/client/Session.ts +4 -4
- package/src/tempo/client/SessionManager.ts +11 -5
- package/src/tempo/client/index.ts +1 -1
- package/src/tempo/index.ts +1 -1
- package/src/tempo/internal/defaults.ts +1 -1
- package/src/tempo/server/Charge.ts +4 -7
- package/src/tempo/server/{MethodIntents.ts → Methods.ts} +3 -3
- package/src/tempo/server/Session.test.ts +4 -7
- package/src/tempo/server/Session.ts +6 -6
- package/src/tempo/server/index.ts +1 -1
- package/src/tempo/server/internal/transport.ts +3 -2
- package/dist/Intent.d.ts +0 -101
- package/dist/Intent.d.ts.map +0 -1
- package/dist/Intent.js +0 -83
- package/dist/Intent.js.map +0 -1
- package/dist/MethodIntent.d.ts +0 -225
- package/dist/MethodIntent.d.ts.map +0 -1
- package/dist/MethodIntent.js +0 -156
- package/dist/MethodIntent.js.map +0 -1
- package/dist/stripe/Intents.d.ts.map +0 -1
- package/dist/stripe/Intents.js +0 -27
- package/dist/stripe/Intents.js.map +0 -1
- package/dist/stripe/client/MethodIntents.d.ts.map +0 -1
- package/dist/stripe/client/MethodIntents.js.map +0 -1
- package/dist/stripe/server/MethodIntents.d.ts.map +0 -1
- package/dist/stripe/server/MethodIntents.js.map +0 -1
- package/dist/tempo/Intents.d.ts.map +0 -1
- package/dist/tempo/Intents.js +0 -81
- package/dist/tempo/Intents.js.map +0 -1
- package/dist/tempo/client/MethodIntents.d.ts.map +0 -1
- package/dist/tempo/client/MethodIntents.js.map +0 -1
- package/dist/tempo/server/MethodIntents.d.ts.map +0 -1
- package/dist/tempo/server/MethodIntents.js.map +0 -1
- package/src/Intent.test.ts +0 -180
- package/src/Intent.ts +0 -109
- package/src/MethodIntent.test.ts +0 -303
- package/src/MethodIntent.ts +0 -388
- package/src/stripe/Intents.ts +0 -27
package/src/Errors.test.ts
CHANGED
|
@@ -11,6 +11,8 @@ import {
|
|
|
11
11
|
InvalidSignatureError,
|
|
12
12
|
MalformedCredentialError,
|
|
13
13
|
PaymentExpiredError,
|
|
14
|
+
PaymentInsufficientError,
|
|
15
|
+
PaymentMethodUnsupportedError,
|
|
14
16
|
PaymentRequiredError,
|
|
15
17
|
SignerMismatchError,
|
|
16
18
|
VerificationFailedError,
|
|
@@ -32,7 +34,7 @@ describe('MalformedCredentialError', () => {
|
|
|
32
34
|
"message": "Credential is malformed.",
|
|
33
35
|
"name": "MalformedCredentialError",
|
|
34
36
|
"status": 402,
|
|
35
|
-
"type": "https://
|
|
37
|
+
"type": "https://paymentauth.org/problems/malformed-credential",
|
|
36
38
|
}
|
|
37
39
|
`)
|
|
38
40
|
})
|
|
@@ -45,7 +47,7 @@ describe('MalformedCredentialError', () => {
|
|
|
45
47
|
"message": "Credential is malformed: invalid base64url.",
|
|
46
48
|
"name": "MalformedCredentialError",
|
|
47
49
|
"status": 402,
|
|
48
|
-
"type": "https://
|
|
50
|
+
"type": "https://paymentauth.org/problems/malformed-credential",
|
|
49
51
|
}
|
|
50
52
|
`)
|
|
51
53
|
})
|
|
@@ -58,7 +60,7 @@ describe('InvalidChallengeError', () => {
|
|
|
58
60
|
"message": "Challenge is invalid.",
|
|
59
61
|
"name": "InvalidChallengeError",
|
|
60
62
|
"status": 402,
|
|
61
|
-
"type": "https://
|
|
63
|
+
"type": "https://paymentauth.org/problems/invalid-challenge",
|
|
62
64
|
}
|
|
63
65
|
`)
|
|
64
66
|
})
|
|
@@ -69,7 +71,7 @@ describe('InvalidChallengeError', () => {
|
|
|
69
71
|
"message": "Challenge "abc123" is invalid.",
|
|
70
72
|
"name": "InvalidChallengeError",
|
|
71
73
|
"status": 402,
|
|
72
|
-
"type": "https://
|
|
74
|
+
"type": "https://paymentauth.org/problems/invalid-challenge",
|
|
73
75
|
}
|
|
74
76
|
`)
|
|
75
77
|
})
|
|
@@ -80,7 +82,7 @@ describe('InvalidChallengeError', () => {
|
|
|
80
82
|
"message": "Challenge is invalid: expired.",
|
|
81
83
|
"name": "InvalidChallengeError",
|
|
82
84
|
"status": 402,
|
|
83
|
-
"type": "https://
|
|
85
|
+
"type": "https://paymentauth.org/problems/invalid-challenge",
|
|
84
86
|
}
|
|
85
87
|
`)
|
|
86
88
|
})
|
|
@@ -93,7 +95,7 @@ describe('InvalidChallengeError', () => {
|
|
|
93
95
|
"message": "Challenge "abc123" is invalid: already used.",
|
|
94
96
|
"name": "InvalidChallengeError",
|
|
95
97
|
"status": 402,
|
|
96
|
-
"type": "https://
|
|
98
|
+
"type": "https://paymentauth.org/problems/invalid-challenge",
|
|
97
99
|
}
|
|
98
100
|
`)
|
|
99
101
|
})
|
|
@@ -106,7 +108,7 @@ describe('VerificationFailedError', () => {
|
|
|
106
108
|
"message": "Payment verification failed.",
|
|
107
109
|
"name": "VerificationFailedError",
|
|
108
110
|
"status": 402,
|
|
109
|
-
"type": "https://
|
|
111
|
+
"type": "https://paymentauth.org/problems/verification-failed",
|
|
110
112
|
}
|
|
111
113
|
`)
|
|
112
114
|
})
|
|
@@ -119,7 +121,7 @@ describe('VerificationFailedError', () => {
|
|
|
119
121
|
"message": "Payment verification failed: invalid signature.",
|
|
120
122
|
"name": "VerificationFailedError",
|
|
121
123
|
"status": 402,
|
|
122
|
-
"type": "https://
|
|
124
|
+
"type": "https://paymentauth.org/problems/verification-failed",
|
|
123
125
|
}
|
|
124
126
|
`)
|
|
125
127
|
})
|
|
@@ -132,7 +134,7 @@ describe('PaymentExpiredError', () => {
|
|
|
132
134
|
"message": "Payment has expired.",
|
|
133
135
|
"name": "PaymentExpiredError",
|
|
134
136
|
"status": 402,
|
|
135
|
-
"type": "https://
|
|
137
|
+
"type": "https://paymentauth.org/problems/payment-expired",
|
|
136
138
|
}
|
|
137
139
|
`)
|
|
138
140
|
})
|
|
@@ -145,7 +147,7 @@ describe('PaymentExpiredError', () => {
|
|
|
145
147
|
"message": "Payment expired at 2025-01-26T12:00:00Z.",
|
|
146
148
|
"name": "PaymentExpiredError",
|
|
147
149
|
"status": 402,
|
|
148
|
-
"type": "https://
|
|
150
|
+
"type": "https://paymentauth.org/problems/payment-expired",
|
|
149
151
|
}
|
|
150
152
|
`)
|
|
151
153
|
})
|
|
@@ -158,7 +160,7 @@ describe('PaymentRequiredError', () => {
|
|
|
158
160
|
"message": "Payment is required.",
|
|
159
161
|
"name": "PaymentRequiredError",
|
|
160
162
|
"status": 402,
|
|
161
|
-
"type": "https://
|
|
163
|
+
"type": "https://paymentauth.org/problems/payment-required",
|
|
162
164
|
}
|
|
163
165
|
`)
|
|
164
166
|
})
|
|
@@ -171,7 +173,7 @@ describe('PaymentRequiredError', () => {
|
|
|
171
173
|
"message": "Payment is required for "api.example.com".",
|
|
172
174
|
"name": "PaymentRequiredError",
|
|
173
175
|
"status": 402,
|
|
174
|
-
"type": "https://
|
|
176
|
+
"type": "https://paymentauth.org/problems/payment-required",
|
|
175
177
|
}
|
|
176
178
|
`)
|
|
177
179
|
})
|
|
@@ -186,7 +188,7 @@ describe('PaymentRequiredError', () => {
|
|
|
186
188
|
"message": "Payment is required for "api.example.com" (API access fee).",
|
|
187
189
|
"name": "PaymentRequiredError",
|
|
188
190
|
"status": 402,
|
|
189
|
-
"type": "https://
|
|
191
|
+
"type": "https://paymentauth.org/problems/payment-required",
|
|
190
192
|
}
|
|
191
193
|
`)
|
|
192
194
|
})
|
|
@@ -199,7 +201,7 @@ describe('InvalidPayloadError', () => {
|
|
|
199
201
|
"message": "Credential payload is invalid.",
|
|
200
202
|
"name": "InvalidPayloadError",
|
|
201
203
|
"status": 402,
|
|
202
|
-
"type": "https://
|
|
204
|
+
"type": "https://paymentauth.org/problems/invalid-payload",
|
|
203
205
|
}
|
|
204
206
|
`)
|
|
205
207
|
})
|
|
@@ -212,7 +214,7 @@ describe('InvalidPayloadError', () => {
|
|
|
212
214
|
"message": "Credential payload is invalid: missing signature field.",
|
|
213
215
|
"name": "InvalidPayloadError",
|
|
214
216
|
"status": 402,
|
|
215
|
-
"type": "https://
|
|
217
|
+
"type": "https://paymentauth.org/problems/invalid-payload",
|
|
216
218
|
}
|
|
217
219
|
`)
|
|
218
220
|
})
|
|
@@ -225,7 +227,7 @@ describe('BadRequestError', () => {
|
|
|
225
227
|
"message": "Bad request.",
|
|
226
228
|
"name": "BadRequestError",
|
|
227
229
|
"status": 400,
|
|
228
|
-
"type": "https://
|
|
230
|
+
"type": "https://paymentauth.org/problems/bad-request",
|
|
229
231
|
}
|
|
230
232
|
`)
|
|
231
233
|
})
|
|
@@ -238,7 +240,59 @@ describe('BadRequestError', () => {
|
|
|
238
240
|
"message": "Bad request: cannot combine hash type with feePayer.",
|
|
239
241
|
"name": "BadRequestError",
|
|
240
242
|
"status": 400,
|
|
241
|
-
"type": "https://
|
|
243
|
+
"type": "https://paymentauth.org/problems/bad-request",
|
|
244
|
+
}
|
|
245
|
+
`)
|
|
246
|
+
})
|
|
247
|
+
})
|
|
248
|
+
|
|
249
|
+
describe('PaymentInsufficientError', () => {
|
|
250
|
+
test('default', () => {
|
|
251
|
+
expect(errorSnapshot(new PaymentInsufficientError())).toMatchInlineSnapshot(`
|
|
252
|
+
{
|
|
253
|
+
"message": "Payment amount is insufficient.",
|
|
254
|
+
"name": "PaymentInsufficientError",
|
|
255
|
+
"status": 402,
|
|
256
|
+
"type": "https://paymentauth.org/problems/payment-insufficient",
|
|
257
|
+
}
|
|
258
|
+
`)
|
|
259
|
+
})
|
|
260
|
+
|
|
261
|
+
test('with reason', () => {
|
|
262
|
+
expect(
|
|
263
|
+
errorSnapshot(new PaymentInsufficientError({ reason: 'expected 1000, received 500' })),
|
|
264
|
+
).toMatchInlineSnapshot(`
|
|
265
|
+
{
|
|
266
|
+
"message": "Payment insufficient: expected 1000, received 500.",
|
|
267
|
+
"name": "PaymentInsufficientError",
|
|
268
|
+
"status": 402,
|
|
269
|
+
"type": "https://paymentauth.org/problems/payment-insufficient",
|
|
270
|
+
}
|
|
271
|
+
`)
|
|
272
|
+
})
|
|
273
|
+
})
|
|
274
|
+
|
|
275
|
+
describe('PaymentMethodUnsupportedError', () => {
|
|
276
|
+
test('default', () => {
|
|
277
|
+
expect(errorSnapshot(new PaymentMethodUnsupportedError())).toMatchInlineSnapshot(`
|
|
278
|
+
{
|
|
279
|
+
"message": "Payment method is not supported.",
|
|
280
|
+
"name": "PaymentMethodUnsupportedError",
|
|
281
|
+
"status": 400,
|
|
282
|
+
"type": "https://paymentauth.org/problems/method-unsupported",
|
|
283
|
+
}
|
|
284
|
+
`)
|
|
285
|
+
})
|
|
286
|
+
|
|
287
|
+
test('with method', () => {
|
|
288
|
+
expect(
|
|
289
|
+
errorSnapshot(new PaymentMethodUnsupportedError({ method: 'bitcoin' })),
|
|
290
|
+
).toMatchInlineSnapshot(`
|
|
291
|
+
{
|
|
292
|
+
"message": "Payment method "bitcoin" is not supported.",
|
|
293
|
+
"name": "PaymentMethodUnsupportedError",
|
|
294
|
+
"status": 400,
|
|
295
|
+
"type": "https://paymentauth.org/problems/method-unsupported",
|
|
242
296
|
}
|
|
243
297
|
`)
|
|
244
298
|
})
|
|
@@ -381,8 +435,8 @@ describe('toProblemDetails', () => {
|
|
|
381
435
|
{
|
|
382
436
|
"detail": "Credential is malformed: invalid JSON.",
|
|
383
437
|
"status": 402,
|
|
384
|
-
"title": "
|
|
385
|
-
"type": "https://
|
|
438
|
+
"title": "Malformed Credential",
|
|
439
|
+
"type": "https://paymentauth.org/problems/malformed-credential",
|
|
386
440
|
}
|
|
387
441
|
`)
|
|
388
442
|
})
|
|
@@ -394,8 +448,8 @@ describe('toProblemDetails', () => {
|
|
|
394
448
|
"challengeId": "abc123",
|
|
395
449
|
"detail": "Challenge "abc123" is invalid: expired.",
|
|
396
450
|
"status": 402,
|
|
397
|
-
"title": "
|
|
398
|
-
"type": "https://
|
|
451
|
+
"title": "Invalid Challenge",
|
|
452
|
+
"type": "https://paymentauth.org/problems/invalid-challenge",
|
|
399
453
|
}
|
|
400
454
|
`)
|
|
401
455
|
})
|
package/src/Errors.ts
CHANGED
|
@@ -5,6 +5,9 @@ export abstract class PaymentError extends Error {
|
|
|
5
5
|
/** RFC 9457 Problem Details type URI. */
|
|
6
6
|
abstract readonly type: string
|
|
7
7
|
|
|
8
|
+
/** Human-readable summary for RFC 9457 Problem Details. */
|
|
9
|
+
abstract readonly title: string
|
|
10
|
+
|
|
8
11
|
/** HTTP status code. */
|
|
9
12
|
readonly status: number = 402
|
|
10
13
|
|
|
@@ -12,7 +15,7 @@ export abstract class PaymentError extends Error {
|
|
|
12
15
|
toProblemDetails(challengeId?: string): PaymentError.ProblemDetails {
|
|
13
16
|
return {
|
|
14
17
|
type: this.type,
|
|
15
|
-
title: this.
|
|
18
|
+
title: this.title,
|
|
16
19
|
status: this.status,
|
|
17
20
|
detail: this.message,
|
|
18
21
|
...(challengeId && { challengeId }),
|
|
@@ -40,7 +43,9 @@ export declare namespace PaymentError {
|
|
|
40
43
|
*/
|
|
41
44
|
export class MalformedCredentialError extends PaymentError {
|
|
42
45
|
override readonly name = 'MalformedCredentialError'
|
|
43
|
-
readonly
|
|
46
|
+
readonly title = 'Malformed Credential'
|
|
47
|
+
override readonly status = 402
|
|
48
|
+
readonly type = 'https://paymentauth.org/problems/malformed-credential'
|
|
44
49
|
|
|
45
50
|
constructor(options: MalformedCredentialError.Options = {}) {
|
|
46
51
|
const { reason } = options
|
|
@@ -60,7 +65,9 @@ export declare namespace MalformedCredentialError {
|
|
|
60
65
|
*/
|
|
61
66
|
export class InvalidChallengeError extends PaymentError {
|
|
62
67
|
override readonly name = 'InvalidChallengeError'
|
|
63
|
-
readonly
|
|
68
|
+
readonly title = 'Invalid Challenge'
|
|
69
|
+
override readonly status = 402
|
|
70
|
+
readonly type = 'https://paymentauth.org/problems/invalid-challenge'
|
|
64
71
|
|
|
65
72
|
constructor(options: InvalidChallengeError.Options = {}) {
|
|
66
73
|
const { id, reason } = options
|
|
@@ -84,7 +91,8 @@ export declare namespace InvalidChallengeError {
|
|
|
84
91
|
*/
|
|
85
92
|
export class VerificationFailedError extends PaymentError {
|
|
86
93
|
override readonly name = 'VerificationFailedError'
|
|
87
|
-
readonly
|
|
94
|
+
readonly title = 'Verification Failed'
|
|
95
|
+
readonly type = 'https://paymentauth.org/problems/verification-failed'
|
|
88
96
|
|
|
89
97
|
constructor(options: VerificationFailedError.Options = {}) {
|
|
90
98
|
const { reason } = options
|
|
@@ -104,7 +112,8 @@ export declare namespace VerificationFailedError {
|
|
|
104
112
|
*/
|
|
105
113
|
export class PaymentActionRequiredError extends PaymentError {
|
|
106
114
|
override readonly name = 'PaymentActionRequiredError'
|
|
107
|
-
readonly
|
|
115
|
+
readonly title = 'Payment Action Required'
|
|
116
|
+
readonly type = 'https://paymentauth.org/problems/payment-action-required'
|
|
108
117
|
|
|
109
118
|
constructor(options: PaymentActionRequiredError.Options = {}) {
|
|
110
119
|
const { reason } = options
|
|
@@ -124,7 +133,8 @@ export declare namespace PaymentActionRequiredError {
|
|
|
124
133
|
*/
|
|
125
134
|
export class PaymentExpiredError extends PaymentError {
|
|
126
135
|
override readonly name = 'PaymentExpiredError'
|
|
127
|
-
readonly
|
|
136
|
+
readonly title = 'Payment Expired'
|
|
137
|
+
readonly type = 'https://paymentauth.org/problems/payment-expired'
|
|
128
138
|
|
|
129
139
|
constructor(options: PaymentExpiredError.Options = {}) {
|
|
130
140
|
const { expires } = options
|
|
@@ -144,7 +154,8 @@ export declare namespace PaymentExpiredError {
|
|
|
144
154
|
*/
|
|
145
155
|
export class PaymentRequiredError extends PaymentError {
|
|
146
156
|
override readonly name = 'PaymentRequiredError'
|
|
147
|
-
readonly
|
|
157
|
+
readonly title = 'Payment Required'
|
|
158
|
+
readonly type = 'https://paymentauth.org/problems/payment-required'
|
|
148
159
|
|
|
149
160
|
constructor(options: PaymentRequiredError.Options = {}) {
|
|
150
161
|
const { description, realm } = options
|
|
@@ -169,7 +180,8 @@ export declare namespace PaymentRequiredError {
|
|
|
169
180
|
*/
|
|
170
181
|
export class InvalidPayloadError extends PaymentError {
|
|
171
182
|
override readonly name = 'InvalidPayloadError'
|
|
172
|
-
readonly
|
|
183
|
+
readonly title = 'Invalid Payload'
|
|
184
|
+
readonly type = 'https://paymentauth.org/problems/invalid-payload'
|
|
173
185
|
|
|
174
186
|
constructor(options: InvalidPayloadError.Options = {}) {
|
|
175
187
|
const { reason } = options
|
|
@@ -189,8 +201,9 @@ export declare namespace InvalidPayloadError {
|
|
|
189
201
|
*/
|
|
190
202
|
export class BadRequestError extends PaymentError {
|
|
191
203
|
override readonly name = 'BadRequestError'
|
|
204
|
+
readonly title = 'Bad Request'
|
|
192
205
|
override readonly status = 400
|
|
193
|
-
readonly type = 'https://
|
|
206
|
+
readonly type = 'https://paymentauth.org/problems/bad-request'
|
|
194
207
|
|
|
195
208
|
constructor(options: BadRequestError.Options = {}) {
|
|
196
209
|
const { reason } = options
|
|
@@ -205,11 +218,57 @@ export declare namespace BadRequestError {
|
|
|
205
218
|
}
|
|
206
219
|
}
|
|
207
220
|
|
|
221
|
+
/**
|
|
222
|
+
* Payment amount is insufficient (too low).
|
|
223
|
+
*/
|
|
224
|
+
export class PaymentInsufficientError extends PaymentError {
|
|
225
|
+
override readonly name = 'PaymentInsufficientError'
|
|
226
|
+
readonly title = 'Payment Insufficient'
|
|
227
|
+
readonly type = 'https://paymentauth.org/problems/payment-insufficient'
|
|
228
|
+
|
|
229
|
+
constructor(options: PaymentInsufficientError.Options = {}) {
|
|
230
|
+
const { reason } = options
|
|
231
|
+
super(reason ? `Payment insufficient: ${reason}.` : 'Payment amount is insufficient.')
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export declare namespace PaymentInsufficientError {
|
|
236
|
+
type Options = {
|
|
237
|
+
/** Reason the payment is insufficient (e.g., "expected 1000, received 500"). */
|
|
238
|
+
reason?: string
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Payment method is not supported by the server.
|
|
244
|
+
*/
|
|
245
|
+
export class PaymentMethodUnsupportedError extends PaymentError {
|
|
246
|
+
override readonly name = 'PaymentMethodUnsupportedError'
|
|
247
|
+
readonly title = 'Method Unsupported'
|
|
248
|
+
override readonly status = 400
|
|
249
|
+
readonly type = 'https://paymentauth.org/problems/method-unsupported'
|
|
250
|
+
|
|
251
|
+
constructor(options: PaymentMethodUnsupportedError.Options = {}) {
|
|
252
|
+
const { method } = options
|
|
253
|
+
super(
|
|
254
|
+
method ? `Payment method "${method}" is not supported.` : 'Payment method is not supported.',
|
|
255
|
+
)
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export declare namespace PaymentMethodUnsupportedError {
|
|
260
|
+
type Options = {
|
|
261
|
+
/** The unsupported method identifier. */
|
|
262
|
+
method?: string
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
208
266
|
/**
|
|
209
267
|
* Insufficient balance in the payment channel.
|
|
210
268
|
*/
|
|
211
269
|
export class InsufficientBalanceError extends PaymentError {
|
|
212
270
|
override readonly name = 'InsufficientBalanceError'
|
|
271
|
+
readonly title = 'Insufficient Balance'
|
|
213
272
|
override readonly status = 402
|
|
214
273
|
readonly type = 'https://paymentauth.org/problems/stream/insufficient-balance'
|
|
215
274
|
|
|
@@ -231,6 +290,7 @@ export declare namespace InsufficientBalanceError {
|
|
|
231
290
|
*/
|
|
232
291
|
export class InvalidSignatureError extends PaymentError {
|
|
233
292
|
override readonly name = 'InvalidSignatureError'
|
|
293
|
+
readonly title = 'Invalid Signature'
|
|
234
294
|
override readonly status = 402
|
|
235
295
|
readonly type = 'https://paymentauth.org/problems/stream/invalid-signature'
|
|
236
296
|
|
|
@@ -251,6 +311,7 @@ export declare namespace InvalidSignatureError {
|
|
|
251
311
|
*/
|
|
252
312
|
export class SignerMismatchError extends PaymentError {
|
|
253
313
|
override readonly name = 'SignerMismatchError'
|
|
314
|
+
readonly title = 'Signer Mismatch'
|
|
254
315
|
override readonly status = 402
|
|
255
316
|
readonly type = 'https://paymentauth.org/problems/stream/signer-mismatch'
|
|
256
317
|
|
|
@@ -271,6 +332,7 @@ export declare namespace SignerMismatchError {
|
|
|
271
332
|
*/
|
|
272
333
|
export class AmountExceedsDepositError extends PaymentError {
|
|
273
334
|
override readonly name = 'AmountExceedsDepositError'
|
|
335
|
+
readonly title = 'Amount Exceeds Deposit'
|
|
274
336
|
override readonly status = 402
|
|
275
337
|
readonly type = 'https://paymentauth.org/problems/stream/amount-exceeds-deposit'
|
|
276
338
|
|
|
@@ -291,6 +353,7 @@ export declare namespace AmountExceedsDepositError {
|
|
|
291
353
|
*/
|
|
292
354
|
export class DeltaTooSmallError extends PaymentError {
|
|
293
355
|
override readonly name = 'DeltaTooSmallError'
|
|
356
|
+
readonly title = 'Delta Too Small'
|
|
294
357
|
override readonly status = 402
|
|
295
358
|
readonly type = 'https://paymentauth.org/problems/stream/delta-too-small'
|
|
296
359
|
|
|
@@ -311,6 +374,7 @@ export declare namespace DeltaTooSmallError {
|
|
|
311
374
|
*/
|
|
312
375
|
export class ChannelNotFoundError extends PaymentError {
|
|
313
376
|
override readonly name = 'ChannelNotFoundError'
|
|
377
|
+
readonly title = 'Channel Not Found'
|
|
314
378
|
override readonly status = 410
|
|
315
379
|
readonly type = 'https://paymentauth.org/problems/stream/channel-not-found'
|
|
316
380
|
|
|
@@ -331,6 +395,7 @@ export declare namespace ChannelNotFoundError {
|
|
|
331
395
|
*/
|
|
332
396
|
export class ChannelClosedError extends PaymentError {
|
|
333
397
|
override readonly name = 'ChannelClosedError'
|
|
398
|
+
readonly title = 'Channel Closed'
|
|
334
399
|
override readonly status = 410
|
|
335
400
|
readonly type = 'https://paymentauth.org/problems/stream/channel-finalized'
|
|
336
401
|
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Method, z } from 'mppx'
|
|
2
|
+
import { describe, expect, expectTypeOf, test } from 'vitest'
|
|
3
|
+
|
|
4
|
+
describe('from', () => {
|
|
5
|
+
test('behavior: creates intent', () => {
|
|
6
|
+
const method = Method.from({
|
|
7
|
+
name: 'tempo',
|
|
8
|
+
intent: 'charge',
|
|
9
|
+
schema: {
|
|
10
|
+
credential: {
|
|
11
|
+
payload: z.object({
|
|
12
|
+
signature: z.string(),
|
|
13
|
+
}),
|
|
14
|
+
},
|
|
15
|
+
request: z.object({
|
|
16
|
+
amount: z.string(),
|
|
17
|
+
currency: z.string(),
|
|
18
|
+
}),
|
|
19
|
+
},
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
expect(method.intent).toBe('charge')
|
|
23
|
+
expect(method.name).toBe('tempo')
|
|
24
|
+
expect(method.schema.request).toBeDefined()
|
|
25
|
+
expect(method.schema.credential.payload).toBeDefined()
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
test('types: intent literal is inferred', () => {
|
|
29
|
+
const method = Method.from({
|
|
30
|
+
name: 'tempo',
|
|
31
|
+
intent: 'charge',
|
|
32
|
+
schema: {
|
|
33
|
+
credential: { payload: z.object({ sig: z.string() }) },
|
|
34
|
+
request: z.object({ amount: z.string() }),
|
|
35
|
+
},
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
expectTypeOf(method.intent).toEqualTypeOf<'charge'>()
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
test('types: name literal is inferred', () => {
|
|
42
|
+
const method = Method.from({
|
|
43
|
+
name: 'tempo',
|
|
44
|
+
intent: 'charge',
|
|
45
|
+
schema: {
|
|
46
|
+
credential: { payload: z.object({ sig: z.string() }) },
|
|
47
|
+
request: z.object({ amount: z.string() }),
|
|
48
|
+
},
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
expectTypeOf(method.name).toEqualTypeOf<'tempo'>()
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
test('types: schema types are preserved', () => {
|
|
55
|
+
const requestSchema = z.object({
|
|
56
|
+
amount: z.string(),
|
|
57
|
+
currency: z.string(),
|
|
58
|
+
})
|
|
59
|
+
const payloadSchema = z.object({
|
|
60
|
+
signature: z.string(),
|
|
61
|
+
type: z.literal('transaction'),
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
const method = Method.from({
|
|
65
|
+
name: 'tempo',
|
|
66
|
+
intent: 'charge',
|
|
67
|
+
schema: {
|
|
68
|
+
credential: { payload: payloadSchema },
|
|
69
|
+
request: requestSchema,
|
|
70
|
+
},
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
expectTypeOf(method.schema.request).toEqualTypeOf(requestSchema)
|
|
74
|
+
expectTypeOf(method.schema.credential.payload).toEqualTypeOf(payloadSchema)
|
|
75
|
+
})
|
|
76
|
+
})
|