@okxweb3/app-x402-core 0.1.2

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.
Files changed (66) hide show
  1. package/README.md +267 -0
  2. package/dist/cjs/OKXFacilitatorClient-BvyQB1QM.d.ts +59 -0
  3. package/dist/cjs/client/index.d.ts +320 -0
  4. package/dist/cjs/client/index.js +564 -0
  5. package/dist/cjs/client/index.js.map +1 -0
  6. package/dist/cjs/facilitator/index.d.ts +198 -0
  7. package/dist/cjs/facilitator/index.js +533 -0
  8. package/dist/cjs/facilitator/index.js.map +1 -0
  9. package/dist/cjs/http/index.d.ts +51 -0
  10. package/dist/cjs/http/index.js +1226 -0
  11. package/dist/cjs/http/index.js.map +1 -0
  12. package/dist/cjs/index.d.ts +6 -0
  13. package/dist/cjs/index.js +155 -0
  14. package/dist/cjs/index.js.map +1 -0
  15. package/dist/cjs/mechanisms-sojpSwWW.d.ts +763 -0
  16. package/dist/cjs/schemas/index.d.ts +309 -0
  17. package/dist/cjs/schemas/index.js +127 -0
  18. package/dist/cjs/schemas/index.js.map +1 -0
  19. package/dist/cjs/server/index.d.ts +2 -0
  20. package/dist/cjs/server/index.js +1880 -0
  21. package/dist/cjs/server/index.js.map +1 -0
  22. package/dist/cjs/types/index.d.ts +1 -0
  23. package/dist/cjs/types/index.js +97 -0
  24. package/dist/cjs/types/index.js.map +1 -0
  25. package/dist/cjs/utils/index.d.ts +48 -0
  26. package/dist/cjs/utils/index.js +116 -0
  27. package/dist/cjs/utils/index.js.map +1 -0
  28. package/dist/cjs/x402HTTPResourceServer-CcsAkcgI.d.ts +466 -0
  29. package/dist/esm/OKXFacilitatorClient-D5E3LX50.d.mts +59 -0
  30. package/dist/esm/chunk-CAXWAW23.mjs +68 -0
  31. package/dist/esm/chunk-CAXWAW23.mjs.map +1 -0
  32. package/dist/esm/chunk-CS33MEMU.mjs +86 -0
  33. package/dist/esm/chunk-CS33MEMU.mjs.map +1 -0
  34. package/dist/esm/chunk-O3IYMTNT.mjs +118 -0
  35. package/dist/esm/chunk-O3IYMTNT.mjs.map +1 -0
  36. package/dist/esm/chunk-TDLQZ6MP.mjs +86 -0
  37. package/dist/esm/chunk-TDLQZ6MP.mjs.map +1 -0
  38. package/dist/esm/chunk-XBQG2CDV.mjs +1792 -0
  39. package/dist/esm/chunk-XBQG2CDV.mjs.map +1 -0
  40. package/dist/esm/client/index.d.mts +320 -0
  41. package/dist/esm/client/index.mjs +318 -0
  42. package/dist/esm/client/index.mjs.map +1 -0
  43. package/dist/esm/facilitator/index.d.mts +198 -0
  44. package/dist/esm/facilitator/index.mjs +387 -0
  45. package/dist/esm/facilitator/index.mjs.map +1 -0
  46. package/dist/esm/http/index.d.mts +51 -0
  47. package/dist/esm/http/index.mjs +34 -0
  48. package/dist/esm/http/index.mjs.map +1 -0
  49. package/dist/esm/index.d.mts +6 -0
  50. package/dist/esm/index.mjs +9 -0
  51. package/dist/esm/index.mjs.map +1 -0
  52. package/dist/esm/mechanisms-sojpSwWW.d.mts +763 -0
  53. package/dist/esm/schemas/index.d.mts +309 -0
  54. package/dist/esm/schemas/index.mjs +41 -0
  55. package/dist/esm/schemas/index.mjs.map +1 -0
  56. package/dist/esm/server/index.d.mts +2 -0
  57. package/dist/esm/server/index.mjs +28 -0
  58. package/dist/esm/server/index.mjs.map +1 -0
  59. package/dist/esm/types/index.d.mts +1 -0
  60. package/dist/esm/types/index.mjs +13 -0
  61. package/dist/esm/types/index.mjs.map +1 -0
  62. package/dist/esm/utils/index.d.mts +48 -0
  63. package/dist/esm/utils/index.mjs +19 -0
  64. package/dist/esm/utils/index.mjs.map +1 -0
  65. package/dist/esm/x402HTTPResourceServer-DBeutKxq.d.mts +466 -0
  66. package/package.json +121 -0
