@neus/sdk 1.1.5 → 1.1.7
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 +96 -17
- package/cjs/index.cjs +96 -17
- package/cli/neus.mjs +31 -6
- package/client.js +2121 -2037
- package/package.json +150 -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,
|
|
@@ -1738,30 +1743,50 @@ ${bytes.length}`;
|
|
|
1738
1743
|
}
|
|
1739
1744
|
throw new ValidationError(`Failed to sign revocation: ${error.message}`);
|
|
1740
1745
|
}
|
|
1741
|
-
const
|
|
1746
|
+
const json = await this._makeRequest("POST", `/api/v1/proofs/revoke-self/${qHash}`, {
|
|
1742
1747
|
walletAddress: address,
|
|
1743
1748
|
signature,
|
|
1744
1749
|
signedTimestamp,
|
|
1745
1750
|
...signerIsEvm ? {} : { chain, signatureMethod }
|
|
1746
1751
|
});
|
|
1747
|
-
const json = await res.json();
|
|
1748
1752
|
if (!json.success) {
|
|
1749
1753
|
throw new ApiError(json.error?.message || "Failed to revoke proof", json.error);
|
|
1750
1754
|
}
|
|
1751
1755
|
return true;
|
|
1752
1756
|
}
|
|
1757
|
+
_buildProofsByWalletQuery(options = {}) {
|
|
1758
|
+
const qs = [];
|
|
1759
|
+
if (options.limit) qs.push(`limit=${encodeURIComponent(String(options.limit))}`);
|
|
1760
|
+
const cursorRaw = options.cursor !== null && options.cursor !== void 0 ? String(options.cursor).trim() : "";
|
|
1761
|
+
if (cursorRaw) qs.push(`cursor=${encodeURIComponent(cursorRaw)}`);
|
|
1762
|
+
else if (options.offset !== void 0 && options.offset !== null) {
|
|
1763
|
+
qs.push(`offset=${encodeURIComponent(String(options.offset))}`);
|
|
1764
|
+
}
|
|
1765
|
+
if (options.q) qs.push(`q=${encodeURIComponent(String(options.q))}`);
|
|
1766
|
+
if (options.qHash) qs.push(`qHash=${encodeURIComponent(String(options.qHash).toLowerCase())}`);
|
|
1767
|
+
if (options.verifierId) qs.push(`verifierId=${encodeURIComponent(String(options.verifierId))}`);
|
|
1768
|
+
if (options.verifierIds) qs.push(`verifierIds=${encodeURIComponent(String(options.verifierIds))}`);
|
|
1769
|
+
if (options.tags) qs.push(`tags=${encodeURIComponent(String(options.tags))}`);
|
|
1770
|
+
if (options.tagPrefix) qs.push(`tagPrefix=${encodeURIComponent(String(options.tagPrefix))}`);
|
|
1771
|
+
if (options.tagContains) qs.push(`tagContains=${encodeURIComponent(String(options.tagContains))}`);
|
|
1772
|
+
if (options.tagPrefixesAll) qs.push(`tagPrefixesAll=${encodeURIComponent(String(options.tagPrefixesAll))}`);
|
|
1773
|
+
if (options.status) qs.push(`status=${encodeURIComponent(String(options.status))}`);
|
|
1774
|
+
if (options.appId) qs.push(`appId=${encodeURIComponent(String(options.appId))}`);
|
|
1775
|
+
if (options.chainCoverage) qs.push(`chainCoverage=${encodeURIComponent(String(options.chainCoverage))}`);
|
|
1776
|
+
if (options.privacyLevel) qs.push(`privacyLevel=${encodeURIComponent(String(options.privacyLevel))}`);
|
|
1777
|
+
if (options.includeHistory) qs.push("includeHistory=1");
|
|
1778
|
+
if (options.includeFacets) qs.push(`includeFacets=${encodeURIComponent(String(options.includeFacets))}`);
|
|
1779
|
+
if (options.visibility) qs.push(`visibility=${encodeURIComponent(String(options.visibility))}`);
|
|
1780
|
+
if (options.isPublicRead) qs.push("isPublicRead=1");
|
|
1781
|
+
return qs;
|
|
1782
|
+
}
|
|
1753
1783
|
async getProofsByWallet(walletAddress, options = {}) {
|
|
1754
1784
|
if (!walletAddress || typeof walletAddress !== "string") {
|
|
1755
1785
|
throw new ValidationError("walletAddress is required");
|
|
1756
1786
|
}
|
|
1757
1787
|
const id = walletAddress.trim();
|
|
1758
1788
|
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())}`);
|
|
1789
|
+
const qs = this._buildProofsByWalletQuery(options);
|
|
1765
1790
|
const query = qs.length ? `?${qs.join("&")}` : "";
|
|
1766
1791
|
const response = await this._makeRequest(
|
|
1767
1792
|
"GET",
|
|
@@ -1774,10 +1799,11 @@ ${bytes.length}`;
|
|
|
1774
1799
|
return {
|
|
1775
1800
|
success: true,
|
|
1776
1801
|
proofs: Array.isArray(proofs) ? proofs : [],
|
|
1777
|
-
totalCount: response.data?.totalCount
|
|
1802
|
+
totalCount: typeof response.data?.totalCount === "number" ? response.data.totalCount : null,
|
|
1778
1803
|
hasMore: Boolean(response.data?.hasMore),
|
|
1779
1804
|
nextOffset: response.data?.nextOffset ?? null,
|
|
1780
|
-
nextCursor: typeof response.data?.nextCursor === "string" && response.data.nextCursor.trim() ? response.data.nextCursor.trim() : null
|
|
1805
|
+
nextCursor: typeof response.data?.nextCursor === "string" && response.data.nextCursor.trim() ? response.data.nextCursor.trim() : null,
|
|
1806
|
+
facets: response.data?.facets || null
|
|
1781
1807
|
};
|
|
1782
1808
|
}
|
|
1783
1809
|
async getPrivateProofsByWallet(walletAddress, options = {}, wallet = null) {
|
|
@@ -1827,12 +1853,7 @@ ${bytes.length}`;
|
|
|
1827
1853
|
}
|
|
1828
1854
|
throw new ValidationError(`Failed to sign message: ${error.message}`);
|
|
1829
1855
|
}
|
|
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())}`);
|
|
1856
|
+
const qs = this._buildProofsByWalletQuery(options);
|
|
1836
1857
|
const query = qs.length ? `?${qs.join("&")}` : "";
|
|
1837
1858
|
const response = await this._makeRequest("GET", `/api/v1/proofs/by-wallet/${encodeURIComponent(pathId)}${query}`, null, {
|
|
1838
1859
|
"x-wallet-address": signerWalletAddress,
|
|
@@ -1847,7 +1868,7 @@ ${bytes.length}`;
|
|
|
1847
1868
|
return {
|
|
1848
1869
|
success: true,
|
|
1849
1870
|
proofs: Array.isArray(proofs) ? proofs : [],
|
|
1850
|
-
totalCount: response.data?.totalCount
|
|
1871
|
+
totalCount: typeof response.data?.totalCount === "number" ? response.data.totalCount : null,
|
|
1851
1872
|
hasMore: Boolean(response.data?.hasMore),
|
|
1852
1873
|
nextOffset: response.data?.nextOffset ?? null,
|
|
1853
1874
|
nextCursor: typeof response.data?.nextCursor === "string" && response.data.nextCursor.trim() ? response.data.nextCursor.trim() : null
|
|
@@ -1964,6 +1985,64 @@ ${bytes.length}`;
|
|
|
1964
1985
|
}
|
|
1965
1986
|
return response;
|
|
1966
1987
|
}
|
|
1988
|
+
/**
|
|
1989
|
+
* Get the public snapshot of a published gate: requirements, charge, schedule,
|
|
1990
|
+
* checkout plan, and reward presence. Never returns the secret reward value —
|
|
1991
|
+
* that is delivered post-verify via fulfillGate().
|
|
1992
|
+
*
|
|
1993
|
+
* @param {string} gateId Published gate handle
|
|
1994
|
+
* @returns {Promise<object>} Public gate snapshot
|
|
1995
|
+
*/
|
|
1996
|
+
async getGate(gateId) {
|
|
1997
|
+
const id = String(gateId || "").trim();
|
|
1998
|
+
if (!id || id.length > 80 || !/^[a-zA-Z0-9:_-]+$/.test(id)) {
|
|
1999
|
+
throw new ValidationError("Valid gateId is required");
|
|
2000
|
+
}
|
|
2001
|
+
const response = await this._makeRequest("GET", `/api/v1/profile/gates/${encodeURIComponent(id)}`);
|
|
2002
|
+
if (!response.success || !response.data?.gate) {
|
|
2003
|
+
throw new ApiError(`Gate lookup failed: ${response.error?.message || "Gate not found"}`, response.error);
|
|
2004
|
+
}
|
|
2005
|
+
return response.data.gate;
|
|
2006
|
+
}
|
|
2007
|
+
/**
|
|
2008
|
+
* Post-verify reward delivery for hosted gate checkout. Requires a verified
|
|
2009
|
+
* proof (qHash) for the gate; paid gates also require payment evidence
|
|
2010
|
+
* (paymentCheckoutSessionId for card, or paymentTxHash for USDC).
|
|
2011
|
+
*
|
|
2012
|
+
* @param {object} params
|
|
2013
|
+
* @param {string} params.gateId Published gate handle
|
|
2014
|
+
* @param {string} params.qHash Verified proof receipt id
|
|
2015
|
+
* @param {string} [params.walletAddress] Wallet bound to the proof (required without a session cookie)
|
|
2016
|
+
* @param {string} [params.paymentCheckoutSessionId] Stripe checkout session id (card rail)
|
|
2017
|
+
* @param {string} [params.paymentTxHash] USDC payment transaction hash (wallet rail)
|
|
2018
|
+
* @returns {Promise<object>} `{ success, data: { gateId, qHash, fulfillment, successReturnUrl? } }`
|
|
2019
|
+
*/
|
|
2020
|
+
async fulfillGate(params = {}) {
|
|
2021
|
+
const gateId = String(params.gateId || "").trim();
|
|
2022
|
+
if (!gateId || gateId.length > 80 || !/^[a-zA-Z0-9:_-]+$/.test(gateId)) {
|
|
2023
|
+
throw new ValidationError("Valid gateId is required");
|
|
2024
|
+
}
|
|
2025
|
+
const qHash = String(params.qHash || "").trim();
|
|
2026
|
+
if (!/^0x[a-fA-F0-9]{64}$/.test(qHash)) {
|
|
2027
|
+
throw new ValidationError("Valid qHash is required");
|
|
2028
|
+
}
|
|
2029
|
+
const body = { qHash };
|
|
2030
|
+
const walletAddress = String(params.walletAddress || "").trim();
|
|
2031
|
+
if (walletAddress) body.walletAddress = walletAddress;
|
|
2032
|
+
const paymentCheckoutSessionId = String(params.paymentCheckoutSessionId || "").trim();
|
|
2033
|
+
if (paymentCheckoutSessionId) body.paymentCheckoutSessionId = paymentCheckoutSessionId;
|
|
2034
|
+
const paymentTxHash = String(params.paymentTxHash || "").trim();
|
|
2035
|
+
if (paymentTxHash) body.paymentTxHash = paymentTxHash;
|
|
2036
|
+
const response = await this._makeRequest(
|
|
2037
|
+
"POST",
|
|
2038
|
+
`/api/v1/profile/gates/${encodeURIComponent(gateId)}/fulfill`,
|
|
2039
|
+
body
|
|
2040
|
+
);
|
|
2041
|
+
if (!response.success) {
|
|
2042
|
+
throw new ApiError(`Gate fulfillment failed: ${response.error?.message || "Unknown error"}`, response.error);
|
|
2043
|
+
}
|
|
2044
|
+
return response;
|
|
2045
|
+
}
|
|
1967
2046
|
async checkGate(params) {
|
|
1968
2047
|
const { walletAddress, requirements, proofs: preloadedProofs } = params;
|
|
1969
2048
|
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,
|
|
@@ -2431,30 +2436,50 @@ ${bytes.length}`;
|
|
|
2431
2436
|
}
|
|
2432
2437
|
throw new ValidationError(`Failed to sign revocation: ${error.message}`);
|
|
2433
2438
|
}
|
|
2434
|
-
const
|
|
2439
|
+
const json = await this._makeRequest("POST", `/api/v1/proofs/revoke-self/${qHash}`, {
|
|
2435
2440
|
walletAddress: address,
|
|
2436
2441
|
signature,
|
|
2437
2442
|
signedTimestamp,
|
|
2438
2443
|
...signerIsEvm ? {} : { chain, signatureMethod }
|
|
2439
2444
|
});
|
|
2440
|
-
const json = await res.json();
|
|
2441
2445
|
if (!json.success) {
|
|
2442
2446
|
throw new ApiError(json.error?.message || "Failed to revoke proof", json.error);
|
|
2443
2447
|
}
|
|
2444
2448
|
return true;
|
|
2445
2449
|
}
|
|
2450
|
+
_buildProofsByWalletQuery(options = {}) {
|
|
2451
|
+
const qs = [];
|
|
2452
|
+
if (options.limit) qs.push(`limit=${encodeURIComponent(String(options.limit))}`);
|
|
2453
|
+
const cursorRaw = options.cursor !== null && options.cursor !== void 0 ? String(options.cursor).trim() : "";
|
|
2454
|
+
if (cursorRaw) qs.push(`cursor=${encodeURIComponent(cursorRaw)}`);
|
|
2455
|
+
else if (options.offset !== void 0 && options.offset !== null) {
|
|
2456
|
+
qs.push(`offset=${encodeURIComponent(String(options.offset))}`);
|
|
2457
|
+
}
|
|
2458
|
+
if (options.q) qs.push(`q=${encodeURIComponent(String(options.q))}`);
|
|
2459
|
+
if (options.qHash) qs.push(`qHash=${encodeURIComponent(String(options.qHash).toLowerCase())}`);
|
|
2460
|
+
if (options.verifierId) qs.push(`verifierId=${encodeURIComponent(String(options.verifierId))}`);
|
|
2461
|
+
if (options.verifierIds) qs.push(`verifierIds=${encodeURIComponent(String(options.verifierIds))}`);
|
|
2462
|
+
if (options.tags) qs.push(`tags=${encodeURIComponent(String(options.tags))}`);
|
|
2463
|
+
if (options.tagPrefix) qs.push(`tagPrefix=${encodeURIComponent(String(options.tagPrefix))}`);
|
|
2464
|
+
if (options.tagContains) qs.push(`tagContains=${encodeURIComponent(String(options.tagContains))}`);
|
|
2465
|
+
if (options.tagPrefixesAll) qs.push(`tagPrefixesAll=${encodeURIComponent(String(options.tagPrefixesAll))}`);
|
|
2466
|
+
if (options.status) qs.push(`status=${encodeURIComponent(String(options.status))}`);
|
|
2467
|
+
if (options.appId) qs.push(`appId=${encodeURIComponent(String(options.appId))}`);
|
|
2468
|
+
if (options.chainCoverage) qs.push(`chainCoverage=${encodeURIComponent(String(options.chainCoverage))}`);
|
|
2469
|
+
if (options.privacyLevel) qs.push(`privacyLevel=${encodeURIComponent(String(options.privacyLevel))}`);
|
|
2470
|
+
if (options.includeHistory) qs.push("includeHistory=1");
|
|
2471
|
+
if (options.includeFacets) qs.push(`includeFacets=${encodeURIComponent(String(options.includeFacets))}`);
|
|
2472
|
+
if (options.visibility) qs.push(`visibility=${encodeURIComponent(String(options.visibility))}`);
|
|
2473
|
+
if (options.isPublicRead) qs.push("isPublicRead=1");
|
|
2474
|
+
return qs;
|
|
2475
|
+
}
|
|
2446
2476
|
async getProofsByWallet(walletAddress, options = {}) {
|
|
2447
2477
|
if (!walletAddress || typeof walletAddress !== "string") {
|
|
2448
2478
|
throw new ValidationError("walletAddress is required");
|
|
2449
2479
|
}
|
|
2450
2480
|
const id = walletAddress.trim();
|
|
2451
2481
|
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())}`);
|
|
2482
|
+
const qs = this._buildProofsByWalletQuery(options);
|
|
2458
2483
|
const query = qs.length ? `?${qs.join("&")}` : "";
|
|
2459
2484
|
const response = await this._makeRequest(
|
|
2460
2485
|
"GET",
|
|
@@ -2467,10 +2492,11 @@ ${bytes.length}`;
|
|
|
2467
2492
|
return {
|
|
2468
2493
|
success: true,
|
|
2469
2494
|
proofs: Array.isArray(proofs) ? proofs : [],
|
|
2470
|
-
totalCount: response.data?.totalCount
|
|
2495
|
+
totalCount: typeof response.data?.totalCount === "number" ? response.data.totalCount : null,
|
|
2471
2496
|
hasMore: Boolean(response.data?.hasMore),
|
|
2472
2497
|
nextOffset: response.data?.nextOffset ?? null,
|
|
2473
|
-
nextCursor: typeof response.data?.nextCursor === "string" && response.data.nextCursor.trim() ? response.data.nextCursor.trim() : null
|
|
2498
|
+
nextCursor: typeof response.data?.nextCursor === "string" && response.data.nextCursor.trim() ? response.data.nextCursor.trim() : null,
|
|
2499
|
+
facets: response.data?.facets || null
|
|
2474
2500
|
};
|
|
2475
2501
|
}
|
|
2476
2502
|
async getPrivateProofsByWallet(walletAddress, options = {}, wallet = null) {
|
|
@@ -2520,12 +2546,7 @@ ${bytes.length}`;
|
|
|
2520
2546
|
}
|
|
2521
2547
|
throw new ValidationError(`Failed to sign message: ${error.message}`);
|
|
2522
2548
|
}
|
|
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())}`);
|
|
2549
|
+
const qs = this._buildProofsByWalletQuery(options);
|
|
2529
2550
|
const query = qs.length ? `?${qs.join("&")}` : "";
|
|
2530
2551
|
const response = await this._makeRequest("GET", `/api/v1/proofs/by-wallet/${encodeURIComponent(pathId)}${query}`, null, {
|
|
2531
2552
|
"x-wallet-address": signerWalletAddress,
|
|
@@ -2540,7 +2561,7 @@ ${bytes.length}`;
|
|
|
2540
2561
|
return {
|
|
2541
2562
|
success: true,
|
|
2542
2563
|
proofs: Array.isArray(proofs) ? proofs : [],
|
|
2543
|
-
totalCount: response.data?.totalCount
|
|
2564
|
+
totalCount: typeof response.data?.totalCount === "number" ? response.data.totalCount : null,
|
|
2544
2565
|
hasMore: Boolean(response.data?.hasMore),
|
|
2545
2566
|
nextOffset: response.data?.nextOffset ?? null,
|
|
2546
2567
|
nextCursor: typeof response.data?.nextCursor === "string" && response.data.nextCursor.trim() ? response.data.nextCursor.trim() : null
|
|
@@ -2657,6 +2678,64 @@ ${bytes.length}`;
|
|
|
2657
2678
|
}
|
|
2658
2679
|
return response;
|
|
2659
2680
|
}
|
|
2681
|
+
/**
|
|
2682
|
+
* Get the public snapshot of a published gate: requirements, charge, schedule,
|
|
2683
|
+
* checkout plan, and reward presence. Never returns the secret reward value —
|
|
2684
|
+
* that is delivered post-verify via fulfillGate().
|
|
2685
|
+
*
|
|
2686
|
+
* @param {string} gateId Published gate handle
|
|
2687
|
+
* @returns {Promise<object>} Public gate snapshot
|
|
2688
|
+
*/
|
|
2689
|
+
async getGate(gateId) {
|
|
2690
|
+
const id = String(gateId || "").trim();
|
|
2691
|
+
if (!id || id.length > 80 || !/^[a-zA-Z0-9:_-]+$/.test(id)) {
|
|
2692
|
+
throw new ValidationError("Valid gateId is required");
|
|
2693
|
+
}
|
|
2694
|
+
const response = await this._makeRequest("GET", `/api/v1/profile/gates/${encodeURIComponent(id)}`);
|
|
2695
|
+
if (!response.success || !response.data?.gate) {
|
|
2696
|
+
throw new ApiError(`Gate lookup failed: ${response.error?.message || "Gate not found"}`, response.error);
|
|
2697
|
+
}
|
|
2698
|
+
return response.data.gate;
|
|
2699
|
+
}
|
|
2700
|
+
/**
|
|
2701
|
+
* Post-verify reward delivery for hosted gate checkout. Requires a verified
|
|
2702
|
+
* proof (qHash) for the gate; paid gates also require payment evidence
|
|
2703
|
+
* (paymentCheckoutSessionId for card, or paymentTxHash for USDC).
|
|
2704
|
+
*
|
|
2705
|
+
* @param {object} params
|
|
2706
|
+
* @param {string} params.gateId Published gate handle
|
|
2707
|
+
* @param {string} params.qHash Verified proof receipt id
|
|
2708
|
+
* @param {string} [params.walletAddress] Wallet bound to the proof (required without a session cookie)
|
|
2709
|
+
* @param {string} [params.paymentCheckoutSessionId] Stripe checkout session id (card rail)
|
|
2710
|
+
* @param {string} [params.paymentTxHash] USDC payment transaction hash (wallet rail)
|
|
2711
|
+
* @returns {Promise<object>} `{ success, data: { gateId, qHash, fulfillment, successReturnUrl? } }`
|
|
2712
|
+
*/
|
|
2713
|
+
async fulfillGate(params = {}) {
|
|
2714
|
+
const gateId = String(params.gateId || "").trim();
|
|
2715
|
+
if (!gateId || gateId.length > 80 || !/^[a-zA-Z0-9:_-]+$/.test(gateId)) {
|
|
2716
|
+
throw new ValidationError("Valid gateId is required");
|
|
2717
|
+
}
|
|
2718
|
+
const qHash = String(params.qHash || "").trim();
|
|
2719
|
+
if (!/^0x[a-fA-F0-9]{64}$/.test(qHash)) {
|
|
2720
|
+
throw new ValidationError("Valid qHash is required");
|
|
2721
|
+
}
|
|
2722
|
+
const body = { qHash };
|
|
2723
|
+
const walletAddress = String(params.walletAddress || "").trim();
|
|
2724
|
+
if (walletAddress) body.walletAddress = walletAddress;
|
|
2725
|
+
const paymentCheckoutSessionId = String(params.paymentCheckoutSessionId || "").trim();
|
|
2726
|
+
if (paymentCheckoutSessionId) body.paymentCheckoutSessionId = paymentCheckoutSessionId;
|
|
2727
|
+
const paymentTxHash = String(params.paymentTxHash || "").trim();
|
|
2728
|
+
if (paymentTxHash) body.paymentTxHash = paymentTxHash;
|
|
2729
|
+
const response = await this._makeRequest(
|
|
2730
|
+
"POST",
|
|
2731
|
+
`/api/v1/profile/gates/${encodeURIComponent(gateId)}/fulfill`,
|
|
2732
|
+
body
|
|
2733
|
+
);
|
|
2734
|
+
if (!response.success) {
|
|
2735
|
+
throw new ApiError(`Gate fulfillment failed: ${response.error?.message || "Unknown error"}`, response.error);
|
|
2736
|
+
}
|
|
2737
|
+
return response;
|
|
2738
|
+
}
|
|
2660
2739
|
async checkGate(params) {
|
|
2661
2740
|
const { walletAddress, requirements, proofs: preloadedProofs } = params;
|
|
2662
2741
|
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
|
}
|