x402check 0.0.1 → 0.1.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.
- package/dist/index.cjs +94 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +42 -2
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +42 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.iife.js +2 -2
- package/dist/index.js +94 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1824,9 +1824,101 @@ function runPipeline(input, options) {
|
|
|
1824
1824
|
};
|
|
1825
1825
|
}
|
|
1826
1826
|
|
|
1827
|
+
//#endregion
|
|
1828
|
+
//#region src/extraction/extract.ts
|
|
1829
|
+
/**
|
|
1830
|
+
* Get a header value, case-insensitive.
|
|
1831
|
+
* Supports both Headers objects and plain Record<string, string>.
|
|
1832
|
+
*/
|
|
1833
|
+
function getHeader(headers, name) {
|
|
1834
|
+
if (!headers) return null;
|
|
1835
|
+
if (typeof headers.get === "function") return headers.get(name);
|
|
1836
|
+
const lower = name.toLowerCase();
|
|
1837
|
+
for (const key of Object.keys(headers)) if (key.toLowerCase() === lower) return headers[key];
|
|
1838
|
+
return null;
|
|
1839
|
+
}
|
|
1840
|
+
/**
|
|
1841
|
+
* Decode base64 string to UTF-8 text.
|
|
1842
|
+
* Works in both browser (atob) and Node (Buffer).
|
|
1843
|
+
*/
|
|
1844
|
+
function decodeBase64(encoded) {
|
|
1845
|
+
if (typeof atob === "function") return atob(encoded);
|
|
1846
|
+
return Buffer.from(encoded, "base64").toString("utf-8");
|
|
1847
|
+
}
|
|
1848
|
+
/**
|
|
1849
|
+
* Check if a parsed object looks like it contains x402 config fields.
|
|
1850
|
+
*/
|
|
1851
|
+
function hasX402Fields(obj) {
|
|
1852
|
+
if (!obj || typeof obj !== "object") return false;
|
|
1853
|
+
const rec = obj;
|
|
1854
|
+
return !!(rec.accepts || rec.payTo || rec.x402Version);
|
|
1855
|
+
}
|
|
1856
|
+
/**
|
|
1857
|
+
* Try to parse the PAYMENT-REQUIRED header value as a base64-encoded JSON config.
|
|
1858
|
+
*/
|
|
1859
|
+
function tryHeaderExtraction(headers) {
|
|
1860
|
+
const headerValue = getHeader(headers, "payment-required");
|
|
1861
|
+
if (!headerValue) return null;
|
|
1862
|
+
try {
|
|
1863
|
+
const decoded = decodeBase64(headerValue);
|
|
1864
|
+
const parsed = JSON.parse(decoded);
|
|
1865
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) return {
|
|
1866
|
+
config: parsed,
|
|
1867
|
+
source: "header"
|
|
1868
|
+
};
|
|
1869
|
+
} catch {}
|
|
1870
|
+
try {
|
|
1871
|
+
const parsed = JSON.parse(headerValue);
|
|
1872
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) return {
|
|
1873
|
+
config: parsed,
|
|
1874
|
+
source: "header"
|
|
1875
|
+
};
|
|
1876
|
+
} catch {}
|
|
1877
|
+
return null;
|
|
1878
|
+
}
|
|
1879
|
+
/**
|
|
1880
|
+
* Extract an x402 config from an HTTP 402 response.
|
|
1881
|
+
*
|
|
1882
|
+
* Extraction priority:
|
|
1883
|
+
* 1. JSON body — if it parses and has x402 fields (accepts, payTo, x402Version)
|
|
1884
|
+
* 2. PAYMENT-REQUIRED header — base64-decoded JSON fallback
|
|
1885
|
+
*
|
|
1886
|
+
* Never throws. Returns structured result with error message on failure.
|
|
1887
|
+
*
|
|
1888
|
+
* @param response - Response-like object with body and/or headers
|
|
1889
|
+
* @returns Extraction result with config, source, and error
|
|
1890
|
+
*/
|
|
1891
|
+
function extractConfig(response) {
|
|
1892
|
+
const body = response.body;
|
|
1893
|
+
if (body && typeof body === "object" && !Array.isArray(body) && hasX402Fields(body)) return {
|
|
1894
|
+
config: body,
|
|
1895
|
+
source: "body",
|
|
1896
|
+
error: null
|
|
1897
|
+
};
|
|
1898
|
+
if (typeof body === "string" && body.trim()) try {
|
|
1899
|
+
const parsed = JSON.parse(body);
|
|
1900
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed) && hasX402Fields(parsed)) return {
|
|
1901
|
+
config: parsed,
|
|
1902
|
+
source: "body",
|
|
1903
|
+
error: null
|
|
1904
|
+
};
|
|
1905
|
+
} catch {}
|
|
1906
|
+
const headerResult = tryHeaderExtraction(response.headers);
|
|
1907
|
+
if (headerResult) return {
|
|
1908
|
+
config: headerResult.config,
|
|
1909
|
+
source: headerResult.source,
|
|
1910
|
+
error: null
|
|
1911
|
+
};
|
|
1912
|
+
return {
|
|
1913
|
+
config: null,
|
|
1914
|
+
source: null,
|
|
1915
|
+
error: "No x402 config found in response body or PAYMENT-REQUIRED header"
|
|
1916
|
+
};
|
|
1917
|
+
}
|
|
1918
|
+
|
|
1827
1919
|
//#endregion
|
|
1828
1920
|
//#region src/index.ts
|
|
1829
|
-
const VERSION = "0.0
|
|
1921
|
+
const VERSION = "0.1.0";
|
|
1830
1922
|
|
|
1831
1923
|
//#endregion
|
|
1832
1924
|
exports.CAIP2_REGEX = CAIP2_REGEX;
|
|
@@ -1838,6 +1930,7 @@ exports.SIMPLE_NAME_TO_CAIP2 = SIMPLE_NAME_TO_CAIP2;
|
|
|
1838
1930
|
exports.VERSION = VERSION;
|
|
1839
1931
|
exports.decodeBase58 = decodeBase58;
|
|
1840
1932
|
exports.detect = detect;
|
|
1933
|
+
exports.extractConfig = extractConfig;
|
|
1841
1934
|
exports.getAssetInfo = getAssetInfo;
|
|
1842
1935
|
exports.getCanonicalNetwork = getCanonicalNetwork;
|
|
1843
1936
|
exports.getNetworkInfo = getNetworkInfo;
|