@@ -0,0 +1,68 @@
1
+ // src/types/facilitator.ts
2
+ var VerifyError = class extends Error {
3
+ /**
4
+ * Creates a VerifyError from a failed verification response.
5
+ *
6
+ * @param statusCode - HTTP status code from the facilitator
7
+ * @param response - The verify response containing error details
8
+ */
9
+ constructor(statusCode, response) {
10
+ const reason = response.invalidReason || "unknown reason";
11
+ const message = response.invalidMessage;
12
+ super(message ? `${reason}: ${message}` : reason);
13
+ this.name = "VerifyError";
14
+ this.statusCode = statusCode;
15
+ this.invalidReason = response.invalidReason;
16
+ this.invalidMessage = response.invalidMessage;
17
+ this.payer = response.payer;
18
+ }
19
+ };
20
+ var SettleError = class extends Error {
21
+ /**
22
+ * Creates a SettleError from a failed settlement response.
23
+ *
24
+ * @param statusCode - HTTP status code from the facilitator
25
+ * @param response - The settle response containing error details
26
+ */
27
+ constructor(statusCode, response) {
28
+ const reason = response.errorReason || "unknown reason";
29
+ const message = response.errorMessage;
30
+ super(message ? `${reason}: ${message}` : reason);
31
+ this.name = "SettleError";
32
+ this.statusCode = statusCode;
33
+ this.errorReason = response.errorReason;
34
+ this.errorMessage = response.errorMessage;
35
+ this.payer = response.payer;
36
+ this.transaction = response.transaction;
37
+ this.network = response.network;
38
+ }
39
+ };
40
+ var FacilitatorResponseError = class extends Error {
41
+ /**
42
+ * Creates a FacilitatorResponseError for malformed facilitator responses.
43
+ *
44
+ * @param message - The boundary error message
45
+ */
46
+ constructor(message) {
47
+ super(message);
48
+ this.name = "FacilitatorResponseError";
49
+ }
50
+ };
51
+ function getFacilitatorResponseError(error) {
52
+ let current = error;
53
+ while (current instanceof Error) {
54
+ if (current instanceof FacilitatorResponseError) {
55
+ return current;
56
+ }
57
+ current = current.cause;
58
+ }
59
+ return null;
60
+ }
61
+
62
+ export {
63
+ VerifyError,
64
+ SettleError,
65
+ FacilitatorResponseError,
66
+ getFacilitatorResponseError
67
+ };
68
+ //# sourceMappingURL=chunk-CAXWAW23.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/types/facilitator.ts"],"sourcesContent":["import { PaymentPayload, PaymentRequirements } from \"./payments\";\nimport { Network } from \"./\";\n\nexport type VerifyRequest = {\n x402Version: number;\n paymentPayload: PaymentPayload;\n paymentRequirements: PaymentRequirements;\n};\n\nexport type VerifyResponse = {\n isValid: boolean;\n invalidReason?: string;\n invalidMessage?: string;\n payer?: string;\n extensions?: Record<string, unknown>;\n};\n\nexport type SettleRequest = {\n x402Version: number;\n paymentPayload: PaymentPayload;\n paymentRequirements: PaymentRequirements;\n};\n\nexport type SettleResponse = {\n success: boolean;\n /** OKX extension: pending (async, Seller trusts Facilitator), success (immediate), timeout (on-chain timed out) */\n status?: \"pending\" | \"success\" | \"timeout\";\n errorReason?: string;\n errorMessage?: string;\n payer?: string;\n transaction: string;\n network: Network;\n /** Actual amount settled in atomic token units. Present for schemes like `upto` where settlement amount may differ from the authorized maximum. */\n amount?: string;\n extensions?: Record<string, unknown>;\n};\n\nexport type SupportedKind = {\n x402Version: number;\n scheme: string;\n network: Network;\n extra?: Record<string, unknown>;\n};\n\nexport type SupportedResponse = {\n kinds: SupportedKind[];\n extensions: string[];\n signers: Record<string, string[]>; // CAIP family pattern → Signer addresses\n};\n\n/**\n * Response from `GET /settle/status?txHash=...`.\n * OKX extension: query on-chain settlement status by transaction hash.\n */\nexport type SettleStatusResponse = {\n success: boolean;\n status?: \"pending\" | \"success\" | \"failed\";\n errorReason?: string;\n errorMessage?: string;\n payer?: string;\n transaction?: string;\n network?: Network;\n};\n\n/**\n * Error thrown when payment verification fails.\n */\nexport class VerifyError extends Error {\n readonly invalidReason?: string;\n readonly invalidMessage?: string;\n readonly payer?: string;\n readonly statusCode: number;\n\n /**\n * Creates a VerifyError from a failed verification response.\n *\n * @param statusCode - HTTP status code from the facilitator\n * @param response - The verify response containing error details\n */\n constructor(statusCode: number, response: VerifyResponse) {\n const reason = response.invalidReason || \"unknown reason\";\n const message = response.invalidMessage;\n super(message ? `${reason}: ${message}` : reason);\n this.name = \"VerifyError\";\n this.statusCode = statusCode;\n this.invalidReason = response.invalidReason;\n this.invalidMessage = response.invalidMessage;\n this.payer = response.payer;\n }\n}\n\n/**\n * Error thrown when payment settlement fails.\n */\nexport class SettleError extends Error {\n readonly errorReason?: string;\n readonly errorMessage?: string;\n readonly payer?: string;\n readonly transaction: string;\n readonly network: Network;\n readonly statusCode: number;\n\n /**\n * Creates a SettleError from a failed settlement response.\n *\n * @param statusCode - HTTP status code from the facilitator\n * @param response - The settle response containing error details\n */\n constructor(statusCode: number, response: SettleResponse) {\n const reason = response.errorReason || \"unknown reason\";\n const message = response.errorMessage;\n super(message ? `${reason}: ${message}` : reason);\n this.name = \"SettleError\";\n this.statusCode = statusCode;\n this.errorReason = response.errorReason;\n this.errorMessage = response.errorMessage;\n this.payer = response.payer;\n this.transaction = response.transaction;\n this.network = response.network;\n }\n}\n\n/**\n * Error thrown when a facilitator returns malformed success payload data.\n */\nexport class FacilitatorResponseError extends Error {\n /**\n * Creates a FacilitatorResponseError for malformed facilitator responses.\n *\n * @param message - The boundary error message\n */\n constructor(message: string) {\n super(message);\n this.name = \"FacilitatorResponseError\";\n }\n}\n\n/**\n * Walks an error cause chain to find the first facilitator response error.\n *\n * @param error - The thrown value to inspect\n * @returns The nested facilitator response error, if present\n */\nexport function getFacilitatorResponseError(error: unknown): FacilitatorResponseError | null {\n let current = error;\n\n while (current instanceof Error) {\n if (current instanceof FacilitatorResponseError) {\n return current;\n }\n current = current.cause;\n }\n\n return null;\n}\n"],"mappings":";AAmEO,IAAM,cAAN,cAA0B,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYrC,YAAY,YAAoB,UAA0B;AACxD,UAAM,SAAS,SAAS,iBAAiB;AACzC,UAAM,UAAU,SAAS;AACzB,UAAM,UAAU,GAAG,MAAM,KAAK,OAAO,KAAK,MAAM;AAChD,SAAK,OAAO;AACZ,SAAK,aAAa;AAClB,SAAK,gBAAgB,SAAS;AAC9B,SAAK,iBAAiB,SAAS;AAC/B,SAAK,QAAQ,SAAS;AAAA,EACxB;AACF;AAKO,IAAM,cAAN,cAA0B,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcrC,YAAY,YAAoB,UAA0B;AACxD,UAAM,SAAS,SAAS,eAAe;AACvC,UAAM,UAAU,SAAS;AACzB,UAAM,UAAU,GAAG,MAAM,KAAK,OAAO,KAAK,MAAM;AAChD,SAAK,OAAO;AACZ,SAAK,aAAa;AAClB,SAAK,cAAc,SAAS;AAC5B,SAAK,eAAe,SAAS;AAC7B,SAAK,QAAQ,SAAS;AACtB,SAAK,cAAc,SAAS;AAC5B,SAAK,UAAU,SAAS;AAAA,EAC1B;AACF;AAKO,IAAM,2BAAN,cAAuC,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMlD,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAQO,SAAS,4BAA4B,OAAiD;AAC3F,MAAI,UAAU;AAEd,SAAO,mBAAmB,OAAO;AAC/B,QAAI,mBAAmB,0BAA0B;AAC/C,aAAO;AAAA,IACT;AACA,cAAU,QAAQ;AAAA,EACpB;AAEA,SAAO;AACT;","names":[]}
@@ -0,0 +1,86 @@
1
+ // src/schemas/index.ts
2
+ import { z } from "zod";
3
+ import { z as z2 } from "zod";
4
+ var NonEmptyString = z.string().min(1);
5
+ var Any = z.record(z.unknown());
6
+ var OptionalAny = z.record(z.unknown()).optional().nullable();
7
+ var NetworkSchema = z.string().min(3).refine((val) => val.includes(":"), {
8
+ message: "Network must be in CAIP-2 format (e.g., 'eip155:196')"
9
+ });
10
+ var ResourceInfoSchema = z.object({
11
+ url: NonEmptyString,
12
+ description: z.string().optional(),
13
+ mimeType: z.string().optional()
14
+ });
15
+ var PaymentRequirementsSchema = z.object({
16
+ scheme: NonEmptyString,
17
+ network: NetworkSchema,
18
+ amount: NonEmptyString,
19
+ asset: NonEmptyString,
20
+ payTo: NonEmptyString,
21
+ maxTimeoutSeconds: z.number().positive(),
22
+ extra: OptionalAny
23
+ });
24
+ var PaymentRequiredSchema = z.object({
25
+ x402Version: z.literal(2),
26
+ error: z.string().optional(),
27
+ resource: ResourceInfoSchema,
28
+ accepts: z.array(PaymentRequirementsSchema).min(1),
29
+ extensions: OptionalAny
30
+ });
31
+ var PaymentPayloadSchema = z.object({
32
+ x402Version: z.literal(2),
33
+ resource: ResourceInfoSchema.optional(),
34
+ accepted: PaymentRequirementsSchema,
35
+ payload: Any,
36
+ extensions: OptionalAny
37
+ });
38
+ function parsePaymentRequired(value) {
39
+ return PaymentRequiredSchema.safeParse(value);
40
+ }
41
+ function validatePaymentRequired(value) {
42
+ return PaymentRequiredSchema.parse(value);
43
+ }
44
+ function isPaymentRequired(value) {
45
+ return PaymentRequiredSchema.safeParse(value).success;
46
+ }
47
+ function parsePaymentRequirements(value) {
48
+ return PaymentRequirementsSchema.safeParse(value);
49
+ }
50
+ function validatePaymentRequirements(value) {
51
+ return PaymentRequirementsSchema.parse(value);
52
+ }
53
+ function isPaymentRequirements(value) {
54
+ return PaymentRequirementsSchema.safeParse(value).success;
55
+ }
56
+ function parsePaymentPayload(value) {
57
+ return PaymentPayloadSchema.safeParse(value);
58
+ }
59
+ function validatePaymentPayload(value) {
60
+ return PaymentPayloadSchema.parse(value);
61
+ }
62
+ function isPaymentPayload(value) {
63
+ return PaymentPayloadSchema.safeParse(value).success;
64
+ }
65
+
66
+ export {
67
+ NonEmptyString,
68
+ Any,
69
+ OptionalAny,
70
+ NetworkSchema,
71
+ ResourceInfoSchema,
72
+ PaymentRequirementsSchema,
73
+ PaymentRequiredSchema,
74
+ PaymentPayloadSchema,
75
+ parsePaymentRequired,
76
+ validatePaymentRequired,
77
+ isPaymentRequired,
78
+ parsePaymentRequirements,
79
+ validatePaymentRequirements,
80
+ isPaymentRequirements,
81
+ parsePaymentPayload,
82
+ validatePaymentPayload,
83
+ isPaymentPayload,
84
+ z2 as z
85
+ };
86
+ //# sourceMappingURL=chunk-CS33MEMU.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/schemas/index.ts"],"sourcesContent":["import { z } from \"zod\";\n\n// ============================================================================\n// Reusable Primitive Schemas\n// ============================================================================\n\n/**\n * Non-empty string schema - a string with at least one character.\n * Used for required string fields that cannot be empty.\n */\nexport const NonEmptyString = z.string().min(1);\nexport type NonEmptyString = z.infer<typeof NonEmptyString>;\n\n/**\n * Any record schema - an object with unknown keys and values.\n * Used for scheme-specific payloads and other extensible objects.\n */\nexport const Any = z.record(z.unknown());\nexport type Any = z.infer<typeof Any>;\n\n/**\n * Optional any record schema - an optional object with unknown keys and values.\n * Used for optional extension fields like `extra` and `extensions`.\n */\nexport const OptionalAny = z.record(z.unknown()).optional().nullable();\nexport type OptionalAny = z.infer<typeof OptionalAny>;\n\n// ============================================================================\n// Network Schemas\n// ============================================================================\n\n/**\n * Network identifier schema - CAIP-2 format validation.\n * Requires minimum length of 3 and a colon separator (e.g., \"eip155:196\", \"eip155:196\").\n */\nexport const NetworkSchema = z\n .string()\n .min(3)\n .refine(val => val.includes(\":\"), {\n message: \"Network must be in CAIP-2 format (e.g., 'eip155:196')\",\n });\nexport type Network = z.infer<typeof NetworkSchema>;\n\n// ============================================================================\n// Shared Schemas\n// ============================================================================\n\n/**\n * ResourceInfo schema for V2 - describes the protected resource.\n */\nexport const ResourceInfoSchema = z.object({\n url: NonEmptyString,\n description: z.string().optional(),\n mimeType: z.string().optional(),\n});\nexport type ResourceInfo = z.infer<typeof ResourceInfoSchema>;\n\n// ============================================================================\n// Payment Schemas\n// ============================================================================\n\n/**\n * PaymentRequirements schema.\n */\nexport const PaymentRequirementsSchema = z.object({\n scheme: NonEmptyString,\n network: NetworkSchema,\n amount: NonEmptyString,\n asset: NonEmptyString,\n payTo: NonEmptyString,\n maxTimeoutSeconds: z.number().positive(),\n extra: OptionalAny,\n});\nexport type PaymentRequirements = z.infer<typeof PaymentRequirementsSchema>;\n\n/**\n * PaymentRequired (402 response) schema.\n * Contains payment requirements when a resource requires payment.\n */\nexport const PaymentRequiredSchema = z.object({\n x402Version: z.literal(2),\n error: z.string().optional(),\n resource: ResourceInfoSchema,\n accepts: z.array(PaymentRequirementsSchema).min(1),\n extensions: OptionalAny,\n});\nexport type PaymentRequired = z.infer<typeof PaymentRequiredSchema>;\n\n/**\n * PaymentPayload schema.\n * Contains the payment data sent by the client.\n */\nexport const PaymentPayloadSchema = z.object({\n x402Version: z.literal(2),\n resource: ResourceInfoSchema.optional(),\n accepted: PaymentRequirementsSchema,\n payload: Any,\n extensions: OptionalAny,\n});\nexport type PaymentPayload = z.infer<typeof PaymentPayloadSchema>;\n\n// ============================================================================\n// Validation Functions\n// ============================================================================\n\n/**\n * Validates a PaymentRequired object (V1 or V2).\n *\n * @param value - The value to validate\n * @returns A result object with success status and data or error\n */\nexport function parsePaymentRequired(\n value: unknown,\n): z.SafeParseReturnType<unknown, PaymentRequired> {\n return PaymentRequiredSchema.safeParse(value);\n}\n\n/**\n * Validates a PaymentRequired object and throws on error.\n *\n * @param value - The value to validate\n * @returns The validated PaymentRequired\n * @throws ZodError if validation fails\n */\nexport function validatePaymentRequired(value: unknown): PaymentRequired {\n return PaymentRequiredSchema.parse(value);\n}\n\n/**\n * Type guard for PaymentRequired (V1 or V2).\n *\n * @param value - The value to check\n * @returns True if the value is a valid PaymentRequired\n */\nexport function isPaymentRequired(value: unknown): value is PaymentRequired {\n return PaymentRequiredSchema.safeParse(value).success;\n}\n\n/**\n * Validates a PaymentRequirements object (V1 or V2).\n *\n * @param value - The value to validate\n * @returns A result object with success status and data or error\n */\nexport function parsePaymentRequirements(\n value: unknown,\n): z.SafeParseReturnType<unknown, PaymentRequirements> {\n return PaymentRequirementsSchema.safeParse(value);\n}\n\n/**\n * Validates a PaymentRequirements object and throws on error.\n *\n * @param value - The value to validate\n * @returns The validated PaymentRequirements\n * @throws ZodError if validation fails\n */\nexport function validatePaymentRequirements(value: unknown): PaymentRequirements {\n return PaymentRequirementsSchema.parse(value);\n}\n\n/**\n * Type guard for PaymentRequirements (V1 or V2).\n *\n * @param value - The value to check\n * @returns True if the value is a valid PaymentRequirements\n */\nexport function isPaymentRequirements(value: unknown): value is PaymentRequirements {\n return PaymentRequirementsSchema.safeParse(value).success;\n}\n\n/**\n * Validates a PaymentPayload object (V1 or V2).\n *\n * @param value - The value to validate\n * @returns A result object with success status and data or error\n */\nexport function parsePaymentPayload(\n value: unknown,\n): z.SafeParseReturnType<unknown, PaymentPayload> {\n return PaymentPayloadSchema.safeParse(value);\n}\n\n/**\n * Validates a PaymentPayload object and throws on error.\n *\n * @param value - The value to validate\n * @returns The validated PaymentPayload\n * @throws ZodError if validation fails\n */\nexport function validatePaymentPayload(value: unknown): PaymentPayload {\n return PaymentPayloadSchema.parse(value);\n}\n\n/**\n * Type guard for PaymentPayload (V1 or V2).\n *\n * @param value - The value to check\n * @returns True if the value is a valid PaymentPayload\n */\nexport function isPaymentPayload(value: unknown): value is PaymentPayload {\n return PaymentPayloadSchema.safeParse(value).success;\n}\n\n// ============================================================================\n// Re-export zod for convenience\n// ============================================================================\n\nexport { z } from \"zod\";\n"],"mappings":";AAAA,SAAS,SAAS;AAgNlB,SAAS,KAAAA,UAAS;AAtMX,IAAM,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC;AAOvC,IAAM,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC;AAOhC,IAAM,cAAc,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,SAAS,EAAE,SAAS;AAW9D,IAAM,gBAAgB,EAC1B,OAAO,EACP,IAAI,CAAC,EACL,OAAO,SAAO,IAAI,SAAS,GAAG,GAAG;AAAA,EAChC,SAAS;AACX,CAAC;AAUI,IAAM,qBAAqB,EAAE,OAAO;AAAA,EACzC,KAAK;AAAA,EACL,aAAa,EAAE,OAAO,EAAE,SAAS;AAAA,EACjC,UAAU,EAAE,OAAO,EAAE,SAAS;AAChC,CAAC;AAUM,IAAM,4BAA4B,EAAE,OAAO;AAAA,EAChD,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,OAAO;AAAA,EACP,mBAAmB,EAAE,OAAO,EAAE,SAAS;AAAA,EACvC,OAAO;AACT,CAAC;AAOM,IAAM,wBAAwB,EAAE,OAAO;AAAA,EAC5C,aAAa,EAAE,QAAQ,CAAC;AAAA,EACxB,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,UAAU;AAAA,EACV,SAAS,EAAE,MAAM,yBAAyB,EAAE,IAAI,CAAC;AAAA,EACjD,YAAY;AACd,CAAC;AAOM,IAAM,uBAAuB,EAAE,OAAO;AAAA,EAC3C,aAAa,EAAE,QAAQ,CAAC;AAAA,EACxB,UAAU,mBAAmB,SAAS;AAAA,EACtC,UAAU;AAAA,EACV,SAAS;AAAA,EACT,YAAY;AACd,CAAC;AAaM,SAAS,qBACd,OACiD;AACjD,SAAO,sBAAsB,UAAU,KAAK;AAC9C;AASO,SAAS,wBAAwB,OAAiC;AACvE,SAAO,sBAAsB,MAAM,KAAK;AAC1C;AAQO,SAAS,kBAAkB,OAA0C;AAC1E,SAAO,sBAAsB,UAAU,KAAK,EAAE;AAChD;AAQO,SAAS,yBACd,OACqD;AACrD,SAAO,0BAA0B,UAAU,KAAK;AAClD;AASO,SAAS,4BAA4B,OAAqC;AAC/E,SAAO,0BAA0B,MAAM,KAAK;AAC9C;AAQO,SAAS,sBAAsB,OAA8C;AAClF,SAAO,0BAA0B,UAAU,KAAK,EAAE;AACpD;AAQO,SAAS,oBACd,OACgD;AAChD,SAAO,qBAAqB,UAAU,KAAK;AAC7C;AASO,SAAS,uBAAuB,OAAgC;AACrE,SAAO,qBAAqB,MAAM,KAAK;AACzC;AAQO,SAAS,iBAAiB,OAAyC;AACxE,SAAO,qBAAqB,UAAU,KAAK,EAAE;AAC/C;","names":["z"]}
@@ -0,0 +1,118 @@
1
+ // src/facilitator/OKXFacilitatorClient.ts
2
+ import crypto from "crypto";
3
+ var OKXFacilitatorClient = class {
4
+ /**
5
+ *
6
+ * @param config
7
+ */
8
+ constructor(config) {
9
+ this.config = {
10
+ baseUrl: "https://web3.okx.com",
11
+ ...config
12
+ };
13
+ }
14
+ /**
15
+ *
16
+ * @param method
17
+ * @param path
18
+ * @param body
19
+ */
20
+ createHeaders(method, path, body) {
21
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
22
+ const prehash = timestamp + method + path + (body ?? "");
23
+ const sign = crypto.createHmac("sha256", this.config.secretKey).update(prehash).digest("base64");
24
+ return {
25
+ "OK-ACCESS-KEY": this.config.apiKey,
26
+ "OK-ACCESS-SIGN": sign,
27
+ "OK-ACCESS-TIMESTAMP": timestamp,
28
+ "OK-ACCESS-PASSPHRASE": this.config.passphrase,
29
+ "Content-Type": "application/json"
30
+ };
31
+ }
32
+ /**
33
+ *
34
+ */
35
+ async getSupported() {
36
+ const path = "/api/v6/pay/x402/supported";
37
+ const res = await fetch(this.config.baseUrl + path, {
38
+ headers: this.createHeaders("GET", path)
39
+ });
40
+ if (!res.ok) throw new Error(`OKX getSupported failed: ${res.status}`);
41
+ const json = await res.json();
42
+ const data = json.data ?? json;
43
+ return data;
44
+ }
45
+ /**
46
+ *
47
+ * @param payload
48
+ * @param requirements
49
+ */
50
+ async verify(payload, requirements) {
51
+ const path = "/api/v6/pay/x402/verify";
52
+ const body = JSON.stringify({
53
+ x402Version: 2,
54
+ paymentPayload: payload,
55
+ paymentRequirements: requirements
56
+ });
57
+ const res = await fetch(this.config.baseUrl + path, {
58
+ method: "POST",
59
+ headers: this.createHeaders("POST", path, body),
60
+ body
61
+ });
62
+ if (!res.ok) throw new Error(`OKX verify failed: ${res.status}`);
63
+ const json = await res.json();
64
+ const data = json.data ?? json;
65
+ return data;
66
+ }
67
+ /**
68
+ *
69
+ * @param payload
70
+ * @param requirements
71
+ */
72
+ async settle(payload, requirements) {
73
+ const path = "/api/v6/pay/x402/settle";
74
+ const bodyObj = {
75
+ x402Version: 2,
76
+ paymentPayload: payload,
77
+ paymentRequirements: requirements
78
+ };
79
+ if (this.config.syncSettle !== void 0) {
80
+ bodyObj.syncSettle = this.config.syncSettle;
81
+ }
82
+ const body = JSON.stringify(bodyObj);
83
+ const res = await fetch(this.config.baseUrl + path, {
84
+ method: "POST",
85
+ headers: this.createHeaders("POST", path, body),
86
+ body
87
+ });
88
+ if (!res.ok) throw new Error(`OKX settle failed: ${res.status}`);
89
+ const json = await res.json();
90
+ const data = json.data ?? json;
91
+ return data;
92
+ }
93
+ /**
94
+ * Query on-chain settlement status by transaction hash.
95
+ *
96
+ * @param txHash - The transaction hash to query
97
+ * @returns Settlement status response
98
+ */
99
+ async getSettleStatus(txHash) {
100
+ const path = `/api/v6/pay/x402/settle/status?txHash=${encodeURIComponent(txHash)}`;
101
+ const res = await fetch(this.config.baseUrl + path, {
102
+ headers: this.createHeaders("GET", path)
103
+ });
104
+ if (!res.ok) throw new Error(`OKX getSettleStatus failed: ${res.status}`);
105
+ const json = await res.json();
106
+ const data = json.data ?? json;
107
+ return data;
108
+ }
109
+ };
110
+
111
+ // src/index.ts
112
+ var x402Version = 2;
113
+
114
+ export {
115
+ OKXFacilitatorClient,
116
+ x402Version
117
+ };
118
+ //# sourceMappingURL=chunk-O3IYMTNT.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/facilitator/OKXFacilitatorClient.ts","../../src/index.ts"],"sourcesContent":["import crypto from \"node:crypto\";\nimport type { FacilitatorClient } from \"../http/httpFacilitatorClient.js\";\nimport type {\n VerifyResponse,\n SettleResponse,\n SettleStatusResponse,\n SupportedResponse,\n} from \"../types/facilitator.js\";\nimport type { PaymentPayload, PaymentRequirements } from \"../types/payments.js\";\n\nexport interface OKXConfig {\n apiKey: string;\n secretKey: string;\n passphrase: string;\n baseUrl?: string;\n /**\n * OKX exact-scheme extension: when true, the settle call tells the facilitator to\n * wait for on-chain confirmation before responding (syncSettle=true in request body).\n * The facilitator then returns status=\"success\" directly (no polling needed).\n * When false (default), the facilitator responds with status=\"pending\" immediately.\n */\n syncSettle?: boolean;\n}\n\n/**\n * OKX facilitator client implementing the FacilitatorClient interface.\n * Uses HMAC-SHA256 signing per OKX REST API authentication spec.\n */\nexport class OKXFacilitatorClient implements FacilitatorClient {\n private config: Required<Omit<OKXConfig, \"syncSettle\">> & Pick<OKXConfig, \"syncSettle\">;\n\n /**\n *\n * @param config\n */\n constructor(config: OKXConfig) {\n this.config = {\n baseUrl: \"https://web3.okx.com\",\n ...config,\n };\n }\n\n /**\n *\n * @param method\n * @param path\n * @param body\n */\n private createHeaders(method: string, path: string, body?: string): Record<string, string> {\n const timestamp = new Date().toISOString();\n const prehash = timestamp + method + path + (body ?? \"\");\n const sign = crypto\n .createHmac(\"sha256\", this.config.secretKey)\n .update(prehash)\n .digest(\"base64\");\n\n return {\n \"OK-ACCESS-KEY\": this.config.apiKey,\n \"OK-ACCESS-SIGN\": sign,\n \"OK-ACCESS-TIMESTAMP\": timestamp,\n \"OK-ACCESS-PASSPHRASE\": this.config.passphrase,\n \"Content-Type\": \"application/json\",\n };\n }\n\n /**\n *\n */\n async getSupported(): Promise<SupportedResponse> {\n const path = \"/api/v6/pay/x402/supported\";\n const res = await fetch(this.config.baseUrl + path, {\n headers: this.createHeaders(\"GET\", path),\n });\n if (!res.ok) throw new Error(`OKX getSupported failed: ${res.status}`);\n const json = (await res.json()) as Record<string, unknown>;\n // OKX API wraps responses in { code, data, msg } envelope\n const data = (json.data ?? json) as SupportedResponse;\n return data;\n }\n\n /**\n *\n * @param payload\n * @param requirements\n */\n async verify(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<VerifyResponse> {\n const path = \"/api/v6/pay/x402/verify\";\n const body = JSON.stringify({\n x402Version: 2,\n paymentPayload: payload,\n paymentRequirements: requirements,\n });\n const res = await fetch(this.config.baseUrl + path, {\n method: \"POST\",\n headers: this.createHeaders(\"POST\", path, body),\n body,\n });\n if (!res.ok) throw new Error(`OKX verify failed: ${res.status}`);\n const json = (await res.json()) as Record<string, unknown>;\n const data = (json.data ?? json) as VerifyResponse;\n return data;\n }\n\n /**\n *\n * @param payload\n * @param requirements\n */\n async settle(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<SettleResponse> {\n const path = \"/api/v6/pay/x402/settle\";\n // Include OKX-extension syncSettle field when configured:\n // syncSettle=true → facilitator waits for on-chain confirmation, returns status=\"success\"\n // syncSettle=false → facilitator returns immediately with status=\"pending\" (default)\n const bodyObj: Record<string, unknown> = {\n x402Version: 2,\n paymentPayload: payload,\n paymentRequirements: requirements,\n };\n if (this.config.syncSettle !== undefined) {\n bodyObj.syncSettle = this.config.syncSettle;\n }\n const body = JSON.stringify(bodyObj);\n const res = await fetch(this.config.baseUrl + path, {\n method: \"POST\",\n headers: this.createHeaders(\"POST\", path, body),\n body,\n });\n if (!res.ok) throw new Error(`OKX settle failed: ${res.status}`);\n const json = (await res.json()) as Record<string, unknown>;\n const data = (json.data ?? json) as SettleResponse;\n return data;\n }\n\n /**\n * Query on-chain settlement status by transaction hash.\n *\n * @param txHash - The transaction hash to query\n * @returns Settlement status response\n */\n async getSettleStatus(txHash: string): Promise<SettleStatusResponse> {\n const path = `/api/v6/pay/x402/settle/status?txHash=${encodeURIComponent(txHash)}`;\n const res = await fetch(this.config.baseUrl + path, {\n headers: this.createHeaders(\"GET\", path),\n });\n if (!res.ok) throw new Error(`OKX getSettleStatus failed: ${res.status}`);\n const json = (await res.json()) as Record<string, unknown>;\n const data = (json.data ?? json) as SettleStatusResponse;\n return data;\n }\n}\n","export const x402Version = 2;\nexport { OKXFacilitatorClient } from \"./facilitator/OKXFacilitatorClient\";\nexport type { OKXConfig } from \"./facilitator/OKXFacilitatorClient\";"],"mappings":"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","names":[]}
@@ -0,0 +1,86 @@
1
+ // src/utils/index.ts
2
+ var findSchemesByNetwork = (map, network) => {
3
+ let implementationsByScheme = map.get(network);
4
+ if (!implementationsByScheme) {
5
+ for (const [registeredNetworkPattern, implementations] of map.entries()) {
6
+ const pattern = registeredNetworkPattern.replace(/[.*+?^${}()|[\]\\]/g, "\\$&").replace(/\\\*/g, ".*");
7
+ const regex = new RegExp(`^${pattern}$`);
8
+ if (regex.test(network)) {
9
+ implementationsByScheme = implementations;
10
+ break;
11
+ }
12
+ }
13
+ }
14
+ return implementationsByScheme;
15
+ };
16
+ var findByNetworkAndScheme = (map, scheme, network) => {
17
+ return findSchemesByNetwork(map, network)?.get(scheme);
18
+ };
19
+ var findFacilitatorBySchemeAndNetwork = (schemeMap, scheme, network) => {
20
+ const schemeData = schemeMap.get(scheme);
21
+ if (!schemeData) return void 0;
22
+ if (schemeData.networks.has(network)) {
23
+ return schemeData.facilitator;
24
+ }
25
+ const patternRegex = new RegExp("^" + schemeData.pattern.replace("*", ".*") + "$");
26
+ if (patternRegex.test(network)) {
27
+ return schemeData.facilitator;
28
+ }
29
+ return void 0;
30
+ };
31
+ var Base64EncodedRegex = /^[A-Za-z0-9+/]*={0,2}$/;
32
+ function safeBase64Encode(data) {
33
+ if (typeof globalThis !== "undefined" && typeof globalThis.btoa === "function") {
34
+ const bytes = new TextEncoder().encode(data);
35
+ const binaryString = Array.from(bytes, (byte) => String.fromCharCode(byte)).join("");
36
+ return globalThis.btoa(binaryString);
37
+ }
38
+ return Buffer.from(data, "utf8").toString("base64");
39
+ }
40
+ function safeBase64Decode(data) {
41
+ if (typeof globalThis !== "undefined" && typeof globalThis.atob === "function") {
42
+ const binaryString = globalThis.atob(data);
43
+ const bytes = new Uint8Array(binaryString.length);
44
+ for (let i = 0; i < binaryString.length; i++) {
45
+ bytes[i] = binaryString.charCodeAt(i);
46
+ }
47
+ const decoder = new TextDecoder("utf-8");
48
+ return decoder.decode(bytes);
49
+ }
50
+ return Buffer.from(data, "base64").toString("utf-8");
51
+ }
52
+ function deepEqual(obj1, obj2) {
53
+ const normalize = (obj) => {
54
+ if (obj === null || obj === void 0) return JSON.stringify(obj);
55
+ if (typeof obj !== "object") return JSON.stringify(obj);
56
+ if (Array.isArray(obj)) {
57
+ return JSON.stringify(
58
+ obj.map(
59
+ (item) => typeof item === "object" && item !== null ? JSON.parse(normalize(item)) : item
60
+ )
61
+ );
62
+ }
63
+ const sorted = {};
64
+ Object.keys(obj).sort().forEach((key) => {
65
+ const value = obj[key];
66
+ sorted[key] = typeof value === "object" && value !== null ? JSON.parse(normalize(value)) : value;
67
+ });
68
+ return JSON.stringify(sorted);
69
+ };
70
+ try {
71
+ return normalize(obj1) === normalize(obj2);
72
+ } catch {
73
+ return JSON.stringify(obj1) === JSON.stringify(obj2);
74
+ }
75
+ }
76
+
77
+ export {
78
+ findSchemesByNetwork,
79
+ findByNetworkAndScheme,
80
+ findFacilitatorBySchemeAndNetwork,
81
+ Base64EncodedRegex,
82
+ safeBase64Encode,
83
+ safeBase64Decode,
84
+ deepEqual
85
+ };
86
+ //# sourceMappingURL=chunk-TDLQZ6MP.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/index.ts"],"sourcesContent":["import { Network } from \"../types\";\n\n/**\n * Scheme data structure for facilitator storage\n */\nexport interface SchemeData<T> {\n facilitator: T;\n networks: Set<Network>;\n pattern: Network;\n}\n\nexport const findSchemesByNetwork = <T>(\n map: Map<string, Map<string, T>>,\n network: Network,\n): Map<string, T> | undefined => {\n // Direct match first\n let implementationsByScheme = map.get(network);\n\n if (!implementationsByScheme) {\n // Try pattern matching for registered network patterns\n for (const [registeredNetworkPattern, implementations] of map.entries()) {\n // Convert the registered network pattern to a regex\n // e.g., \"eip155:*\" becomes /^eip155:.*$/\n const pattern = registeredNetworkPattern\n .replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\") // Escape special regex chars except *\n .replace(/\\\\\\*/g, \".*\"); // Replace escaped * with .*\n\n const regex = new RegExp(`^${pattern}$`);\n\n if (regex.test(network)) {\n implementationsByScheme = implementations;\n break;\n }\n }\n }\n\n return implementationsByScheme;\n};\n\nexport const findByNetworkAndScheme = <T>(\n map: Map<string, Map<string, T>>,\n scheme: string,\n network: Network,\n): T | undefined => {\n return findSchemesByNetwork(map, network)?.get(scheme);\n};\n\n/**\n * Finds a facilitator by scheme and network using pattern matching.\n * Works with new SchemeData storage structure.\n *\n * @param schemeMap - Map of scheme names to SchemeData\n * @param scheme - The scheme to find\n * @param network - The network to match against\n * @returns The facilitator if found, undefined otherwise\n */\nexport const findFacilitatorBySchemeAndNetwork = <T>(\n schemeMap: Map<string, SchemeData<T>>,\n scheme: string,\n network: Network,\n): T | undefined => {\n const schemeData = schemeMap.get(scheme);\n if (!schemeData) return undefined;\n\n // Check if network is in the stored networks set\n if (schemeData.networks.has(network)) {\n return schemeData.facilitator;\n }\n\n // Try pattern matching\n const patternRegex = new RegExp(\"^\" + schemeData.pattern.replace(\"*\", \".*\") + \"$\");\n if (patternRegex.test(network)) {\n return schemeData.facilitator;\n }\n\n return undefined;\n};\n\nexport const Base64EncodedRegex = /^[A-Za-z0-9+/]*={0,2}$/;\n\n/**\n * Encodes a string to base64 format\n *\n * @param data - The string to be encoded to base64\n * @returns The base64 encoded string\n */\nexport function safeBase64Encode(data: string): string {\n if (typeof globalThis !== \"undefined\" && typeof globalThis.btoa === \"function\") {\n const bytes = new TextEncoder().encode(data);\n const binaryString = Array.from(bytes, byte => String.fromCharCode(byte)).join(\"\");\n return globalThis.btoa(binaryString);\n }\n return Buffer.from(data, \"utf8\").toString(\"base64\");\n}\n\n/**\n * Decodes a base64 string back to its original format\n *\n * @param data - The base64 encoded string to be decoded\n * @returns The decoded string in UTF-8 format\n */\nexport function safeBase64Decode(data: string): string {\n if (typeof globalThis !== \"undefined\" && typeof globalThis.atob === \"function\") {\n const binaryString = globalThis.atob(data);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n const decoder = new TextDecoder(\"utf-8\");\n return decoder.decode(bytes);\n }\n return Buffer.from(data, \"base64\").toString(\"utf-8\");\n}\n\n/**\n * Deep equality comparison for payment requirements\n * Uses a normalized JSON.stringify for consistent comparison\n *\n * @param obj1 - First object to compare\n * @param obj2 - Second object to compare\n * @returns True if objects are deeply equal\n */\nexport function deepEqual(obj1: unknown, obj2: unknown): boolean {\n // Normalize and stringify both objects for comparison\n // This handles nested objects, arrays, and different property orders\n const normalize = (obj: unknown): string => {\n // Handle primitives and null/undefined\n if (obj === null || obj === undefined) return JSON.stringify(obj);\n if (typeof obj !== \"object\") return JSON.stringify(obj);\n\n // Handle arrays\n if (Array.isArray(obj)) {\n return JSON.stringify(\n obj.map(item =>\n typeof item === \"object\" && item !== null ? JSON.parse(normalize(item)) : item,\n ),\n );\n }\n\n // Handle objects - sort keys and recursively normalize values\n const sorted: Record<string, unknown> = {};\n Object.keys(obj as Record<string, unknown>)\n .sort()\n .forEach(key => {\n const value = (obj as Record<string, unknown>)[key];\n sorted[key] =\n typeof value === \"object\" && value !== null ? JSON.parse(normalize(value)) : value;\n });\n return JSON.stringify(sorted);\n };\n\n try {\n return normalize(obj1) === normalize(obj2);\n } catch {\n // Fallback to simple comparison if normalization fails\n return JSON.stringify(obj1) === JSON.stringify(obj2);\n }\n}\n"],"mappings":"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","names":[]}