@neus/sdk 1.1.0 → 1.1.2

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/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);
@@ -1955,21 +2089,20 @@ var init_client = __esm({
1955
2089
  return hex;
1956
2090
  }
1957
2091
  };
1958
- const isFarcasterWallet = (() => {
2092
+ const isBaseMiniAppWallet = (() => {
1959
2093
  if (typeof window === "undefined") return false;
1960
2094
  try {
1961
2095
  const w = window;
1962
- const fc = w.farcaster;
1963
- if (!fc || !fc.context) return false;
1964
- const fcProvider = fc.provider || fc.walletProvider || fc.context && fc.context.walletProvider;
1965
- if (fcProvider === provider) return true;
1966
- if (w.mini && w.mini.wallet === provider && fc && fc.context) return true;
1967
- if (w.ethereum === provider && fc && fc.context) return true;
2096
+ const mini = w.mini;
2097
+ if (!mini) return false;
2098
+ const miniProvider = mini.wallet || mini.provider;
2099
+ if (miniProvider === provider) return true;
2100
+ if (w.ethereum === provider && mini) return true;
1968
2101
  } catch {
1969
2102
  }
1970
2103
  return false;
1971
2104
  })();
1972
- if (isFarcasterWallet) {
2105
+ if (isBaseMiniAppWallet) {
1973
2106
  try {
1974
2107
  const hexMsg = toHexUtf82(message);
1975
2108
  signature2 = await provider.request({ method: "personal_sign", params: [hexMsg, walletAddress2] });
@@ -2102,7 +2235,8 @@ ${bytes.length}`;
2102
2235
  ...delegationQHash && { delegationQHash },
2103
2236
  options: optionsPayload
2104
2237
  };
2105
- const response = await this._makeRequest("POST", "/api/v1/verification", requestData);
2238
+ const sponsorHeaders = await this._resolveSponsorGrantHeaders(normalizedVerifierIds);
2239
+ const response = await this._makeRequest("POST", "/api/v1/verification", requestData, sponsorHeaders);
2106
2240
  if (!response.success) {
2107
2241
  throw new ApiError(`Verification failed: ${response.error?.message || "Unknown error"}`, response.error);
2108
2242
  }
@@ -2317,7 +2451,9 @@ ${bytes.length}`;
2317
2451
  const pathId = /^0x[a-fA-F0-9]{40}$/i.test(id) ? id.toLowerCase() : id;
2318
2452
  const qs = [];
2319
2453
  if (options.limit) qs.push(`limit=${encodeURIComponent(String(options.limit))}`);
2320
- if (options.offset) qs.push(`offset=${encodeURIComponent(String(options.offset))}`);
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))}`);
2321
2457
  if (options.qHash) qs.push(`qHash=${encodeURIComponent(options.qHash.toLowerCase())}`);
2322
2458
  const query = qs.length ? `?${qs.join("&")}` : "";
2323
2459
  const response = await this._makeRequest(
@@ -2333,7 +2469,8 @@ ${bytes.length}`;
2333
2469
  proofs: Array.isArray(proofs) ? proofs : [],
2334
2470
  totalCount: response.data?.totalCount ?? proofs.length,
2335
2471
  hasMore: Boolean(response.data?.hasMore),
2336
- nextOffset: response.data?.nextOffset ?? null
2472
+ nextOffset: response.data?.nextOffset ?? null,
2473
+ nextCursor: typeof response.data?.nextCursor === "string" && response.data.nextCursor.trim() ? response.data.nextCursor.trim() : null
2337
2474
  };
2338
2475
  }
2339
2476
  async getPrivateProofsByWallet(walletAddress, options = {}, wallet = null) {
@@ -2385,7 +2522,9 @@ ${bytes.length}`;
2385
2522
  }
2386
2523
  const qs = [];
2387
2524
  if (options.limit) qs.push(`limit=${encodeURIComponent(String(options.limit))}`);
2388
- if (options.offset) qs.push(`offset=${encodeURIComponent(String(options.offset))}`);
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))}`);
2389
2528
  if (options.qHash) qs.push(`qHash=${encodeURIComponent(options.qHash.toLowerCase())}`);
2390
2529
  const query = qs.length ? `?${qs.join("&")}` : "";
