mppx 0.1.1 → 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/dist/Challenge.d.ts +16 -16
- package/dist/Challenge.d.ts.map +1 -1
- package/dist/Challenge.js +7 -7
- 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 +7 -7
- package/dist/client/Mppx.d.ts.map +1 -1
- package/dist/client/Mppx.js +3 -3
- package/dist/client/Mppx.js.map +1 -1
- package/dist/client/internal/Fetch.d.ts +10 -10
- package/dist/client/internal/Fetch.d.ts.map +1 -1
- package/dist/client/internal/Fetch.js +2 -2
- 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 +40 -27
- package/dist/stripe/client/Charge.d.ts.map +1 -1
- package/dist/stripe/client/Charge.js +15 -7
- package/dist/stripe/client/Charge.js.map +1 -1
- package/dist/stripe/client/{MethodIntents.d.ts → Methods.d.ts} +24 -23
- package/dist/stripe/client/Methods.d.ts.map +1 -0
- package/dist/stripe/client/{MethodIntents.js → Methods.js} +3 -3
- 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.js +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/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/package.json +1 -1
- package/src/Challenge.test-d.ts +3 -3
- package/src/Challenge.test.ts +6 -6
- package/src/Challenge.ts +32 -32
- 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 +10 -10
- package/src/client/Transport.test.ts +2 -2
- package/src/client/internal/Fetch.ts +21 -24
- 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/{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 +29 -16
- package/src/stripe/client/{MethodIntents.ts → Methods.ts} +2 -2
- 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 +1 -1
- package/src/tempo/client/index.ts +1 -1
- package/src/tempo/index.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/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.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
|
+
})
|
package/src/Method.ts
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import type * as Challenge from './Challenge.js'
|
|
2
|
+
import type * as Credential from './Credential.js'
|
|
3
|
+
import type { ExactPartial, LooseOmit, MaybePromise } from './internal/types.js'
|
|
4
|
+
import type * as Receipt from './Receipt.js'
|
|
5
|
+
import type * as Transport from './server/Transport.js'
|
|
6
|
+
import type * as z from './zod.js'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A payment method.
|
|
10
|
+
*/
|
|
11
|
+
export type Method = {
|
|
12
|
+
name: string
|
|
13
|
+
intent: string
|
|
14
|
+
schema: {
|
|
15
|
+
credential: {
|
|
16
|
+
payload: z.ZodMiniType
|
|
17
|
+
}
|
|
18
|
+
request: z.ZodMiniType<Record<string, unknown>>
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Creates a payment method.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* import { z } from 'zod/mini'
|
|
28
|
+
* import { Method } from 'mppx'
|
|
29
|
+
*
|
|
30
|
+
* const tempoCharge = Method.from({
|
|
31
|
+
* name: 'tempo',
|
|
32
|
+
* intent: 'charge',
|
|
33
|
+
* schema: {
|
|
34
|
+
* credential: {
|
|
35
|
+
* payload: z.object({
|
|
36
|
+
* signature: z.string(),
|
|
37
|
+
* type: z.literal('transaction'),
|
|
38
|
+
* }),
|
|
39
|
+
* },
|
|
40
|
+
* request: z.object({
|
|
41
|
+
* amount: z.string(),
|
|
42
|
+
* currency: z.string(),
|
|
43
|
+
* recipient: z.string(),
|
|
44
|
+
* }),
|
|
45
|
+
* },
|
|
46
|
+
* })
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export function from<const method extends Method>(method: method): method {
|
|
50
|
+
return method
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* A client-side configured method with credential creation logic.
|
|
55
|
+
*/
|
|
56
|
+
export type Client<
|
|
57
|
+
method extends Method = Method,
|
|
58
|
+
context extends z.ZodMiniType | undefined = z.ZodMiniType | undefined,
|
|
59
|
+
> = method & {
|
|
60
|
+
context?: context
|
|
61
|
+
createCredential: CreateCredentialFn<
|
|
62
|
+
method,
|
|
63
|
+
context extends z.ZodMiniType ? z.output<context> : Record<never, never>
|
|
64
|
+
>
|
|
65
|
+
}
|
|
66
|
+
export type AnyClient = Client<any, any>
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* A server-side configured method with verification logic.
|
|
70
|
+
*/
|
|
71
|
+
export type Server<
|
|
72
|
+
method extends Method = Method,
|
|
73
|
+
defaults extends ExactPartial<z.input<method['schema']['request']>> = {},
|
|
74
|
+
transportOverride = undefined,
|
|
75
|
+
> = method & {
|
|
76
|
+
defaults?: defaults | undefined
|
|
77
|
+
request?: RequestFn<method> | undefined
|
|
78
|
+
respond?: RespondFn<method> | undefined
|
|
79
|
+
transport?: transportOverride | undefined
|
|
80
|
+
verify: VerifyFn<method>
|
|
81
|
+
}
|
|
82
|
+
export type AnyServer = Server<any, any, any>
|
|
83
|
+
|
|
84
|
+
/** Credential creation function for a single method. */
|
|
85
|
+
export type CreateCredentialFn<method extends Method, context = unknown> = (
|
|
86
|
+
parameters: {
|
|
87
|
+
challenge: Challenge.Challenge<
|
|
88
|
+
z.output<method['schema']['request']>,
|
|
89
|
+
method['intent'],
|
|
90
|
+
method['name']
|
|
91
|
+
>
|
|
92
|
+
} & ([keyof context] extends [never] ? unknown : { context: context }),
|
|
93
|
+
) => Promise<string>
|
|
94
|
+
|
|
95
|
+
/** Request transform function for a single method. */
|
|
96
|
+
export type RequestFn<method extends Method> = (options: {
|
|
97
|
+
credential?: Credential.Credential | null | undefined
|
|
98
|
+
request: z.input<method['schema']['request']>
|
|
99
|
+
}) => MaybePromise<z.input<method['schema']['request']>>
|
|
100
|
+
|
|
101
|
+
/** Verification function for a single method. */
|
|
102
|
+
export type VerifyFn<method extends Method> = (parameters: {
|
|
103
|
+
credential: Credential.Credential<
|
|
104
|
+
z.output<method['schema']['credential']['payload']>,
|
|
105
|
+
Challenge.Challenge<z.output<method['schema']['request']>, method['intent'], method['name']>
|
|
106
|
+
>
|
|
107
|
+
request: z.input<method['schema']['request']>
|
|
108
|
+
}) => Promise<Receipt.Receipt>
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Optional respond function for a server-side method.
|
|
112
|
+
*
|
|
113
|
+
* Called after `verify` succeeds. If it returns a `Response`, the library
|
|
114
|
+
* treats the request as fully handled (e.g. channel open/close) and
|
|
115
|
+
* `withReceipt()` will short-circuit — returning the management response
|
|
116
|
+
* with the receipt header attached without invoking any user-supplied
|
|
117
|
+
* response or generator. If it returns `undefined`, the server handler
|
|
118
|
+
* is expected to serve content via `withReceipt(response)`.
|
|
119
|
+
*
|
|
120
|
+
* **HTTP-only.** The `input` parameter is a `Request` object; MCP transports
|
|
121
|
+
* do not invoke this hook.
|
|
122
|
+
*/
|
|
123
|
+
export type RespondFn<method extends Method> = (parameters: {
|
|
124
|
+
credential: Credential.Credential<
|
|
125
|
+
z.output<method['schema']['credential']['payload']>,
|
|
126
|
+
Challenge.Challenge<z.output<method['schema']['request']>, method['intent'], method['name']>
|
|
127
|
+
>
|
|
128
|
+
input: globalThis.Request
|
|
129
|
+
receipt: Receipt.Receipt
|
|
130
|
+
request: z.input<method['schema']['request']>
|
|
131
|
+
}) => MaybePromise<globalThis.Response | undefined>
|
|
132
|
+
|
|
133
|
+
/** Partial request type for defaults. */
|
|
134
|
+
export type RequestDefaults<method extends Method> = ExactPartial<
|
|
135
|
+
z.input<method['schema']['request']>
|
|
136
|
+
>
|
|
137
|
+
|
|
138
|
+
/** Makes fields optional if they exist in defaults. */
|
|
139
|
+
export type WithDefaults<request, defaults> = [keyof defaults] extends [never]
|
|
140
|
+
? request
|
|
141
|
+
: LooseOmit<request, keyof defaults & string> &
|
|
142
|
+
ExactPartial<Pick<request, keyof defaults & keyof request>>
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Extends a method with client-side credential creation logic.
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* ```ts
|
|
149
|
+
* import { Method } from 'mppx'
|
|
150
|
+
* import { Methods } from 'mppx/tempo'
|
|
151
|
+
*
|
|
152
|
+
* const tempoCharge = Method.toClient(Methods.charge, {
|
|
153
|
+
* async createCredential({ challenge }) {
|
|
154
|
+
* return Credential.serialize({ challenge, payload: { ... } })
|
|
155
|
+
* },
|
|
156
|
+
* })
|
|
157
|
+
* ```
|
|
158
|
+
*/
|
|
159
|
+
export function toClient<
|
|
160
|
+
const method extends Method,
|
|
161
|
+
const context extends z.ZodMiniType | undefined = undefined,
|
|
162
|
+
>(method: method, options: toClient.Options<method, context>): Client<method, context> {
|
|
163
|
+
const { context, createCredential } = options
|
|
164
|
+
return {
|
|
165
|
+
...method,
|
|
166
|
+
context,
|
|
167
|
+
createCredential,
|
|
168
|
+
} as Client<method, context>
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export declare namespace toClient {
|
|
172
|
+
type Options<method extends Method, context extends z.ZodMiniType | undefined = undefined> = {
|
|
173
|
+
context?: context
|
|
174
|
+
createCredential: CreateCredentialFn<
|
|
175
|
+
method,
|
|
176
|
+
context extends z.ZodMiniType ? z.output<context> : Record<never, never>
|
|
177
|
+
>
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Extends a method with server-side verification logic.
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* ```ts
|
|
186
|
+
* import { Method } from 'mppx'
|
|
187
|
+
* import { Methods } from 'mppx/tempo'
|
|
188
|
+
*
|
|
189
|
+
* const tempoCharge = Method.toServer(Methods.charge, {
|
|
190
|
+
* async verify({ credential }) {
|
|
191
|
+
* // verification logic
|
|
192
|
+
* return { status: 'success', ... }
|
|
193
|
+
* },
|
|
194
|
+
* })
|
|
195
|
+
* ```
|
|
196
|
+
*/
|
|
197
|
+
export function toServer<
|
|
198
|
+
const method extends Method,
|
|
199
|
+
const defaults extends RequestDefaults<method> = {},
|
|
200
|
+
const transportOverride extends Transport.AnyTransport | undefined = undefined,
|
|
201
|
+
>(
|
|
202
|
+
method: method,
|
|
203
|
+
options: toServer.Options<method, defaults, transportOverride>,
|
|
204
|
+
): Server<method, defaults, transportOverride> {
|
|
205
|
+
const { defaults, request, respond, transport, verify } = options
|
|
206
|
+
return {
|
|
207
|
+
...method,
|
|
208
|
+
defaults,
|
|
209
|
+
request,
|
|
210
|
+
respond,
|
|
211
|
+
transport,
|
|
212
|
+
verify,
|
|
213
|
+
} as Server<method, defaults, transportOverride>
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export declare namespace toServer {
|
|
217
|
+
type Options<
|
|
218
|
+
method extends Method,
|
|
219
|
+
defaults extends RequestDefaults<method> = {},
|
|
220
|
+
transportOverride extends Transport.AnyTransport | undefined = undefined,
|
|
221
|
+
> = {
|
|
222
|
+
defaults?: defaults | undefined
|
|
223
|
+
request?: RequestFn<method> | undefined
|
|
224
|
+
respond?: RespondFn<method> | undefined
|
|
225
|
+
transport?: transportOverride | undefined
|
|
226
|
+
verify: VerifyFn<method>
|
|
227
|
+
}
|
|
228
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PaymentRequest } from 'mppx'
|
|
2
|
-
import {
|
|
2
|
+
import { Methods } from 'mppx/tempo'
|
|
3
3
|
import { describe, expect, test } from 'vitest'
|
|
4
4
|
|
|
5
5
|
describe('from', () => {
|
|
@@ -21,7 +21,7 @@ describe('from', () => {
|
|
|
21
21
|
|
|
22
22
|
describe('fromIntent', () => {
|
|
23
23
|
test('creates a validated request from intent', () => {
|
|
24
|
-
const request = PaymentRequest.fromIntent(
|
|
24
|
+
const request = PaymentRequest.fromIntent(Methods.charge, {
|
|
25
25
|
amount: '1',
|
|
26
26
|
currency: '0x20c0000000000000000000000000000000000001',
|
|
27
27
|
decimals: 6,
|
|
@@ -39,7 +39,7 @@ describe('fromIntent', () => {
|
|
|
39
39
|
})
|
|
40
40
|
|
|
41
41
|
test('includes methodDetails fields', () => {
|
|
42
|
-
const request = PaymentRequest.fromIntent(
|
|
42
|
+
const request = PaymentRequest.fromIntent(Methods.charge, {
|
|
43
43
|
amount: '1',
|
|
44
44
|
currency: '0x20c0000000000000000000000000000000000001',
|
|
45
45
|
decimals: 6,
|
|
@@ -62,7 +62,7 @@ describe('fromIntent', () => {
|
|
|
62
62
|
|
|
63
63
|
test('throws on invalid request', () => {
|
|
64
64
|
expect(() =>
|
|
65
|
-
PaymentRequest.fromIntent(
|
|
65
|
+
PaymentRequest.fromIntent(Methods.charge, {
|
|
66
66
|
amount: 123,
|
|
67
67
|
currency: '0x20c0000000000000000000000000000000000001',
|
|
68
68
|
recipient: '0x742d35Cc6634C0532925a3b844Bc9e7595f8fE00',
|
package/src/PaymentRequest.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Base64 } from 'ox'
|
|
2
2
|
import type { Compute } from './internal/types.js'
|
|
3
|
-
import type * as
|
|
3
|
+
import type * as Method from './Method.js'
|
|
4
4
|
import type * as z from './zod.js'
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -62,16 +62,16 @@ export function from<const request extends Request>(request: request): request {
|
|
|
62
62
|
/**
|
|
63
63
|
* Creates a validated request from a method intent.
|
|
64
64
|
*
|
|
65
|
-
* @param
|
|
65
|
+
* @param method - The method to validate against.
|
|
66
66
|
* @param request - Request parameters.
|
|
67
67
|
* @returns A validated request.
|
|
68
68
|
*
|
|
69
69
|
* @example
|
|
70
70
|
* ```ts
|
|
71
71
|
* import { Request } from 'mppx'
|
|
72
|
-
* import {
|
|
72
|
+
* import { Methods } from 'mppx/tempo'
|
|
73
73
|
*
|
|
74
|
-
* const request = Request.fromIntent(
|
|
74
|
+
* const request = Request.fromIntent(Methods.charge, {
|
|
75
75
|
* amount: '1000000',
|
|
76
76
|
* currency: '0x20c0000000000000000000000000000000000001',
|
|
77
77
|
* recipient: '0x742d35Cc6634C0532925a3b844Bc9e7595f8fE00',
|
|
@@ -80,11 +80,11 @@ export function from<const request extends Request>(request: request): request {
|
|
|
80
80
|
* })
|
|
81
81
|
* ```
|
|
82
82
|
*/
|
|
83
|
-
export function fromIntent<const
|
|
84
|
-
|
|
85
|
-
request: z.input<
|
|
86
|
-
): Request<z.output<
|
|
87
|
-
return
|
|
83
|
+
export function fromIntent<const method extends Method.Method>(
|
|
84
|
+
method: method,
|
|
85
|
+
request: z.input<method['schema']['request']>,
|
|
86
|
+
): Request<z.output<method['schema']['request']>> {
|
|
87
|
+
return method.schema.request.parse(request) as Request<z.output<method['schema']['request']>>
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
/**
|
package/src/cli.test.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { accounts, asset, client, fundAccount } from '~test/tempo/viem.js'
|
|
|
11
11
|
import * as Store from './Store.js'
|
|
12
12
|
import * as Mppx_server from './server/Mppx.js'
|
|
13
13
|
import { toNodeListener } from './server/Mppx.js'
|
|
14
|
-
import { tempo } from './tempo/server/
|
|
14
|
+
import { tempo } from './tempo/server/Methods.js'
|
|
15
15
|
|
|
16
16
|
const cliPath = path.resolve(import.meta.dirname, 'cli.ts')
|
|
17
17
|
const cwd = path.resolve(import.meta.dirname, '..')
|
|
@@ -117,7 +117,7 @@ describe('basic charge (examples/basic)', () => {
|
|
|
117
117
|
})
|
|
118
118
|
|
|
119
119
|
try {
|
|
120
|
-
const { stdout } = await runAsync([httpServer.url, '--rpc-url', rpcUrl, '
|
|
120
|
+
const { stdout } = await runAsync([httpServer.url, '--rpc-url', rpcUrl, '-s'], {
|
|
121
121
|
input: '',
|
|
122
122
|
})
|
|
123
123
|
expect(stdout).toContain('paid')
|
|
@@ -179,7 +179,7 @@ describe('session multi-fetch (examples/session/multi-fetch)', () => {
|
|
|
179
179
|
|
|
180
180
|
try {
|
|
181
181
|
const { stdout } = await runAsync(
|
|
182
|
-
[httpServer.url, '--rpc-url', rpcUrl, '
|
|
182
|
+
[httpServer.url, '--rpc-url', rpcUrl, '-s', '--deposit', '10'],
|
|
183
183
|
{ input: '' },
|
|
184
184
|
)
|
|
185
185
|
expect(stdout).toContain('scraped-content')
|
|
@@ -227,9 +227,10 @@ describe('session multi-fetch (examples/session/multi-fetch)', () => {
|
|
|
227
227
|
|
|
228
228
|
try {
|
|
229
229
|
// First request: open a channel, answer "y" to proceed, "n" to close channel
|
|
230
|
-
const first = await runAsync(
|
|
231
|
-
|
|
232
|
-
|
|
230
|
+
const first = await runAsync(
|
|
231
|
+
[httpServer.url, '--rpc-url', rpcUrl, '--confirm', '--deposit', '10'],
|
|
232
|
+
{ input: 'y\nn\n' },
|
|
233
|
+
)
|
|
233
234
|
expect(first.stdout).toContain('scraped-content')
|
|
234
235
|
|
|
235
236
|
// Extract channel ID from stderr (logged as "Channel opened 0x...")
|
|
@@ -239,17 +240,7 @@ describe('session multi-fetch (examples/session/multi-fetch)', () => {
|
|
|
239
240
|
|
|
240
241
|
// Second request: reuse the channel via --channel
|
|
241
242
|
const second = await runAsync(
|
|
242
|
-
[
|
|
243
|
-
httpServer.url,
|
|
244
|
-
'--rpc-url',
|
|
245
|
-
rpcUrl,
|
|
246
|
-
'--yes',
|
|
247
|
-
'-s',
|
|
248
|
-
'--channel',
|
|
249
|
-
channelId,
|
|
250
|
-
'--deposit',
|
|
251
|
-
'10',
|
|
252
|
-
],
|
|
243
|
+
[httpServer.url, '--rpc-url', rpcUrl, '-s', '--channel', channelId, '--deposit', '10'],
|
|
253
244
|
{ input: '' },
|
|
254
245
|
)
|
|
255
246
|
expect(second.stdout).toContain('scraped-content')
|
|
@@ -322,10 +313,9 @@ describe('session sse (examples/session/sse)', () => {
|
|
|
322
313
|
})
|
|
323
314
|
|
|
324
315
|
try {
|
|
325
|
-
const { stdout } = await runAsync(
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
)
|
|
316
|
+
const { stdout } = await runAsync([httpServer.url, '--rpc-url', rpcUrl, '--deposit', '10'], {
|
|
317
|
+
input: '',
|
|
318
|
+
})
|
|
329
319
|
expect(stdout.trim()).toBe('Hello world!')
|
|
330
320
|
} finally {
|
|
331
321
|
httpServer.close()
|
|
@@ -528,9 +518,9 @@ test('mppx --help', () => {
|
|
|
528
518
|
-L, --location Follow redirects
|
|
529
519
|
-X, --method <method> HTTP method
|
|
530
520
|
--channel <id> Reuse existing stream channel ID
|
|
521
|
+
--confirm Show confirmation prompts
|
|
531
522
|
--deposit <amount> Deposit amount for stream payments (human-readable units)
|
|
532
523
|
--json <json> Send JSON body (sets Content-Type and Accept, implies POST)
|
|
533
|
-
--yes Skip confirmation prompts
|
|
534
524
|
-V, --version Display version number
|
|
535
525
|
-h, --help Display this message
|
|
536
526
|
|