New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details
Socket
Book a DemoSign in
Socket

@x402/fetch

Package Overview
Dependencies
Maintainers
2
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@x402/fetch - npm Package Compare versions

Comparing version
2.1.0
to
2.2.0
+2
-2
dist/cjs/index.d.ts

@@ -42,3 +42,3 @@ import { x402Client, x402HTTPClient, x402ClientConfig } from '@x402/core/client';

*/
declare function wrapFetchWithPayment(fetch: typeof globalThis.fetch, client: x402Client | x402HTTPClient): (input: RequestInfo, init?: RequestInit) => Promise<Response>;
declare function wrapFetchWithPayment(fetch: typeof globalThis.fetch, client: x402Client | x402HTTPClient): (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
/**

@@ -51,4 +51,4 @@ * Creates a payment-enabled fetch function from a configuration object.

*/
declare function wrapFetchWithPaymentFromConfig(fetch: typeof globalThis.fetch, config: x402ClientConfig): (input: RequestInfo, init?: RequestInit) => Promise<Response>;
declare function wrapFetchWithPaymentFromConfig(fetch: typeof globalThis.fetch, config: x402ClientConfig): (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
export { wrapFetchWithPayment, wrapFetchWithPaymentFromConfig };

@@ -36,3 +36,5 @@ "use strict";

return async (input, init) => {
const response = await fetch(input, init);
const request = new Request(input, init);
const clonedRequest = request.clone();
const response = await fetch(request);
if (response.status !== 402) {

@@ -67,18 +69,13 @@ return response;

const paymentHeaders = httpClient.encodePaymentSignatureHeader(paymentPayload);
if (!init) {
throw new Error("Missing fetch request configuration");
}
if (init.__is402Retry) {
if (clonedRequest.headers.has("PAYMENT-SIGNATURE") || clonedRequest.headers.has("X-PAYMENT")) {
throw new Error("Payment already attempted");
}
const newInit = {
...init,
headers: {
...init.headers || {},
...paymentHeaders,
"Access-Control-Expose-Headers": "PAYMENT-RESPONSE,X-PAYMENT-RESPONSE"
},
__is402Retry: true
};
const secondResponse = await fetch(input, newInit);
for (const [key, value] of Object.entries(paymentHeaders)) {
clonedRequest.headers.set(key, value);
}
clonedRequest.headers.set(
"Access-Control-Expose-Headers",
"PAYMENT-RESPONSE,X-PAYMENT-RESPONSE"
);
const secondResponse = await fetch(clonedRequest);
return secondResponse;

@@ -85,0 +82,0 @@ };

@@ -1,1 +0,1 @@

{"version":3,"sources":["../../src/index.ts"],"sourcesContent":["import { x402Client, x402ClientConfig, x402HTTPClient } from \"@x402/core/client\";\nimport { type PaymentRequired } from \"@x402/core/types\";\n\n/**\n * Enables the payment of APIs using the x402 payment protocol v2.\n *\n * This function wraps the native fetch API to automatically handle 402 Payment Required responses\n * by creating and sending payment headers. It will:\n * 1. Make the initial request\n * 2. If a 402 response is received, parse the payment requirements\n * 3. Create a payment header using the configured x402HTTPClient\n * 4. Retry the request with the payment header\n *\n * @param fetch - The fetch function to wrap (typically globalThis.fetch)\n * @param client - Configured x402Client or x402HTTPClient instance for handling payments\n * @returns A wrapped fetch function that handles 402 responses automatically\n *\n * @example\n * ```typescript\n * import { wrapFetchWithPayment, x402Client } from '@x402/fetch';\n * import { ExactEvmScheme } from '@x402/evm';\n * import { ExactSvmScheme } from '@x402/svm';\n *\n * const client = new x402Client()\n * .register('eip155:8453', new ExactEvmScheme(evmSigner))\n * .register('solana:mainnet', new ExactSvmScheme(svmSigner))\n * .register('eip155:1', new ExactEvmScheme(evmSigner), 1); // v1 protocol\n *\n * const fetchWithPay = wrapFetchWithPayment(fetch, client);\n *\n * // Make a request that may require payment\n * const response = await fetchWithPay('https://api.example.com/paid-endpoint');\n * ```\n *\n * @throws {Error} If no schemes are provided\n * @throws {Error} If the request configuration is missing\n * @throws {Error} If a payment has already been attempted for this request\n * @throws {Error} If there's an error creating the payment header\n */\nexport function wrapFetchWithPayment(\n fetch: typeof globalThis.fetch,\n client: x402Client | x402HTTPClient,\n) {\n const httpClient = client instanceof x402HTTPClient ? client : new x402HTTPClient(client);\n\n return async (input: RequestInfo, init?: RequestInit) => {\n const response = await fetch(input, init);\n\n if (response.status !== 402) {\n return response;\n }\n\n // Parse payment requirements from response\n let paymentRequired: PaymentRequired;\n try {\n // Create getHeader function for case-insensitive header lookup\n const getHeader = (name: string) => response.headers.get(name);\n\n // Try to get from headers first (v2), then from body (v1)\n let body: PaymentRequired | undefined;\n try {\n const responseText = await response.text();\n if (responseText) {\n body = JSON.parse(responseText) as PaymentRequired;\n }\n } catch {\n // Ignore JSON parse errors - might be header-only response\n }\n\n paymentRequired = httpClient.getPaymentRequiredResponse(getHeader, body);\n } catch (error) {\n throw new Error(\n `Failed to parse payment requirements: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n\n // Create payment payload (copy extensions from PaymentRequired)\n let paymentPayload;\n try {\n paymentPayload = await client.createPaymentPayload(paymentRequired);\n } catch (error) {\n throw new Error(\n `Failed to create payment payload: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n\n // Encode payment header\n const paymentHeaders = httpClient.encodePaymentSignatureHeader(paymentPayload);\n\n // Ensure we have request init\n if (!init) {\n throw new Error(\"Missing fetch request configuration\");\n }\n\n // Check if this is already a retry to prevent infinite loops\n if ((init as { __is402Retry?: boolean }).__is402Retry) {\n throw new Error(\"Payment already attempted\");\n }\n\n // Create new request with payment header\n const newInit = {\n ...init,\n headers: {\n ...(init.headers || {}),\n ...paymentHeaders,\n \"Access-Control-Expose-Headers\": \"PAYMENT-RESPONSE,X-PAYMENT-RESPONSE\",\n },\n __is402Retry: true,\n };\n\n // Retry the request with payment\n const secondResponse = await fetch(input, newInit);\n return secondResponse;\n };\n}\n\n/**\n * Creates a payment-enabled fetch function from a configuration object.\n *\n * @param fetch - The fetch function to wrap (typically globalThis.fetch)\n * @param config - Configuration options including scheme registrations and selectors\n * @returns A wrapped fetch function that handles 402 responses automatically\n */\nexport function wrapFetchWithPaymentFromConfig(\n fetch: typeof globalThis.fetch,\n config: x402ClientConfig,\n) {\n const client = x402Client.fromConfig(config);\n return wrapFetchWithPayment(fetch, client);\n}\n\n// Re-export types and utilities for convenience\nexport { x402Client, x402HTTPClient } from \"@x402/core/client\";\nexport type {\n PaymentPolicy,\n SchemeRegistration,\n SelectPaymentRequirements,\n x402ClientConfig,\n} from \"@x402/core/client\";\nexport { decodePaymentResponseHeader } from \"@x402/core/http\";\nexport type {\n Network,\n PaymentPayload,\n PaymentRequired,\n PaymentRequirements,\n SchemeNetworkClient,\n} from \"@x402/core/types\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAA6D;AAoI7D,IAAAA,iBAA2C;AAO3C,kBAA4C;AApGrC,SAAS,qBACd,OACA,QACA;AACA,QAAM,aAAa,kBAAkB,+BAAiB,SAAS,IAAI,6BAAe,MAAM;AAExF,SAAO,OAAO,OAAoB,SAAuB;AACvD,UAAM,WAAW,MAAM,MAAM,OAAO,IAAI;AAExC,QAAI,SAAS,WAAW,KAAK;AAC3B,aAAO;AAAA,IACT;AAGA,QAAI;AACJ,QAAI;AAEF,YAAM,YAAY,CAAC,SAAiB,SAAS,QAAQ,IAAI,IAAI;AAG7D,UAAI;AACJ,UAAI;AACF,cAAM,eAAe,MAAM,SAAS,KAAK;AACzC,YAAI,cAAc;AAChB,iBAAO,KAAK,MAAM,YAAY;AAAA,QAChC;AAAA,MACF,QAAQ;AAAA,MAER;AAEA,wBAAkB,WAAW,2BAA2B,WAAW,IAAI;AAAA,IACzE,SAAS,OAAO;AACd,YAAM,IAAI;AAAA,QACR,yCAAyC,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,MACnG;AAAA,IACF;AAGA,QAAI;AACJ,QAAI;AACF,uBAAiB,MAAM,OAAO,qBAAqB,eAAe;AAAA,IACpE,SAAS,OAAO;AACd,YAAM,IAAI;AAAA,QACR,qCAAqC,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,MAC/F;AAAA,IACF;AAGA,UAAM,iBAAiB,WAAW,6BAA6B,cAAc;AAG7E,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,qCAAqC;AAAA,IACvD;AAGA,QAAK,KAAoC,cAAc;AACrD,YAAM,IAAI,MAAM,2BAA2B;AAAA,IAC7C;AAGA,UAAM,UAAU;AAAA,MACd,GAAG;AAAA,MACH,SAAS;AAAA,QACP,GAAI,KAAK,WAAW,CAAC;AAAA,QACrB,GAAG;AAAA,QACH,iCAAiC;AAAA,MACnC;AAAA,MACA,cAAc;AAAA,IAChB;AAGA,UAAM,iBAAiB,MAAM,MAAM,OAAO,OAAO;AACjD,WAAO;AAAA,EACT;AACF;AASO,SAAS,+BACd,OACA,QACA;AACA,QAAM,SAAS,yBAAW,WAAW,MAAM;AAC3C,SAAO,qBAAqB,OAAO,MAAM;AAC3C;","names":["import_client"]}
{"version":3,"sources":["../../src/index.ts"],"sourcesContent":["import { x402Client, x402ClientConfig, x402HTTPClient } from \"@x402/core/client\";\nimport { type PaymentRequired } from \"@x402/core/types\";\n\n/**\n * Enables the payment of APIs using the x402 payment protocol v2.\n *\n * This function wraps the native fetch API to automatically handle 402 Payment Required responses\n * by creating and sending payment headers. It will:\n * 1. Make the initial request\n * 2. If a 402 response is received, parse the payment requirements\n * 3. Create a payment header using the configured x402HTTPClient\n * 4. Retry the request with the payment header\n *\n * @param fetch - The fetch function to wrap (typically globalThis.fetch)\n * @param client - Configured x402Client or x402HTTPClient instance for handling payments\n * @returns A wrapped fetch function that handles 402 responses automatically\n *\n * @example\n * ```typescript\n * import { wrapFetchWithPayment, x402Client } from '@x402/fetch';\n * import { ExactEvmScheme } from '@x402/evm';\n * import { ExactSvmScheme } from '@x402/svm';\n *\n * const client = new x402Client()\n * .register('eip155:8453', new ExactEvmScheme(evmSigner))\n * .register('solana:mainnet', new ExactSvmScheme(svmSigner))\n * .register('eip155:1', new ExactEvmScheme(evmSigner), 1); // v1 protocol\n *\n * const fetchWithPay = wrapFetchWithPayment(fetch, client);\n *\n * // Make a request that may require payment\n * const response = await fetchWithPay('https://api.example.com/paid-endpoint');\n * ```\n *\n * @throws {Error} If no schemes are provided\n * @throws {Error} If the request configuration is missing\n * @throws {Error} If a payment has already been attempted for this request\n * @throws {Error} If there's an error creating the payment header\n */\nexport function wrapFetchWithPayment(\n fetch: typeof globalThis.fetch,\n client: x402Client | x402HTTPClient,\n) {\n const httpClient = client instanceof x402HTTPClient ? client : new x402HTTPClient(client);\n\n return async (input: RequestInfo | URL, init?: RequestInit) => {\n const request = new Request(input, init);\n const clonedRequest = request.clone();\n\n const response = await fetch(request);\n\n if (response.status !== 402) {\n return response;\n }\n\n // Parse payment requirements from response\n let paymentRequired: PaymentRequired;\n try {\n // Create getHeader function for case-insensitive header lookup\n const getHeader = (name: string) => response.headers.get(name);\n\n // Try to get from headers first (v2), then from body (v1)\n let body: PaymentRequired | undefined;\n try {\n const responseText = await response.text();\n if (responseText) {\n body = JSON.parse(responseText) as PaymentRequired;\n }\n } catch {\n // Ignore JSON parse errors - might be header-only response\n }\n\n paymentRequired = httpClient.getPaymentRequiredResponse(getHeader, body);\n } catch (error) {\n throw new Error(\n `Failed to parse payment requirements: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n\n // Create payment payload (copy extensions from PaymentRequired)\n let paymentPayload;\n try {\n paymentPayload = await client.createPaymentPayload(paymentRequired);\n } catch (error) {\n throw new Error(\n `Failed to create payment payload: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n\n // Encode payment header\n const paymentHeaders = httpClient.encodePaymentSignatureHeader(paymentPayload);\n\n // Check if this is already a retry to prevent infinite loops\n if (clonedRequest.headers.has(\"PAYMENT-SIGNATURE\") || clonedRequest.headers.has(\"X-PAYMENT\")) {\n throw new Error(\"Payment already attempted\");\n }\n\n // Add payment headers to cloned request\n for (const [key, value] of Object.entries(paymentHeaders)) {\n clonedRequest.headers.set(key, value);\n }\n clonedRequest.headers.set(\n \"Access-Control-Expose-Headers\",\n \"PAYMENT-RESPONSE,X-PAYMENT-RESPONSE\",\n );\n\n // Retry the request with payment\n const secondResponse = await fetch(clonedRequest);\n return secondResponse;\n };\n}\n\n/**\n * Creates a payment-enabled fetch function from a configuration object.\n *\n * @param fetch - The fetch function to wrap (typically globalThis.fetch)\n * @param config - Configuration options including scheme registrations and selectors\n * @returns A wrapped fetch function that handles 402 responses automatically\n */\nexport function wrapFetchWithPaymentFromConfig(\n fetch: typeof globalThis.fetch,\n config: x402ClientConfig,\n) {\n const client = x402Client.fromConfig(config);\n return wrapFetchWithPayment(fetch, client);\n}\n\n// Re-export types and utilities for convenience\nexport { x402Client, x402HTTPClient } from \"@x402/core/client\";\nexport type {\n PaymentPolicy,\n SchemeRegistration,\n SelectPaymentRequirements,\n x402ClientConfig,\n} from \"@x402/core/client\";\nexport { decodePaymentResponseHeader } from \"@x402/core/http\";\nexport type {\n Network,\n PaymentPayload,\n PaymentRequired,\n PaymentRequirements,\n SchemeNetworkClient,\n} from \"@x402/core/types\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAA6D;AAgI7D,IAAAA,iBAA2C;AAO3C,kBAA4C;AAhGrC,SAAS,qBACd,OACA,QACA;AACA,QAAM,aAAa,kBAAkB,+BAAiB,SAAS,IAAI,6BAAe,MAAM;AAExF,SAAO,OAAO,OAA0B,SAAuB;AAC7D,UAAM,UAAU,IAAI,QAAQ,OAAO,IAAI;AACvC,UAAM,gBAAgB,QAAQ,MAAM;AAEpC,UAAM,WAAW,MAAM,MAAM,OAAO;AAEpC,QAAI,SAAS,WAAW,KAAK;AAC3B,aAAO;AAAA,IACT;AAGA,QAAI;AACJ,QAAI;AAEF,YAAM,YAAY,CAAC,SAAiB,SAAS,QAAQ,IAAI,IAAI;AAG7D,UAAI;AACJ,UAAI;AACF,cAAM,eAAe,MAAM,SAAS,KAAK;AACzC,YAAI,cAAc;AAChB,iBAAO,KAAK,MAAM,YAAY;AAAA,QAChC;AAAA,MACF,QAAQ;AAAA,MAER;AAEA,wBAAkB,WAAW,2BAA2B,WAAW,IAAI;AAAA,IACzE,SAAS,OAAO;AACd,YAAM,IAAI;AAAA,QACR,yCAAyC,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,MACnG;AAAA,IACF;AAGA,QAAI;AACJ,QAAI;AACF,uBAAiB,MAAM,OAAO,qBAAqB,eAAe;AAAA,IACpE,SAAS,OAAO;AACd,YAAM,IAAI;AAAA,QACR,qCAAqC,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,MAC/F;AAAA,IACF;AAGA,UAAM,iBAAiB,WAAW,6BAA6B,cAAc;AAG7E,QAAI,cAAc,QAAQ,IAAI,mBAAmB,KAAK,cAAc,QAAQ,IAAI,WAAW,GAAG;AAC5F,YAAM,IAAI,MAAM,2BAA2B;AAAA,IAC7C;AAGA,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,cAAc,GAAG;AACzD,oBAAc,QAAQ,IAAI,KAAK,KAAK;AAAA,IACtC;AACA,kBAAc,QAAQ;AAAA,MACpB;AAAA,MACA;AAAA,IACF;AAGA,UAAM,iBAAiB,MAAM,MAAM,aAAa;AAChD,WAAO;AAAA,EACT;AACF;AASO,SAAS,+BACd,OACA,QACA;AACA,QAAM,SAAS,yBAAW,WAAW,MAAM;AAC3C,SAAO,qBAAqB,OAAO,MAAM;AAC3C;","names":["import_client"]}

@@ -42,3 +42,3 @@ import { x402Client, x402HTTPClient, x402ClientConfig } from '@x402/core/client';

*/
declare function wrapFetchWithPayment(fetch: typeof globalThis.fetch, client: x402Client | x402HTTPClient): (input: RequestInfo, init?: RequestInit) => Promise<Response>;
declare function wrapFetchWithPayment(fetch: typeof globalThis.fetch, client: x402Client | x402HTTPClient): (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
/**

@@ -51,4 +51,4 @@ * Creates a payment-enabled fetch function from a configuration object.

*/
declare function wrapFetchWithPaymentFromConfig(fetch: typeof globalThis.fetch, config: x402ClientConfig): (input: RequestInfo, init?: RequestInit) => Promise<Response>;
declare function wrapFetchWithPaymentFromConfig(fetch: typeof globalThis.fetch, config: x402ClientConfig): (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
export { wrapFetchWithPayment, wrapFetchWithPaymentFromConfig };

@@ -8,3 +8,5 @@ // src/index.ts

return async (input, init) => {
const response = await fetch(input, init);
const request = new Request(input, init);
const clonedRequest = request.clone();
const response = await fetch(request);
if (response.status !== 402) {

@@ -39,18 +41,13 @@ return response;

const paymentHeaders = httpClient.encodePaymentSignatureHeader(paymentPayload);
if (!init) {
throw new Error("Missing fetch request configuration");
}
if (init.__is402Retry) {
if (clonedRequest.headers.has("PAYMENT-SIGNATURE") || clonedRequest.headers.has("X-PAYMENT")) {
throw new Error("Payment already attempted");
}
const newInit = {
...init,
headers: {
...init.headers || {},
...paymentHeaders,
"Access-Control-Expose-Headers": "PAYMENT-RESPONSE,X-PAYMENT-RESPONSE"
},
__is402Retry: true
};
const secondResponse = await fetch(input, newInit);
for (const [key, value] of Object.entries(paymentHeaders)) {
clonedRequest.headers.set(key, value);
}
clonedRequest.headers.set(
"Access-Control-Expose-Headers",
"PAYMENT-RESPONSE,X-PAYMENT-RESPONSE"
);
const secondResponse = await fetch(clonedRequest);
return secondResponse;

@@ -57,0 +54,0 @@ };

@@ -1,1 +0,1 @@

{"version":3,"sources":["../../src/index.ts"],"sourcesContent":["import { x402Client, x402ClientConfig, x402HTTPClient } from \"@x402/core/client\";\nimport { type PaymentRequired } from \"@x402/core/types\";\n\n/**\n * Enables the payment of APIs using the x402 payment protocol v2.\n *\n * This function wraps the native fetch API to automatically handle 402 Payment Required responses\n * by creating and sending payment headers. It will:\n * 1. Make the initial request\n * 2. If a 402 response is received, parse the payment requirements\n * 3. Create a payment header using the configured x402HTTPClient\n * 4. Retry the request with the payment header\n *\n * @param fetch - The fetch function to wrap (typically globalThis.fetch)\n * @param client - Configured x402Client or x402HTTPClient instance for handling payments\n * @returns A wrapped fetch function that handles 402 responses automatically\n *\n * @example\n * ```typescript\n * import { wrapFetchWithPayment, x402Client } from '@x402/fetch';\n * import { ExactEvmScheme } from '@x402/evm';\n * import { ExactSvmScheme } from '@x402/svm';\n *\n * const client = new x402Client()\n * .register('eip155:8453', new ExactEvmScheme(evmSigner))\n * .register('solana:mainnet', new ExactSvmScheme(svmSigner))\n * .register('eip155:1', new ExactEvmScheme(evmSigner), 1); // v1 protocol\n *\n * const fetchWithPay = wrapFetchWithPayment(fetch, client);\n *\n * // Make a request that may require payment\n * const response = await fetchWithPay('https://api.example.com/paid-endpoint');\n * ```\n *\n * @throws {Error} If no schemes are provided\n * @throws {Error} If the request configuration is missing\n * @throws {Error} If a payment has already been attempted for this request\n * @throws {Error} If there's an error creating the payment header\n */\nexport function wrapFetchWithPayment(\n fetch: typeof globalThis.fetch,\n client: x402Client | x402HTTPClient,\n) {\n const httpClient = client instanceof x402HTTPClient ? client : new x402HTTPClient(client);\n\n return async (input: RequestInfo, init?: RequestInit) => {\n const response = await fetch(input, init);\n\n if (response.status !== 402) {\n return response;\n }\n\n // Parse payment requirements from response\n let paymentRequired: PaymentRequired;\n try {\n // Create getHeader function for case-insensitive header lookup\n const getHeader = (name: string) => response.headers.get(name);\n\n // Try to get from headers first (v2), then from body (v1)\n let body: PaymentRequired | undefined;\n try {\n const responseText = await response.text();\n if (responseText) {\n body = JSON.parse(responseText) as PaymentRequired;\n }\n } catch {\n // Ignore JSON parse errors - might be header-only response\n }\n\n paymentRequired = httpClient.getPaymentRequiredResponse(getHeader, body);\n } catch (error) {\n throw new Error(\n `Failed to parse payment requirements: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n\n // Create payment payload (copy extensions from PaymentRequired)\n let paymentPayload;\n try {\n paymentPayload = await client.createPaymentPayload(paymentRequired);\n } catch (error) {\n throw new Error(\n `Failed to create payment payload: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n\n // Encode payment header\n const paymentHeaders = httpClient.encodePaymentSignatureHeader(paymentPayload);\n\n // Ensure we have request init\n if (!init) {\n throw new Error(\"Missing fetch request configuration\");\n }\n\n // Check if this is already a retry to prevent infinite loops\n if ((init as { __is402Retry?: boolean }).__is402Retry) {\n throw new Error(\"Payment already attempted\");\n }\n\n // Create new request with payment header\n const newInit = {\n ...init,\n headers: {\n ...(init.headers || {}),\n ...paymentHeaders,\n \"Access-Control-Expose-Headers\": \"PAYMENT-RESPONSE,X-PAYMENT-RESPONSE\",\n },\n __is402Retry: true,\n };\n\n // Retry the request with payment\n const secondResponse = await fetch(input, newInit);\n return secondResponse;\n };\n}\n\n/**\n * Creates a payment-enabled fetch function from a configuration object.\n *\n * @param fetch - The fetch function to wrap (typically globalThis.fetch)\n * @param config - Configuration options including scheme registrations and selectors\n * @returns A wrapped fetch function that handles 402 responses automatically\n */\nexport function wrapFetchWithPaymentFromConfig(\n fetch: typeof globalThis.fetch,\n config: x402ClientConfig,\n) {\n const client = x402Client.fromConfig(config);\n return wrapFetchWithPayment(fetch, client);\n}\n\n// Re-export types and utilities for convenience\nexport { x402Client, x402HTTPClient } from \"@x402/core/client\";\nexport type {\n PaymentPolicy,\n SchemeRegistration,\n SelectPaymentRequirements,\n x402ClientConfig,\n} from \"@x402/core/client\";\nexport { decodePaymentResponseHeader } from \"@x402/core/http\";\nexport type {\n Network,\n PaymentPayload,\n PaymentRequired,\n PaymentRequirements,\n SchemeNetworkClient,\n} from \"@x402/core/types\";\n"],"mappings":";AAAA,SAAS,YAA8B,sBAAsB;AAoI7D,SAAS,cAAAA,aAAY,kBAAAC,uBAAsB;AAO3C,SAAS,mCAAmC;AApGrC,SAAS,qBACd,OACA,QACA;AACA,QAAM,aAAa,kBAAkB,iBAAiB,SAAS,IAAI,eAAe,MAAM;AAExF,SAAO,OAAO,OAAoB,SAAuB;AACvD,UAAM,WAAW,MAAM,MAAM,OAAO,IAAI;AAExC,QAAI,SAAS,WAAW,KAAK;AAC3B,aAAO;AAAA,IACT;AAGA,QAAI;AACJ,QAAI;AAEF,YAAM,YAAY,CAAC,SAAiB,SAAS,QAAQ,IAAI,IAAI;AAG7D,UAAI;AACJ,UAAI;AACF,cAAM,eAAe,MAAM,SAAS,KAAK;AACzC,YAAI,cAAc;AAChB,iBAAO,KAAK,MAAM,YAAY;AAAA,QAChC;AAAA,MACF,QAAQ;AAAA,MAER;AAEA,wBAAkB,WAAW,2BAA2B,WAAW,IAAI;AAAA,IACzE,SAAS,OAAO;AACd,YAAM,IAAI;AAAA,QACR,yCAAyC,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,MACnG;AAAA,IACF;AAGA,QAAI;AACJ,QAAI;AACF,uBAAiB,MAAM,OAAO,qBAAqB,eAAe;AAAA,IACpE,SAAS,OAAO;AACd,YAAM,IAAI;AAAA,QACR,qCAAqC,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,MAC/F;AAAA,IACF;AAGA,UAAM,iBAAiB,WAAW,6BAA6B,cAAc;AAG7E,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,qCAAqC;AAAA,IACvD;AAGA,QAAK,KAAoC,cAAc;AACrD,YAAM,IAAI,MAAM,2BAA2B;AAAA,IAC7C;AAGA,UAAM,UAAU;AAAA,MACd,GAAG;AAAA,MACH,SAAS;AAAA,QACP,GAAI,KAAK,WAAW,CAAC;AAAA,QACrB,GAAG;AAAA,QACH,iCAAiC;AAAA,MACnC;AAAA,MACA,cAAc;AAAA,IAChB;AAGA,UAAM,iBAAiB,MAAM,MAAM,OAAO,OAAO;AACjD,WAAO;AAAA,EACT;AACF;AASO,SAAS,+BACd,OACA,QACA;AACA,QAAM,SAAS,WAAW,WAAW,MAAM;AAC3C,SAAO,qBAAqB,OAAO,MAAM;AAC3C;","names":["x402Client","x402HTTPClient"]}
{"version":3,"sources":["../../src/index.ts"],"sourcesContent":["import { x402Client, x402ClientConfig, x402HTTPClient } from \"@x402/core/client\";\nimport { type PaymentRequired } from \"@x402/core/types\";\n\n/**\n * Enables the payment of APIs using the x402 payment protocol v2.\n *\n * This function wraps the native fetch API to automatically handle 402 Payment Required responses\n * by creating and sending payment headers. It will:\n * 1. Make the initial request\n * 2. If a 402 response is received, parse the payment requirements\n * 3. Create a payment header using the configured x402HTTPClient\n * 4. Retry the request with the payment header\n *\n * @param fetch - The fetch function to wrap (typically globalThis.fetch)\n * @param client - Configured x402Client or x402HTTPClient instance for handling payments\n * @returns A wrapped fetch function that handles 402 responses automatically\n *\n * @example\n * ```typescript\n * import { wrapFetchWithPayment, x402Client } from '@x402/fetch';\n * import { ExactEvmScheme } from '@x402/evm';\n * import { ExactSvmScheme } from '@x402/svm';\n *\n * const client = new x402Client()\n * .register('eip155:8453', new ExactEvmScheme(evmSigner))\n * .register('solana:mainnet', new ExactSvmScheme(svmSigner))\n * .register('eip155:1', new ExactEvmScheme(evmSigner), 1); // v1 protocol\n *\n * const fetchWithPay = wrapFetchWithPayment(fetch, client);\n *\n * // Make a request that may require payment\n * const response = await fetchWithPay('https://api.example.com/paid-endpoint');\n * ```\n *\n * @throws {Error} If no schemes are provided\n * @throws {Error} If the request configuration is missing\n * @throws {Error} If a payment has already been attempted for this request\n * @throws {Error} If there's an error creating the payment header\n */\nexport function wrapFetchWithPayment(\n fetch: typeof globalThis.fetch,\n client: x402Client | x402HTTPClient,\n) {\n const httpClient = client instanceof x402HTTPClient ? client : new x402HTTPClient(client);\n\n return async (input: RequestInfo | URL, init?: RequestInit) => {\n const request = new Request(input, init);\n const clonedRequest = request.clone();\n\n const response = await fetch(request);\n\n if (response.status !== 402) {\n return response;\n }\n\n // Parse payment requirements from response\n let paymentRequired: PaymentRequired;\n try {\n // Create getHeader function for case-insensitive header lookup\n const getHeader = (name: string) => response.headers.get(name);\n\n // Try to get from headers first (v2), then from body (v1)\n let body: PaymentRequired | undefined;\n try {\n const responseText = await response.text();\n if (responseText) {\n body = JSON.parse(responseText) as PaymentRequired;\n }\n } catch {\n // Ignore JSON parse errors - might be header-only response\n }\n\n paymentRequired = httpClient.getPaymentRequiredResponse(getHeader, body);\n } catch (error) {\n throw new Error(\n `Failed to parse payment requirements: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n\n // Create payment payload (copy extensions from PaymentRequired)\n let paymentPayload;\n try {\n paymentPayload = await client.createPaymentPayload(paymentRequired);\n } catch (error) {\n throw new Error(\n `Failed to create payment payload: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n\n // Encode payment header\n const paymentHeaders = httpClient.encodePaymentSignatureHeader(paymentPayload);\n\n // Check if this is already a retry to prevent infinite loops\n if (clonedRequest.headers.has(\"PAYMENT-SIGNATURE\") || clonedRequest.headers.has(\"X-PAYMENT\")) {\n throw new Error(\"Payment already attempted\");\n }\n\n // Add payment headers to cloned request\n for (const [key, value] of Object.entries(paymentHeaders)) {\n clonedRequest.headers.set(key, value);\n }\n clonedRequest.headers.set(\n \"Access-Control-Expose-Headers\",\n \"PAYMENT-RESPONSE,X-PAYMENT-RESPONSE\",\n );\n\n // Retry the request with payment\n const secondResponse = await fetch(clonedRequest);\n return secondResponse;\n };\n}\n\n/**\n * Creates a payment-enabled fetch function from a configuration object.\n *\n * @param fetch - The fetch function to wrap (typically globalThis.fetch)\n * @param config - Configuration options including scheme registrations and selectors\n * @returns A wrapped fetch function that handles 402 responses automatically\n */\nexport function wrapFetchWithPaymentFromConfig(\n fetch: typeof globalThis.fetch,\n config: x402ClientConfig,\n) {\n const client = x402Client.fromConfig(config);\n return wrapFetchWithPayment(fetch, client);\n}\n\n// Re-export types and utilities for convenience\nexport { x402Client, x402HTTPClient } from \"@x402/core/client\";\nexport type {\n PaymentPolicy,\n SchemeRegistration,\n SelectPaymentRequirements,\n x402ClientConfig,\n} from \"@x402/core/client\";\nexport { decodePaymentResponseHeader } from \"@x402/core/http\";\nexport type {\n Network,\n PaymentPayload,\n PaymentRequired,\n PaymentRequirements,\n SchemeNetworkClient,\n} from \"@x402/core/types\";\n"],"mappings":";AAAA,SAAS,YAA8B,sBAAsB;AAgI7D,SAAS,cAAAA,aAAY,kBAAAC,uBAAsB;AAO3C,SAAS,mCAAmC;AAhGrC,SAAS,qBACd,OACA,QACA;AACA,QAAM,aAAa,kBAAkB,iBAAiB,SAAS,IAAI,eAAe,MAAM;AAExF,SAAO,OAAO,OAA0B,SAAuB;AAC7D,UAAM,UAAU,IAAI,QAAQ,OAAO,IAAI;AACvC,UAAM,gBAAgB,QAAQ,MAAM;AAEpC,UAAM,WAAW,MAAM,MAAM,OAAO;AAEpC,QAAI,SAAS,WAAW,KAAK;AAC3B,aAAO;AAAA,IACT;AAGA,QAAI;AACJ,QAAI;AAEF,YAAM,YAAY,CAAC,SAAiB,SAAS,QAAQ,IAAI,IAAI;AAG7D,UAAI;AACJ,UAAI;AACF,cAAM,eAAe,MAAM,SAAS,KAAK;AACzC,YAAI,cAAc;AAChB,iBAAO,KAAK,MAAM,YAAY;AAAA,QAChC;AAAA,MACF,QAAQ;AAAA,MAER;AAEA,wBAAkB,WAAW,2BAA2B,WAAW,IAAI;AAAA,IACzE,SAAS,OAAO;AACd,YAAM,IAAI;AAAA,QACR,yCAAyC,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,MACnG;AAAA,IACF;AAGA,QAAI;AACJ,QAAI;AACF,uBAAiB,MAAM,OAAO,qBAAqB,eAAe;AAAA,IACpE,SAAS,OAAO;AACd,YAAM,IAAI;AAAA,QACR,qCAAqC,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,MAC/F;AAAA,IACF;AAGA,UAAM,iBAAiB,WAAW,6BAA6B,cAAc;AAG7E,QAAI,cAAc,QAAQ,IAAI,mBAAmB,KAAK,cAAc,QAAQ,IAAI,WAAW,GAAG;AAC5F,YAAM,IAAI,MAAM,2BAA2B;AAAA,IAC7C;AAGA,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,cAAc,GAAG;AACzD,oBAAc,QAAQ,IAAI,KAAK,KAAK;AAAA,IACtC;AACA,kBAAc,QAAQ;AAAA,MACpB;AAAA,MACA;AAAA,IACF;AAGA,UAAM,iBAAiB,MAAM,MAAM,aAAa;AAChD,WAAO;AAAA,EACT;AACF;AASO,SAAS,+BACd,OACA,QACA;AACA,QAAM,SAAS,WAAW,WAAW,MAAM;AAC3C,SAAO,qBAAqB,OAAO,MAAM;AAC3C;","names":["x402Client","x402HTTPClient"]}
{
"name": "@x402/fetch",
"version": "2.1.0",
"version": "2.2.0",
"main": "./dist/cjs/index.js",

@@ -32,3 +32,3 @@ "module": "./dist/esm/index.js",

"zod": "^3.24.2",
"@x402/core": "^2.1.0"
"@x402/core": "^2.2.0"
},

@@ -35,0 +35,0 @@ "exports": {