@neus/sdk 1.1.0 → 1.1.1
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/README.md +206 -206
- package/cjs/client.cjs +141 -2
- package/cjs/errors.cjs +2 -35
- package/cjs/gates.cjs +1 -21
- package/cjs/index.cjs +153 -2
- package/cjs/utils.cjs +2 -0
- package/cli/neus.mjs +18 -10
- package/client.js +91 -2
- package/errors.js +154 -189
- package/gates.js +0 -20
- package/index.js +2 -0
- package/package.json +142 -143
- package/sponsor.js +95 -0
- package/types.d.ts +30 -1
- package/utils.js +2 -0
- package/widgets/README.md +1 -1
- package/widgets/verify-gate/dist/VerifyGate.js +20 -5
- package/CHANGELOG.md +0 -3
- package/neus-logo.svg +0 -3
package/cjs/index.cjs
CHANGED
|
@@ -167,6 +167,89 @@ var init_errors = __esm({
|
|
|
167
167
|
}
|
|
168
168
|
});
|
|
169
169
|
|
|
170
|
+
// sponsor.js
|
|
171
|
+
async function fetchSponsorGrant(params = {}) {
|
|
172
|
+
const {
|
|
173
|
+
apiUrl = "https://api.neus.network",
|
|
174
|
+
appId,
|
|
175
|
+
orgWallet,
|
|
176
|
+
verifierIds = [],
|
|
177
|
+
targetChains = [],
|
|
178
|
+
origin,
|
|
179
|
+
expiresInSeconds = 900,
|
|
180
|
+
fetchImpl = fetch
|
|
181
|
+
} = params;
|
|
182
|
+
const normalizedAppId = typeof appId === "string" ? appId.trim() : "";
|
|
183
|
+
const normalizedOrg = typeof orgWallet === "string" ? orgWallet.trim().toLowerCase() : "";
|
|
184
|
+
if (!normalizedAppId) {
|
|
185
|
+
throw new ValidationError("appId is required for sponsor grant");
|
|
186
|
+
}
|
|
187
|
+
if (!normalizedOrg || !/^0x[a-f0-9]{40}$/.test(normalizedOrg)) {
|
|
188
|
+
throw new ValidationError("orgWallet must be a valid EVM address");
|
|
189
|
+
}
|
|
190
|
+
let base = String(apiUrl || "https://api.neus.network").replace(/\/+$/, "");
|
|
191
|
+
try {
|
|
192
|
+
const url = new URL(base);
|
|
193
|
+
if (url.hostname.endsWith("neus.network") && url.protocol === "http:") {
|
|
194
|
+
url.protocol = "https:";
|
|
195
|
+
}
|
|
196
|
+
base = url.toString().replace(/\/+$/, "");
|
|
197
|
+
} catch {
|
|
198
|
+
}
|
|
199
|
+
const headers = {
|
|
200
|
+
"Content-Type": "application/json",
|
|
201
|
+
Accept: "application/json",
|
|
202
|
+
"X-Neus-App": normalizedAppId,
|
|
203
|
+
"X-Neus-Sdk": "js"
|
|
204
|
+
};
|
|
205
|
+
if (typeof origin === "string" && origin.trim()) {
|
|
206
|
+
headers.Origin = origin.trim();
|
|
207
|
+
}
|
|
208
|
+
const body = {
|
|
209
|
+
orgWallet: normalizedOrg,
|
|
210
|
+
scope: "sponsored-verification",
|
|
211
|
+
expiresInSeconds,
|
|
212
|
+
...Array.isArray(verifierIds) && verifierIds.length > 0 ? { verifierIds: verifierIds.map((v) => String(v).trim()).filter(Boolean).slice(0, 25) } : {},
|
|
213
|
+
...Array.isArray(targetChains) && targetChains.length > 0 ? { targetChains: targetChains.filter((n) => Number.isFinite(Number(n))).slice(0, 25) } : {}
|
|
214
|
+
};
|
|
215
|
+
let response;
|
|
216
|
+
try {
|
|
217
|
+
response = await fetchImpl(`${base}/api/v1/sponsor/grant`, {
|
|
218
|
+
method: "POST",
|
|
219
|
+
headers,
|
|
220
|
+
body: JSON.stringify(body)
|
|
221
|
+
});
|
|
222
|
+
} catch (error) {
|
|
223
|
+
throw new NetworkError(`Sponsor grant request failed: ${error?.message || String(error)}`);
|
|
224
|
+
}
|
|
225
|
+
let payload;
|
|
226
|
+
try {
|
|
227
|
+
payload = await response.json();
|
|
228
|
+
} catch {
|
|
229
|
+
payload = { success: false, error: { message: "Invalid JSON response" } };
|
|
230
|
+
}
|
|
231
|
+
if (!response.ok || payload?.success !== true) {
|
|
232
|
+
throw ApiError.fromResponse(response, payload);
|
|
233
|
+
}
|
|
234
|
+
const token = payload?.data?.sponsorGrant;
|
|
235
|
+
if (!token || typeof token !== "string") {
|
|
236
|
+
throw new ApiError("Sponsor grant response missing sponsorGrant token", payload?.error);
|
|
237
|
+
}
|
|
238
|
+
return {
|
|
239
|
+
sponsorGrant: token,
|
|
240
|
+
exp: payload?.data?.exp,
|
|
241
|
+
orgWallet: payload?.data?.orgWallet || normalizedOrg,
|
|
242
|
+
appId: payload?.data?.appId || normalizedAppId,
|
|
243
|
+
maxCredits: payload?.data?.maxCredits
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
var init_sponsor = __esm({
|
|
247
|
+
"sponsor.js"() {
|
|
248
|
+
"use strict";
|
|
249
|
+
init_errors();
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
|
|
170
253
|
// utils.js
|
|
171
254
|
function encodeBase58Bytes(input) {
|
|
172
255
|
let source;
|
|
@@ -956,6 +1039,8 @@ function getHostedCheckoutUrl(opts = {}) {
|
|
|
956
1039
|
if (opts.intent) params.set("intent", String(opts.intent));
|
|
957
1040
|
if (opts.origin) params.set("origin", String(opts.origin));
|
|
958
1041
|
if (opts.oauthProvider) params.set("oauthProvider", String(opts.oauthProvider));
|
|
1042
|
+
if (opts.appId) params.set("appId", String(opts.appId));
|
|
1043
|
+
if (opts.billingWallet) params.set("billingWallet", String(opts.billingWallet).trim().toLowerCase());
|
|
959
1044
|
const qs = params.toString();
|
|
960
1045
|
return qs ? `${base}?${qs}` : base;
|
|
961
1046
|
}
|
|
@@ -1091,6 +1176,7 @@ var init_client = __esm({
|
|
|
1091
1176
|
"client.js"() {
|
|
1092
1177
|
"use strict";
|
|
1093
1178
|
init_errors();
|
|
1179
|
+
init_sponsor();
|
|
1094
1180
|
init_utils();
|
|
1095
1181
|
FALLBACK_PUBLIC_VERIFIER_CATALOG = {
|
|
1096
1182
|
"ownership-basic": { supportsDirectApi: true },
|
|
@@ -1430,6 +1516,54 @@ var init_client = __esm({
|
|
|
1430
1516
|
}
|
|
1431
1517
|
} catch {
|
|
1432
1518
|
}
|
|
1519
|
+
this._sponsorGrantCache = null;
|
|
1520
|
+
}
|
|
1521
|
+
_getBillingWallet() {
|
|
1522
|
+
const raw = this.config.billingWallet || this.config.sponsorOrgWallet || this.config.orgWallet || null;
|
|
1523
|
+
if (typeof raw !== "string") return null;
|
|
1524
|
+
const trimmed = raw.trim().toLowerCase();
|
|
1525
|
+
return /^0x[a-f0-9]{40}$/.test(trimmed) ? trimmed : null;
|
|
1526
|
+
}
|
|
1527
|
+
_resolveIntegratorOrigin() {
|
|
1528
|
+
if (typeof this.config.appOrigin === "string" && this.config.appOrigin.trim()) {
|
|
1529
|
+
return this.config.appOrigin.trim();
|
|
1530
|
+
}
|
|
1531
|
+
try {
|
|
1532
|
+
if (typeof window !== "undefined" && window.location?.origin) {
|
|
1533
|
+
return window.location.origin;
|
|
1534
|
+
}
|
|
1535
|
+
} catch {
|
|
1536
|
+
}
|
|
1537
|
+
return null;
|
|
1538
|
+
}
|
|
1539
|
+
async _resolveSponsorGrantHeaders(verifierIds = []) {
|
|
1540
|
+
const appId = typeof this.config.appId === "string" ? this.config.appId.trim() : "";
|
|
1541
|
+
const orgWallet = this._getBillingWallet();
|
|
1542
|
+
if (!appId || !orgWallet) {
|
|
1543
|
+
return {};
|
|
1544
|
+
}
|
|
1545
|
+
const normalizedVerifierIds = Array.isArray(verifierIds) ? verifierIds.map((v) => String(v || "").trim()).filter(Boolean).slice(0, 25) : [];
|
|
1546
|
+
const cacheKey = `${appId}:${orgWallet}:${normalizedVerifierIds.join(",")}`;
|
|
1547
|
+
const now = Date.now();
|
|
1548
|
+
if (this._sponsorGrantCache && this._sponsorGrantCache.key === cacheKey && this._sponsorGrantCache.expMs > now + 3e4) {
|
|
1549
|
+
return { "X-Sponsor-Grant": this._sponsorGrantCache.token };
|
|
1550
|
+
}
|
|
1551
|
+
const origin = this._resolveIntegratorOrigin();
|
|
1552
|
+
const grant = await fetchSponsorGrant({
|
|
1553
|
+
apiUrl: this.baseUrl,
|
|
1554
|
+
appId,
|
|
1555
|
+
orgWallet,
|
|
1556
|
+
verifierIds: normalizedVerifierIds,
|
|
1557
|
+
origin
|
|
1558
|
+
});
|
|
1559
|
+
const expSeconds = Number(grant?.exp);
|
|
1560
|
+
const expMs = Number.isFinite(expSeconds) && expSeconds > 0 ? expSeconds * 1e3 : now + 15 * 60 * 1e3;
|
|
1561
|
+
this._sponsorGrantCache = {
|
|
1562
|
+
key: cacheKey,
|
|
1563
|
+
token: grant.sponsorGrant,
|
|
1564
|
+
expMs
|
|
1565
|
+
};
|
|
1566
|
+
return { "X-Sponsor-Grant": grant.sponsorGrant };
|
|
1433
1567
|
}
|
|
1434
1568
|
_getHubChainId() {
|
|
1435
1569
|
const configured = Number(this.config?.hubChainId);
|
|
@@ -2102,7 +2236,8 @@ ${bytes.length}`;
|
|
|
2102
2236
|
...delegationQHash && { delegationQHash },
|
|
2103
2237
|
options: optionsPayload
|
|
2104
2238
|
};
|
|
2105
|
-
const
|
|
2239
|
+
const sponsorHeaders = await this._resolveSponsorGrantHeaders(normalizedVerifierIds);
|
|
2240
|
+
const response = await this._makeRequest("POST", "/api/v1/verification", requestData, sponsorHeaders);
|
|
2106
2241
|
if (!response.success) {
|
|
2107
2242
|
throw new ApiError(`Verification failed: ${response.error?.message || "Unknown error"}`, response.error);
|
|
2108
2243
|
}
|
|
@@ -2495,7 +2630,20 @@ ${bytes.length}`;
|
|
|
2495
2630
|
};
|
|
2496
2631
|
}
|
|
2497
2632
|
}
|
|
2498
|
-
|
|
2633
|
+
let mergedHeaders = headersOverride;
|
|
2634
|
+
if (!mergedHeaders) {
|
|
2635
|
+
try {
|
|
2636
|
+
const sponsorHeaders = await this._resolveSponsorGrantHeaders(
|
|
2637
|
+
Array.isArray(params.verifierIds) ? params.verifierIds : params.verifierIds ? [params.verifierIds] : []
|
|
2638
|
+
);
|
|
2639
|
+
if (sponsorHeaders && Object.keys(sponsorHeaders).length > 0) {
|
|
2640
|
+
mergedHeaders = sponsorHeaders;
|
|
2641
|
+
}
|
|
2642
|
+
} catch (error) {
|
|
2643
|
+
this._log("Sponsor grant unavailable for gateCheck (continuing without)", error?.message || String(error));
|
|
2644
|
+
}
|
|
2645
|
+
}
|
|
2646
|
+
const response = await this._makeRequest("GET", `/api/v1/proofs/check?${qs.toString()}`, null, mergedHeaders);
|
|
2499
2647
|
if (!response.success) {
|
|
2500
2648
|
throw new ApiError(`Gate check failed: ${response.error?.message || "Unknown error"}`, response.error);
|
|
2501
2649
|
}
|
|
@@ -2784,6 +2932,7 @@ __export(index_exports, {
|
|
|
2784
2932
|
default: () => index_default,
|
|
2785
2933
|
delay: () => delay,
|
|
2786
2934
|
deriveDid: () => deriveDid,
|
|
2935
|
+
fetchSponsorGrant: () => fetchSponsorGrant,
|
|
2787
2936
|
formatTimestamp: () => formatTimestamp,
|
|
2788
2937
|
formatVerificationStatus: () => formatVerificationStatus,
|
|
2789
2938
|
getHostedCheckoutUrl: () => getHostedCheckoutUrl,
|
|
@@ -2850,6 +2999,7 @@ function combineGates(...gates) {
|
|
|
2850
2999
|
}
|
|
2851
3000
|
|
|
2852
3001
|
// index.js
|
|
3002
|
+
init_sponsor();
|
|
2853
3003
|
init_errors();
|
|
2854
3004
|
var index_default = {
|
|
2855
3005
|
NeusClient: () => Promise.resolve().then(() => (init_client(), client_exports)).then((m) => m.NeusClient),
|
|
@@ -2892,6 +3042,7 @@ var index_default = {
|
|
|
2892
3042
|
createVerificationData,
|
|
2893
3043
|
delay,
|
|
2894
3044
|
deriveDid,
|
|
3045
|
+
fetchSponsorGrant,
|
|
2895
3046
|
formatTimestamp,
|
|
2896
3047
|
formatVerificationStatus,
|
|
2897
3048
|
getHostedCheckoutUrl,
|
package/cjs/utils.cjs
CHANGED
|
@@ -1012,6 +1012,8 @@ function getHostedCheckoutUrl(opts = {}) {
|
|
|
1012
1012
|
if (opts.intent) params.set("intent", String(opts.intent));
|
|
1013
1013
|
if (opts.origin) params.set("origin", String(opts.origin));
|
|
1014
1014
|
if (opts.oauthProvider) params.set("oauthProvider", String(opts.oauthProvider));
|
|
1015
|
+
if (opts.appId) params.set("appId", String(opts.appId));
|
|
1016
|
+
if (opts.billingWallet) params.set("billingWallet", String(opts.billingWallet).trim().toLowerCase());
|
|
1015
1017
|
const qs = params.toString();
|
|
1016
1018
|
return qs ? `${base}?${qs}` : base;
|
|
1017
1019
|
}
|
package/cli/neus.mjs
CHANGED
|
@@ -496,14 +496,21 @@ function cursorConfigPath(scope, cwd) {
|
|
|
496
496
|
}
|
|
497
497
|
|
|
498
498
|
function vscodeConfigPath(scope, cwd) {
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
499
|
+
if (scope !== 'user') {
|
|
500
|
+
return path.join(cwd, '.vscode', 'mcp.json');
|
|
501
|
+
}
|
|
502
|
+
if (process.platform === 'darwin') {
|
|
503
|
+
return path.join(os.homedir(), 'Library', 'Application Support', 'Code', 'User', 'mcp.json');
|
|
504
|
+
}
|
|
505
|
+
if (process.platform === 'win32') {
|
|
506
|
+
return path.join(
|
|
507
|
+
process.env.APPDATA || path.join(os.homedir(), 'AppData', 'Roaming'),
|
|
508
|
+
'Code',
|
|
509
|
+
'User',
|
|
510
|
+
'mcp.json'
|
|
511
|
+
);
|
|
512
|
+
}
|
|
513
|
+
return path.join(os.homedir(), '.config', 'Code', 'User', 'mcp.json');
|
|
507
514
|
}
|
|
508
515
|
|
|
509
516
|
function claudeProjectConfigPath(cwd) {
|
|
@@ -1255,9 +1262,10 @@ function printResultSummary(command, scope, results, accessKey) {
|
|
|
1255
1262
|
);
|
|
1256
1263
|
}
|
|
1257
1264
|
if (command === 'init' || command === 'setup') {
|
|
1258
|
-
lines.push('
|
|
1265
|
+
lines.push('All hosts (Cursor, Codex, OpenClaw, Hermes, Windsurf, Gemini, …): https://docs.neus.network/mcp/ide-plugin');
|
|
1266
|
+
lines.push('Claude Code plugin: neus-trust@neus — same page');
|
|
1259
1267
|
lines.push(
|
|
1260
|
-
'
|
|
1268
|
+
'Auto-setup clients: claude, cursor, vscode — re-run with --client to limit scope'
|
|
1261
1269
|
);
|
|
1262
1270
|
}
|
|
1263
1271
|
if ((command === 'init' || command === 'auth') && accessKey) {
|
package/client.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ApiError, ValidationError, NetworkError, ConfigurationError } from './errors.js';
|
|
2
|
+
import { fetchSponsorGrant } from './sponsor.js';
|
|
2
3
|
import {
|
|
3
4
|
PORTABLE_PROOF_SIGNER_HEADER,
|
|
4
5
|
constructVerificationMessage,
|
|
@@ -396,6 +397,77 @@ export class NeusClient {
|
|
|
396
397
|
} catch {
|
|
397
398
|
void 0;
|
|
398
399
|
}
|
|
400
|
+
|
|
401
|
+
/** @type {{ token: string, expMs: number, key: string } | null} */
|
|
402
|
+
this._sponsorGrantCache = null;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
_getBillingWallet() {
|
|
406
|
+
const raw =
|
|
407
|
+
this.config.billingWallet ||
|
|
408
|
+
this.config.sponsorOrgWallet ||
|
|
409
|
+
this.config.orgWallet ||
|
|
410
|
+
null;
|
|
411
|
+
if (typeof raw !== 'string') return null;
|
|
412
|
+
const trimmed = raw.trim().toLowerCase();
|
|
413
|
+
return /^0x[a-f0-9]{40}$/.test(trimmed) ? trimmed : null;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
_resolveIntegratorOrigin() {
|
|
417
|
+
if (typeof this.config.appOrigin === 'string' && this.config.appOrigin.trim()) {
|
|
418
|
+
return this.config.appOrigin.trim();
|
|
419
|
+
}
|
|
420
|
+
try {
|
|
421
|
+
if (typeof window !== 'undefined' && window.location?.origin) {
|
|
422
|
+
return window.location.origin;
|
|
423
|
+
}
|
|
424
|
+
} catch {
|
|
425
|
+
void 0;
|
|
426
|
+
}
|
|
427
|
+
return null;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
async _resolveSponsorGrantHeaders(verifierIds = []) {
|
|
431
|
+
const appId = typeof this.config.appId === 'string' ? this.config.appId.trim() : '';
|
|
432
|
+
const orgWallet = this._getBillingWallet();
|
|
433
|
+
if (!appId || !orgWallet) {
|
|
434
|
+
return {};
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
const normalizedVerifierIds = Array.isArray(verifierIds)
|
|
438
|
+
? verifierIds.map((v) => String(v || '').trim()).filter(Boolean).slice(0, 25)
|
|
439
|
+
: [];
|
|
440
|
+
const cacheKey = `${appId}:${orgWallet}:${normalizedVerifierIds.join(',')}`;
|
|
441
|
+
const now = Date.now();
|
|
442
|
+
if (
|
|
443
|
+
this._sponsorGrantCache &&
|
|
444
|
+
this._sponsorGrantCache.key === cacheKey &&
|
|
445
|
+
this._sponsorGrantCache.expMs > now + 30_000
|
|
446
|
+
) {
|
|
447
|
+
return { 'X-Sponsor-Grant': this._sponsorGrantCache.token };
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
const origin = this._resolveIntegratorOrigin();
|
|
451
|
+
const grant = await fetchSponsorGrant({
|
|
452
|
+
apiUrl: this.baseUrl,
|
|
453
|
+
appId,
|
|
454
|
+
orgWallet,
|
|
455
|
+
verifierIds: normalizedVerifierIds,
|
|
456
|
+
origin
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
const expSeconds = Number(grant?.exp);
|
|
460
|
+
const expMs = Number.isFinite(expSeconds) && expSeconds > 0
|
|
461
|
+
? expSeconds * 1000
|
|
462
|
+
: now + 15 * 60 * 1000;
|
|
463
|
+
|
|
464
|
+
this._sponsorGrantCache = {
|
|
465
|
+
key: cacheKey,
|
|
466
|
+
token: grant.sponsorGrant,
|
|
467
|
+
expMs
|
|
468
|
+
};
|
|
469
|
+
|
|
470
|
+
return { 'X-Sponsor-Grant': grant.sponsorGrant };
|
|
399
471
|
}
|
|
400
472
|
|
|
401
473
|
_getHubChainId() {
|
|
@@ -1147,7 +1219,8 @@ export class NeusClient {
|
|
|
1147
1219
|
options: optionsPayload
|
|
1148
1220
|
};
|
|
1149
1221
|
|
|
1150
|
-
const
|
|
1222
|
+
const sponsorHeaders = await this._resolveSponsorGrantHeaders(normalizedVerifierIds);
|
|
1223
|
+
const response = await this._makeRequest('POST', '/api/v1/verification', requestData, sponsorHeaders);
|
|
1151
1224
|
|
|
1152
1225
|
if (!response.success) {
|
|
1153
1226
|
throw new ApiError(`Verification failed: ${response.error?.message || 'Unknown error'}`, response.error);
|
|
@@ -1619,7 +1692,23 @@ export class NeusClient {
|
|
|
1619
1692
|
}
|
|
1620
1693
|
}
|
|
1621
1694
|
|
|
1622
|
-
|
|
1695
|
+
let mergedHeaders = headersOverride;
|
|
1696
|
+
if (!mergedHeaders) {
|
|
1697
|
+
try {
|
|
1698
|
+
const sponsorHeaders = await this._resolveSponsorGrantHeaders(
|
|
1699
|
+
Array.isArray(params.verifierIds)
|
|
1700
|
+
? params.verifierIds
|
|
1701
|
+
: (params.verifierIds ? [params.verifierIds] : [])
|
|
1702
|
+
);
|
|
1703
|
+
if (sponsorHeaders && Object.keys(sponsorHeaders).length > 0) {
|
|
1704
|
+
mergedHeaders = sponsorHeaders;
|
|
1705
|
+
}
|
|
1706
|
+
} catch (error) {
|
|
1707
|
+
this._log('Sponsor grant unavailable for gateCheck (continuing without)', error?.message || String(error));
|
|
1708
|
+
}
|
|
1709
|
+
}
|
|
1710
|
+
|
|
1711
|
+
const response = await this._makeRequest('GET', `/api/v1/proofs/check?${qs.toString()}`, null, mergedHeaders);
|
|
1623
1712
|
if (!response.success) {
|
|
1624
1713
|
throw new ApiError(`Gate check failed: ${response.error?.message || 'Unknown error'}`, response.error);
|
|
1625
1714
|
}
|