@neus/sdk 1.1.5 → 1.1.6
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/cjs/client.cjs +95 -15
- package/cjs/index.cjs +95 -15
- package/cli/neus.mjs +31 -6
- package/client.js +100 -15
- package/package.json +147 -147
- package/types.d.ts +146 -3
package/cjs/client.cjs
CHANGED
|
@@ -1530,6 +1530,11 @@ ${bytes.length}`;
|
|
|
1530
1530
|
storeOriginalContent: typeof options?.storeOriginalContent === "boolean" ? options.storeOriginalContent : true
|
|
1531
1531
|
};
|
|
1532
1532
|
if (typeof options?.enableIpfs === "boolean") optionsPayload.enableIpfs = options.enableIpfs;
|
|
1533
|
+
if (options?.publishToHub === true) {
|
|
1534
|
+
optionsPayload.publishToHub = true;
|
|
1535
|
+
} else {
|
|
1536
|
+
delete optionsPayload.publishToHub;
|
|
1537
|
+
}
|
|
1533
1538
|
const requestData = {
|
|
1534
1539
|
verifierIds: normalizedVerifierIds,
|
|
1535
1540
|
data,
|
|
@@ -1750,18 +1755,39 @@ ${bytes.length}`;
|
|
|
1750
1755
|
}
|
|
1751
1756
|
return true;
|
|
1752
1757
|
}
|
|
1758
|
+
_buildProofsByWalletQuery(options = {}) {
|
|
1759
|
+
const qs = [];
|
|
1760
|
+
if (options.limit) qs.push(`limit=${encodeURIComponent(String(options.limit))}`);
|
|
1761
|
+
const cursorRaw = options.cursor !== null && options.cursor !== void 0 ? String(options.cursor).trim() : "";
|
|
1762
|
+
if (cursorRaw) qs.push(`cursor=${encodeURIComponent(cursorRaw)}`);
|
|
1763
|
+
else if (options.offset !== void 0 && options.offset !== null) {
|
|
1764
|
+
qs.push(`offset=${encodeURIComponent(String(options.offset))}`);
|
|
1765
|
+
}
|
|
1766
|
+
if (options.q) qs.push(`q=${encodeURIComponent(String(options.q))}`);
|
|
1767
|
+
if (options.qHash) qs.push(`qHash=${encodeURIComponent(String(options.qHash).toLowerCase())}`);
|
|
1768
|
+
if (options.verifierId) qs.push(`verifierId=${encodeURIComponent(String(options.verifierId))}`);
|
|
1769
|
+
if (options.verifierIds) qs.push(`verifierIds=${encodeURIComponent(String(options.verifierIds))}`);
|
|
1770
|
+
if (options.tags) qs.push(`tags=${encodeURIComponent(String(options.tags))}`);
|
|
1771
|
+
if (options.tagPrefix) qs.push(`tagPrefix=${encodeURIComponent(String(options.tagPrefix))}`);
|
|
1772
|
+
if (options.tagContains) qs.push(`tagContains=${encodeURIComponent(String(options.tagContains))}`);
|
|
1773
|
+
if (options.tagPrefixesAll) qs.push(`tagPrefixesAll=${encodeURIComponent(String(options.tagPrefixesAll))}`);
|
|
1774
|
+
if (options.status) qs.push(`status=${encodeURIComponent(String(options.status))}`);
|
|
1775
|
+
if (options.appId) qs.push(`appId=${encodeURIComponent(String(options.appId))}`);
|
|
1776
|
+
if (options.chainCoverage) qs.push(`chainCoverage=${encodeURIComponent(String(options.chainCoverage))}`);
|
|
1777
|
+
if (options.privacyLevel) qs.push(`privacyLevel=${encodeURIComponent(String(options.privacyLevel))}`);
|
|
1778
|
+
if (options.includeHistory) qs.push("includeHistory=1");
|
|
1779
|
+
if (options.includeFacets) qs.push(`includeFacets=${encodeURIComponent(String(options.includeFacets))}`);
|
|
1780
|
+
if (options.visibility) qs.push(`visibility=${encodeURIComponent(String(options.visibility))}`);
|
|
1781
|
+
if (options.isPublicRead) qs.push("isPublicRead=1");
|
|
1782
|
+
return qs;
|
|
1783
|
+
}
|
|
1753
1784
|
async getProofsByWallet(walletAddress, options = {}) {
|
|
1754
1785
|
if (!walletAddress || typeof walletAddress !== "string") {
|
|
1755
1786
|
throw new ValidationError("walletAddress is required");
|
|
1756
1787
|
}
|
|
1757
1788
|
const id = walletAddress.trim();
|
|
1758
1789
|
const pathId = /^0x[a-fA-F0-9]{40}$/i.test(id) ? id.toLowerCase() : id;
|
|
1759
|
-
const qs =
|
|
1760
|
-
if (options.limit) qs.push(`limit=${encodeURIComponent(String(options.limit))}`);
|
|
1761
|
-
const cursorRaw = options.cursor !== null && options.cursor !== void 0 ? String(options.cursor).trim() : "";
|
|
1762
|
-
if (cursorRaw) qs.push(`cursor=${encodeURIComponent(cursorRaw)}`);
|
|
1763
|
-
else if (options.offset) qs.push(`offset=${encodeURIComponent(String(options.offset))}`);
|
|
1764
|
-
if (options.qHash) qs.push(`qHash=${encodeURIComponent(options.qHash.toLowerCase())}`);
|
|
1790
|
+
const qs = this._buildProofsByWalletQuery(options);
|
|
1765
1791
|
const query = qs.length ? `?${qs.join("&")}` : "";
|
|
1766
1792
|
const response = await this._makeRequest(
|
|
1767
1793
|
"GET",
|
|
@@ -1774,10 +1800,11 @@ ${bytes.length}`;
|
|
|
1774
1800
|
return {
|
|
1775
1801
|
success: true,
|
|
1776
1802
|
proofs: Array.isArray(proofs) ? proofs : [],
|
|
1777
|
-
totalCount: response.data?.totalCount
|
|
1803
|
+
totalCount: typeof response.data?.totalCount === "number" ? response.data.totalCount : null,
|
|
1778
1804
|
hasMore: Boolean(response.data?.hasMore),
|
|
1779
1805
|
nextOffset: response.data?.nextOffset ?? null,
|
|
1780
|
-
nextCursor: typeof response.data?.nextCursor === "string" && response.data.nextCursor.trim() ? response.data.nextCursor.trim() : null
|
|
1806
|
+
nextCursor: typeof response.data?.nextCursor === "string" && response.data.nextCursor.trim() ? response.data.nextCursor.trim() : null,
|
|
1807
|
+
facets: response.data?.facets || null
|
|
1781
1808
|
};
|
|
1782
1809
|
}
|
|
1783
1810
|
async getPrivateProofsByWallet(walletAddress, options = {}, wallet = null) {
|
|
@@ -1827,12 +1854,7 @@ ${bytes.length}`;
|
|
|
1827
1854
|
}
|
|
1828
1855
|
throw new ValidationError(`Failed to sign message: ${error.message}`);
|
|
1829
1856
|
}
|
|
1830
|
-
const qs =
|
|
1831
|
-
if (options.limit) qs.push(`limit=${encodeURIComponent(String(options.limit))}`);
|
|
1832
|
-
const cursorRaw = options.cursor !== null && options.cursor !== void 0 ? String(options.cursor).trim() : "";
|
|
1833
|
-
if (cursorRaw) qs.push(`cursor=${encodeURIComponent(cursorRaw)}`);
|
|
1834
|
-
else if (options.offset) qs.push(`offset=${encodeURIComponent(String(options.offset))}`);
|
|
1835
|
-
if (options.qHash) qs.push(`qHash=${encodeURIComponent(options.qHash.toLowerCase())}`);
|
|
1857
|
+
const qs = this._buildProofsByWalletQuery(options);
|
|
1836
1858
|
const query = qs.length ? `?${qs.join("&")}` : "";
|
|
1837
1859
|
const response = await this._makeRequest("GET", `/api/v1/proofs/by-wallet/${encodeURIComponent(pathId)}${query}`, null, {
|
|
1838
1860
|
"x-wallet-address": signerWalletAddress,
|
|
@@ -1847,7 +1869,7 @@ ${bytes.length}`;
|
|
|
1847
1869
|
return {
|
|
1848
1870
|
success: true,
|
|
1849
1871
|
proofs: Array.isArray(proofs) ? proofs : [],
|
|
1850
|
-
totalCount: response.data?.totalCount
|
|
1872
|
+
totalCount: typeof response.data?.totalCount === "number" ? response.data.totalCount : null,
|
|
1851
1873
|
hasMore: Boolean(response.data?.hasMore),
|
|
1852
1874
|
nextOffset: response.data?.nextOffset ?? null,
|
|
1853
1875
|
nextCursor: typeof response.data?.nextCursor === "string" && response.data.nextCursor.trim() ? response.data.nextCursor.trim() : null
|
|
@@ -1964,6 +1986,64 @@ ${bytes.length}`;
|
|
|
1964
1986
|
}
|
|
1965
1987
|
return response;
|
|
1966
1988
|
}
|
|
1989
|
+
/**
|
|
1990
|
+
* Get the public snapshot of a published gate: requirements, charge, schedule,
|
|
1991
|
+
* checkout plan, and reward presence. Never returns the secret reward value —
|
|
1992
|
+
* that is delivered post-verify via fulfillGate().
|
|
1993
|
+
*
|
|
1994
|
+
* @param {string} gateId Published gate handle
|
|
1995
|
+
* @returns {Promise<object>} Public gate snapshot
|
|
1996
|
+
*/
|
|
1997
|
+
async getGate(gateId) {
|
|
1998
|
+
const id = String(gateId || "").trim();
|
|
1999
|
+
if (!id || id.length > 80 || !/^[a-zA-Z0-9:_-]+$/.test(id)) {
|
|
2000
|
+
throw new ValidationError("Valid gateId is required");
|
|
2001
|
+
}
|
|
2002
|
+
const response = await this._makeRequest("GET", `/api/v1/gates/${encodeURIComponent(id)}`);
|
|
2003
|
+
if (!response.success || !response.data?.gate) {
|
|
2004
|
+
throw new ApiError(`Gate lookup failed: ${response.error?.message || "Gate not found"}`, response.error);
|
|
2005
|
+
}
|
|
2006
|
+
return response.data.gate;
|
|
2007
|
+
}
|
|
2008
|
+
/**
|
|
2009
|
+
* Post-verify reward delivery for hosted gate checkout. Requires a verified
|
|
2010
|
+
* proof (qHash) for the gate; paid gates also require payment evidence
|
|
2011
|
+
* (paymentCheckoutSessionId for card, or paymentTxHash for USDC).
|
|
2012
|
+
*
|
|
2013
|
+
* @param {object} params
|
|
2014
|
+
* @param {string} params.gateId Published gate handle
|
|
2015
|
+
* @param {string} params.qHash Verified proof receipt id
|
|
2016
|
+
* @param {string} [params.walletAddress] Wallet bound to the proof (required without a session cookie)
|
|
2017
|
+
* @param {string} [params.paymentCheckoutSessionId] Stripe checkout session id (card rail)
|
|
2018
|
+
* @param {string} [params.paymentTxHash] USDC payment transaction hash (wallet rail)
|
|
2019
|
+
* @returns {Promise<object>} `{ success, data: { gateId, qHash, fulfillment, successReturnUrl? } }`
|
|
2020
|
+
*/
|
|
2021
|
+
async fulfillGate(params = {}) {
|
|
2022
|
+
const gateId = String(params.gateId || "").trim();
|
|
2023
|
+
if (!gateId || gateId.length > 80 || !/^[a-zA-Z0-9:_-]+$/.test(gateId)) {
|
|
2024
|
+
throw new ValidationError("Valid gateId is required");
|
|
2025
|
+
}
|
|
2026
|
+
const qHash = String(params.qHash || "").trim();
|
|
2027
|
+
if (!/^0x[a-fA-F0-9]{64}$/.test(qHash)) {
|
|
2028
|
+
throw new ValidationError("Valid qHash is required");
|
|
2029
|
+
}
|
|
2030
|
+
const body = { qHash };
|
|
2031
|
+
const walletAddress = String(params.walletAddress || "").trim();
|
|
2032
|
+
if (walletAddress) body.walletAddress = walletAddress;
|
|
2033
|
+
const paymentCheckoutSessionId = String(params.paymentCheckoutSessionId || "").trim();
|
|
2034
|
+
if (paymentCheckoutSessionId) body.paymentCheckoutSessionId = paymentCheckoutSessionId;
|
|
2035
|
+
const paymentTxHash = String(params.paymentTxHash || "").trim();
|
|
2036
|
+
if (paymentTxHash) body.paymentTxHash = paymentTxHash;
|
|
2037
|
+
const response = await this._makeRequest(
|
|
2038
|
+
"POST",
|
|
2039
|
+
`/api/v1/gates/${encodeURIComponent(gateId)}/fulfill`,
|
|
2040
|
+
body
|
|
2041
|
+
);
|
|
2042
|
+
if (!response.success) {
|
|
2043
|
+
throw new ApiError(`Gate fulfillment failed: ${response.error?.message || "Unknown error"}`, response.error);
|
|
2044
|
+
}
|
|
2045
|
+
return response;
|
|
2046
|
+
}
|
|
1967
2047
|
async checkGate(params) {
|
|
1968
2048
|
const { walletAddress, requirements, proofs: preloadedProofs } = params;
|
|
1969
2049
|
if (!validateUniversalAddress(walletAddress)) {
|
package/cjs/index.cjs
CHANGED
|
@@ -2223,6 +2223,11 @@ ${bytes.length}`;
|
|
|
2223
2223
|
storeOriginalContent: typeof options?.storeOriginalContent === "boolean" ? options.storeOriginalContent : true
|
|
2224
2224
|
};
|
|
2225
2225
|
if (typeof options?.enableIpfs === "boolean") optionsPayload.enableIpfs = options.enableIpfs;
|
|
2226
|
+
if (options?.publishToHub === true) {
|
|
2227
|
+
optionsPayload.publishToHub = true;
|
|
2228
|
+
} else {
|
|
2229
|
+
delete optionsPayload.publishToHub;
|
|
2230
|
+
}
|
|
2226
2231
|
const requestData = {
|
|
2227
2232
|
verifierIds: normalizedVerifierIds,
|
|
2228
2233
|
data,
|
|
@@ -2443,18 +2448,39 @@ ${bytes.length}`;
|
|
|
2443
2448
|
}
|
|
2444
2449
|
return true;
|
|
2445
2450
|
}
|
|
2451
|
+
_buildProofsByWalletQuery(options = {}) {
|
|
2452
|
+
const qs = [];
|
|
2453
|
+
if (options.limit) qs.push(`limit=${encodeURIComponent(String(options.limit))}`);
|
|
2454
|
+
const cursorRaw = options.cursor !== null && options.cursor !== void 0 ? String(options.cursor).trim() : "";
|
|
2455
|
+
if (cursorRaw) qs.push(`cursor=${encodeURIComponent(cursorRaw)}`);
|
|
2456
|
+
else if (options.offset !== void 0 && options.offset !== null) {
|
|
2457
|
+
qs.push(`offset=${encodeURIComponent(String(options.offset))}`);
|
|
2458
|
+
}
|
|
2459
|
+
if (options.q) qs.push(`q=${encodeURIComponent(String(options.q))}`);
|
|
2460
|
+
if (options.qHash) qs.push(`qHash=${encodeURIComponent(String(options.qHash).toLowerCase())}`);
|
|
2461
|
+
if (options.verifierId) qs.push(`verifierId=${encodeURIComponent(String(options.verifierId))}`);
|
|
2462
|
+
if (options.verifierIds) qs.push(`verifierIds=${encodeURIComponent(String(options.verifierIds))}`);
|
|
2463
|
+
if (options.tags) qs.push(`tags=${encodeURIComponent(String(options.tags))}`);
|
|
2464
|
+
if (options.tagPrefix) qs.push(`tagPrefix=${encodeURIComponent(String(options.tagPrefix))}`);
|
|
2465
|
+
if (options.tagContains) qs.push(`tagContains=${encodeURIComponent(String(options.tagContains))}`);
|
|
2466
|
+
if (options.tagPrefixesAll) qs.push(`tagPrefixesAll=${encodeURIComponent(String(options.tagPrefixesAll))}`);
|
|
2467
|
+
if (options.status) qs.push(`status=${encodeURIComponent(String(options.status))}`);
|
|
2468
|
+
if (options.appId) qs.push(`appId=${encodeURIComponent(String(options.appId))}`);
|
|
2469
|
+
if (options.chainCoverage) qs.push(`chainCoverage=${encodeURIComponent(String(options.chainCoverage))}`);
|
|
2470
|
+
if (options.privacyLevel) qs.push(`privacyLevel=${encodeURIComponent(String(options.privacyLevel))}`);
|
|
2471
|
+
if (options.includeHistory) qs.push("includeHistory=1");
|
|
2472
|
+
if (options.includeFacets) qs.push(`includeFacets=${encodeURIComponent(String(options.includeFacets))}`);
|
|
2473
|
+
if (options.visibility) qs.push(`visibility=${encodeURIComponent(String(options.visibility))}`);
|
|
2474
|
+
if (options.isPublicRead) qs.push("isPublicRead=1");
|
|
2475
|
+
return qs;
|
|
2476
|
+
}
|
|
2446
2477
|
async getProofsByWallet(walletAddress, options = {}) {
|
|
2447
2478
|
if (!walletAddress || typeof walletAddress !== "string") {
|
|
2448
2479
|
throw new ValidationError("walletAddress is required");
|
|
2449
2480
|
}
|
|
2450
2481
|
const id = walletAddress.trim();
|
|
2451
2482
|
const pathId = /^0x[a-fA-F0-9]{40}$/i.test(id) ? id.toLowerCase() : id;
|
|
2452
|
-
const qs =
|
|
2453
|
-
if (options.limit) qs.push(`limit=${encodeURIComponent(String(options.limit))}`);
|
|
2454
|
-
const cursorRaw = options.cursor !== null && options.cursor !== void 0 ? String(options.cursor).trim() : "";
|
|
2455
|
-
if (cursorRaw) qs.push(`cursor=${encodeURIComponent(cursorRaw)}`);
|
|
2456
|
-
else if (options.offset) qs.push(`offset=${encodeURIComponent(String(options.offset))}`);
|
|
2457
|
-
if (options.qHash) qs.push(`qHash=${encodeURIComponent(options.qHash.toLowerCase())}`);
|
|
2483
|
+
const qs = this._buildProofsByWalletQuery(options);
|
|
2458
2484
|
const query = qs.length ? `?${qs.join("&")}` : "";
|
|
2459
2485
|
const response = await this._makeRequest(
|
|
2460
2486
|
"GET",
|
|
@@ -2467,10 +2493,11 @@ ${bytes.length}`;
|
|
|
2467
2493
|
return {
|
|
2468
2494
|
success: true,
|
|
2469
2495
|
proofs: Array.isArray(proofs) ? proofs : [],
|
|
2470
|
-
totalCount: response.data?.totalCount
|
|
2496
|
+
totalCount: typeof response.data?.totalCount === "number" ? response.data.totalCount : null,
|
|
2471
2497
|
hasMore: Boolean(response.data?.hasMore),
|
|
2472
2498
|
nextOffset: response.data?.nextOffset ?? null,
|
|
2473
|
-
nextCursor: typeof response.data?.nextCursor === "string" && response.data.nextCursor.trim() ? response.data.nextCursor.trim() : null
|
|
2499
|
+
nextCursor: typeof response.data?.nextCursor === "string" && response.data.nextCursor.trim() ? response.data.nextCursor.trim() : null,
|
|
2500
|
+
facets: response.data?.facets || null
|
|
2474
2501
|
};
|
|
2475
2502
|
}
|
|
2476
2503
|
async getPrivateProofsByWallet(walletAddress, options = {}, wallet = null) {
|
|
@@ -2520,12 +2547,7 @@ ${bytes.length}`;
|
|
|
2520
2547
|
}
|
|
2521
2548
|
throw new ValidationError(`Failed to sign message: ${error.message}`);
|
|
2522
2549
|
}
|
|
2523
|
-
const qs =
|
|
2524
|
-
if (options.limit) qs.push(`limit=${encodeURIComponent(String(options.limit))}`);
|
|
2525
|
-
const cursorRaw = options.cursor !== null && options.cursor !== void 0 ? String(options.cursor).trim() : "";
|
|
2526
|
-
if (cursorRaw) qs.push(`cursor=${encodeURIComponent(cursorRaw)}`);
|
|
2527
|
-
else if (options.offset) qs.push(`offset=${encodeURIComponent(String(options.offset))}`);
|
|
2528
|
-
if (options.qHash) qs.push(`qHash=${encodeURIComponent(options.qHash.toLowerCase())}`);
|
|
2550
|
+
const qs = this._buildProofsByWalletQuery(options);
|
|
2529
2551
|
const query = qs.length ? `?${qs.join("&")}` : "";
|
|
2530
2552
|
const response = await this._makeRequest("GET", `/api/v1/proofs/by-wallet/${encodeURIComponent(pathId)}${query}`, null, {
|
|
2531
2553
|
"x-wallet-address": signerWalletAddress,
|
|
@@ -2540,7 +2562,7 @@ ${bytes.length}`;
|
|
|
2540
2562
|
return {
|
|
2541
2563
|
success: true,
|
|
2542
2564
|
proofs: Array.isArray(proofs) ? proofs : [],
|
|
2543
|
-
totalCount: response.data?.totalCount
|
|
2565
|
+
totalCount: typeof response.data?.totalCount === "number" ? response.data.totalCount : null,
|
|
2544
2566
|
hasMore: Boolean(response.data?.hasMore),
|
|
2545
2567
|
nextOffset: response.data?.nextOffset ?? null,
|
|
2546
2568
|
nextCursor: typeof response.data?.nextCursor === "string" && response.data.nextCursor.trim() ? response.data.nextCursor.trim() : null
|
|
@@ -2657,6 +2679,64 @@ ${bytes.length}`;
|
|
|
2657
2679
|
}
|
|
2658
2680
|
return response;
|
|
2659
2681
|
}
|
|
2682
|
+
/**
|
|
2683
|
+
* Get the public snapshot of a published gate: requirements, charge, schedule,
|
|
2684
|
+
* checkout plan, and reward presence. Never returns the secret reward value —
|
|
2685
|
+
* that is delivered post-verify via fulfillGate().
|
|
2686
|
+
*
|
|
2687
|
+
* @param {string} gateId Published gate handle
|
|
2688
|
+
* @returns {Promise<object>} Public gate snapshot
|
|
2689
|
+
*/
|
|
2690
|
+
async getGate(gateId) {
|
|
2691
|
+
const id = String(gateId || "").trim();
|
|
2692
|
+
if (!id || id.length > 80 || !/^[a-zA-Z0-9:_-]+$/.test(id)) {
|
|
2693
|
+
throw new ValidationError("Valid gateId is required");
|
|
2694
|
+
}
|
|
2695
|
+
const response = await this._makeRequest("GET", `/api/v1/gates/${encodeURIComponent(id)}`);
|
|
2696
|
+
if (!response.success || !response.data?.gate) {
|
|
2697
|
+
throw new ApiError(`Gate lookup failed: ${response.error?.message || "Gate not found"}`, response.error);
|
|
2698
|
+
}
|
|
2699
|
+
return response.data.gate;
|
|
2700
|
+
}
|
|
2701
|
+
/**
|
|
2702
|
+
* Post-verify reward delivery for hosted gate checkout. Requires a verified
|
|
2703
|
+
* proof (qHash) for the gate; paid gates also require payment evidence
|
|
2704
|
+
* (paymentCheckoutSessionId for card, or paymentTxHash for USDC).
|
|
2705
|
+
*
|
|
2706
|
+
* @param {object} params
|
|
2707
|
+
* @param {string} params.gateId Published gate handle
|
|
2708
|
+
* @param {string} params.qHash Verified proof receipt id
|
|
2709
|
+
* @param {string} [params.walletAddress] Wallet bound to the proof (required without a session cookie)
|
|
2710
|
+
* @param {string} [params.paymentCheckoutSessionId] Stripe checkout session id (card rail)
|
|
2711
|
+
* @param {string} [params.paymentTxHash] USDC payment transaction hash (wallet rail)
|
|
2712
|
+
* @returns {Promise<object>} `{ success, data: { gateId, qHash, fulfillment, successReturnUrl? } }`
|
|
2713
|
+
*/
|
|
2714
|
+
async fulfillGate(params = {}) {
|
|
2715
|
+
const gateId = String(params.gateId || "").trim();
|
|
2716
|
+
if (!gateId || gateId.length > 80 || !/^[a-zA-Z0-9:_-]+$/.test(gateId)) {
|
|
2717
|
+
throw new ValidationError("Valid gateId is required");
|
|
2718
|
+
}
|
|
2719
|
+
const qHash = String(params.qHash || "").trim();
|
|
2720
|
+
if (!/^0x[a-fA-F0-9]{64}$/.test(qHash)) {
|
|
2721
|
+
throw new ValidationError("Valid qHash is required");
|
|
2722
|
+
}
|
|
2723
|
+
const body = { qHash };
|
|
2724
|
+
const walletAddress = String(params.walletAddress || "").trim();
|
|
2725
|
+
if (walletAddress) body.walletAddress = walletAddress;
|
|
2726
|
+
const paymentCheckoutSessionId = String(params.paymentCheckoutSessionId || "").trim();
|
|
2727
|
+
if (paymentCheckoutSessionId) body.paymentCheckoutSessionId = paymentCheckoutSessionId;
|
|
2728
|
+
const paymentTxHash = String(params.paymentTxHash || "").trim();
|
|
2729
|
+
if (paymentTxHash) body.paymentTxHash = paymentTxHash;
|
|
2730
|
+
const response = await this._makeRequest(
|
|
2731
|
+
"POST",
|
|
2732
|
+
`/api/v1/gates/${encodeURIComponent(gateId)}/fulfill`,
|
|
2733
|
+
body
|
|
2734
|
+
);
|
|
2735
|
+
if (!response.success) {
|
|
2736
|
+
throw new ApiError(`Gate fulfillment failed: ${response.error?.message || "Unknown error"}`, response.error);
|
|
2737
|
+
}
|
|
2738
|
+
return response;
|
|
2739
|
+
}
|
|
2660
2740
|
async checkGate(params) {
|
|
2661
2741
|
const { walletAddress, requirements, proofs: preloadedProofs } = params;
|
|
2662
2742
|
if (!validateUniversalAddress(walletAddress)) {
|
package/cli/neus.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { exec, spawnSync } from 'node:child_process';
|
|
3
3
|
import { createHash, randomBytes } from 'node:crypto';
|
|
4
4
|
import fs from 'node:fs';
|
|
5
5
|
import os from 'node:os';
|
|
@@ -12,6 +12,13 @@ import {
|
|
|
12
12
|
} from '../mcp-hosts.js';
|
|
13
13
|
|
|
14
14
|
const __cliDir = path.dirname(fileURLToPath(import.meta.url));
|
|
15
|
+
const CLI_PACKAGE_VERSION = (() => {
|
|
16
|
+
try {
|
|
17
|
+
return JSON.parse(fs.readFileSync(path.join(__cliDir, '..', 'package.json'), 'utf8')).version;
|
|
18
|
+
} catch {
|
|
19
|
+
return '0.0.0';
|
|
20
|
+
}
|
|
21
|
+
})();
|
|
15
22
|
|
|
16
23
|
const NEUS_APP_URL = 'https://neus.network';
|
|
17
24
|
const NEUS_TOKEN_ENDPOINT = 'https://neus.network/api/v1/auth/mcp/token';
|
|
@@ -137,6 +144,7 @@ function describeClientResult(command, result) {
|
|
|
137
144
|
}
|
|
138
145
|
if (result.changed) return 'updated';
|
|
139
146
|
if (result.authConfigured) return 'signed in';
|
|
147
|
+
if (result.configured) return 'ready';
|
|
140
148
|
return 'ready';
|
|
141
149
|
}
|
|
142
150
|
|
|
@@ -296,6 +304,7 @@ function envAccessKey() {
|
|
|
296
304
|
|
|
297
305
|
/** --access-key flag, else NEUS_ACCESS_KEY from the environment, else browser sign-in. */
|
|
298
306
|
function resolveAccessKey(options) {
|
|
307
|
+
if (options?.oauth) return '';
|
|
299
308
|
const explicit = String(options.accessKey || '').trim();
|
|
300
309
|
if (explicit) return explicit;
|
|
301
310
|
return envAccessKey();
|
|
@@ -307,6 +316,7 @@ function resolveLiveAccessKey(options, scope, cwd) {
|
|
|
307
316
|
if (explicit) return explicit;
|
|
308
317
|
const installed = readInstalledAccessKey(scope, cwd);
|
|
309
318
|
if (installed) return installed;
|
|
319
|
+
if (options?.oauth) return '';
|
|
310
320
|
return envAccessKey();
|
|
311
321
|
}
|
|
312
322
|
|
|
@@ -579,7 +589,8 @@ function parseArgs(argv) {
|
|
|
579
589
|
live: false,
|
|
580
590
|
json: false,
|
|
581
591
|
dryRun: false,
|
|
582
|
-
project: false
|
|
592
|
+
project: false,
|
|
593
|
+
oauth: false
|
|
583
594
|
};
|
|
584
595
|
|
|
585
596
|
for (let index = 1; index < argv.length; index += 1) {
|
|
@@ -635,6 +646,10 @@ function parseArgs(argv) {
|
|
|
635
646
|
index += 1;
|
|
636
647
|
continue;
|
|
637
648
|
}
|
|
649
|
+
if (token === '--oauth') {
|
|
650
|
+
options.oauth = true;
|
|
651
|
+
continue;
|
|
652
|
+
}
|
|
638
653
|
if (token === '--help' || token === '-h') {
|
|
639
654
|
return { command: 'help', options };
|
|
640
655
|
}
|
|
@@ -668,6 +683,7 @@ function printUsage(exitCode = 0) {
|
|
|
668
683
|
' --client <name[,name]> Limit setup to claude, codex, cursor, or vscode',
|
|
669
684
|
' --project Write shared project config instead of user config',
|
|
670
685
|
' --access-key <npk_...> Override profile access key (else uses NEUS_ACCESS_KEY if set)',
|
|
686
|
+
' --oauth Force browser OAuth (ignore NEUS_ACCESS_KEY in the environment)',
|
|
671
687
|
' --from <source> Import source: auto, cursor, claude-code, or claude-desktop',
|
|
672
688
|
' --to <format> Export format: manifest or json',
|
|
673
689
|
' --output <path> Write exported manifest to a specific path',
|
|
@@ -1383,7 +1399,7 @@ async function runLiveMcpDiagnostics(accessKey) {
|
|
|
1383
1399
|
params: {
|
|
1384
1400
|
protocolVersion: '2025-11-25',
|
|
1385
1401
|
capabilities: {},
|
|
1386
|
-
clientInfo: { name: 'neus-cli', version:
|
|
1402
|
+
clientInfo: { name: 'neus-cli', version: CLI_PACKAGE_VERSION }
|
|
1387
1403
|
},
|
|
1388
1404
|
accessKey,
|
|
1389
1405
|
signal: controller.signal
|
|
@@ -1699,9 +1715,12 @@ async function runAuthBrowser(options) {
|
|
|
1699
1715
|
logStep('next', 'wait', 'finish sign-in in the browser');
|
|
1700
1716
|
}
|
|
1701
1717
|
|
|
1702
|
-
const
|
|
1703
|
-
|
|
1704
|
-
|
|
1718
|
+
const openCommand = process.platform === 'win32'
|
|
1719
|
+
? `cmd /c start "" "${authUrl.replace(/"/g, '\\"')}"`
|
|
1720
|
+
: process.platform === 'darwin'
|
|
1721
|
+
? `open "${authUrl.replace(/"/g, '\\"')}"`
|
|
1722
|
+
: `xdg-open "${authUrl.replace(/"/g, '\\"')}"`;
|
|
1723
|
+
exec(openCommand, { shell: true }, err => {
|
|
1705
1724
|
if (err && !options.json) {
|
|
1706
1725
|
logStep('warn', 'browser', 'open the URL above manually');
|
|
1707
1726
|
}
|
|
@@ -1816,6 +1835,12 @@ async function runSetup(options) {
|
|
|
1816
1835
|
}
|
|
1817
1836
|
|
|
1818
1837
|
if (options.json) {
|
|
1838
|
+
payload.authRequired = !accessKey && !options.dryRun;
|
|
1839
|
+
if (payload.authRequired) {
|
|
1840
|
+
payload.nextCommand = clients.length === 1 && clients[0] === 'codex'
|
|
1841
|
+
? 'neus auth --client codex'
|
|
1842
|
+
: 'neus auth';
|
|
1843
|
+
}
|
|
1819
1844
|
printJson(payload);
|
|
1820
1845
|
return payload;
|
|
1821
1846
|
}
|
package/client.js
CHANGED
|
@@ -1204,6 +1204,12 @@ export class NeusClient {
|
|
|
1204
1204
|
typeof options?.storeOriginalContent === 'boolean' ? options.storeOriginalContent : true
|
|
1205
1205
|
};
|
|
1206
1206
|
if (typeof options?.enableIpfs === 'boolean') optionsPayload.enableIpfs = options.enableIpfs;
|
|
1207
|
+
// Receipts persist offchain by default; hub registry anchoring is explicit opt-in.
|
|
1208
|
+
if (options?.publishToHub === true) {
|
|
1209
|
+
optionsPayload.publishToHub = true;
|
|
1210
|
+
} else {
|
|
1211
|
+
delete optionsPayload.publishToHub;
|
|
1212
|
+
}
|
|
1207
1213
|
|
|
1208
1214
|
const requestData = {
|
|
1209
1215
|
verifierIds: normalizedVerifierIds,
|
|
@@ -1471,6 +1477,33 @@ export class NeusClient {
|
|
|
1471
1477
|
return true;
|
|
1472
1478
|
}
|
|
1473
1479
|
|
|
1480
|
+
_buildProofsByWalletQuery(options = {}) {
|
|
1481
|
+
const qs = [];
|
|
1482
|
+
if (options.limit) qs.push(`limit=${encodeURIComponent(String(options.limit))}`);
|
|
1483
|
+
const cursorRaw = options.cursor !== null && options.cursor !== undefined ? String(options.cursor).trim() : '';
|
|
1484
|
+
if (cursorRaw) qs.push(`cursor=${encodeURIComponent(cursorRaw)}`);
|
|
1485
|
+
else if (options.offset !== undefined && options.offset !== null) {
|
|
1486
|
+
qs.push(`offset=${encodeURIComponent(String(options.offset))}`);
|
|
1487
|
+
}
|
|
1488
|
+
if (options.q) qs.push(`q=${encodeURIComponent(String(options.q))}`);
|
|
1489
|
+
if (options.qHash) qs.push(`qHash=${encodeURIComponent(String(options.qHash).toLowerCase())}`);
|
|
1490
|
+
if (options.verifierId) qs.push(`verifierId=${encodeURIComponent(String(options.verifierId))}`);
|
|
1491
|
+
if (options.verifierIds) qs.push(`verifierIds=${encodeURIComponent(String(options.verifierIds))}`);
|
|
1492
|
+
if (options.tags) qs.push(`tags=${encodeURIComponent(String(options.tags))}`);
|
|
1493
|
+
if (options.tagPrefix) qs.push(`tagPrefix=${encodeURIComponent(String(options.tagPrefix))}`);
|
|
1494
|
+
if (options.tagContains) qs.push(`tagContains=${encodeURIComponent(String(options.tagContains))}`);
|
|
1495
|
+
if (options.tagPrefixesAll) qs.push(`tagPrefixesAll=${encodeURIComponent(String(options.tagPrefixesAll))}`);
|
|
1496
|
+
if (options.status) qs.push(`status=${encodeURIComponent(String(options.status))}`);
|
|
1497
|
+
if (options.appId) qs.push(`appId=${encodeURIComponent(String(options.appId))}`);
|
|
1498
|
+
if (options.chainCoverage) qs.push(`chainCoverage=${encodeURIComponent(String(options.chainCoverage))}`);
|
|
1499
|
+
if (options.privacyLevel) qs.push(`privacyLevel=${encodeURIComponent(String(options.privacyLevel))}`);
|
|
1500
|
+
if (options.includeHistory) qs.push('includeHistory=1');
|
|
1501
|
+
if (options.includeFacets) qs.push(`includeFacets=${encodeURIComponent(String(options.includeFacets))}`);
|
|
1502
|
+
if (options.visibility) qs.push(`visibility=${encodeURIComponent(String(options.visibility))}`);
|
|
1503
|
+
if (options.isPublicRead) qs.push('isPublicRead=1');
|
|
1504
|
+
return qs;
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1474
1507
|
async getProofsByWallet(walletAddress, options = {}) {
|
|
1475
1508
|
if (!walletAddress || typeof walletAddress !== 'string') {
|
|
1476
1509
|
throw new ValidationError('walletAddress is required');
|
|
@@ -1479,12 +1512,7 @@ export class NeusClient {
|
|
|
1479
1512
|
const id = walletAddress.trim();
|
|
1480
1513
|
const pathId = /^0x[a-fA-F0-9]{40}$/i.test(id) ? id.toLowerCase() : id;
|
|
1481
1514
|
|
|
1482
|
-
const qs =
|
|
1483
|
-
if (options.limit) qs.push(`limit=${encodeURIComponent(String(options.limit))}`);
|
|
1484
|
-
const cursorRaw = options.cursor !== null && options.cursor !== undefined ? String(options.cursor).trim() : '';
|
|
1485
|
-
if (cursorRaw) qs.push(`cursor=${encodeURIComponent(cursorRaw)}`);
|
|
1486
|
-
else if (options.offset) qs.push(`offset=${encodeURIComponent(String(options.offset))}`);
|
|
1487
|
-
if (options.qHash) qs.push(`qHash=${encodeURIComponent(options.qHash.toLowerCase())}`);
|
|
1515
|
+
const qs = this._buildProofsByWalletQuery(options);
|
|
1488
1516
|
|
|
1489
1517
|
const query = qs.length ? `?${qs.join('&')}` : '';
|
|
1490
1518
|
const response = await this._makeRequest(
|
|
@@ -1500,13 +1528,14 @@ export class NeusClient {
|
|
|
1500
1528
|
return {
|
|
1501
1529
|
success: true,
|
|
1502
1530
|
proofs: Array.isArray(proofs) ? proofs : [],
|
|
1503
|
-
totalCount: response.data?.totalCount
|
|
1531
|
+
totalCount: typeof response.data?.totalCount === 'number' ? response.data.totalCount : null,
|
|
1504
1532
|
hasMore: Boolean(response.data?.hasMore),
|
|
1505
1533
|
nextOffset: response.data?.nextOffset ?? null,
|
|
1506
1534
|
nextCursor:
|
|
1507
1535
|
typeof response.data?.nextCursor === 'string' && response.data.nextCursor.trim()
|
|
1508
1536
|
? response.data.nextCursor.trim()
|
|
1509
|
-
: null
|
|
1537
|
+
: null,
|
|
1538
|
+
facets: response.data?.facets || null,
|
|
1510
1539
|
};
|
|
1511
1540
|
}
|
|
1512
1541
|
|
|
@@ -1569,12 +1598,7 @@ export class NeusClient {
|
|
|
1569
1598
|
throw new ValidationError(`Failed to sign message: ${error.message}`);
|
|
1570
1599
|
}
|
|
1571
1600
|
|
|
1572
|
-
const qs =
|
|
1573
|
-
if (options.limit) qs.push(`limit=${encodeURIComponent(String(options.limit))}`);
|
|
1574
|
-
const cursorRaw = options.cursor !== null && options.cursor !== undefined ? String(options.cursor).trim() : '';
|
|
1575
|
-
if (cursorRaw) qs.push(`cursor=${encodeURIComponent(cursorRaw)}`);
|
|
1576
|
-
else if (options.offset) qs.push(`offset=${encodeURIComponent(String(options.offset))}`);
|
|
1577
|
-
if (options.qHash) qs.push(`qHash=${encodeURIComponent(options.qHash.toLowerCase())}`);
|
|
1601
|
+
const qs = this._buildProofsByWalletQuery(options);
|
|
1578
1602
|
const query = qs.length ? `?${qs.join('&')}` : '';
|
|
1579
1603
|
|
|
1580
1604
|
const response = await this._makeRequest('GET', `/api/v1/proofs/by-wallet/${encodeURIComponent(pathId)}${query}`, null, {
|
|
@@ -1592,7 +1616,7 @@ export class NeusClient {
|
|
|
1592
1616
|
return {
|
|
1593
1617
|
success: true,
|
|
1594
1618
|
proofs: Array.isArray(proofs) ? proofs : [],
|
|
1595
|
-
totalCount: response.data?.totalCount
|
|
1619
|
+
totalCount: typeof response.data?.totalCount === 'number' ? response.data.totalCount : null,
|
|
1596
1620
|
hasMore: Boolean(response.data?.hasMore),
|
|
1597
1621
|
nextOffset: response.data?.nextOffset ?? null,
|
|
1598
1622
|
nextCursor:
|
|
@@ -1730,6 +1754,67 @@ export class NeusClient {
|
|
|
1730
1754
|
return response;
|
|
1731
1755
|
}
|
|
1732
1756
|
|
|
1757
|
+
/**
|
|
1758
|
+
* Get the public snapshot of a published gate: requirements, charge, schedule,
|
|
1759
|
+
* checkout plan, and reward presence. Never returns the secret reward value —
|
|
1760
|
+
* that is delivered post-verify via fulfillGate().
|
|
1761
|
+
*
|
|
1762
|
+
* @param {string} gateId Published gate handle
|
|
1763
|
+
* @returns {Promise<object>} Public gate snapshot
|
|
1764
|
+
*/
|
|
1765
|
+
async getGate(gateId) {
|
|
1766
|
+
const id = String(gateId || '').trim();
|
|
1767
|
+
if (!id || id.length > 80 || !/^[a-zA-Z0-9:_-]+$/.test(id)) {
|
|
1768
|
+
throw new ValidationError('Valid gateId is required');
|
|
1769
|
+
}
|
|
1770
|
+
const response = await this._makeRequest('GET', `/api/v1/gates/${encodeURIComponent(id)}`);
|
|
1771
|
+
if (!response.success || !response.data?.gate) {
|
|
1772
|
+
throw new ApiError(`Gate lookup failed: ${response.error?.message || 'Gate not found'}`, response.error);
|
|
1773
|
+
}
|
|
1774
|
+
return response.data.gate;
|
|
1775
|
+
}
|
|
1776
|
+
|
|
1777
|
+
/**
|
|
1778
|
+
* Post-verify reward delivery for hosted gate checkout. Requires a verified
|
|
1779
|
+
* proof (qHash) for the gate; paid gates also require payment evidence
|
|
1780
|
+
* (paymentCheckoutSessionId for card, or paymentTxHash for USDC).
|
|
1781
|
+
*
|
|
1782
|
+
* @param {object} params
|
|
1783
|
+
* @param {string} params.gateId Published gate handle
|
|
1784
|
+
* @param {string} params.qHash Verified proof receipt id
|
|
1785
|
+
* @param {string} [params.walletAddress] Wallet bound to the proof (required without a session cookie)
|
|
1786
|
+
* @param {string} [params.paymentCheckoutSessionId] Stripe checkout session id (card rail)
|
|
1787
|
+
* @param {string} [params.paymentTxHash] USDC payment transaction hash (wallet rail)
|
|
1788
|
+
* @returns {Promise<object>} `{ success, data: { gateId, qHash, fulfillment, successReturnUrl? } }`
|
|
1789
|
+
*/
|
|
1790
|
+
async fulfillGate(params = {}) {
|
|
1791
|
+
const gateId = String(params.gateId || '').trim();
|
|
1792
|
+
if (!gateId || gateId.length > 80 || !/^[a-zA-Z0-9:_-]+$/.test(gateId)) {
|
|
1793
|
+
throw new ValidationError('Valid gateId is required');
|
|
1794
|
+
}
|
|
1795
|
+
const qHash = String(params.qHash || '').trim();
|
|
1796
|
+
if (!/^0x[a-fA-F0-9]{64}$/.test(qHash)) {
|
|
1797
|
+
throw new ValidationError('Valid qHash is required');
|
|
1798
|
+
}
|
|
1799
|
+
const body = { qHash };
|
|
1800
|
+
const walletAddress = String(params.walletAddress || '').trim();
|
|
1801
|
+
if (walletAddress) body.walletAddress = walletAddress;
|
|
1802
|
+
const paymentCheckoutSessionId = String(params.paymentCheckoutSessionId || '').trim();
|
|
1803
|
+
if (paymentCheckoutSessionId) body.paymentCheckoutSessionId = paymentCheckoutSessionId;
|
|
1804
|
+
const paymentTxHash = String(params.paymentTxHash || '').trim();
|
|
1805
|
+
if (paymentTxHash) body.paymentTxHash = paymentTxHash;
|
|
1806
|
+
|
|
1807
|
+
const response = await this._makeRequest(
|
|
1808
|
+
'POST',
|
|
1809
|
+
`/api/v1/gates/${encodeURIComponent(gateId)}/fulfill`,
|
|
1810
|
+
body
|
|
1811
|
+
);
|
|
1812
|
+
if (!response.success) {
|
|
1813
|
+
throw new ApiError(`Gate fulfillment failed: ${response.error?.message || 'Unknown error'}`, response.error);
|
|
1814
|
+
}
|
|
1815
|
+
return response;
|
|
1816
|
+
}
|
|
1817
|
+
|
|
1733
1818
|
async checkGate(params) {
|
|
1734
1819
|
const { walletAddress, requirements, proofs: preloadedProofs } = params;
|
|
1735
1820
|
|
package/package.json
CHANGED
|
@@ -1,147 +1,147 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@neus/sdk",
|
|
3
|
-
"version": "1.1.
|
|
4
|
-
"description": "NEUS makes trust portable across the internet — so people, apps, and AI agents can prove what is real before access, payout, or execution.",
|
|
5
|
-
"bin": {
|
|
6
|
-
"neus": "cli/neus.mjs"
|
|
7
|
-
},
|
|
8
|
-
"main": "index.js",
|
|
9
|
-
"type": "module",
|
|
10
|
-
"types": "types.d.ts",
|
|
11
|
-
"exports": {
|
|
12
|
-
".": {
|
|
13
|
-
"types": "./types.d.ts",
|
|
14
|
-
"import": "./index.js",
|
|
15
|
-
"require": "./cjs/index.cjs"
|
|
16
|
-
},
|
|
17
|
-
"./client": {
|
|
18
|
-
"types": "./types.d.ts",
|
|
19
|
-
"import": "./client.js",
|
|
20
|
-
"require": "./cjs/client.cjs"
|
|
21
|
-
},
|
|
22
|
-
"./utils": {
|
|
23
|
-
"import": "./utils.js",
|
|
24
|
-
"require": "./cjs/utils.cjs"
|
|
25
|
-
},
|
|
26
|
-
"./errors": {
|
|
27
|
-
"import": "./errors.js",
|
|
28
|
-
"require": "./cjs/errors.cjs"
|
|
29
|
-
},
|
|
30
|
-
"./gates": {
|
|
31
|
-
"import": "./gates.js",
|
|
32
|
-
"require": "./cjs/gates.cjs"
|
|
33
|
-
},
|
|
34
|
-
"./mcp-hosts": {
|
|
35
|
-
"import": "./mcp-hosts.js",
|
|
36
|
-
"require": "./cjs/mcp-hosts.cjs"
|
|
37
|
-
},
|
|
38
|
-
"./widgets": {
|
|
39
|
-
"types": "./types.d.ts",
|
|
40
|
-
"import": "./widgets/index.js",
|
|
41
|
-
"require": "./widgets.cjs"
|
|
42
|
-
},
|
|
43
|
-
"./widgets/verify-gate": {
|
|
44
|
-
"types": "./types.d.ts",
|
|
45
|
-
"import": "./widgets/verify-gate/index.js",
|
|
46
|
-
"require": "./widgets.cjs"
|
|
47
|
-
}
|
|
48
|
-
},
|
|
49
|
-
"sideEffects": false,
|
|
50
|
-
"scripts": {
|
|
51
|
-
"test": "npm run build:cjs && vitest run",
|
|
52
|
-
"test:coverage": "vitest run --coverage",
|
|
53
|
-
"lint": "eslint . --ignore-pattern widgets/verify-gate/dist/**",
|
|
54
|
-
"format": "prettier --write \"**/*.js\"",
|
|
55
|
-
"build": "npm run build:widgets && npm run build:cjs",
|
|
56
|
-
"build:widgets": "npx esbuild widgets/verify-gate/VerifyGate.jsx widgets/verify-gate/ProofBadge.jsx --bundle --platform=browser --format=esm --outdir=widgets/verify-gate/dist --jsx=automatic --legal-comments=none --external:react --external:react-dom --external:react/jsx-runtime --external:@neus/sdk/client",
|
|
57
|
-
"build:cjs": "npx esbuild index.js client.js utils.js errors.js gates.js mcp-hosts.js --bundle --platform=node --format=cjs --outdir=cjs --out-extension:.js=.cjs --legal-comments=none --external:ethers --external:@zkpassport/sdk --external:react --external:react-dom --external:react/jsx-runtime",
|
|
58
|
-
"prepack": "npm run build",
|
|
59
|
-
"prepublishOnly": "npm run lint && npm test && npm run build"
|
|
60
|
-
},
|
|
61
|
-
"keywords": [
|
|
62
|
-
"neus",
|
|
63
|
-
"verification",
|
|
64
|
-
"cryptographic-proofs",
|
|
65
|
-
"identity",
|
|
66
|
-
"authentication",
|
|
67
|
-
"blockchain",
|
|
68
|
-
"cross-chain",
|
|
69
|
-
"web3",
|
|
70
|
-
"passwordless",
|
|
71
|
-
"universal-protocol",
|
|
72
|
-
"proof",
|
|
73
|
-
"ownership",
|
|
74
|
-
"sdk",
|
|
75
|
-
"mcp",
|
|
76
|
-
"model-context-protocol",
|
|
77
|
-
"oauth"
|
|
78
|
-
],
|
|
79
|
-
"author": "NEUS Network",
|
|
80
|
-
"license": "Apache-2.0",
|
|
81
|
-
"repository": {
|
|
82
|
-
"type": "git",
|
|
83
|
-
"url": "git+https://github.com/neus/network.git",
|
|
84
|
-
"directory": "sdk"
|
|
85
|
-
},
|
|
86
|
-
"bugs": {
|
|
87
|
-
"url": "https://github.com/neus/network/issues"
|
|
88
|
-
},
|
|
89
|
-
"homepage": "https://neus.network",
|
|
90
|
-
"publishConfig": {
|
|
91
|
-
"access": "public",
|
|
92
|
-
"registry": "https://registry.npmjs.org"
|
|
93
|
-
},
|
|
94
|
-
"engines": {
|
|
95
|
-
"node": ">=20.0.0"
|
|
96
|
-
},
|
|
97
|
-
"peerDependencies": {
|
|
98
|
-
"ethers": "^6.0.0",
|
|
99
|
-
"react": ">=17.0.0",
|
|
100
|
-
"react-dom": ">=17.0.0"
|
|
101
|
-
},
|
|
102
|
-
"peerDependenciesMeta": {
|
|
103
|
-
"@zkpassport/sdk": {
|
|
104
|
-
"optional": true
|
|
105
|
-
},
|
|
106
|
-
"react": {
|
|
107
|
-
"optional": true
|
|
108
|
-
},
|
|
109
|
-
"react-dom": {
|
|
110
|
-
"optional": true
|
|
111
|
-
}
|
|
112
|
-
},
|
|
113
|
-
"optionalDependencies": {
|
|
114
|
-
"@zkpassport/sdk": "^0.14.0"
|
|
115
|
-
},
|
|
116
|
-
"dependencies": {
|
|
117
|
-
"bs58": "^6.0.0"
|
|
118
|
-
},
|
|
119
|
-
"devDependencies": {
|
|
120
|
-
"@vitest/coverage-v8": "^4.1.3",
|
|
121
|
-
"esbuild": "^0.28.0",
|
|
122
|
-
"eslint": "^8.56.0",
|
|
123
|
-
"eslint-plugin-react": "^7.37.2",
|
|
124
|
-
"prettier": "^3.2.0",
|
|
125
|
-
"vitest": "^4.1.3"
|
|
126
|
-
},
|
|
127
|
-
"files": [
|
|
128
|
-
"cli/neus.mjs",
|
|
129
|
-
"mcp-hosts.js",
|
|
130
|
-
"index.js",
|
|
131
|
-
"client.js",
|
|
132
|
-
"utils.js",
|
|
133
|
-
"errors.js",
|
|
134
|
-
"gates.js",
|
|
135
|
-
"sponsor.js",
|
|
136
|
-
"cjs/**",
|
|
137
|
-
"widgets.cjs",
|
|
138
|
-
"types.d.ts",
|
|
139
|
-
"README.md",
|
|
140
|
-
"SECURITY.md",
|
|
141
|
-
"LICENSE",
|
|
142
|
-
"widgets/index.js",
|
|
143
|
-
"widgets/verify-gate/index.js",
|
|
144
|
-
"widgets/verify-gate/dist/VerifyGate.js",
|
|
145
|
-
"widgets/verify-gate/dist/ProofBadge.js"
|
|
146
|
-
]
|
|
147
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@neus/sdk",
|
|
3
|
+
"version": "1.1.6",
|
|
4
|
+
"description": "NEUS makes trust portable across the internet — so people, apps, and AI agents can prove what is real before access, payout, or execution.",
|
|
5
|
+
"bin": {
|
|
6
|
+
"neus": "cli/neus.mjs"
|
|
7
|
+
},
|
|
8
|
+
"main": "index.js",
|
|
9
|
+
"type": "module",
|
|
10
|
+
"types": "types.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./types.d.ts",
|
|
14
|
+
"import": "./index.js",
|
|
15
|
+
"require": "./cjs/index.cjs"
|
|
16
|
+
},
|
|
17
|
+
"./client": {
|
|
18
|
+
"types": "./types.d.ts",
|
|
19
|
+
"import": "./client.js",
|
|
20
|
+
"require": "./cjs/client.cjs"
|
|
21
|
+
},
|
|
22
|
+
"./utils": {
|
|
23
|
+
"import": "./utils.js",
|
|
24
|
+
"require": "./cjs/utils.cjs"
|
|
25
|
+
},
|
|
26
|
+
"./errors": {
|
|
27
|
+
"import": "./errors.js",
|
|
28
|
+
"require": "./cjs/errors.cjs"
|
|
29
|
+
},
|
|
30
|
+
"./gates": {
|
|
31
|
+
"import": "./gates.js",
|
|
32
|
+
"require": "./cjs/gates.cjs"
|
|
33
|
+
},
|
|
34
|
+
"./mcp-hosts": {
|
|
35
|
+
"import": "./mcp-hosts.js",
|
|
36
|
+
"require": "./cjs/mcp-hosts.cjs"
|
|
37
|
+
},
|
|
38
|
+
"./widgets": {
|
|
39
|
+
"types": "./types.d.ts",
|
|
40
|
+
"import": "./widgets/index.js",
|
|
41
|
+
"require": "./widgets.cjs"
|
|
42
|
+
},
|
|
43
|
+
"./widgets/verify-gate": {
|
|
44
|
+
"types": "./types.d.ts",
|
|
45
|
+
"import": "./widgets/verify-gate/index.js",
|
|
46
|
+
"require": "./widgets.cjs"
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"sideEffects": false,
|
|
50
|
+
"scripts": {
|
|
51
|
+
"test": "npm run build:cjs && vitest run",
|
|
52
|
+
"test:coverage": "vitest run --coverage",
|
|
53
|
+
"lint": "eslint . --ignore-pattern widgets/verify-gate/dist/**",
|
|
54
|
+
"format": "prettier --write \"**/*.js\"",
|
|
55
|
+
"build": "npm run build:widgets && npm run build:cjs",
|
|
56
|
+
"build:widgets": "npx esbuild widgets/verify-gate/VerifyGate.jsx widgets/verify-gate/ProofBadge.jsx --bundle --platform=browser --format=esm --outdir=widgets/verify-gate/dist --jsx=automatic --legal-comments=none --external:react --external:react-dom --external:react/jsx-runtime --external:@neus/sdk/client",
|
|
57
|
+
"build:cjs": "npx esbuild index.js client.js utils.js errors.js gates.js mcp-hosts.js --bundle --platform=node --format=cjs --outdir=cjs --out-extension:.js=.cjs --legal-comments=none --external:ethers --external:@zkpassport/sdk --external:react --external:react-dom --external:react/jsx-runtime",
|
|
58
|
+
"prepack": "npm run build",
|
|
59
|
+
"prepublishOnly": "npm run lint && npm test && npm run build"
|
|
60
|
+
},
|
|
61
|
+
"keywords": [
|
|
62
|
+
"neus",
|
|
63
|
+
"verification",
|
|
64
|
+
"cryptographic-proofs",
|
|
65
|
+
"identity",
|
|
66
|
+
"authentication",
|
|
67
|
+
"blockchain",
|
|
68
|
+
"cross-chain",
|
|
69
|
+
"web3",
|
|
70
|
+
"passwordless",
|
|
71
|
+
"universal-protocol",
|
|
72
|
+
"proof",
|
|
73
|
+
"ownership",
|
|
74
|
+
"sdk",
|
|
75
|
+
"mcp",
|
|
76
|
+
"model-context-protocol",
|
|
77
|
+
"oauth"
|
|
78
|
+
],
|
|
79
|
+
"author": "NEUS Network",
|
|
80
|
+
"license": "Apache-2.0",
|
|
81
|
+
"repository": {
|
|
82
|
+
"type": "git",
|
|
83
|
+
"url": "git+https://github.com/neus/network.git",
|
|
84
|
+
"directory": "sdk"
|
|
85
|
+
},
|
|
86
|
+
"bugs": {
|
|
87
|
+
"url": "https://github.com/neus/network/issues"
|
|
88
|
+
},
|
|
89
|
+
"homepage": "https://neus.network",
|
|
90
|
+
"publishConfig": {
|
|
91
|
+
"access": "public",
|
|
92
|
+
"registry": "https://registry.npmjs.org"
|
|
93
|
+
},
|
|
94
|
+
"engines": {
|
|
95
|
+
"node": ">=20.0.0"
|
|
96
|
+
},
|
|
97
|
+
"peerDependencies": {
|
|
98
|
+
"ethers": "^6.0.0",
|
|
99
|
+
"react": ">=17.0.0",
|
|
100
|
+
"react-dom": ">=17.0.0"
|
|
101
|
+
},
|
|
102
|
+
"peerDependenciesMeta": {
|
|
103
|
+
"@zkpassport/sdk": {
|
|
104
|
+
"optional": true
|
|
105
|
+
},
|
|
106
|
+
"react": {
|
|
107
|
+
"optional": true
|
|
108
|
+
},
|
|
109
|
+
"react-dom": {
|
|
110
|
+
"optional": true
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
"optionalDependencies": {
|
|
114
|
+
"@zkpassport/sdk": "^0.14.0"
|
|
115
|
+
},
|
|
116
|
+
"dependencies": {
|
|
117
|
+
"bs58": "^6.0.0"
|
|
118
|
+
},
|
|
119
|
+
"devDependencies": {
|
|
120
|
+
"@vitest/coverage-v8": "^4.1.3",
|
|
121
|
+
"esbuild": "^0.28.0",
|
|
122
|
+
"eslint": "^8.56.0",
|
|
123
|
+
"eslint-plugin-react": "^7.37.2",
|
|
124
|
+
"prettier": "^3.2.0",
|
|
125
|
+
"vitest": "^4.1.3"
|
|
126
|
+
},
|
|
127
|
+
"files": [
|
|
128
|
+
"cli/neus.mjs",
|
|
129
|
+
"mcp-hosts.js",
|
|
130
|
+
"index.js",
|
|
131
|
+
"client.js",
|
|
132
|
+
"utils.js",
|
|
133
|
+
"errors.js",
|
|
134
|
+
"gates.js",
|
|
135
|
+
"sponsor.js",
|
|
136
|
+
"cjs/**",
|
|
137
|
+
"widgets.cjs",
|
|
138
|
+
"types.d.ts",
|
|
139
|
+
"README.md",
|
|
140
|
+
"SECURITY.md",
|
|
141
|
+
"LICENSE",
|
|
142
|
+
"widgets/index.js",
|
|
143
|
+
"widgets/verify-gate/index.js",
|
|
144
|
+
"widgets/verify-gate/dist/VerifyGate.js",
|
|
145
|
+
"widgets/verify-gate/dist/ProofBadge.js"
|
|
146
|
+
]
|
|
147
|
+
}
|
package/types.d.ts
CHANGED
|
@@ -51,6 +51,12 @@
|
|
|
51
51
|
|
|
52
52
|
checkGate(params: CheckGateParams): Promise<CheckGateResult>;
|
|
53
53
|
|
|
54
|
+
/** Public gate snapshot (requirements, charge, schedule — never the secret reward value). */
|
|
55
|
+
getGate(gateId: string): Promise<PublicGateSnapshot>;
|
|
56
|
+
|
|
57
|
+
/** Post-verify reward delivery for hosted gate checkout (session or wallet-bound). */
|
|
58
|
+
fulfillGate(params: FulfillGateParams): Promise<GateFulfillmentResponse>;
|
|
59
|
+
|
|
54
60
|
}
|
|
55
61
|
|
|
56
62
|
export type PrivacyLevel = 'public' | 'private';
|
|
@@ -102,6 +108,8 @@
|
|
|
102
108
|
enableIpfs?: boolean;
|
|
103
109
|
storeOriginalContent?: boolean;
|
|
104
110
|
targetChains?: number[];
|
|
111
|
+
/** Anchor the receipt on the hub registry chain. Defaults to false (receipts persist offchain). */
|
|
112
|
+
publishToHub?: boolean;
|
|
105
113
|
publicDisplay?: boolean;
|
|
106
114
|
meta?: Record<string, any>;
|
|
107
115
|
verifierOptions?: Record<string, any>;
|
|
@@ -429,12 +437,102 @@
|
|
|
429
437
|
scheme: string;
|
|
430
438
|
label: string;
|
|
431
439
|
amountUsd: number;
|
|
432
|
-
methods:
|
|
440
|
+
/** Payment methods offered to visitors: 'usdc' and/or 'stripe' (card). */
|
|
441
|
+
methods: Array<'usdc' | 'stripe' | string>;
|
|
442
|
+
/** True when the owner can receive card payouts (Stripe Connect ready). */
|
|
443
|
+
cardPayoutReady?: boolean;
|
|
433
444
|
appliesTo: string;
|
|
445
|
+
/** 'verifyThenCharge' (default) or 'chargeThenVerify'. */
|
|
434
446
|
executionOrder?: string;
|
|
435
447
|
recipient?: string;
|
|
436
448
|
};
|
|
437
449
|
|
|
450
|
+
/** One gate requirement row on the wire (protocol shape used by published gates). */
|
|
451
|
+
export interface GateMatchRowWire {
|
|
452
|
+
path: string;
|
|
453
|
+
op?: 'eq' | 'gte' | 'lte' | string;
|
|
454
|
+
value: string;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
export interface GateRequirementWire {
|
|
458
|
+
verifierId: string;
|
|
459
|
+
match?: GateMatchRowWire[];
|
|
460
|
+
optional?: boolean;
|
|
461
|
+
minCount?: number;
|
|
462
|
+
maxAgeMs?: number;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/** Public snapshot returned by GET /api/v1/gates/{gateId} — never includes the secret reward value. */
|
|
466
|
+
export interface PublicGateSnapshot {
|
|
467
|
+
schemaVersion: number;
|
|
468
|
+
gateId: string;
|
|
469
|
+
name?: string;
|
|
470
|
+
status?: string;
|
|
471
|
+
version?: number;
|
|
472
|
+
requirements: GateRequirementWire[];
|
|
473
|
+
policy?: {
|
|
474
|
+
visibility?: string;
|
|
475
|
+
gateFreshnessHours?: number;
|
|
476
|
+
};
|
|
477
|
+
monetization?: {
|
|
478
|
+
charge?: NeusPublicGateCharge | null;
|
|
479
|
+
};
|
|
480
|
+
checkout?: {
|
|
481
|
+
mode?: string;
|
|
482
|
+
flowPlan?: {
|
|
483
|
+
batches?: number;
|
|
484
|
+
hasInteractive?: boolean;
|
|
485
|
+
hasBackground?: boolean;
|
|
486
|
+
};
|
|
487
|
+
description?: string;
|
|
488
|
+
successReturnUrl?: string;
|
|
489
|
+
};
|
|
490
|
+
marketplaceTemplate?: {
|
|
491
|
+
templateId: string;
|
|
492
|
+
label?: string;
|
|
493
|
+
tags?: string[];
|
|
494
|
+
};
|
|
495
|
+
schedule?: {
|
|
496
|
+
startsAt?: string;
|
|
497
|
+
endsAt?: string;
|
|
498
|
+
};
|
|
499
|
+
artifact?: {
|
|
500
|
+
type: string;
|
|
501
|
+
label?: string;
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
export interface FulfillGateParams {
|
|
506
|
+
gateId: string;
|
|
507
|
+
/** Verified proof receipt id for this checkout. */
|
|
508
|
+
qHash: string;
|
|
509
|
+
/** Required when no session cookie binds the wallet. */
|
|
510
|
+
walletAddress?: string;
|
|
511
|
+
/** Stripe checkout session id for paid gates (card rail). */
|
|
512
|
+
paymentCheckoutSessionId?: string;
|
|
513
|
+
/** USDC payment transaction hash for paid gates (wallet rail). */
|
|
514
|
+
paymentTxHash?: string;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
export interface GateFulfillmentResult {
|
|
518
|
+
delivery: 'access_granted' | 'redirect' | 'download' | 'reveal' | string;
|
|
519
|
+
type?: string;
|
|
520
|
+
value?: string;
|
|
521
|
+
label?: string;
|
|
522
|
+
message?: string;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
export interface GateFulfillmentResponse {
|
|
526
|
+
success: boolean;
|
|
527
|
+
data?: {
|
|
528
|
+
gateId: string;
|
|
529
|
+
qHash: string;
|
|
530
|
+
fulfillment: GateFulfillmentResult;
|
|
531
|
+
successReturnUrl?: string;
|
|
532
|
+
};
|
|
533
|
+
error?: any;
|
|
534
|
+
}
|
|
535
|
+
|
|
438
536
|
export const NEUS_CONSTANTS: {
|
|
439
537
|
HUB_CHAIN_ID: number;
|
|
440
538
|
TESTNET_CHAINS: number[];
|
|
@@ -482,16 +580,36 @@
|
|
|
482
580
|
cursor?: string;
|
|
483
581
|
chain?: string;
|
|
484
582
|
signatureMethod?: string;
|
|
583
|
+
q?: string;
|
|
584
|
+
qHash?: string;
|
|
585
|
+
verifierId?: string;
|
|
586
|
+
verifierIds?: string;
|
|
587
|
+
tags?: string;
|
|
588
|
+
tagPrefix?: string;
|
|
589
|
+
tagContains?: string;
|
|
590
|
+
tagPrefixesAll?: string;
|
|
591
|
+
status?: string;
|
|
592
|
+
appId?: string;
|
|
593
|
+
chainCoverage?: 'hub-only' | 'cross-chain';
|
|
594
|
+
privacyLevel?: 'public' | 'private';
|
|
595
|
+
includeHistory?: boolean;
|
|
596
|
+
includeFacets?: string;
|
|
597
|
+
visibility?: 'public';
|
|
598
|
+
isPublicRead?: boolean;
|
|
485
599
|
}
|
|
486
600
|
|
|
487
601
|
export interface ProofsResult {
|
|
488
602
|
success: boolean;
|
|
489
603
|
proofs: any[];
|
|
490
|
-
totalCount: number;
|
|
604
|
+
totalCount: number | null;
|
|
491
605
|
hasMore: boolean;
|
|
492
606
|
nextOffset?: number | null;
|
|
493
607
|
/** Keyset continuation when the API returns cursor paging (preferred over deep offsets). */
|
|
494
608
|
nextCursor?: string | null;
|
|
609
|
+
facets?: {
|
|
610
|
+
tags?: string[];
|
|
611
|
+
truncated?: boolean;
|
|
612
|
+
} | null;
|
|
495
613
|
}
|
|
496
614
|
|
|
497
615
|
export interface GateRequirement {
|
|
@@ -499,7 +617,11 @@
|
|
|
499
617
|
maxAgeMs?: number;
|
|
500
618
|
optional?: boolean;
|
|
501
619
|
minCount?: number;
|
|
502
|
-
|
|
620
|
+
/**
|
|
621
|
+
* Either the protocol wire shape (array of { path, op, value } rows — what
|
|
622
|
+
* published gates store) or a flat { path: value } map for client-side checks.
|
|
623
|
+
*/
|
|
624
|
+
match?: GateMatchRowWire[] | Record<string, any>;
|
|
503
625
|
}
|
|
504
626
|
|
|
505
627
|
export interface CheckGateParams {
|
|
@@ -577,6 +699,25 @@
|
|
|
577
699
|
matchedTags?: string[];
|
|
578
700
|
projections?: Array<Record<string, any>> | null;
|
|
579
701
|
criteria?: Record<string, any>;
|
|
702
|
+
/**
|
|
703
|
+
* Per-requirement gate evaluation — present whenever `gateId` was passed.
|
|
704
|
+
* `allRequiredSatisfied === true` is the ONLY readiness signal for gate
|
|
705
|
+
* checkout; `eligible`/`matchedCount` alone are not sufficient.
|
|
706
|
+
*/
|
|
707
|
+
gate?: {
|
|
708
|
+
gateId: string | null;
|
|
709
|
+
allRequiredSatisfied: boolean;
|
|
710
|
+
satisfiedVerifierIds: string[];
|
|
711
|
+
missingVerifierIds: string[];
|
|
712
|
+
/** verifierId → qHash map for `options.reusedVerifierProofs` on submit (requires includeQHashes=true). */
|
|
713
|
+
reusedVerifierProofs?: Record<string, string>;
|
|
714
|
+
/** Per-requirement rows (requires includeQHashes=true). */
|
|
715
|
+
rows?: Array<{
|
|
716
|
+
verifierId: string;
|
|
717
|
+
satisfied: boolean;
|
|
718
|
+
qHashes?: string[];
|
|
719
|
+
}>;
|
|
720
|
+
};
|
|
580
721
|
};
|
|
581
722
|
error?: any;
|
|
582
723
|
}
|
|
@@ -830,6 +971,8 @@
|
|
|
830
971
|
|
|
831
972
|
interface VerifyOptions {
|
|
832
973
|
targetChains?: number[];
|
|
974
|
+
/** Anchor the receipt on the hub registry chain. Defaults to false (receipts persist offchain). */
|
|
975
|
+
publishToHub?: boolean;
|
|
833
976
|
enableIpfs?: boolean;
|
|
834
977
|
privacyLevel?: 'private' | 'public';
|
|
835
978
|
publicDisplay?: boolean;
|