@faremeter/middleware 0.15.0 → 0.16.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.
@@ -1,4 +1,4 @@
1
- import { type x402PaymentRequirements, type x402PaymentPayload } from "@faremeter/types/x402";
1
+ import { type x402PaymentRequirements, type x402PaymentPayload, x402VerifyResponse, x402SettleResponse } from "@faremeter/types/x402";
2
2
  import { type AgedLRUCacheOpts } from "./cache.js";
3
3
  export declare function findMatchingPaymentRequirements(accepts: x402PaymentRequirements[], payload: x402PaymentPayload): {
4
4
  scheme: string;
@@ -19,6 +19,7 @@ type getPaymentRequiredResponseArgs = {
19
19
  facilitatorURL: string;
20
20
  accepts: RelaxedRequirements[];
21
21
  resource: string;
22
+ fetch?: typeof fetch;
22
23
  };
23
24
  export declare function getPaymentRequiredResponse(args: getPaymentRequiredResponseArgs): Promise<{
24
25
  x402Version: number;
@@ -44,17 +45,33 @@ export type CommonMiddlewareArgs = {
44
45
  accepts: (RelaxedRequirements | RelaxedRequirements[])[];
45
46
  cacheConfig?: createPaymentRequiredResponseCacheOpts;
46
47
  };
48
+ export type SettleResult<MiddlewareResponse> = {
49
+ success: true;
50
+ facilitatorResponse: x402SettleResponse;
51
+ } | {
52
+ success: false;
53
+ errorResponse: MiddlewareResponse;
54
+ };
55
+ export type VerifyResult<MiddlewareResponse> = {
56
+ success: true;
57
+ facilitatorResponse: x402VerifyResponse;
58
+ } | {
59
+ success: false;
60
+ errorResponse: MiddlewareResponse;
61
+ };
62
+ export type MiddlewareBodyContext<MiddlewareResponse> = {
63
+ paymentRequirements: x402PaymentRequirements;
64
+ paymentPayload: x402PaymentPayload;
65
+ settle: () => Promise<SettleResult<MiddlewareResponse>>;
66
+ verify: () => Promise<VerifyResult<MiddlewareResponse>>;
67
+ };
47
68
  export type HandleMiddlewareRequestArgs<MiddlewareResponse = unknown> = CommonMiddlewareArgs & {
48
69
  resource: string;
49
70
  getHeader: (key: string) => string | undefined;
50
71
  getPaymentRequiredResponse: typeof getPaymentRequiredResponse;
51
72
  sendJSONResponse: (status: PossibleStatusCodes, obj: PossibleJSONResponse) => MiddlewareResponse;
52
- body: (context: {
53
- paymentRequirements: x402PaymentRequirements;
54
- paymentPayload: x402PaymentPayload;
55
- settle: () => Promise<MiddlewareResponse | undefined>;
56
- verify: () => Promise<MiddlewareResponse | undefined>;
57
- }) => Promise<MiddlewareResponse | undefined>;
73
+ body: (context: MiddlewareBodyContext<MiddlewareResponse>) => Promise<MiddlewareResponse | undefined>;
74
+ fetch?: typeof fetch;
58
75
  };
59
76
  export declare function handleMiddlewareRequest<MiddlewareResponse>(args: HandleMiddlewareRequestArgs<MiddlewareResponse>): Promise<MiddlewareResponse | undefined>;
60
77
  export type createPaymentRequiredResponseCacheOpts = AgedLRUCacheOpts & {
@@ -1 +1 @@
1
- {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/common.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,kBAAkB,EAOxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,KAAK,gBAAgB,EAAgB,MAAM,SAAS,CAAC;AAI9D,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,uBAAuB,EAAE,EAClC,OAAO,EAAE,kBAAkB;;;;;;;;;;;;cA6B5B;AAED,wBAAgB,8BAA8B,CAAC,GAAG,EAAE,QAAQ,QAS3D;AAED,MAAM,MAAM,mBAAmB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;AAEnE,KAAK,8BAA8B,GAAG;IACpC,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE,8BAA8B;;;;;;;;;;;;oBA9BU,CAAC;aAAuB,CAAC;;;GA4DxE;AAED,KAAK,mBAAmB,GAAG,GAAG,CAAC;AAC/B,KAAK,oBAAoB,GAAG,MAAM,CAAC;AAEnC,MAAM,MAAM,oBAAoB,GAAG;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,CAAC,mBAAmB,GAAG,mBAAmB,EAAE,CAAC,EAAE,CAAC;IACzD,WAAW,CAAC,EAAE,sCAAsC,CAAC;CACtD,CAAC;AAEF,MAAM,MAAM,2BAA2B,CAAC,kBAAkB,GAAG,OAAO,IAClE,oBAAoB,GAAG;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IAC/C,0BAA0B,EAAE,OAAO,0BAA0B,CAAC;IAC9D,gBAAgB,EAAE,CAChB,MAAM,EAAE,mBAAmB,EAC3B,GAAG,EAAE,oBAAoB,KACtB,kBAAkB,CAAC;IACxB,IAAI,EAAE,CAAC,OAAO,EAAE;QACd,mBAAmB,EAAE,uBAAuB,CAAC;QAC7C,cAAc,EAAE,kBAAkB,CAAC;QACnC,MAAM,EAAE,MAAM,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC,CAAC;QACtD,MAAM,EAAE,MAAM,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC,CAAC;KACvD,KAAK,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC,CAAC;CAC/C,CAAC;AAEJ,wBAAsB,uBAAuB,CAAC,kBAAkB,EAC9D,IAAI,EAAE,2BAA2B,CAAC,kBAAkB,CAAC,2CA4GtD;AAED,MAAM,MAAM,sCAAsC,GAAG,gBAAgB,GAAG;IACtE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AACF,wBAAgB,kCAAkC,CAChD,IAAI,GAAE,sCAA2C;;EA8BlD"}
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/common.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,kBAAkB,EAIvB,kBAAkB,EAElB,kBAAkB,EACnB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,KAAK,gBAAgB,EAAgB,MAAM,SAAS,CAAC;AAI9D,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,uBAAuB,EAAE,EAClC,OAAO,EAAE,kBAAkB;;;;;;;;;;;;cA6B5B;AAED,wBAAgB,8BAA8B,CAAC,GAAG,EAAE,QAAQ,QAS3D;AAED,MAAM,MAAM,mBAAmB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;AAEnE,KAAK,8BAA8B,GAAG;IACpC,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB,CAAC;AAEF,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE,8BAA8B;;;;;;;;;;;;oBA/BU,CAAC;aAAuB,CAAC;;;GA8DxE;AAED,KAAK,mBAAmB,GAAG,GAAG,CAAC;AAC/B,KAAK,oBAAoB,GAAG,MAAM,CAAC;AAEnC,MAAM,MAAM,oBAAoB,GAAG;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,CAAC,mBAAmB,GAAG,mBAAmB,EAAE,CAAC,EAAE,CAAC;IACzD,WAAW,CAAC,EAAE,sCAAsC,CAAC;CACtD,CAAC;AAEF,MAAM,MAAM,YAAY,CAAC,kBAAkB,IACvC;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,mBAAmB,EAAE,kBAAkB,CAAA;CAAE,GAC1D;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,aAAa,EAAE,kBAAkB,CAAA;CAAE,CAAC;AAE1D,MAAM,MAAM,YAAY,CAAC,kBAAkB,IACvC;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,mBAAmB,EAAE,kBAAkB,CAAA;CAAE,GAC1D;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,aAAa,EAAE,kBAAkB,CAAA;CAAE,CAAC;AAE1D,MAAM,MAAM,qBAAqB,CAAC,kBAAkB,IAAI;IACtD,mBAAmB,EAAE,uBAAuB,CAAC;IAC7C,cAAc,EAAE,kBAAkB,CAAC;IACnC,MAAM,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,kBAAkB,CAAC,CAAC,CAAC;IACxD,MAAM,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,kBAAkB,CAAC,CAAC,CAAC;CACzD,CAAC;AAEF,MAAM,MAAM,2BAA2B,CAAC,kBAAkB,GAAG,OAAO,IAClE,oBAAoB,GAAG;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IAC/C,0BAA0B,EAAE,OAAO,0BAA0B,CAAC;IAC9D,gBAAgB,EAAE,CAChB,MAAM,EAAE,mBAAmB,EAC3B,GAAG,EAAE,oBAAoB,KACtB,kBAAkB,CAAC;IACxB,IAAI,EAAE,CACJ,OAAO,EAAE,qBAAqB,CAAC,kBAAkB,CAAC,KAC/C,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC,CAAC;IAC7C,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB,CAAC;AAEJ,wBAAsB,uBAAuB,CAAC,kBAAkB,EAC9D,IAAI,EAAE,2BAA2B,CAAC,kBAAkB,CAAC,2CAkHtD;AAED,MAAM,MAAM,sCAAsC,GAAG,gBAAgB,GAAG;IACtE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AACF,wBAAgB,kCAAkC,CAChD,IAAI,GAAE,sCAA2C;;EA8BlD"}
@@ -15,7 +15,7 @@ export function findMatchingPaymentRequirements(accepts, payload) {
15
15
  possible = accepts.filter((x) => x.network === payload.network && x.scheme === payload.scheme);
16
16
  }
17
17
  if (possible.length > 1) {
18
- logger.warning(`found ${possible.length} ambiguous matching requirements for client payment: {*}`, payload);
18
+ logger.warning(`found ${possible.length} ambiguous matching requirements for client payment`, payload);
19
19
  }
20
20
  // XXX - If there are more than one, this really should be an error.
21
21
  // For now, err on the side of potential compatibility.
@@ -30,11 +30,12 @@ export function gateGetPaymentRequiredResponse(res) {
30
30
  throw new Error(msg);
31
31
  }
32
32
  export async function getPaymentRequiredResponse(args) {
33
+ const fetchFn = args.fetch ?? fetch;
33
34
  const accepts = args.accepts.map((x) => ({
34
35
  ...x,
35
36
  resource: x.resource ?? args.resource,
36
37
  }));
37
- const t = await fetch(`${args.facilitatorURL}/accepts`, {
38
+ const t = await fetchFn(`${args.facilitatorURL}/accepts`, {
38
39
  method: "POST",
39
40
  headers: {
40
41
  Accept: "application/json",
@@ -54,10 +55,12 @@ export async function getPaymentRequiredResponse(args) {
54
55
  }
55
56
  export async function handleMiddlewareRequest(args) {
56
57
  const accepts = args.accepts.flat();
58
+ const fetchFn = args.fetch ?? fetch;
57
59
  const paymentRequiredResponse = await args.getPaymentRequiredResponse({
58
60
  accepts,
59
61
  facilitatorURL: args.facilitatorURL,
60
62
  resource: args.resource,
63
+ fetch: fetchFn,
61
64
  });
62
65
  const sendPaymentRequired = () => args.sendJSONResponse(402, paymentRequiredResponse);
63
66
  const paymentHeader = args.getHeader("X-PAYMENT");
@@ -81,7 +84,7 @@ export async function handleMiddlewareRequest(args) {
81
84
  paymentPayload,
82
85
  paymentRequirements,
83
86
  };
84
- const t = await fetch(`${args.facilitatorURL}/settle`, {
87
+ const t = await fetchFn(`${args.facilitatorURL}/settle`, {
85
88
  method: "POST",
86
89
  headers: {
87
90
  Accept: "application/json",
@@ -97,8 +100,9 @@ export async function handleMiddlewareRequest(args) {
97
100
  }
98
101
  if (!settlementResponse.success) {
99
102
  logger.warning("failed to settle payment: {error}", settlementResponse);
100
- return sendPaymentRequired();
103
+ return { success: false, errorResponse: sendPaymentRequired() };
101
104
  }
105
+ return { success: true, facilitatorResponse: settlementResponse };
102
106
  };
103
107
  const verify = async () => {
104
108
  const verifyRequest = {
@@ -107,7 +111,7 @@ export async function handleMiddlewareRequest(args) {
107
111
  paymentPayload,
108
112
  paymentRequirements,
109
113
  };
110
- const t = await fetch(`${args.facilitatorURL}/verify`, {
114
+ const t = await fetchFn(`${args.facilitatorURL}/verify`, {
111
115
  method: "POST",
112
116
  headers: {
113
117
  Accept: "application/json",
@@ -122,9 +126,10 @@ export async function handleMiddlewareRequest(args) {
122
126
  throw new Error(msg);
123
127
  }
124
128
  if (!verifyResponse.isValid) {
125
- logger.warning("failed to settle payment: {invalidReason}", verifyResponse);
126
- return sendPaymentRequired();
129
+ logger.warning("failed to verify payment: {invalidReason}", verifyResponse);
130
+ return { success: false, errorResponse: sendPaymentRequired() };
127
131
  }
132
+ return { success: true, facilitatorResponse: verifyResponse };
128
133
  };
129
134
  return await args.body({
130
135
  paymentRequirements,
@@ -9,9 +9,9 @@ export async function createMiddleware(args) {
9
9
  getHeader: (key) => req.header(key),
10
10
  sendJSONResponse: (status, body) => res.status(status).json(body),
11
11
  body: async ({ settle }) => {
12
- const response = await settle();
13
- if (response !== undefined) {
14
- return response;
12
+ const settleResult = await settle();
13
+ if (!settleResult.success) {
14
+ return settleResult.errorResponse;
15
15
  }
16
16
  next();
17
17
  },
package/dist/src/hono.js CHANGED
@@ -16,16 +16,16 @@ export async function createMiddleware(args) {
16
16
  // If configured, try to verify the transaction before running
17
17
  // the next operation.
18
18
  const verifyResult = await verify();
19
- if (verifyResult !== undefined) {
20
- return verifyResult;
19
+ if (!verifyResult.success) {
20
+ return verifyResult.errorResponse;
21
21
  }
22
22
  }
23
23
  else {
24
24
  // Otherwise just settle the payment beforehand, like we've
25
25
  // done historically.
26
26
  const settleResult = await settle();
27
- if (settleResult !== undefined) {
28
- return settleResult;
27
+ if (!settleResult.success) {
28
+ return settleResult.errorResponse;
29
29
  }
30
30
  }
31
31
  await next();
@@ -33,14 +33,14 @@ export async function createMiddleware(args) {
33
33
  // Close out the verification, by actually settling the
34
34
  // payment.
35
35
  const settleResult = await settle();
36
- if (settleResult !== undefined) {
36
+ if (!settleResult.success) {
37
37
  // If the settlement fails, we need to explicitly
38
38
  // overwrite the downstream result. See:
39
39
  //
40
40
  // https://hono.dev/docs/guides/middleware#modify-the-response-after-next
41
41
  //
42
42
  c.res = undefined;
43
- c.res = settleResult;
43
+ c.res = settleResult.errorResponse;
44
44
  }
45
45
  }
46
46
  },
@@ -1,2 +1,2 @@
1
- export declare const logger: import("@logtape/logtape").Logger;
1
+ export declare const logger: import("@faremeter/logs").Logger;
2
2
  //# sourceMappingURL=logger.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/logger.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,MAAM,mCAAyC,CAAC"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/logger.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,MAAM,kCAA+C,CAAC"}
@@ -1,2 +1,2 @@
1
- import { getLogger } from "@logtape/logtape";
2
- export const logger = getLogger(["faremeter", "middleware"]);
1
+ import { getLogger } from "@faremeter/logs";
2
+ export const logger = await getLogger(["faremeter", "middleware"]);