2391
2530
  const response = await this._makeRequest("GET", `/api/v1/proofs/by-wallet/${encodeURIComponent(pathId)}${query}`, null, {
@@ -2403,7 +2542,8 @@ ${bytes.length}`;
2403
2542
  proofs: Array.isArray(proofs) ? proofs : [],
2404
2543
  totalCount: response.data?.totalCount ?? proofs.length,
2405
2544
  hasMore: Boolean(response.data?.hasMore),
2406
- nextOffset: response.data?.nextOffset ?? null
2545
+ nextOffset: response.data?.nextOffset ?? null,
2546
+ nextCursor: typeof response.data?.nextCursor === "string" && response.data.nextCursor.trim() ? response.data.nextCursor.trim() : null
2407
2547
  };
2408
2548
  }
2409
2549
  async gateCheck(params = {}) {
@@ -2411,6 +2551,8 @@ ${bytes.length}`;
2411
2551
  if (!validateUniversalAddress(address, params.chain)) {
2412
2552
  throw new ValidationError("Valid address is required");
2413
2553
  }
2554
+ const gateIdParam = typeof params.gateId === "string" ? params.gateId.trim() : "";
2555
+ const verifierIds = gateIdParam ? void 0 : params.verifierIds;
2414
2556
  const qs = new URLSearchParams();
2415
2557
  qs.set("address", address);
2416
2558
  const setIfPresent = (key, value) => {
@@ -2432,7 +2574,8 @@ ${bytes.length}`;
2432
2574
  }
2433
2575
  setIfPresent(key, value);
2434
2576
  };
2435
- setCsvIfPresent("verifierIds", params.verifierIds);
2577
+ setIfPresent("gateId", gateIdParam);
2578
+ setCsvIfPresent("verifierIds", verifierIds);
2436
2579
  setBoolIfPresent("requireAll", params.requireAll);
2437
2580
  setIfPresent("minCount", params.minCount);
2438
2581
  setIfPresent("sinceDays", params.sinceDays);
@@ -2495,7 +2638,20 @@ ${bytes.length}`;
2495
2638
  };
2496
2639
  }
2497
2640
  }
2498
- const response = await this._makeRequest("GET", `/api/v1/proofs/check?${qs.toString()}`, null, headersOverride);
2641
+ let mergedHeaders = headersOverride;
2642
+ if (!mergedHeaders && !gateIdParam) {
2643
+ try {
2644
+ const sponsorHeaders = await this._resolveSponsorGrantHeaders(
2645
+ Array.isArray(verifierIds) ? verifierIds : verifierIds ? [verifierIds] : []
2646
+ );
2647
+ if (sponsorHeaders && Object.keys(sponsorHeaders).length > 0) {
2648
+ mergedHeaders = sponsorHeaders;
2649
+ }
2650
+ } catch (error) {
2651
+ this._log("Sponsor grant unavailable for gateCheck (continuing without)", error?.message || String(error));
2652
+ }
2653
+ }
2654
+ const response = await this._makeRequest("GET", `/api/v1/proofs/check?${qs.toString()}`, null, mergedHeaders);
2499
2655
  if (!response.success) {
2500
2656
  throw new ApiError(`Gate check failed: ${response.error?.message || "Unknown error"}`, response.error);
2501
2657
  }
