@armory-sh/middleware-hono 0.3.21 → 0.3.22-alpha.3.20

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.
@@ -0,0 +1,58 @@
1
+ // src/extensions.ts
2
+ var declareDiscoveryExtension = (config = {}) => {
3
+ const info = {};
4
+ if (config.input !== void 0) {
5
+ info.input = config.input;
6
+ }
7
+ if (config.inputSchema !== void 0) {
8
+ info.inputSchema = config.inputSchema;
9
+ }
10
+ if (config.output !== void 0) {
11
+ info.output = config.output;
12
+ }
13
+ return { info, schema: { type: "object" } };
14
+ };
15
+ var declareSIWxExtension = (config = {}) => {
16
+ const info = {};
17
+ if (config.domain !== void 0) {
18
+ info.domain = config.domain;
19
+ }
20
+ if (config.resourceUri !== void 0) {
21
+ info.resourceUri = config.resourceUri;
22
+ }
23
+ if (config.network !== void 0) {
24
+ info.network = config.network;
25
+ }
26
+ if (config.statement !== void 0) {
27
+ info.statement = config.statement;
28
+ }
29
+ if (config.version !== void 0) {
30
+ info.version = config.version;
31
+ }
32
+ if (config.expirationSeconds !== void 0) {
33
+ info.expirationSeconds = config.expirationSeconds;
34
+ }
35
+ return { info, schema: { type: "object" } };
36
+ };
37
+ function buildExtensions(config) {
38
+ const extensions = {};
39
+ if (config.bazaar) {
40
+ extensions.bazaar = declareDiscoveryExtension(config.bazaar);
41
+ }
42
+ if (config.signInWithX) {
43
+ extensions["sign-in-with-x"] = declareSIWxExtension(config.signInWithX);
44
+ }
45
+ return extensions;
46
+ }
47
+ function extractExtension(extensions, key) {
48
+ if (!extensions || typeof extensions !== "object") {
49
+ return null;
50
+ }
51
+ const extension = extensions[key];
52
+ if (!extension || typeof extension !== "object") {
53
+ return null;
54
+ }
55
+ return extension;
56
+ }
57
+
58
+ export { buildExtensions, extractExtension };
@@ -1,60 +1 @@
1
- // src/extensions.ts
2
- var declareDiscoveryExtension = (config = {}) => {
3
- const info = {};
4
- if (config.input !== void 0) {
5
- info.input = config.input;
6
- }
7
- if (config.inputSchema !== void 0) {
8
- info.inputSchema = config.inputSchema;
9
- }
10
- if (config.output !== void 0) {
11
- info.output = config.output;
12
- }
13
- return { info, schema: { type: "object" } };
14
- };
15
- var declareSIWxExtension = (config = {}) => {
16
- const info = {};
17
- if (config.domain !== void 0) {
18
- info.domain = config.domain;
19
- }
20
- if (config.resourceUri !== void 0) {
21
- info.resourceUri = config.resourceUri;
22
- }
23
- if (config.network !== void 0) {
24
- info.network = config.network;
25
- }
26
- if (config.statement !== void 0) {
27
- info.statement = config.statement;
28
- }
29
- if (config.version !== void 0) {
30
- info.version = config.version;
31
- }
32
- if (config.expirationSeconds !== void 0) {
33
- info.expirationSeconds = config.expirationSeconds;
34
- }
35
- return { info, schema: { type: "object" } };
36
- };
37
- function buildExtensions(config) {
38
- const extensions = {};
39
- if (config.bazaar) {
40
- extensions.bazaar = declareDiscoveryExtension(config.bazaar);
41
- }
42
- if (config.signInWithX) {
43
- extensions["sign-in-with-x"] = declareSIWxExtension(config.signInWithX);
44
- }
45
- return extensions;
46
- }
47
- function extractExtension(extensions, key) {
48
- if (!extensions || typeof extensions !== "object") {
49
- return null;
50
- }
51
- const extension = extensions[key];
52
- if (!extension || typeof extension !== "object") {
53
- return null;
54
- }
55
- return extension;
56
- }
57
- export {
58
- buildExtensions,
59
- extractExtension
60
- };
1
+ export { buildExtensions, extractExtension } from './chunk-XYM6YXAQ.js';
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Context, Next } from 'hono';
2
- import { PaymentRequirementsV2, ValidationError, PaymentRequirements, PaymentPayloadV2 } from '@armory-sh/base';
2
+ import { PaymentRequirementsV2, ValidationError, PaymentRequirements, X402PaymentPayload } from '@armory-sh/base';
3
3
  import { ExtensionConfig } from './extensions.js';
