mppx 0.3.14 → 0.3.16
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 -0
- package/dist/Challenge.d.ts +38 -0
- package/dist/Challenge.d.ts.map +1 -1
- package/dist/Challenge.js +62 -0
- package/dist/Challenge.js.map +1 -1
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +4 -0
- package/dist/bin.js.map +1 -0
- package/dist/cli.d.ts +26 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +1478 -915
- package/dist/cli.js.map +1 -1
- package/dist/client/Mppx.d.ts +2 -0
- package/dist/client/Mppx.d.ts.map +1 -1
- package/dist/client/Mppx.js +2 -0
- package/dist/client/Mppx.js.map +1 -1
- package/dist/client/internal/Fetch.d.ts.map +1 -1
- package/dist/client/internal/Fetch.js +16 -4
- package/dist/client/internal/Fetch.js.map +1 -1
- package/dist/middlewares/internal/mppx.d.ts +6 -1
- package/dist/middlewares/internal/mppx.d.ts.map +1 -1
- package/dist/middlewares/internal/mppx.js +4 -0
- package/dist/middlewares/internal/mppx.js.map +1 -1
- package/dist/server/Mppx.d.ts +79 -1
- package/dist/server/Mppx.d.ts.map +1 -1
- package/dist/server/Mppx.js +135 -7
- package/dist/server/Mppx.js.map +1 -1
- package/dist/tempo/client/ChannelOps.d.ts.map +1 -1
- package/dist/tempo/client/ChannelOps.js +1 -0
- package/dist/tempo/client/ChannelOps.js.map +1 -1
- package/dist/tempo/server/Charge.d.ts.map +1 -1
- package/dist/tempo/server/Charge.js +4 -4
- package/dist/tempo/server/Charge.js.map +1 -1
- package/dist/tempo/session/Chain.d.ts.map +1 -1
- package/dist/tempo/session/Chain.js +9 -6
- package/dist/tempo/session/Chain.js.map +1 -1
- package/package.json +4 -4
- package/src/Challenge.ts +72 -0
- package/src/bin.ts +4 -0
- package/src/cli.test.ts +180 -252
- package/src/cli.ts +1085 -485
- package/src/client/Mppx.test-d.ts +9 -0
- package/src/client/Mppx.test.ts +78 -0
- package/src/client/Mppx.ts +5 -0
- package/src/client/internal/Fetch.test.ts +1 -1
- package/src/client/internal/Fetch.ts +18 -6
- package/src/middlewares/internal/mppx.test.ts +152 -0
- package/src/middlewares/internal/mppx.ts +22 -3
- package/src/server/Mppx.test-d.ts +94 -299
- package/src/server/Mppx.test.ts +650 -0
- package/src/server/Mppx.ts +213 -9
- package/src/tempo/client/ChannelOps.ts +1 -0
- package/src/tempo/server/Charge.ts +4 -3
- package/src/tempo/session/Chain.ts +8 -5
- package/dist/tempo/internal/simulate.d.ts +0 -21
- package/dist/tempo/internal/simulate.d.ts.map +0 -1
- package/dist/tempo/internal/simulate.js +0 -31
- package/dist/tempo/internal/simulate.js.map +0 -1
- package/src/tempo/internal/simulate.ts +0 -49
|
@@ -1,20 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { describe, expectTypeOf, test } from 'vitest'
|
|
5
|
-
import * as Method from '../Method.js'
|
|
6
|
-
import * as z from '../zod.js'
|
|
7
|
-
import * as Mppx from './Mppx.js'
|
|
1
|
+
import { Method, z } from 'mppx'
|
|
2
|
+
import { Mppx } from 'mppx/server'
|
|
3
|
+
import { assertType, describe, expectTypeOf, test } from 'vitest'
|
|
8
4
|
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const fooCharge = Method.from({
|
|
13
|
-
name: 'test',
|
|
5
|
+
const mockChargeA = Method.from({
|
|
6
|
+
name: 'alpha',
|
|
14
7
|
intent: 'charge',
|
|
15
8
|
schema: {
|
|
16
9
|
credential: {
|
|
17
|
-
payload: z.object({
|
|
10
|
+
payload: z.object({ token: z.string() }),
|
|
18
11
|
},
|
|
19
12
|
request: z.object({
|
|
20
13
|
amount: z.string(),
|
|
@@ -25,317 +18,119 @@ const fooCharge = Method.from({
|
|
|
25
18
|
},
|
|
26
19
|
})
|
|
27
20
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
realm: 'api.example.com',
|
|
44
|
-
secretKey: 'secret',
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
expectTypeOf(handler.methods).toEqualTypeOf([method] as const)
|
|
48
|
-
expectTypeOf(handler.realm).toBeString()
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
test('has method functions matching methods', () => {
|
|
52
|
-
const method = Method.toServer(fooCharge, {
|
|
53
|
-
async verify() {
|
|
54
|
-
return {
|
|
55
|
-
method: 'test',
|
|
56
|
-
reference: '0x123',
|
|
57
|
-
status: 'success' as const,
|
|
58
|
-
timestamp: new Date().toISOString(),
|
|
59
|
-
}
|
|
60
|
-
},
|
|
61
|
-
})
|
|
21
|
+
const mockChargeB = Method.from({
|
|
22
|
+
name: 'beta',
|
|
23
|
+
intent: 'charge',
|
|
24
|
+
schema: {
|
|
25
|
+
credential: {
|
|
26
|
+
payload: z.object({ token: z.string() }),
|
|
27
|
+
},
|
|
28
|
+
request: z.object({
|
|
29
|
+
amount: z.string(),
|
|
30
|
+
currency: z.string(),
|
|
31
|
+
decimals: z.number(),
|
|
32
|
+
recipient: z.string(),
|
|
33
|
+
}),
|
|
34
|
+
},
|
|
35
|
+
})
|
|
62
36
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
37
|
+
const alphaMethod = Method.toServer(mockChargeA, {
|
|
38
|
+
async verify() {
|
|
39
|
+
return {
|
|
40
|
+
method: 'alpha',
|
|
41
|
+
reference: 'tx',
|
|
42
|
+
status: 'success' as const,
|
|
43
|
+
timestamp: new Date().toISOString(),
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
})
|
|
68
47
|
|
|
69
|
-
|
|
70
|
-
|
|
48
|
+
const betaMethod = Method.toServer(mockChargeB, {
|
|
49
|
+
async verify() {
|
|
50
|
+
return {
|
|
51
|
+
method: 'beta',
|
|
52
|
+
reference: 'tx',
|
|
53
|
+
status: 'success' as const,
|
|
54
|
+
timestamp: new Date().toISOString(),
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
})
|
|
71
58
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
async verify() {
|
|
75
|
-
return {
|
|
76
|
-
method: 'test',
|
|
77
|
-
reference: '0x123',
|
|
78
|
-
status: 'success' as const,
|
|
79
|
-
timestamp: new Date().toISOString(),
|
|
80
|
-
}
|
|
81
|
-
},
|
|
82
|
-
})
|
|
59
|
+
const secretKey = 'test-secret'
|
|
60
|
+
const realm = 'api.example.com'
|
|
83
61
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
secretKey: 'secret',
|
|
88
|
-
})
|
|
62
|
+
describe('Mppx type tests', () => {
|
|
63
|
+
test('compose exists on the instance and returns a handler', () => {
|
|
64
|
+
const mppx = Mppx.create({ methods: [alphaMethod, betaMethod], realm, secretKey })
|
|
89
65
|
|
|
90
|
-
|
|
91
|
-
amount: '1000',
|
|
92
|
-
currency: '0x1234',
|
|
93
|
-
decimals: 6,
|
|
94
|
-
expires: '2025-01-01T00:00:00Z',
|
|
95
|
-
recipient: '0xabc',
|
|
96
|
-
})
|
|
66
|
+
expectTypeOf(mppx.compose).toBeFunction()
|
|
97
67
|
})
|
|
98
68
|
|
|
99
|
-
test('
|
|
100
|
-
const
|
|
101
|
-
async verify() {
|
|
102
|
-
return {
|
|
103
|
-
method: 'test',
|
|
104
|
-
reference: '0x123',
|
|
105
|
-
status: 'success' as const,
|
|
106
|
-
timestamp: new Date().toISOString(),
|
|
107
|
-
}
|
|
108
|
-
},
|
|
109
|
-
})
|
|
110
|
-
|
|
111
|
-
const handler = Mppx.create({
|
|
112
|
-
methods: [method],
|
|
113
|
-
realm: 'api.example.com',
|
|
114
|
-
secretKey: 'secret',
|
|
115
|
-
})
|
|
69
|
+
test('compose accepts method reference tuples', () => {
|
|
70
|
+
const mppx = Mppx.create({ methods: [alphaMethod, betaMethod], realm, secretKey })
|
|
116
71
|
|
|
117
|
-
const
|
|
118
|
-
amount: '
|
|
119
|
-
currency: '
|
|
72
|
+
const opts = {
|
|
73
|
+
amount: '100',
|
|
74
|
+
currency: '0x01',
|
|
120
75
|
decimals: 6,
|
|
121
|
-
|
|
122
|
-
recipient: '0xabc',
|
|
123
|
-
})
|
|
124
|
-
|
|
125
|
-
const result = await chargeHandler(new Request('https://example.com'))
|
|
126
|
-
|
|
127
|
-
if (result.status === 402) {
|
|
128
|
-
expectTypeOf(result.challenge).toEqualTypeOf<Response>()
|
|
129
|
-
} else {
|
|
130
|
-
expectTypeOf(result.withReceipt).toBeFunction()
|
|
76
|
+
recipient: '0x02',
|
|
131
77
|
}
|
|
132
|
-
})
|
|
133
|
-
|
|
134
|
-
test('multiple methods', () => {
|
|
135
|
-
const fooAuthorize = Method.from({
|
|
136
|
-
name: 'test',
|
|
137
|
-
intent: 'authorize',
|
|
138
|
-
schema: {
|
|
139
|
-
credential: {
|
|
140
|
-
payload: z.object({ token: z.string() }),
|
|
141
|
-
},
|
|
142
|
-
request: z.object({
|
|
143
|
-
scope: z.string(),
|
|
144
|
-
duration: z.number(),
|
|
145
|
-
}),
|
|
146
|
-
},
|
|
147
|
-
})
|
|
148
78
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
},
|
|
154
|
-
async verify() {
|
|
155
|
-
return {
|
|
156
|
-
method: 'test',
|
|
157
|
-
reference: '0x123',
|
|
158
|
-
status: 'success' as const,
|
|
159
|
-
timestamp: new Date().toISOString(),
|
|
160
|
-
}
|
|
161
|
-
},
|
|
162
|
-
})
|
|
163
|
-
|
|
164
|
-
const authorizeMethod = Method.toServer(fooAuthorize, {
|
|
165
|
-
async verify() {
|
|
166
|
-
return {
|
|
167
|
-
method: 'test',
|
|
168
|
-
reference: '0x456',
|
|
169
|
-
status: 'success' as const,
|
|
170
|
-
timestamp: new Date().toISOString(),
|
|
171
|
-
}
|
|
172
|
-
},
|
|
173
|
-
})
|
|
79
|
+
// Should compile — method reference entries
|
|
80
|
+
const handler = mppx.compose([alphaMethod, opts], [betaMethod, opts])
|
|
81
|
+
expectTypeOf(handler).toBeFunction()
|
|
82
|
+
})
|
|
174
83
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
realm: 'api.example.com',
|
|
178
|
-
secretKey: 'secret',
|
|
179
|
-
})
|
|
84
|
+
test('compose accepts string key tuples', () => {
|
|
85
|
+
const mppx = Mppx.create({ methods: [alphaMethod, betaMethod], realm, secretKey })
|
|
180
86
|
|
|
181
|
-
|
|
182
|
-
amount: '
|
|
183
|
-
currency: '
|
|
87
|
+
const opts = {
|
|
88
|
+
amount: '100',
|
|
89
|
+
currency: '0x01',
|
|
184
90
|
decimals: 6,
|
|
185
|
-
recipient: '
|
|
186
|
-
}
|
|
91
|
+
recipient: '0x02',
|
|
92
|
+
}
|
|
187
93
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
})
|
|
94
|
+
// Should compile — string key entries
|
|
95
|
+
const handler = mppx.compose(['alpha/charge', opts], ['beta/charge', opts])
|
|
96
|
+
expectTypeOf(handler).toBeFunction()
|
|
192
97
|
})
|
|
193
98
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
const handler = Mppx.create({
|
|
197
|
-
methods: [tempo({ currency: '0x1234', recipient: '0xabc', getClient })],
|
|
198
|
-
realm: 'api.example.com',
|
|
199
|
-
secretKey: 'secret',
|
|
200
|
-
})
|
|
201
|
-
|
|
202
|
-
// currency and recipient should be optional since they're in defaults
|
|
203
|
-
handler.charge({
|
|
204
|
-
amount: '1000',
|
|
205
|
-
decimals: 6,
|
|
206
|
-
})
|
|
207
|
-
|
|
208
|
-
// But can still be overridden
|
|
209
|
-
handler.charge({
|
|
210
|
-
amount: '1000',
|
|
211
|
-
currency: '0x5678',
|
|
212
|
-
decimals: 6,
|
|
213
|
-
recipient: '0xdef',
|
|
214
|
-
})
|
|
215
|
-
})
|
|
216
|
-
|
|
217
|
-
test('non-defaulted fields remain required', () => {
|
|
218
|
-
const handler = Mppx.create({
|
|
219
|
-
methods: [tempo({ currency: '0x1234', getClient })],
|
|
220
|
-
realm: 'api.example.com',
|
|
221
|
-
secretKey: 'secret',
|
|
222
|
-
})
|
|
223
|
-
|
|
224
|
-
// recipient is still required since it's not in defaults
|
|
225
|
-
handler.charge({
|
|
226
|
-
amount: '1000',
|
|
227
|
-
decimals: 6,
|
|
228
|
-
recipient: '0xabc',
|
|
229
|
-
})
|
|
230
|
-
})
|
|
231
|
-
|
|
232
|
-
test('no defaults means all fields required', () => {
|
|
233
|
-
const handler = Mppx.create({
|
|
234
|
-
methods: [tempo({ getClient })],
|
|
235
|
-
realm: 'api.example.com',
|
|
236
|
-
secretKey: 'secret',
|
|
237
|
-
})
|
|
238
|
-
|
|
239
|
-
// All required fields must be provided
|
|
240
|
-
handler.charge({
|
|
241
|
-
amount: '1000',
|
|
242
|
-
currency: '0x1234',
|
|
243
|
-
decimals: 6,
|
|
244
|
-
recipient: '0xabc',
|
|
245
|
-
})
|
|
246
|
-
})
|
|
99
|
+
test('nested handlers are accessible', () => {
|
|
100
|
+
const mppx = Mppx.create({ methods: [alphaMethod, betaMethod], realm, secretKey })
|
|
247
101
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
})
|
|
254
|
-
|
|
255
|
-
type ChargeOptions = Parameters<typeof handler.charge>[0]
|
|
256
|
-
|
|
257
|
-
// currency and recipient should be optional (include undefined)
|
|
258
|
-
expectTypeOf<ChargeOptions['currency']>().toEqualTypeOf<string | undefined>()
|
|
259
|
-
expectTypeOf<ChargeOptions['recipient']>().toEqualTypeOf<string | undefined>()
|
|
260
|
-
|
|
261
|
-
// amount should still be required (no undefined)
|
|
262
|
-
expectTypeOf<ChargeOptions['amount']>().toEqualTypeOf<string>()
|
|
263
|
-
})
|
|
264
|
-
|
|
265
|
-
test('account as Account defaults recipient', () => {
|
|
266
|
-
const handler = Mppx.create({
|
|
267
|
-
methods: [tempo.charge({ currency: '0x1234', account })],
|
|
268
|
-
realm: 'api.example.com',
|
|
269
|
-
secretKey: 'secret',
|
|
270
|
-
})
|
|
271
|
-
|
|
272
|
-
// recipient is defaulted via account, so it should be optional
|
|
273
|
-
handler.charge({
|
|
274
|
-
amount: '1000',
|
|
275
|
-
decimals: 6,
|
|
276
|
-
})
|
|
277
|
-
|
|
278
|
-
// can still override recipient
|
|
279
|
-
handler.charge({
|
|
280
|
-
amount: '1000',
|
|
281
|
-
decimals: 6,
|
|
282
|
-
recipient: '0xdef',
|
|
283
|
-
})
|
|
284
|
-
})
|
|
102
|
+
expectTypeOf(mppx.alpha).toBeObject()
|
|
103
|
+
expectTypeOf(mppx.alpha.charge).toBeFunction()
|
|
104
|
+
expectTypeOf(mppx.beta).toBeObject()
|
|
105
|
+
expectTypeOf(mppx.beta.charge).toBeFunction()
|
|
106
|
+
})
|
|
285
107
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
methods: [tempo.charge({ currency: '0x1234', account, feePayer: true })],
|
|
289
|
-
realm: 'api.example.com',
|
|
290
|
-
secretKey: 'secret',
|
|
291
|
-
})
|
|
108
|
+
test('slash key handlers are accessible', () => {
|
|
109
|
+
const mppx = Mppx.create({ methods: [alphaMethod, betaMethod], realm, secretKey })
|
|
292
110
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
decimals: 6,
|
|
296
|
-
})
|
|
297
|
-
})
|
|
111
|
+
expectTypeOf(mppx['alpha/charge']).toBeFunction()
|
|
112
|
+
expectTypeOf(mppx['beta/charge']).toBeFunction()
|
|
298
113
|
})
|
|
299
114
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
],
|
|
310
|
-
realm: 'api.example.com',
|
|
311
|
-
secretKey: 'secret',
|
|
312
|
-
})
|
|
313
|
-
})
|
|
115
|
+
test('compose return type is a request handler returning the response union', () => {
|
|
116
|
+
const mppx = Mppx.create({ methods: [alphaMethod], realm, secretKey })
|
|
117
|
+
|
|
118
|
+
const opts = {
|
|
119
|
+
amount: '100',
|
|
120
|
+
currency: '0x01',
|
|
121
|
+
decimals: 6,
|
|
122
|
+
recipient: '0x02',
|
|
123
|
+
}
|
|
314
124
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
methods: [tempo({ currency: '0x1234', recipient: '0xabc', getClient })],
|
|
318
|
-
realm: 'api.example.com',
|
|
319
|
-
secretKey: 'secret',
|
|
320
|
-
})
|
|
321
|
-
})
|
|
125
|
+
const handler = mppx.compose([alphaMethod, opts])
|
|
126
|
+
type HandlerReturn = ReturnType<typeof handler>
|
|
322
127
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
realm: 'api.example.com',
|
|
327
|
-
secretKey: 'secret',
|
|
328
|
-
})
|
|
329
|
-
})
|
|
128
|
+
assertType<Promise<{ status: 402; challenge: Response } | { status: 200; withReceipt: any }>>(
|
|
129
|
+
{} as Awaited<HandlerReturn> as any,
|
|
130
|
+
)
|
|
330
131
|
})
|
|
331
|
-
})
|
|
332
|
-
|
|
333
|
-
describe('create.Config', () => {
|
|
334
|
-
test('requires methods, realm, and secretKey', () => {
|
|
335
|
-
type Config = Mppx.create.Config
|
|
336
132
|
|
|
337
|
-
|
|
338
|
-
expectTypeOf
|
|
339
|
-
expectTypeOf<Config>().toHaveProperty('secretKey')
|
|
133
|
+
test('static Mppx.compose accepts configured handlers', () => {
|
|
134
|
+
expectTypeOf(Mppx.compose).toBeFunction()
|
|
340
135
|
})
|
|
341
136
|
})
|