@@ -2784,6 +2940,7 @@ __export(index_exports, {
2784
2940
  default: () => index_default,
2785
2941
  delay: () => delay,
2786
2942
  deriveDid: () => deriveDid,
2943
+ fetchSponsorGrant: () => fetchSponsorGrant,
2787
2944
  formatTimestamp: () => formatTimestamp,
2788
2945
  formatVerificationStatus: () => formatVerificationStatus,
2789
2946
  getHostedCheckoutUrl: () => getHostedCheckoutUrl,
@@ -2850,6 +3007,7 @@ function combineGates(...gates) {
2850
3007
  }
2851
3008
 
2852
3009
  // index.js
3010
+ init_sponsor();
2853
3011
  init_errors();
2854
3012
  var index_default = {
2855
3013
  NeusClient: () => Promise.resolve().then(() => (init_client(), client_exports)).then((m) => m.NeusClient),
@@ -2892,6 +3050,7 @@ var index_default = {
2892
3050
  createVerificationData,
2893
3051
  delay,
2894
3052
  deriveDid,
3053
+ fetchSponsorGrant,
2895
3054
  formatTimestamp,
2896
3055
  formatVerificationStatus,
2897
3056
  getHostedCheckoutUrl,
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // mcp-hosts.js
21
+ var mcp_hosts_exports = {};
22
+ __export(mcp_hosts_exports, {
23
+ IDE_HOST_BRAND_LOGOS: () => IDE_HOST_BRAND_LOGOS,
24
+ IDE_HOST_LABELS: () => IDE_HOST_LABELS,
25
+ MCP_INSTALL_CLIENTS: () => MCP_INSTALL_CLIENTS,
26
+ MCP_INSTALL_HOSTS: () => MCP_INSTALL_HOSTS,
27
+ NEUS_AUTH_CLI: () => NEUS_AUTH_CLI,
28
+ NEUS_MCP_SERVER_NAME: () => NEUS_MCP_SERVER_NAME,
29
+ NEUS_MCP_SETUP_DOCS_URL: () => NEUS_MCP_SETUP_DOCS_URL,
30
+ NEUS_MCP_URL: () => NEUS_MCP_URL,
31
+ NEUS_SETUP_CLI: () => NEUS_SETUP_CLI,
32
+ buildAuthCommandForClient: () => buildAuthCommandForClient,
33
+ buildCursorMcpInstallUrl: () => buildCursorMcpInstallUrl,
34
+ buildNeusMcpHttpConfig: () => buildNeusMcpHttpConfig,
35
+ buildSetupCommandForClient: () => buildSetupCommandForClient,
36
+ buildSetupCommandForHost: () => buildSetupCommandForHost,
37
+ buildVsCodeMcpInstallUrl: () => buildVsCodeMcpInstallUrl,
38
+ supportsMcpInstallDeeplink: () => supportsMcpInstallDeeplink
39
+ });
40
+ module.exports = __toCommonJS(mcp_hosts_exports);
41
+ var NEUS_MCP_SERVER_NAME = "neus";
42
+ var NEUS_MCP_URL = "https://mcp.neus.network/mcp";
43
+ var NEUS_SETUP_CLI = "npx -y -p @neus/sdk neus setup";
44
+ var NEUS_AUTH_CLI = "npx -y -p @neus/sdk neus auth";
45
+ var NEUS_MCP_SETUP_DOCS_URL = "https://docs.neus.network/mcp/ide-plugin";
46
+ var MCP_INSTALL_CLIENTS = ["claude", "codex", "cursor", "vscode"];
47
+ var MCP_INSTALL_HOSTS = ["cursor", "claude", "codex"];
48
+ var IDE_HOST_LABELS = {
49
+ cursor: "Cursor",
50
+ claude: "Claude Code",
51
+ codex: "Codex"
52
+ };
53
+ var IDE_HOST_BRAND_LOGOS = {
54
+ cursor: "/images/brandLogos/cursor.svg",
55
+ claude: "/images/brandLogos/anthropic.svg",
56
+ codex: "/images/brandLogos/openai.svg"
57
+ };
58
+ function buildNeusMcpHttpConfig(accessKey) {
59
+ const key = String(accessKey || "").trim();
60
+ return {
61
+ type: "http",
62
+ url: NEUS_MCP_URL,
63
+ ...key ? { headers: { Authorization: `Bearer ${key}` } } : {}
64
+ };
65
+ }
66
+ function encodeBase64Json(value) {
67
+ const json = JSON.stringify(value);
68
+ if (typeof globalThis.btoa === "function") {
69
+ return globalThis.btoa(json);
70
+ }
71
+ return Buffer.from(json, "utf8").toString("base64");
72
+ }
73
+ function buildCursorMcpInstallUrl(accessKey) {
74
+ const config = buildNeusMcpHttpConfig(accessKey);
75
+ const encoded = encodeBase64Json(config);
76
+ return `cursor://anysphere.cursor-deeplink/mcp/install?name=${encodeURIComponent(NEUS_MCP_SERVER_NAME)}&config=${encodeURIComponent(encoded)}`;
77
+ }
78
+ function buildVsCodeMcpInstallUrl(accessKey) {
79
+ const payload = {
80
+ name: NEUS_MCP_SERVER_NAME,
81
+ ...buildNeusMcpHttpConfig(accessKey)
82
+ };
83
+ return `vscode:mcp/install?${encodeURIComponent(JSON.stringify(payload))}`;
84
+ }
85
+ function buildAuthCommandForClient(client) {
86
+ if (client === "codex") {
87
+ return `${NEUS_AUTH_CLI} --client codex`;
88
+ }
89
+ return NEUS_AUTH_CLI;
90
+ }
91
+ function buildSetupCommandForClient(client, accessKey) {
92
+ const key = String(accessKey || "").trim();
93
+ const setup = key ? `${NEUS_SETUP_CLI} --client ${client} --access-key ${key}` : `${NEUS_SETUP_CLI} --client ${client}`;
94
+ if (key) return setup;
95
+ return `${setup}
96
+ ${buildAuthCommandForClient(client)}`;
97
+ }
98
+ function buildSetupCommandForHost(host, accessKey) {
99
+ return buildSetupCommandForClient(host, accessKey);
100
+ }
101
+ function supportsMcpInstallDeeplink(host) {
102
+ if (host !== "cursor") return false;
103
+ if (typeof navigator === "undefined") return false;
104
+ const ua = navigator.userAgent || "";
105
+ return !/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(ua);
106
+ }
107
+ // Annotate the CommonJS export names for ESM import in node:
108
+ 0 && (module.exports = {
109
+ IDE_HOST_BRAND_LOGOS,
110
+ IDE_HOST_LABELS,
111
+ MCP_INSTALL_CLIENTS,
112
+ MCP_INSTALL_HOSTS,
113
+ NEUS_AUTH_CLI,
114
+ NEUS_MCP_SERVER_NAME,
115
+ NEUS_MCP_SETUP_DOCS_URL,
116
+ NEUS_MCP_URL,
117
+ NEUS_SETUP_CLI,
118
+ buildAuthCommandForClient,
119
+ buildCursorMcpInstallUrl,
120
+ buildNeusMcpHttpConfig,
121
+ buildSetupCommandForClient,
122
+ buildSetupCommandForHost,
123
+ buildVsCodeMcpInstallUrl,
124
+ supportsMcpInstallDeeplink
125
+ });
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
  }