4
4
  export { buildExtensions, extractExtension } from './extensions.js';
5
5
 
@@ -41,12 +41,12 @@ declare const routeAwarePaymentMiddleware: (config: RouteAwarePaymentConfig) =>
41
41
 
42
42
  interface AdvancedPaymentConfig {
43
43
  requirements: PaymentRequirements;
44
- facilitatorUrl?: string;
44
+ facilitatorUrl: string;
45
45
  network?: string;
46
46
  }
47
47
  interface AugmentedRequest extends Request {
48
48
  payment?: {
49
- payload: PaymentPayloadV2;
49
+ payload: X402PaymentPayload;
50
50
  payerAddress: string;
51
51
  verified: boolean;
52
52
  };
package/dist/index.js CHANGED
@@ -1,80 +1,7 @@
1
- // src/index.ts
2
- import {
3
- createPaymentRequiredHeaders,
4
- PAYMENT_SIGNATURE_HEADER,
5
- decodePaymentV2
6
- } from "@armory-sh/base";
7
-
8
- // src/simple.ts
9
- import {
10
- resolveNetwork,
11
- resolveToken,
12
- safeBase64Encode,
13
- V2_HEADERS,
14
- registerToken
15
- } from "@armory-sh/base";
16
- import {
17
- TOKENS
18
- } from "@armory-sh/base";
1
+ import { buildExtensions } from './chunk-XYM6YXAQ.js';
2
+ export { buildExtensions, extractExtension } from './chunk-XYM6YXAQ.js';
3
+ import { V2_HEADERS, safeBase64Encode, decodePayloadHeader, verifyPayment, createPaymentRequiredHeaders, settlePayment, createSettlementHeaders, matchRoute, PAYMENT_SIGNATURE_HEADER, TOKENS, registerToken, resolveNetwork, resolveToken, validateRouteConfig } from '@armory-sh/base';
19
4
 
20
- // src/extensions.ts
21
- var declareDiscoveryExtension = (config = {}) => {
22
- const info = {};
23
- if (config.input !== void 0) {
24
- info.input = config.input;
25
- }
26
- if (config.inputSchema !== void 0) {
27
- info.inputSchema = config.inputSchema;
28
- }
29
- if (config.output !== void 0) {
30
- info.output = config.output;
31
- }
32
- return { info, schema: { type: "object" } };
33
- };
34
- var declareSIWxExtension = (config = {}) => {
35
- const info = {};
36
- if (config.domain !== void 0) {
37
- info.domain = config.domain;
38
- }
39
- if (config.resourceUri !== void 0) {
40
- info.resourceUri = config.resourceUri;
41
- }
42
- if (config.network !== void 0) {
43
- info.network = config.network;
44
- }
45
- if (config.statement !== void 0) {
46
- info.statement = config.statement;
47
- }
48
- if (config.version !== void 0) {
49
- info.version = config.version;
50
- }
51
- if (config.expirationSeconds !== void 0) {
52
- info.expirationSeconds = config.expirationSeconds;
53
- }
54
- return { info, schema: { type: "object" } };
55
- };
56
- function buildExtensions(config) {
57
- const extensions = {};
58
- if (config.bazaar) {
59
- extensions.bazaar = declareDiscoveryExtension(config.bazaar);
60
- }
61
- if (config.signInWithX) {
62
- extensions["sign-in-with-x"] = declareSIWxExtension(config.signInWithX);
63
- }
64
- return extensions;
65
- }
66
- function extractExtension(extensions, key) {
67
- if (!extensions || typeof extensions !== "object") {
68
- return null;
69
- }
70
- const extension = extensions[key];
71
- if (!extension || typeof extension !== "object") {
72
- return null;
73
- }
74
- return extension;
75
- }
76
-
77
- // src/simple.ts
78
5
  var isValidationError = (value) => {
79
6
  return typeof value === "object" && value !== null && "code" in value;
80
7
  };
@@ -225,7 +152,7 @@ function createPaymentRequirements(config) {
225
152
  requirements.push({
226
153
  scheme: "exact",
227
154
  network: network.caip2,
228
- amount: atomicAmount,
155
+ maxAmountRequired: atomicAmount,
229
156
  asset: tokenConfig.contractAddress,
230
157
  payTo: resolvedPayTo,
231
158
  maxTimeoutSeconds,
@@ -241,8 +168,10 @@ function createPaymentRequirements(config) {
241
168
  }
242
169
  function paymentMiddleware(config) {
243
170
  const { requirements, error } = createPaymentRequirements(config);
171
+ console.log("[payment-middleware] Initialized with requirements:", JSON.stringify(requirements, null, 2));
244
172
  return async (c, next) => {
245
173
  if (error) {
174
+ console.log("[payment-middleware] Configuration error:", error.message);
246
175
  c.status(500);
247
176
  return c.json({
248
177
  error: "Payment middleware configuration error",
@@ -250,6 +179,7 @@ function paymentMiddleware(config) {
250
179
  });
251
180
  }
252
181
  const paymentHeader = c.req.header(V2_HEADERS.PAYMENT_SIGNATURE);
182
+ console.log("[payment-middleware] Payment header present:", !!paymentHeader);
253
183
  if (!paymentHeader) {
254
184
  const resource = {
255
185
  url: c.req.url,
@@ -263,6 +193,7 @@ function paymentMiddleware(config) {
263
193
  accepts: requirements,
264
194
  extensions: config.extensions ? buildExtensions(config.extensions) : void 0
265
195
  };
196
+ console.log("[payment-middleware] Returning 402 with requirements:", JSON.stringify(paymentRequired.accepts, null, 2));
266
197
  c.status(402);
267
198
  c.header(V2_HEADERS.PAYMENT_REQUIRED, safeBase64Encode(JSON.stringify(paymentRequired)));
268
199
  return c.json({
@@ -270,34 +201,65 @@ function paymentMiddleware(config) {
270
201
  accepts: requirements
271
202
  });
272
203
  }
273
- const payload = paymentHeader;
204
+ const primaryRequirement = requirements[0];
205
+ if (!primaryRequirement) {
206
+ console.log("[payment-middleware] No requirements configured");
207
+ c.status(500);
208
+ return c.json({ error: "Payment middleware configuration error", details: "No payment requirements configured" });
209
+ }
210
+ console.log("[payment-middleware] Primary requirement:", JSON.stringify(primaryRequirement, null, 2));
274
211
  let parsedPayload;
275
212
  try {
276
- const decoded = atob(payload);
277
- parsedPayload = JSON.parse(decoded);
213
+ parsedPayload = decodePayloadHeader(paymentHeader, {
214
+ accepted: primaryRequirement
215
+ });
278
216
  } catch {
279
- try {
280
- parsedPayload = JSON.parse(payload);
281
- } catch {
282
- c.status(400);
283
- return c.json({ error: "Invalid payment payload" });
284
- }
217
+ c.status(400);
218
+ return c.json({ error: "Invalid payment payload" });
219
+ }
220
+ const requirementFacilitatorUrl = primaryRequirement.extra?.facilitatorUrl;
221
+ const facilitatorUrl = config.facilitatorUrl ?? (typeof requirementFacilitatorUrl === "string" ? requirementFacilitatorUrl : void 0);
222
+ console.log("[payment-middleware] Facilitator URL:", facilitatorUrl);
223
+ if (!facilitatorUrl) {
224
+ console.log("[payment-middleware] No facilitator URL configured");
225
+ c.status(500);
226
+ return c.json({ error: "Payment middleware configuration error", message: "Facilitator URL is required for verification" });
227
+ }
228
+ console.log("[payment-middleware] Verifying payment with facilitator...");
229
+ const verifyResult = await verifyPayment(parsedPayload, primaryRequirement, { url: facilitatorUrl });
230
+ console.log("[payment-middleware] Verify result:", JSON.stringify(verifyResult, null, 2));
231
+ if (!verifyResult.isValid) {
232
+ console.log("[payment-middleware] Verification failed:", verifyResult.invalidReason);
233
+ c.status(402);
234
+ c.header(V2_HEADERS.PAYMENT_REQUIRED, createPaymentRequiredHeaders(requirements)[V2_HEADERS.PAYMENT_REQUIRED]);
235
+ return c.json({ error: "Payment verification failed", message: verifyResult.invalidReason });
285
236
  }
237
+ console.log("[payment-middleware] Payment verified, setting payment context");
286
238
  c.set("payment", {
287
239
  payload: parsedPayload,
288
- verified: false
240
+ payerAddress: verifyResult.payer,
241
+ verified: true
289
242
  });
290
- return next();
243
+ await next();
244
+ if (c.res.status >= 400) {
245
+ return;
246
+ }
247
+ console.log("[payment-middleware] Settling payment...");
248
+ const settleResult = await settlePayment(parsedPayload, primaryRequirement, { url: facilitatorUrl });
249
+ console.log("[payment-middleware] Settle result:", JSON.stringify(settleResult, null, 2));
250
+ if (!settleResult.success) {
251
+ console.log("[payment-middleware] Settlement failed:", settleResult.errorReason);
252
+ c.status(502);
253
+ c.res = c.json({ error: "Settlement failed", details: settleResult.errorReason }, 502);
254
+ return;
255
+ }
256
+ console.log("[payment-middleware] Payment settled, tx:", settleResult.transaction);
257
+ const headers = createSettlementHeaders(settleResult);
258
+ for (const [key, value] of Object.entries(headers)) {
259
+ c.header(key, value);
260
+ }
291
261
  };
292
262
  }
293
-
294
- // src/routes.ts
295
- import {
296
- safeBase64Encode as safeBase64Encode2,
297
- V2_HEADERS as V2_HEADERS2,
298
- matchRoute,
299
- validateRouteConfig
300
- } from "@armory-sh/base";
301
263
  var resolveRouteConfig = (config) => {
302
264
  const validationError = validateRouteConfig(config);
303
265
  if (validationError) {
@@ -342,7 +304,7 @@ var routeAwarePaymentMiddleware = (config) => {
342
304
  details: requirementsError.message
343
305
  });
344
306
  }
345
- const paymentHeader = c.req.header(V2_HEADERS2.PAYMENT_SIGNATURE);
307
+ const paymentHeader = c.req.header(V2_HEADERS.PAYMENT_SIGNATURE);
346
308
  if (!paymentHeader) {
347
309
  const resource = {
348
310
  url: c.req.url,
@@ -357,38 +319,66 @@ var routeAwarePaymentMiddleware = (config) => {
357
319
  };
358
320
  c.status(402);
359
321
  c.header(
360
- V2_HEADERS2.PAYMENT_REQUIRED,
361
- safeBase64Encode2(JSON.stringify(paymentRequired))
322
+ V2_HEADERS.PAYMENT_REQUIRED,
323
+ safeBase64Encode(JSON.stringify(paymentRequired))
362
324
  );
363
325
  return c.json({
364
326
  error: "Payment required",
365
327
  accepts: requirements
366
328
  });
367
329
  }
330
+ const primaryRequirement = requirements[0];
331
+ if (!primaryRequirement) {
332
+ c.status(500);
333
+ return c.json({ error: "Payment middleware configuration error", details: "No payment requirements configured" });
334
+ }
368
335
  let parsedPayload;
369
336
  try {
370
- const decoded = atob(paymentHeader);
371
- parsedPayload = JSON.parse(decoded);
337
+ parsedPayload = decodePayloadHeader(paymentHeader, {
338
+ accepted: primaryRequirement
339
+ });
372
340
  } catch {
373
- try {
374
- parsedPayload = JSON.parse(paymentHeader);
375
- } catch {
376
- c.status(400);
377
- return c.json({ error: "Invalid payment payload" });
378
- }
341
+ c.status(400);
342
+ return c.json({ error: "Invalid payment payload" });
343
+ }
344
+ const requirementFacilitatorUrl = primaryRequirement.extra?.facilitatorUrl;
345
+ const facilitatorUrl = matchedRoute.config.facilitatorUrl ?? (typeof requirementFacilitatorUrl === "string" ? requirementFacilitatorUrl : void 0);
346
+ if (!facilitatorUrl) {
347
+ c.status(500);
348
+ return c.json({ error: "Payment middleware configuration error", message: "Facilitator URL is required for verification" });
349
+ }
350
+ const verifyResult = await verifyPayment(parsedPayload, primaryRequirement, { url: facilitatorUrl });
351
+ if (!verifyResult.isValid) {
352
+ c.status(402);
353
+ c.header(V2_HEADERS.PAYMENT_REQUIRED, createPaymentRequiredHeaders(requirements)[V2_HEADERS.PAYMENT_REQUIRED]);
354
+ return c.json({ error: "Payment verification failed", message: verifyResult.invalidReason });
379
355
  }
380
356
  c.set("payment", {
381
357
  payload: parsedPayload,
382
- verified: false,
358
+ payerAddress: verifyResult.payer,
359
+ verified: true,
383
360
  route: matchedRoute.pattern
384
361
  });
385
- return next();
362
+ await next();
363
+ if (c.res.status >= 400) {
364
+ return;
365
+ }
366
+ const settleResult = await settlePayment(parsedPayload, primaryRequirement, { url: facilitatorUrl });
367
+ if (!settleResult.success) {
368
+ c.status(502);
369
+ c.res = c.json({ error: "Settlement failed", details: settleResult.errorReason }, 502);
370
+ return;
371
+ }
372
+ const headers = createSettlementHeaders(settleResult);
373
+ for (const [key, value] of Object.entries(headers)) {
374
+ c.header(key, value);
375
+ }
386
376
  };
387
377
  };
388
378
 
389
379
  // src/index.ts
390
380
  var advancedPaymentMiddleware = (config) => {
391
- const { requirements, facilitatorUrl, network = "base" } = config;
381
+ const { requirements, facilitatorUrl } = config;
392
382
  return async (c, next) => {
393
383
  const paymentHeader = c.req.header(PAYMENT_SIGNATURE_HEADER);
394
384
  if (!paymentHeader) {
@@ -402,31 +392,52 @@ var advancedPaymentMiddleware = (config) => {
402
392
  accepts: [requirements]
403
393
  });
404
394
  }
405
- let paymentPayload = null;
395
+ let paymentPayload;
406
396
  try {
407
- paymentPayload = decodePaymentV2(paymentHeader);
397
+ paymentPayload = decodePayloadHeader(paymentHeader, {
398
+ accepted: requirements
399
+ });
408
400
  } catch (e) {
409
401
  c.status(400);
410
402
  return c.json({ error: "Invalid payment payload", details: String(e) });
411
403
  }
412
- if (!paymentPayload) {
413
- c.status(400);
414
- return c.json({ error: "Invalid payment payload" });
404
+ if (!facilitatorUrl) {
405
+ c.status(500);
406
+ return c.json({ error: "Payment middleware configuration error", message: "Facilitator URL is required for verification" });
407
+ }
408
+ const verifyResult = await verifyPayment(paymentPayload, requirements, { url: facilitatorUrl });
409
+ if (!verifyResult.isValid) {
410
+ const requiredHeaders = createPaymentRequiredHeaders(requirements);
411
+ c.status(402);
412
+ for (const [key, value] of Object.entries(requiredHeaders)) {
413
+ c.header(key, value);
414
+ }
415
+ return c.json({
416
+ error: "Payment verification failed",
417
+ message: verifyResult.invalidReason
418
+ });
415
419
  }
416
- const payerAddress = paymentPayload.payload.authorization.from;
420
+ const payerAddress = verifyResult.payer ?? paymentPayload.payload.authorization.from;
417
421
  c.set("payment", {
418
422
  payload: paymentPayload,
419
423
  payerAddress,
420
424
  verified: true
421
425
  });
422
- return next();
426
+ await next();
427
+ if (c.res.status >= 400) {
428
+ return;
429
+ }
430
+ const settleResult = await settlePayment(paymentPayload, requirements, { url: facilitatorUrl });
431
+ if (!settleResult.success) {
432
+ c.status(502);
433
+ c.res = c.json({ error: "Settlement failed", details: settleResult.errorReason }, 502);
434
+ return;
435
+ }
436
+ const settlementHeaders = createSettlementHeaders(settleResult);
437
+ for (const [key, value] of Object.entries(settlementHeaders)) {
438
+ c.header(key, value);
439
+ }
423
440
  };
424
441
  };
425
- export {
426
- advancedPaymentMiddleware,
427
- buildExtensions,
428
- createPaymentRequirements,
429
- extractExtension,
430
- paymentMiddleware,
431
- routeAwarePaymentMiddleware
432
- };
442
+
443
+ export { advancedPaymentMiddleware, createPaymentRequirements, paymentMiddleware, routeAwarePaymentMiddleware };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@armory-sh/middleware-hono",
3
- "version": "0.3.21",
3
+ "version": "0.3.22-alpha.3.20",
4
4
  "license": "MIT",
5
5
  "author": "Sawyer Cutler <sawyer@dirtroad.dev>",
6
6
  "type": "module",
@@ -26,15 +26,15 @@
26
26
  },
27
27
  "repository": {
28
28
  "type": "git",
29
- "url": "git+https://github.com/thegreataxios/armory.git",
29
+ "url": "git+https://github.com/TheGreatAxios/armory.git",
30
30
  "directory": "packages/middleware-hono"
31
31
  },
32
32
  "peerDependencies": {
33
33
  "hono": "^4"
34
34
  },
35
35
  "dependencies": {
36
- "@armory-sh/base": "0.2.21",
37
- "@armory-sh/extensions": "0.1.2"
36
+ "@armory-sh/base": "0.2.22",
37
+ "@armory-sh/extensions": "0.1.3"
38
38
  },
39
39
  "devDependencies": {
40
40
  "bun-types": "latest",