@neus/sdk 1.0.2 → 1.0.3

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
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -33,6 +34,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
33
34
  var SDKError, ApiError, ValidationError, NetworkError, ConfigurationError, VerificationError, AuthenticationError;
34
35
  var init_errors = __esm({
35
36
  "errors.js"() {
37
+ "use strict";
36
38
  SDKError = class _SDKError extends Error {
37
39
  constructor(message, code = "SDK_ERROR", details = {}) {
38
40
  super(message);
@@ -166,6 +168,49 @@ var init_errors = __esm({
166
168
  });
167
169
 
168
170
  // utils.js
171
+ function encodeBase58Bytes(input) {
172
+ let source;
173
+ if (input instanceof Uint8Array) {
174
+ source = input;
175
+ } else if (input instanceof ArrayBuffer) {
176
+ source = new Uint8Array(input);
177
+ } else if (ArrayBuffer.isView(input)) {
178
+ source = new Uint8Array(input.buffer, input.byteOffset, input.byteLength);
179
+ } else if (typeof Buffer !== "undefined" && typeof Buffer.isBuffer === "function" && Buffer.isBuffer(input)) {
180
+ source = new Uint8Array(input);
181
+ } else {
182
+ throw new SDKError("Unsupported non-EVM signature byte format", "INVALID_SIGNATURE_FORMAT");
183
+ }
184
+ if (source.length === 0)
185
+ return "";
186
+ let zeroes = 0;
187
+ while (zeroes < source.length && source[zeroes] === 0) {
188
+ zeroes++;
189
+ }
190
+ const iFactor = Math.log(256) / Math.log(58);
191
+ const size = (source.length - zeroes) * iFactor + 1 >>> 0;
192
+ const b58 = new Uint8Array(size);
193
+ let length = 0;
194
+ for (let i = zeroes; i < source.length; i++) {
195
+ let carry = source[i];
196
+ let j = 0;
197
+ for (let k = size - 1; (carry !== 0 || j < length) && k >= 0; k--, j++) {
198
+ carry += 256 * b58[k];
199
+ b58[k] = carry % 58;
200
+ carry = carry / 58 | 0;
201
+ }
202
+ length = j;
203
+ }
204
+ let it = size - length;
205
+ while (it < size && b58[it] === 0) {
206
+ it++;
207
+ }
208
+ let out = BASE58_ALPHABET[0].repeat(zeroes);
209
+ for (; it < size; it++) {
210
+ out += BASE58_ALPHABET[b58[it]];
211
+ }
212
+ return out;
213
+ }
169
214
  function deterministicStringify(obj) {
170
215
  if (obj === null || obj === void 0) {
171
216
  return JSON.stringify(obj);
@@ -224,6 +269,29 @@ function validateWalletAddress(address) {
224
269
  }
225
270
  return /^0x[a-fA-F0-9]{40}$/.test(address);
226
271
  }
272
+ function validateUniversalAddress(address, chain) {
273
+ if (!address || typeof address !== "string")
274
+ return false;
275
+ const value = address.trim();
276
+ if (!value)
277
+ return false;
278
+ const chainRef = typeof chain === "string" ? chain.trim().toLowerCase() : "";
279
+ const namespace = chainRef.includes(":") ? chainRef.split(":")[0] : "";
280
+ if (validateWalletAddress(value))
281
+ return true;
282
+ if (namespace === "eip155")
283
+ return false;
284
+ if (namespace === "solana") {
285
+ return /^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(value);
286
+ }
287
+ if (namespace === "bip122") {
288
+ return /^(bc1|tb1|bcrt1)[a-z0-9]{11,87}$/.test(value.toLowerCase()) || /^[13mn2][a-km-zA-HJ-NP-Z1-9]{25,62}$/.test(value);
289
+ }
290
+ if (namespace === "near") {
291
+ return /^[a-z0-9._-]{2,64}$/.test(value);
292
+ }
293
+ return /^[A-Za-z0-9][A-Za-z0-9._:-]{1,127}$/.test(value);
294
+ }
227
295
  function validateTimestamp(timestamp, maxAgeMs = 5 * 60 * 1e3) {
228
296
  if (!timestamp || typeof timestamp !== "number") {
229
297
  return false;
@@ -245,7 +313,7 @@ function createVerificationData(content, owner, reference = null) {
245
313
  };
246
314
  return {
247
315
  content,
248
- owner: owner.toLowerCase(),
316
+ owner: validateWalletAddress(owner) ? owner.toLowerCase() : owner,
249
317
  reference: reference || {
250
318
  // Must be a valid backend enum value; 'content' is not supported.
251
319
  type: "other",
@@ -270,6 +338,261 @@ function deriveDid(address, chainIdOrChain) {
270
338
  return `did:pkh:eip155:${chainContext}:${address.toLowerCase()}`;
271
339
  }
272
340
  }
341
+ async function resolveDID(params, options = {}) {
342
+ const endpointPath = options.endpoint || "/api/v1/profile/did/resolve";
343
+ const apiUrl = typeof options.apiUrl === "string" ? options.apiUrl.trim() : "";
344
+ const resolveEndpoint = (path) => {
345
+ if (!path || typeof path !== "string")
346
+ return null;
347
+ const trimmedPath = path.trim();
348
+ if (!trimmedPath)
349
+ return null;
350
+ if (/^https?:\/\//i.test(trimmedPath))
351
+ return trimmedPath;
352
+ if (trimmedPath.startsWith("/")) {
353
+ if (!apiUrl)
354
+ return trimmedPath;
355
+ try {
356
+ return new URL(trimmedPath, apiUrl.endsWith("/") ? apiUrl : `${apiUrl}/`).toString();
357
+ } catch {
358
+ return null;
359
+ }
360
+ }
361
+ const base = apiUrl || NEUS_CONSTANTS.API_BASE_URL;
362
+ if (!base || typeof base !== "string")
363
+ return null;
364
+ try {
365
+ return new URL(trimmedPath, base.endsWith("/") ? base : `${base}/`).toString();
366
+ } catch {
367
+ return null;
368
+ }
369
+ };
370
+ const endpoint = resolveEndpoint(endpointPath);
371
+ if (!endpoint) {
372
+ throw new SDKError("resolveDID requires a valid endpoint", "INVALID_ENDPOINT");
373
+ }
374
+ const payload = {
375
+ walletAddress: params?.walletAddress,
376
+ chainId: params?.chainId,
377
+ chain: params?.chain
378
+ };
379
+ const isRelative = endpoint.startsWith("/") || !/^https?:\/\//i.test(endpoint);
380
+ const credentialsMode = options.credentials !== void 0 ? options.credentials : isRelative ? "same-origin" : "omit";
381
+ try {
382
+ const response = await fetch(endpoint, {
383
+ method: "POST",
384
+ headers: {
385
+ "Content-Type": "application/json",
386
+ Accept: "application/json",
387
+ ...options.headers || {}
388
+ },
389
+ body: JSON.stringify(payload),
390
+ credentials: credentialsMode
391
+ });
392
+ const json = await response.json().catch(() => null);
393
+ if (!response.ok) {
394
+ const msg = json?.error?.message || json?.error || json?.message || "DID resolution failed";
395
+ throw new SDKError(msg, "DID_RESOLVE_FAILED", json);
396
+ }
397
+ const did = json?.data?.did || json?.did;
398
+ if (!did || typeof did !== "string") {
399
+ throw new SDKError("DID resolution missing DID", "DID_RESOLVE_MISSING", json);
400
+ }
401
+ return { did, data: json?.data || null, raw: json };
402
+ } catch (error) {
403
+ if (error instanceof SDKError)
404
+ throw error;
405
+ throw new SDKError(`DID resolution failed: ${error?.message || error}`, "DID_RESOLVE_FAILED");
406
+ }
407
+ }
408
+ async function standardizeVerificationRequest(params, options = {}) {
409
+ const endpointPath = options.endpoint || "/api/v1/verification/standardize";
410
+ const apiUrl = typeof options.apiUrl === "string" ? options.apiUrl.trim() : "";
411
+ const resolveEndpoint = (path) => {
412
+ if (!path || typeof path !== "string")
413
+ return null;
414
+ const trimmedPath = path.trim();
415
+ if (!trimmedPath)
416
+ return null;
417
+ if (/^https?:\/\//i.test(trimmedPath))
418
+ return trimmedPath;
419
+ if (trimmedPath.startsWith("/")) {
420
+ if (!apiUrl)
421
+ return trimmedPath;
422
+ try {
423
+ return new URL(trimmedPath, apiUrl.endsWith("/") ? apiUrl : `${apiUrl}/`).toString();
424
+ } catch {
425
+ return null;
426
+ }
427
+ }
428
+ const base = apiUrl || NEUS_CONSTANTS.API_BASE_URL;
429
+ if (!base || typeof base !== "string")
430
+ return null;
431
+ try {
432
+ return new URL(trimmedPath, base.endsWith("/") ? base : `${base}/`).toString();
433
+ } catch {
434
+ return null;
435
+ }
436
+ };
437
+ const endpoint = resolveEndpoint(endpointPath);
438
+ if (!endpoint) {
439
+ throw new SDKError("standardizeVerificationRequest requires a valid endpoint", "INVALID_ENDPOINT");
440
+ }
441
+ const isRelative = endpoint.startsWith("/") || !/^https?:\/\//i.test(endpoint);
442
+ const credentialsMode = options.credentials !== void 0 ? options.credentials : isRelative ? "same-origin" : "omit";
443
+ try {
444
+ const response = await fetch(endpoint, {
445
+ method: "POST",
446
+ headers: {
447
+ "Content-Type": "application/json",
448
+ Accept: "application/json",
449
+ ...options.headers || {}
450
+ },
451
+ body: JSON.stringify(params || {}),
452
+ credentials: credentialsMode
453
+ });
454
+ const json = await response.json().catch(() => null);
455
+ if (!response.ok) {
456
+ const msg = json?.error?.message || json?.error || json?.message || "Standardize request failed";
457
+ throw new SDKError(msg, "STANDARDIZE_FAILED", json);
458
+ }
459
+ return json?.data || json;
460
+ } catch (error) {
461
+ if (error instanceof SDKError)
462
+ throw error;
463
+ throw new SDKError(`Standardize request failed: ${error?.message || error}`, "STANDARDIZE_FAILED");
464
+ }
465
+ }
466
+ function resolveZkPassportConfig(overrides = {}) {
467
+ const defaults = {
468
+ provider: "zkpassport",
469
+ scope: "basic_kyc",
470
+ checkSanctions: true,
471
+ requireFaceMatch: true,
472
+ faceMatchMode: "strict"
473
+ };
474
+ return {
475
+ ...defaults,
476
+ ...overrides && typeof overrides === "object" ? overrides : {}
477
+ };
478
+ }
479
+ function toHexUtf8(value) {
480
+ const input = typeof value === "string" ? value : String(value || "");
481
+ const bytes = new TextEncoder().encode(input);
482
+ return `0x${Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("")}`;
483
+ }
484
+ async function signMessage({ provider, message, walletAddress, chain } = {}) {
485
+ const msg = typeof message === "string" ? message : String(message || "");
486
+ if (!msg) {
487
+ throw new SDKError("signMessage: message is required", "INVALID_ARGUMENT");
488
+ }
489
+ const resolvedProvider = provider || (typeof window !== "undefined" && window?.ethereum ? window.ethereum : null);
490
+ if (!resolvedProvider) {
491
+ throw new SDKError("signMessage: provider is required", "SIGNER_UNAVAILABLE");
492
+ }
493
+ const chainStr = typeof chain === "string" && chain.trim().length > 0 ? chain.trim() : "eip155";
494
+ const namespace = chainStr.includes(":") ? chainStr.split(":")[0] || "eip155" : "eip155";
495
+ const resolveAddress = async () => {
496
+ if (typeof walletAddress === "string" && walletAddress.trim().length > 0)
497
+ return walletAddress;
498
+ if (namespace === "solana") {
499
+ if (resolvedProvider?.publicKey && typeof resolvedProvider.publicKey.toBase58 === "function") {
500
+ const pk = resolvedProvider.publicKey.toBase58();
501
+ if (typeof pk === "string" && pk)
502
+ return pk;
503
+ }
504
+ if (typeof resolvedProvider.getAddress === "function") {
505
+ const addr = await resolvedProvider.getAddress().catch(() => null);
506
+ if (typeof addr === "string" && addr)
507
+ return addr;
508
+ }
509
+ if (typeof resolvedProvider.address === "string" && resolvedProvider.address)
510
+ return resolvedProvider.address;
511
+ return null;
512
+ }
513
+ if (typeof resolvedProvider.address === "string" && resolvedProvider.address)
514
+ return resolvedProvider.address;
515
+ if (typeof resolvedProvider.getAddress === "function")
516
+ return await resolvedProvider.getAddress();
517
+ if (typeof resolvedProvider.request === "function") {
518
+ let accounts = await resolvedProvider.request({ method: "eth_accounts" }).catch(() => []);
519
+ if (!Array.isArray(accounts) || accounts.length === 0) {
520
+ accounts = await resolvedProvider.request({ method: "eth_requestAccounts" }).catch(() => []);
521
+ }
522
+ if (Array.isArray(accounts) && accounts[0])
523
+ return accounts[0];
524
+ }
525
+ return null;
526
+ };
527
+ if (namespace !== "eip155") {
528
+ if (typeof resolvedProvider.signMessage === "function") {
529
+ const encoded = typeof msg === "string" ? new TextEncoder().encode(msg) : msg;
530
+ const result = await resolvedProvider.signMessage(encoded);
531
+ if (typeof result === "string" && result)
532
+ return result;
533
+ if (result instanceof Uint8Array)
534
+ return encodeBase58Bytes(result);
535
+ if (result instanceof ArrayBuffer)
536
+ return encodeBase58Bytes(new Uint8Array(result));
537
+ if (ArrayBuffer.isView(result))
538
+ return encodeBase58Bytes(result);
539
+ if (typeof Buffer !== "undefined" && typeof Buffer.isBuffer === "function" && Buffer.isBuffer(result))
540
+ return encodeBase58Bytes(result);
541
+ }
542
+ throw new SDKError("Non-EVM signing requires provider.signMessage", "SIGNER_UNAVAILABLE");
543
+ }
544
+ const address = await resolveAddress();
545
+ if (typeof resolvedProvider.request === "function" && address) {
546
+ let firstPersonalSignError = null;
547
+ try {
548
+ const sig = await resolvedProvider.request({ method: "personal_sign", params: [msg, address] });
549
+ if (typeof sig === "string" && sig)
550
+ return sig;
551
+ } catch (error) {
552
+ firstPersonalSignError = error;
553
+ }
554
+ let secondPersonalSignError = null;
555
+ try {
556
+ const sig = await resolvedProvider.request({ method: "personal_sign", params: [address, msg] });
557
+ if (typeof sig === "string" && sig)
558
+ return sig;
559
+ } catch (error) {
560
+ secondPersonalSignError = error;
561
+ const signatureErrorMessage = String(
562
+ error?.message || error?.reason || firstPersonalSignError?.message || firstPersonalSignError?.reason || ""
563
+ ).toLowerCase();
564
+ const needsHex = /byte|bytes|invalid byte sequence|encoding|non-hex/i.test(signatureErrorMessage);
565
+ if (needsHex) {
566
+ try {
567
+ const hexMsg = toHexUtf8(msg);
568
+ const sig = await resolvedProvider.request({ method: "personal_sign", params: [hexMsg, address] });
569
+ if (typeof sig === "string" && sig)
570
+ return sig;
571
+ } catch {
572
+ }
573
+ }
574
+ }
575
+ try {
576
+ const sig = await resolvedProvider.request({ method: "eth_sign", params: [address, msg] });
577
+ if (typeof sig === "string" && sig)
578
+ return sig;
579
+ } catch {
580
+ }
581
+ if (secondPersonalSignError || firstPersonalSignError) {
582
+ const lastError = secondPersonalSignError || firstPersonalSignError;
583
+ const isUserRejection = [4001, "ACTION_REJECTED"].includes(lastError?.code);
584
+ if (isUserRejection) {
585
+ throw lastError;
586
+ }
587
+ }
588
+ }
589
+ if (typeof resolvedProvider.signMessage === "function") {
590
+ const result = await resolvedProvider.signMessage(msg);
591
+ if (typeof result === "string" && result)
592
+ return result;
593
+ }
594
+ throw new SDKError("Unable to sign message with provided wallet/provider", "SIGNER_UNAVAILABLE");
595
+ }
273
596
  function isTerminalStatus(status) {
274
597
  if (!status || typeof status !== "string")
275
598
  return false;
@@ -461,7 +784,7 @@ function validateVerifierPayload(verifierId, data) {
461
784
  result.missing.push(key);
462
785
  });
463
786
  if (!("ownerAddress" in data)) {
464
- result.warnings.push("ownerAddress omitted (most deployments default to the signed walletAddress)");
787
+ result.warnings.push("ownerAddress omitted (defaults to the signed walletAddress)");
465
788
  }
466
789
  } else if (id === "token-holding") {
467
790
  ["contractAddress", "minBalance", "chainId"].forEach((key) => {
@@ -469,7 +792,7 @@ function validateVerifierPayload(verifierId, data) {
469
792
  result.missing.push(key);
470
793
  });
471
794
  if (!("ownerAddress" in data)) {
472
- result.warnings.push("ownerAddress omitted (most deployments default to the signed walletAddress)");
795
+ result.warnings.push("ownerAddress omitted (defaults to the signed walletAddress)");
473
796
  }
474
797
  } else if (id === "ownership-basic") {
475
798
  if (!("owner" in data))
@@ -606,10 +929,12 @@ function validateSignatureComponents({ walletAddress, signature, signedTimestamp
606
929
  }
607
930
  return result;
608
931
  }
609
- var StatusPoller, NEUS_CONSTANTS;
932
+ var BASE58_ALPHABET, StatusPoller, NEUS_CONSTANTS;
610
933
  var init_utils = __esm({
611
934
  "utils.js"() {
935
+ "use strict";
612
936
  init_errors();
937
+ BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
613
938
  StatusPoller = class {
614
939
  constructor(client, qHash, options = {}) {
615
940
  this.client = client;
@@ -714,23 +1039,42 @@ __export(client_exports, {
714
1039
  NeusClient: () => NeusClient,
715
1040
  constructVerificationMessage: () => constructVerificationMessage
716
1041
  });
717
- var validateVerifierData, NeusClient;
1042
+ var FALLBACK_PUBLIC_VERIFIERS, INTERACTIVE_VERIFIERS, EVM_ADDRESS_RE, validateVerifierData, NeusClient;
718
1043
  var init_client = __esm({
719
1044
  "client.js"() {
1045
+ "use strict";
720
1046
  init_errors();
721
1047
  init_utils();
1048
+ FALLBACK_PUBLIC_VERIFIERS = [
1049
+ "ownership-basic",
1050
+ "ownership-pseudonym",
1051
+ "ownership-dns-txt",
1052
+ "ownership-social",
1053
+ "ownership-org-oauth",
1054
+ "contract-ownership",
1055
+ "nft-ownership",
1056
+ "token-holding",
1057
+ "wallet-link",
1058
+ "wallet-risk",
1059
+ "proof-of-human",
1060
+ "agent-identity",
1061
+ "agent-delegation",
1062
+ "ai-content-moderation"
1063
+ ];
1064
+ INTERACTIVE_VERIFIERS = /* @__PURE__ */ new Set([
1065
+ "ownership-social",
1066
+ "ownership-org-oauth",
1067
+ "proof-of-human"
1068
+ ]);
1069
+ EVM_ADDRESS_RE = /^0x[a-fA-F0-9]{40}$/;
722
1070
  validateVerifierData = (verifierId, data) => {
723
1071
  if (!data || typeof data !== "object") {
724
1072
  return { valid: false, error: "Data object is required" };
725
1073
  }
726
- const ownerField = verifierId === "nft-ownership" || verifierId === "token-holding" ? "ownerAddress" : "owner";
727
- if (data[ownerField] && !validateWalletAddress(data[ownerField])) {
728
- return { valid: false, error: `Invalid ${ownerField} address` };
729
- }
730
1074
  switch (verifierId) {
731
1075
  case "ownership-basic":
732
- if (!data.owner || !validateWalletAddress(data.owner)) {
733
- return { valid: false, error: "owner (wallet address) is required" };
1076
+ if (!data.owner || !validateUniversalAddress(data.owner, typeof data.chain === "string" ? data.chain : void 0)) {
1077
+ return { valid: false, error: "owner (universal wallet address) is required" };
734
1078
  }
735
1079
  if (data.content !== void 0 && data.content !== null) {
736
1080
  if (typeof data.content !== "string") {
@@ -856,17 +1200,20 @@ var init_client = __esm({
856
1200
  }
857
1201
  break;
858
1202
  case "wallet-link":
859
- if (!data.primaryWalletAddress || !validateWalletAddress(data.primaryWalletAddress)) {
1203
+ if (!data.primaryWalletAddress || !validateUniversalAddress(data.primaryWalletAddress, data.chain)) {
860
1204
  return { valid: false, error: "primaryWalletAddress is required" };
861
1205
  }
862
- if (!data.secondaryWalletAddress || !validateWalletAddress(data.secondaryWalletAddress)) {
1206
+ if (!data.secondaryWalletAddress || !validateUniversalAddress(data.secondaryWalletAddress, data.chain)) {
863
1207
  return { valid: false, error: "secondaryWalletAddress is required" };
864
1208
  }
865
1209
  if (!data.signature || typeof data.signature !== "string") {
866
1210
  return { valid: false, error: "signature is required (signed by secondary wallet)" };
867
1211
  }
868
- if (typeof data.chainId !== "number") {
869
- return { valid: false, error: "chainId is required" };
1212
+ if (typeof data.chain !== "string" || !/^[a-z0-9]+:[^\s]+$/.test(data.chain)) {
1213
+ return { valid: false, error: "chain is required (namespace:reference)" };
1214
+ }
1215
+ if (typeof data.signatureMethod !== "string" || !data.signatureMethod.trim()) {
1216
+ return { valid: false, error: "signatureMethod is required" };
870
1217
  }
871
1218
  if (typeof data.signedTimestamp !== "number") {
872
1219
  return { valid: false, error: "signedTimestamp is required" };
@@ -961,7 +1308,7 @@ var init_client = __esm({
961
1308
  }
962
1309
  break;
963
1310
  case "wallet-risk":
964
- if (data.walletAddress && !validateWalletAddress(data.walletAddress)) {
1311
+ if (data.walletAddress && !validateUniversalAddress(data.walletAddress, data.chain)) {
965
1312
  return { valid: false, error: "Invalid walletAddress" };
966
1313
  }
967
1314
  break;
@@ -993,6 +1340,26 @@ var init_client = __esm({
993
1340
  if (typeof this.config.apiKey === "string" && this.config.apiKey.trim().length > 0) {
994
1341
  this.defaultHeaders["Authorization"] = `Bearer ${this.config.apiKey.trim()}`;
995
1342
  }
1343
+ if (typeof this.config.appId === "string" && this.config.appId.trim().length > 0) {
1344
+ this.defaultHeaders["X-Neus-App"] = this.config.appId.trim();
1345
+ }
1346
+ if (typeof this.config.sponsorGrant === "string" && this.config.sponsorGrant.trim().length > 0) {
1347
+ this.defaultHeaders["X-Sponsor-Grant"] = this.config.sponsorGrant.trim();
1348
+ }
1349
+ if (typeof this.config.paymentSignature === "string" && this.config.paymentSignature.trim().length > 0) {
1350
+ this.defaultHeaders["PAYMENT-SIGNATURE"] = this.config.paymentSignature.trim();
1351
+ }
1352
+ if (this.config.extraHeaders && typeof this.config.extraHeaders === "object") {
1353
+ for (const [k, v] of Object.entries(this.config.extraHeaders)) {
1354
+ if (!k || v === void 0 || v === null)
1355
+ continue;
1356
+ const key = String(k).trim();
1357
+ const value = String(v).trim();
1358
+ if (!key || !value)
1359
+ continue;
1360
+ this.defaultHeaders[key] = value;
1361
+ }
1362
+ }
996
1363
  try {
997
1364
  if (typeof window !== "undefined" && window.location && window.location.origin) {
998
1365
  this.defaultHeaders["X-Client-Origin"] = window.location.origin;
@@ -1000,6 +1367,122 @@ var init_client = __esm({
1000
1367
  } catch {
1001
1368
  }
1002
1369
  }
1370
+ _getHubChainId() {
1371
+ const configured = Number(this.config?.hubChainId);
1372
+ if (Number.isFinite(configured) && configured > 0)
1373
+ return Math.floor(configured);
1374
+ return NEUS_CONSTANTS.HUB_CHAIN_ID;
1375
+ }
1376
+ _normalizeIdentity(value) {
1377
+ let raw = String(value || "").trim();
1378
+ if (!raw)
1379
+ return "";
1380
+ const didMatch = raw.match(/^did:pkh:([^:]+):([^:]+):(.+)$/i);
1381
+ if (didMatch && didMatch[3]) {
1382
+ raw = String(didMatch[3]).trim();
1383
+ }
1384
+ return EVM_ADDRESS_RE.test(raw) ? raw.toLowerCase() : raw;
1385
+ }
1386
+ _inferChainForAddress(address, explicitChain) {
1387
+ if (typeof explicitChain === "string" && explicitChain.includes(":"))
1388
+ return explicitChain.trim();
1389
+ const raw = String(address || "").trim();
1390
+ const didMatch = raw.match(/^did:pkh:([^:]+):([^:]+):(.+)$/i);
1391
+ if (didMatch && didMatch[1] && didMatch[2]) {
1392
+ return `${didMatch[1]}:${didMatch[2]}`;
1393
+ }
1394
+ if (EVM_ADDRESS_RE.test(raw)) {
1395
+ return `eip155:${this._getHubChainId()}`;
1396
+ }
1397
+ return "solana:mainnet";
1398
+ }
1399
+ async _resolveWalletSigner(wallet) {
1400
+ if (!wallet) {
1401
+ throw new ConfigurationError("No wallet provider available");
1402
+ }
1403
+ if (wallet.address) {
1404
+ return { signerWalletAddress: wallet.address, provider: wallet };
1405
+ }
1406
+ if (wallet.publicKey && typeof wallet.publicKey.toBase58 === "function") {
1407
+ return { signerWalletAddress: wallet.publicKey.toBase58(), provider: wallet };
1408
+ }
1409
+ if (typeof wallet.getAddress === "function") {
1410
+ const signerWalletAddress = await wallet.getAddress().catch(() => null);
1411
+ return { signerWalletAddress, provider: wallet };
1412
+ }
1413
+ if (wallet.selectedAddress || wallet.request) {
1414
+ const provider = wallet;
1415
+ if (wallet.selectedAddress) {
1416
+ return { signerWalletAddress: wallet.selectedAddress, provider };
1417
+ }
1418
+ const accounts = await provider.request({ method: "eth_accounts" });
1419
+ if (!accounts || accounts.length === 0) {
1420
+ throw new ConfigurationError("No wallet accounts available");
1421
+ }
1422
+ return { signerWalletAddress: accounts[0], provider };
1423
+ }
1424
+ throw new ConfigurationError("Invalid wallet provider");
1425
+ }
1426
+ _getDefaultBrowserWallet() {
1427
+ if (typeof window === "undefined")
1428
+ return null;
1429
+ return window.ethereum || window.solana || window.phantom && window.phantom.solana || null;
1430
+ }
1431
+ async _buildPrivateGateAuth({ address, wallet, chain, signatureMethod } = {}) {
1432
+ const providerWallet = wallet || this._getDefaultBrowserWallet();
1433
+ const { signerWalletAddress, provider } = await this._resolveWalletSigner(providerWallet);
1434
+ if (!signerWalletAddress || typeof signerWalletAddress !== "string") {
1435
+ throw new ConfigurationError("No wallet accounts available");
1436
+ }
1437
+ const normalizedSigner = this._normalizeIdentity(signerWalletAddress);
1438
+ const normalizedAddress = this._normalizeIdentity(address);
1439
+ if (!normalizedSigner || normalizedSigner !== normalizedAddress) {
1440
+ throw new ValidationError("wallet must match address when includePrivate=true");
1441
+ }
1442
+ const signerIsEvm = EVM_ADDRESS_RE.test(normalizedSigner);
1443
+ const resolvedChain = this._inferChainForAddress(normalizedSigner, chain);
1444
+ const resolvedSignatureMethod = typeof signatureMethod === "string" && signatureMethod.trim() ? signatureMethod.trim() : signerIsEvm ? "eip191" : "ed25519";
1445
+ const signedTimestamp = Date.now();
1446
+ const message = constructVerificationMessage({
1447
+ walletAddress: signerWalletAddress,
1448
+ signedTimestamp,
1449
+ data: { action: "gate_check_private_proofs", walletAddress: normalizedAddress },
1450
+ verifierIds: ["ownership-basic"],
1451
+ ...signerIsEvm ? { chainId: this._getHubChainId() } : { chain: resolvedChain }
1452
+ });
1453
+ let signature;
1454
+ try {
1455
+ signature = await signMessage({
1456
+ provider,
1457
+ message,
1458
+ walletAddress: signerWalletAddress,
1459
+ ...signerIsEvm ? {} : { chain: resolvedChain }
1460
+ });
1461
+ } catch (error) {
1462
+ if (error.code === 4001) {
1463
+ throw new ValidationError("User rejected signature request");
1464
+ }
1465
+ throw new ValidationError(`Failed to sign message: ${error.message}`);
1466
+ }
1467
+ return {
1468
+ walletAddress: signerWalletAddress,
1469
+ signature,
1470
+ signedTimestamp,
1471
+ ...signerIsEvm ? {} : { chain: resolvedChain, signatureMethod: resolvedSignatureMethod }
1472
+ };
1473
+ }
1474
+ async createGatePrivateAuth(params = {}) {
1475
+ const address = (params.address || "").toString();
1476
+ if (!validateUniversalAddress(address, params.chain)) {
1477
+ throw new ValidationError("Valid address is required");
1478
+ }
1479
+ return this._buildPrivateGateAuth({
1480
+ address,
1481
+ wallet: params.wallet,
1482
+ chain: params.chain,
1483
+ signatureMethod: params.signatureMethod
1484
+ });
1485
+ }
1003
1486
  // ============================================================================
1004
1487
  // CORE VERIFICATION METHODS
1005
1488
  // ============================================================================
@@ -1021,7 +1504,7 @@ var init_client = __esm({
1021
1504
  * @param {string} [params.verifier] - Verifier ID (auto path)
1022
1505
  * @param {string} [params.content] - Content/description (auto path)
1023
1506
  * @param {Object} [params.wallet] - Optional injected wallet/provider (auto path)
1024
- * @returns {Promise<Object>} Verification result with qHash
1507
+ * @returns {Promise<Object>} Verification result with proofId (qHash is a deprecated alias)
1025
1508
  *
1026
1509
  * @example
1027
1510
  * const proof = await client.verify({
@@ -1046,7 +1529,7 @@ var init_client = __esm({
1046
1529
  * @param {Object} [params.data] - Structured verification data
1047
1530
  * @param {Object} [params.wallet] - Wallet provider
1048
1531
  * @param {Object} [params.options] - Additional options
1049
- * @returns {Promise<Object>} Verification result with qHash
1532
+ * @returns {Promise<Object>} Verification result with proofId (qHash is a deprecated alias)
1050
1533
  *
1051
1534
  * @example
1052
1535
  * // Simple ownership proof
@@ -1062,25 +1545,23 @@ var init_client = __esm({
1062
1545
  if (verifier === "ownership-basic" && !data2 && (!content || typeof content !== "string")) {
1063
1546
  throw new ValidationError("content is required and must be a string (or use data param with owner + reference)");
1064
1547
  }
1065
- const validVerifiers = [
1066
- "ownership-basic",
1067
- "ownership-pseudonym",
1068
- // Pseudonymous identity (public)
1069
- "nft-ownership",
1070
- "token-holding",
1071
- "ownership-dns-txt",
1072
- "wallet-link",
1073
- "contract-ownership",
1074
- "wallet-risk",
1075
- // Wallet risk assessment (public)
1076
- // AI & Agent verifiers (ERC-8004 aligned)
1077
- "agent-identity",
1078
- "agent-delegation",
1079
- "ai-content-moderation"
1080
- ];
1548
+ let validVerifiers = FALLBACK_PUBLIC_VERIFIERS;
1549
+ try {
1550
+ const discovered = await this.getVerifiers();
1551
+ if (Array.isArray(discovered) && discovered.length > 0) {
1552
+ validVerifiers = discovered;
1553
+ }
1554
+ } catch {
1555
+ }
1081
1556
  if (!validVerifiers.includes(verifier)) {
1082
1557
  throw new ValidationError(`Invalid verifier '${verifier}'. Must be one of: ${validVerifiers.join(", ")}.`);
1083
1558
  }
1559
+ if (INTERACTIVE_VERIFIERS.has(verifier)) {
1560
+ const hostedCheckoutUrl = options2?.hostedCheckoutUrl || "https://neus.network/verify";
1561
+ throw new ValidationError(
1562
+ `${verifier} requires hosted interactive checkout. Use VerifyGate or redirect to ${hostedCheckoutUrl}.`
1563
+ );
1564
+ }
1084
1565
  const requiresDataParam = [
1085
1566
  "ownership-dns-txt",
1086
1567
  "wallet-link",
@@ -1098,8 +1579,12 @@ var init_client = __esm({
1098
1579
  }
1099
1580
  let walletAddress2, provider;
1100
1581
  if (wallet) {
1101
- walletAddress2 = wallet.address || wallet.selectedAddress;
1582
+ walletAddress2 = wallet.address || wallet.selectedAddress || wallet.walletAddress || (typeof wallet.getAddress === "function" ? await wallet.getAddress() : null);
1102
1583
  provider = wallet.provider || wallet;
1584
+ if (!walletAddress2 && provider && typeof provider.request === "function") {
1585
+ const accounts = await provider.request({ method: "eth_accounts" });
1586
+ walletAddress2 = Array.isArray(accounts) ? accounts[0] : null;
1587
+ }
1103
1588
  } else {
1104
1589
  if (typeof window === "undefined" || !window.ethereum) {
1105
1590
  throw new ConfigurationError("No Web3 wallet detected. Please install MetaMask or provide wallet parameter.");
@@ -1175,14 +1660,18 @@ var init_client = __esm({
1175
1660
  if (!data2?.signature) {
1176
1661
  throw new ValidationError("wallet-link requires signature in data parameter (signed by secondary wallet)");
1177
1662
  }
1178
- if (typeof data2?.chainId !== "number") {
1179
- throw new ValidationError("wallet-link requires chainId (number) in data parameter");
1663
+ if (typeof data2?.chain !== "string" || !/^[a-z0-9]+:[^\s]+$/.test(data2.chain)) {
1664
+ throw new ValidationError("wallet-link requires chain (namespace:reference) in data parameter");
1665
+ }
1666
+ if (typeof data2?.signatureMethod !== "string" || !data2.signatureMethod.trim()) {
1667
+ throw new ValidationError("wallet-link requires signatureMethod in data parameter");
1180
1668
  }
1181
1669
  verificationData = {
1182
1670
  primaryWalletAddress: walletAddress2,
1183
1671
  secondaryWalletAddress: data2.secondaryWalletAddress,
1184
1672
  signature: data2.signature,
1185
- chainId: data2.chainId,
1673
+ chain: data2.chain,
1674
+ signatureMethod: data2.signatureMethod,
1186
1675
  signedTimestamp: data2?.signedTimestamp || Date.now()
1187
1676
  };
1188
1677
  } else if (verifier === "contract-ownership") {
@@ -1271,12 +1760,12 @@ var init_client = __esm({
1271
1760
  signedTimestamp: signedTimestamp2,
1272
1761
  data: verificationData,
1273
1762
  verifierIds: verifierIds2,
1274
- chainId: NEUS_CONSTANTS.HUB_CHAIN_ID
1763
+ chainId: this._getHubChainId()
1275
1764
  // Protocol-managed chain
1276
1765
  });
1277
1766
  let signature2;
1278
1767
  try {
1279
- const toHexUtf8 = (s) => {
1768
+ const toHexUtf82 = (s) => {
1280
1769
  try {
1281
1770
  const enc = new TextEncoder();
1282
1771
  const bytes = enc.encode(s);
@@ -1312,7 +1801,7 @@ var init_client = __esm({
1312
1801
  })();
1313
1802
  if (isFarcasterWallet) {
1314
1803
  try {
1315
- const hexMsg = toHexUtf8(message);
1804
+ const hexMsg = toHexUtf82(message);
1316
1805
  signature2 = await provider.request({ method: "personal_sign", params: [hexMsg, walletAddress2] });
1317
1806
  } catch (e) {
1318
1807
  }
@@ -1361,7 +1850,7 @@ ${bytes.length}`;
1361
1850
  }
1362
1851
  } else if (needsHex) {
1363
1852
  this._log("Retrying personal_sign with hex-encoded message");
1364
- const hexMsg = toHexUtf8(message);
1853
+ const hexMsg = toHexUtf82(message);
1365
1854
  signature2 = await provider.request({ method: "personal_sign", params: [hexMsg, walletAddress2] });
1366
1855
  } else {
1367
1856
  throw e;
@@ -1459,18 +1948,18 @@ ${bytes.length}`;
1459
1948
  /**
1460
1949
  * Get verification status
1461
1950
  *
1462
- * @param {string} qHash - Verification ID (qHash or proofId)
1951
+ * @param {string} proofId - Proof ID (standard). `qHash` is a deprecated alias (same value).
1463
1952
  * @returns {Promise<Object>} Verification status and data
1464
1953
  *
1465
1954
  * @example
1466
1955
  * const result = await client.getStatus('0x...');
1467
1956
  * console.log('Status:', result.status);
1468
1957
  */
1469
- async getStatus(qHash) {
1470
- if (!qHash || typeof qHash !== "string") {
1471
- throw new ValidationError("qHash is required");
1958
+ async getStatus(proofId) {
1959
+ if (!proofId || typeof proofId !== "string") {
1960
+ throw new ValidationError("proofId is required");
1472
1961
  }
1473
- const response = await this._makeRequest("GET", `/api/v1/verification/status/${qHash}`);
1962
+ const response = await this._makeRequest("GET", `/api/v1/verification/status/${proofId}`);
1474
1963
  if (!response.success) {
1475
1964
  throw new ApiError(`Failed to get status: ${response.error?.message || "Unknown error"}`, response.error);
1476
1965
  }
@@ -1479,70 +1968,72 @@ ${bytes.length}`;
1479
1968
  /**
1480
1969
  * Get private proof status with wallet signature
1481
1970
  *
1482
- * @param {string} qHash - Verification ID
1971
+ * @param {string} proofId - Proof ID (standard). `qHash` is a deprecated alias (same value).
1483
1972
  * @param {Object} wallet - Wallet provider (window.ethereum or ethers Wallet)
1484
1973
  * @returns {Promise<Object>} Private verification status and data
1485
1974
  *
1486
1975
  * @example
1487
1976
  * // Access private proof
1488
- * const privateData = await client.getPrivateStatus(qHash, window.ethereum);
1977
+ * const privateData = await client.getPrivateStatus(proofId, window.ethereum);
1489
1978
  */
1490
- async getPrivateStatus(qHash, wallet = null) {
1491
- if (!qHash || typeof qHash !== "string") {
1492
- throw new ValidationError("qHash is required");
1979
+ async getPrivateStatus(proofId, wallet = null) {
1980
+ if (!proofId || typeof proofId !== "string") {
1981
+ throw new ValidationError("proofId is required");
1493
1982
  }
1494
- if (!wallet) {
1495
- if (typeof window === "undefined" || !window.ethereum) {
1496
- throw new ConfigurationError("No wallet provider available");
1983
+ const isPreSignedAuth = wallet && typeof wallet === "object" && typeof wallet.walletAddress === "string" && typeof wallet.signature === "string" && typeof wallet.signedTimestamp === "number";
1984
+ if (isPreSignedAuth) {
1985
+ const auth = wallet;
1986
+ const headers = {
1987
+ "x-wallet-address": String(auth.walletAddress),
1988
+ "x-signature": String(auth.signature),
1989
+ "x-signed-timestamp": String(auth.signedTimestamp),
1990
+ ...typeof auth.chain === "string" && auth.chain.trim() ? { "x-chain": auth.chain.trim() } : {},
1991
+ ...typeof auth.signatureMethod === "string" && auth.signatureMethod.trim() ? { "x-signature-method": auth.signatureMethod.trim() } : {}
1992
+ };
1993
+ const response2 = await this._makeRequest("GET", `/api/v1/verification/status/${proofId}`, null, headers);
1994
+ if (!response2.success) {
1995
+ throw new ApiError(
1996
+ `Failed to access private proof: ${response2.error?.message || "Unauthorized"}`,
1997
+ response2.error
1998
+ );
1497
1999
  }
1498
- wallet = window.ethereum;
2000
+ return this._formatResponse(response2);
1499
2001
  }
1500
- let walletAddress, provider;
1501
- if (wallet.address) {
1502
- walletAddress = wallet.address;
1503
- provider = wallet;
1504
- } else if (wallet.selectedAddress || wallet.request) {
1505
- provider = wallet;
1506
- if (wallet.selectedAddress) {
1507
- walletAddress = wallet.selectedAddress;
1508
- } else {
1509
- const accounts = await provider.request({ method: "eth_accounts" });
1510
- if (!accounts || accounts.length === 0) {
1511
- throw new ConfigurationError("No wallet accounts available");
1512
- }
1513
- walletAddress = accounts[0];
1514
- }
1515
- } else {
1516
- throw new ConfigurationError("Invalid wallet provider");
2002
+ const providerWallet = wallet || this._getDefaultBrowserWallet();
2003
+ const { signerWalletAddress: walletAddress, provider } = await this._resolveWalletSigner(providerWallet);
2004
+ if (!walletAddress || typeof walletAddress !== "string") {
2005
+ throw new ConfigurationError("No wallet accounts available");
1517
2006
  }
2007
+ const signerIsEvm = EVM_ADDRESS_RE.test(this._normalizeIdentity(walletAddress));
2008
+ const chain = this._inferChainForAddress(walletAddress);
2009
+ const signatureMethod = signerIsEvm ? "eip191" : "ed25519";
1518
2010
  const signedTimestamp = Date.now();
1519
2011
  const message = constructVerificationMessage({
1520
2012
  walletAddress,
1521
2013
  signedTimestamp,
1522
- data: { action: "access_private_proof", qHash },
2014
+ data: { action: "access_private_proof", qHash: proofId },
1523
2015
  verifierIds: ["ownership-basic"],
1524
- chainId: NEUS_CONSTANTS.HUB_CHAIN_ID
2016
+ ...signerIsEvm ? { chainId: this._getHubChainId() } : { chain }
1525
2017
  });
1526
2018
  let signature;
1527
2019
  try {
1528
- if (provider.signMessage) {
1529
- signature = await provider.signMessage(message);
1530
- } else {
1531
- signature = await provider.request({
1532
- method: "personal_sign",
1533
- params: [message, walletAddress]
1534
- });
1535
- }
2020
+ signature = await signMessage({
2021
+ provider,
2022
+ message,
2023
+ walletAddress,
2024
+ ...signerIsEvm ? {} : { chain }
2025
+ });
1536
2026
  } catch (error) {
1537
2027
  if (error.code === 4001) {
1538
2028
  throw new ValidationError("User rejected signature request");
1539
2029
  }
1540
2030
  throw new ValidationError(`Failed to sign message: ${error.message}`);
1541
2031
  }
1542
- const response = await this._makeRequest("GET", `/api/v1/verification/status/${qHash}`, null, {
2032
+ const response = await this._makeRequest("GET", `/api/v1/verification/status/${proofId}`, null, {
1543
2033
  "x-wallet-address": walletAddress,
1544
2034
  "x-signature": signature,
1545
- "x-signed-timestamp": signedTimestamp.toString()
2035
+ "x-signed-timestamp": signedTimestamp.toString(),
2036
+ ...signerIsEvm ? {} : { "x-chain": chain, "x-signature-method": signatureMethod }
1546
2037
  });
1547
2038
  if (!response.success) {
1548
2039
  throw new ApiError(
@@ -1583,7 +2074,7 @@ ${bytes.length}`;
1583
2074
  * Polls the verification status until it reaches a terminal state (completed or failed).
1584
2075
  * Useful for providing real-time feedback to users during verification.
1585
2076
  *
1586
- * @param {string} qHash - Verification ID to poll
2077
+ * @param {string} proofId - Proof ID to poll (standard). `qHash` is a deprecated alias (same value).
1587
2078
  * @param {Object} [options] - Polling options
1588
2079
  * @param {number} [options.interval=5000] - Polling interval in ms
1589
2080
  * @param {number} [options.timeout=120000] - Total timeout in ms
@@ -1591,7 +2082,7 @@ ${bytes.length}`;
1591
2082
  * @returns {Promise<Object>} Final verification status
1592
2083
  *
1593
2084
  * @example
1594
- * const finalStatus = await client.pollProofStatus(qHash, {
2085
+ * const finalStatus = await client.pollProofStatus(proofId, {
1595
2086
  * interval: 3000,
1596
2087
  * timeout: 60000,
1597
2088
  * onProgress: (status) => {
@@ -1602,20 +2093,20 @@ ${bytes.length}`;
1602
2093
  * }
1603
2094
  * });
1604
2095
  */
1605
- async pollProofStatus(qHash, options = {}) {
2096
+ async pollProofStatus(proofId, options = {}) {
1606
2097
  const {
1607
2098
  interval = 5e3,
1608
2099
  timeout = 12e4,
1609
2100
  onProgress
1610
2101
  } = options;
1611
- if (!qHash || typeof qHash !== "string") {
1612
- throw new ValidationError("qHash is required");
2102
+ if (!proofId || typeof proofId !== "string") {
2103
+ throw new ValidationError("proofId is required");
1613
2104
  }
1614
2105
  const startTime = Date.now();
1615
2106
  let consecutiveRateLimits = 0;
1616
2107
  while (Date.now() - startTime < timeout) {
1617
2108
  try {
1618
- const status = await this.getStatus(qHash);
2109
+ const status = await this.getStatus(proofId);
1619
2110
  consecutiveRateLimits = 0;
1620
2111
  if (onProgress && typeof onProgress === "function") {
1621
2112
  onProgress(status.data || status);
@@ -1663,70 +2154,51 @@ ${bytes.length}`;
1663
2154
  }
1664
2155
  }
1665
2156
  /** Revoke your own proof (owner-signed) */
1666
- async revokeOwnProof(qHash, wallet) {
1667
- if (!qHash || typeof qHash !== "string") {
1668
- throw new ValidationError("qHash is required");
2157
+ async revokeOwnProof(proofId, wallet) {
2158
+ if (!proofId || typeof proofId !== "string") {
2159
+ throw new ValidationError("proofId is required");
2160
+ }
2161
+ const providerWallet = wallet || this._getDefaultBrowserWallet();
2162
+ const { signerWalletAddress: address, provider } = await this._resolveWalletSigner(providerWallet);
2163
+ if (!address || typeof address !== "string") {
2164
+ throw new ConfigurationError("No wallet accounts available");
1669
2165
  }
1670
- const address = wallet?.address || await this._getWalletAddress();
2166
+ const signerIsEvm = EVM_ADDRESS_RE.test(this._normalizeIdentity(address));
2167
+ const chain = this._inferChainForAddress(address);
2168
+ const signatureMethod = signerIsEvm ? "eip191" : "ed25519";
1671
2169
  const signedTimestamp = Date.now();
1672
- const hubChainId = NEUS_CONSTANTS.HUB_CHAIN_ID;
1673
2170
  const message = constructVerificationMessage({
1674
2171
  walletAddress: address,
1675
2172
  signedTimestamp,
1676
- data: { action: "revoke_proof", qHash },
2173
+ // Keep wire payload key `qHash` for backwards compatibility.
2174
+ data: { action: "revoke_proof", qHash: proofId },
1677
2175
  verifierIds: ["ownership-basic"],
1678
- chainId: hubChainId
2176
+ ...signerIsEvm ? { chainId: this._getHubChainId() } : { chain }
1679
2177
  });
1680
2178
  let signature;
1681
2179
  try {
1682
- const toHexUtf8 = (s) => {
1683
- const enc = new TextEncoder();
1684
- const bytes = enc.encode(s);
1685
- let hex = "0x";
1686
- for (let i = 0; i < bytes.length; i++)
1687
- hex += bytes[i].toString(16).padStart(2, "0");
1688
- return hex;
1689
- };
1690
- const isFarcasterWallet = (() => {
1691
- if (typeof window === "undefined")
1692
- return false;
1693
- try {
1694
- const w = window;
1695
- const fc = w.farcaster;
1696
- if (!fc || !fc.context)
1697
- return false;
1698
- const fcProvider = fc.provider || fc.walletProvider || fc.context && fc.context.walletProvider;
1699
- if (fcProvider === w.ethereum)
1700
- return true;
1701
- if (w.mini && w.mini.wallet === w.ethereum && fc && fc.context)
1702
- return true;
1703
- if (w.ethereum && fc && fc.context)
1704
- return true;
1705
- } catch {
1706
- }
1707
- return false;
1708
- })();
1709
- if (isFarcasterWallet) {
1710
- try {
1711
- const hexMsg = toHexUtf8(message);
1712
- signature = await window.ethereum.request({ method: "personal_sign", params: [hexMsg, address] });
1713
- } catch {
1714
- }
1715
- }
1716
- if (!signature) {
1717
- signature = await window.ethereum.request({ method: "personal_sign", params: [message, address] });
1718
- }
2180
+ signature = await signMessage({
2181
+ provider,
2182
+ message,
2183
+ walletAddress: address,
2184
+ ...signerIsEvm ? {} : { chain }
2185
+ });
1719
2186
  } catch (error) {
1720
2187
  if (error.code === 4001) {
1721
2188
  throw new ValidationError("User rejected revocation signature");
1722
2189
  }
1723
2190
  throw new ValidationError(`Failed to sign revocation: ${error.message}`);
1724
2191
  }
1725
- const res = await fetch(`${this.config.apiUrl}/api/v1/proofs/${qHash}/revoke-self`, {
2192
+ const res = await fetch(`${this.config.apiUrl}/api/v1/proofs/${proofId}/revoke-self`, {
1726
2193
  method: "POST",
1727
2194
  // SECURITY: Do not put proof signatures into Authorization headers.
1728
2195
  headers: { "Content-Type": "application/json" },
1729
- body: JSON.stringify({ walletAddress: address, signature, signedTimestamp })
2196
+ body: JSON.stringify({
2197
+ walletAddress: address,
2198
+ signature,
2199
+ signedTimestamp,
2200
+ ...signerIsEvm ? {} : { chain, signatureMethod }
2201
+ })
1730
2202
  });
1731
2203
  const json = await res.json();
1732
2204
  if (!json.success) {
@@ -1740,7 +2212,7 @@ ${bytes.length}`;
1740
2212
  /**
1741
2213
  * GET PROOFS BY WALLET - Fetch proofs for a wallet address
1742
2214
  *
1743
- * @param {string} walletAddress - Wallet address (0x...) or DID (did:pkh:...)
2215
+ * @param {string} walletAddress - Wallet identity (EVM/Solana/DID)
1744
2216
  * @param {Object} [options] - Filter options
1745
2217
  * @param {number} [options.limit] - Max results (default: 50; higher limits require owner access)
1746
2218
  * @param {number} [options.offset] - Pagination offset (default: 0)
@@ -1785,7 +2257,7 @@ ${bytes.length}`;
1785
2257
  *
1786
2258
  * Signs an owner-access intent and requests private proofs via signature headers.
1787
2259
  *
1788
- * @param {string} walletAddress - Wallet address (0x...) or DID (did:pkh:...)
2260
+ * @param {string} walletAddress - Wallet identity (EVM/Solana/DID)
1789
2261
  * @param {Object} [options]
1790
2262
  * @param {number} [options.limit] - Max results (server enforces caps)
1791
2263
  * @param {number} [options.offset] - Pagination offset
@@ -1797,48 +2269,41 @@ ${bytes.length}`;
1797
2269
  }
1798
2270
  const id = walletAddress.trim();
1799
2271
  const pathId = /^0x[a-fA-F0-9]{40}$/i.test(id) ? id.toLowerCase() : id;
2272
+ const requestedIdentity = this._normalizeIdentity(id);
1800
2273
  if (!wallet) {
1801
- if (typeof window === "undefined" || !window.ethereum) {
2274
+ const defaultWallet = this._getDefaultBrowserWallet();
2275
+ if (!defaultWallet) {
1802
2276
  throw new ConfigurationError("No wallet provider available");
1803
2277
  }
1804
- wallet = window.ethereum;
2278
+ wallet = defaultWallet;
1805
2279
  }
1806
- let signerWalletAddress, provider;
1807
- if (wallet.address) {
1808
- signerWalletAddress = wallet.address;
1809
- provider = wallet;
1810
- } else if (wallet.selectedAddress || wallet.request) {
1811
- provider = wallet;
1812
- if (wallet.selectedAddress) {
1813
- signerWalletAddress = wallet.selectedAddress;
1814
- } else {
1815
- const accounts = await provider.request({ method: "eth_accounts" });
1816
- if (!accounts || accounts.length === 0) {
1817
- throw new ConfigurationError("No wallet accounts available");
1818
- }
1819
- signerWalletAddress = accounts[0];
1820
- }
1821
- } else {
1822
- throw new ConfigurationError("Invalid wallet provider");
2280
+ const { signerWalletAddress, provider } = await this._resolveWalletSigner(wallet);
2281
+ if (!signerWalletAddress || typeof signerWalletAddress !== "string") {
2282
+ throw new ConfigurationError("No wallet accounts available");
2283
+ }
2284
+ const normalizedSigner = this._normalizeIdentity(signerWalletAddress);
2285
+ if (!normalizedSigner || normalizedSigner !== requestedIdentity) {
2286
+ throw new ValidationError("wallet must match walletAddress for private proof access");
1823
2287
  }
2288
+ const signerIsEvm = EVM_ADDRESS_RE.test(normalizedSigner);
2289
+ const chain = this._inferChainForAddress(normalizedSigner, options?.chain);
2290
+ const signatureMethod = typeof options?.signatureMethod === "string" && options.signatureMethod.trim() ? options.signatureMethod.trim() : signerIsEvm ? "eip191" : "ed25519";
1824
2291
  const signedTimestamp = Date.now();
1825
2292
  const message = constructVerificationMessage({
1826
2293
  walletAddress: signerWalletAddress,
1827
2294
  signedTimestamp,
1828
- data: { action: "access_private_proofs_by_wallet", walletAddress: signerWalletAddress.toLowerCase() },
2295
+ data: { action: "access_private_proofs_by_wallet", walletAddress: normalizedSigner },
1829
2296
  verifierIds: ["ownership-basic"],
1830
- chainId: NEUS_CONSTANTS.HUB_CHAIN_ID
2297
+ ...signerIsEvm ? { chainId: this._getHubChainId() } : { chain }
1831
2298
  });
1832
2299
  let signature;
1833
2300
  try {
1834
- if (provider.signMessage) {
1835
- signature = await provider.signMessage(message);
1836
- } else {
1837
- signature = await provider.request({
1838
- method: "personal_sign",
1839
- params: [message, signerWalletAddress]
1840
- });
1841
- }
2301
+ signature = await signMessage({
2302
+ provider,
2303
+ message,
2304
+ walletAddress: signerWalletAddress,
2305
+ ...signerIsEvm ? {} : { chain }
2306
+ });
1842
2307
  } catch (error) {
1843
2308
  if (error.code === 4001) {
1844
2309
  throw new ValidationError("User rejected signature request");
@@ -1854,7 +2319,8 @@ ${bytes.length}`;
1854
2319
  const response = await this._makeRequest("GET", `/api/v1/proofs/byWallet/${encodeURIComponent(pathId)}${query}`, null, {
1855
2320
  "x-wallet-address": signerWalletAddress,
1856
2321
  "x-signature": signature,
1857
- "x-signed-timestamp": signedTimestamp.toString()
2322
+ "x-signed-timestamp": signedTimestamp.toString(),
2323
+ ...signerIsEvm ? {} : { "x-chain": chain, "x-signature-method": signatureMethod }
1858
2324
  });
1859
2325
  if (!response.success) {
1860
2326
  throw new ApiError(`Failed to get proofs: ${response.error?.message || "Unauthorized"}`, response.error);
@@ -1871,25 +2337,31 @@ ${bytes.length}`;
1871
2337
  /**
1872
2338
  * GATE CHECK (API) - Minimal eligibility check
1873
2339
  *
1874
- * Calls the public gate endpoint and returns a **minimal** yes/no response
1875
- * against **public + discoverable** proofs only.
2340
+ * Calls the gate endpoint and returns a **minimal** yes/no response.
2341
+ * By default this checks **public + discoverable** proofs only.
1876
2342
  *
1877
- * Prefer this over `checkGate()` for server-side integrations that want the
2343
+ * When `includePrivate=true`, this can perform owner-signed private checks
2344
+ * (no full proof payloads returned) by providing a wallet/provider.
2345
+ *
2346
+ * Prefer this over `checkGate()` for integrations that want the
1878
2347
  * smallest, most stable surface area (and do NOT need full proof payloads).
1879
2348
  *
1880
2349
  * @param {Object} params - Gate check query params
1881
- * @param {string} params.address - Wallet address to check (0x...)
2350
+ * @param {string} params.address - Wallet identity to check (EVM/Solana/DID)
1882
2351
  * @param {Array<string>|string} [params.verifierIds] - Verifier IDs to match (array or comma-separated)
1883
2352
  * @param {boolean} [params.requireAll] - Require all verifierIds on a single proof
1884
2353
  * @param {number} [params.minCount] - Minimum number of matching proofs
1885
2354
  * @param {number} [params.sinceDays] - Optional time window in days
1886
2355
  * @param {number} [params.since] - Optional unix timestamp in ms (lower bound)
1887
2356
  * @param {number} [params.limit] - Max rows to scan (server may clamp)
2357
+ * @param {boolean} [params.includePrivate] - Include private proofs for owner-authenticated requests
2358
+ * @param {boolean} [params.includeQHashes] - Include matched qHashes in response (minimal IDs only)
2359
+ * @param {Object} [params.wallet] - Optional wallet/provider used to sign includePrivate owner checks
1888
2360
  * @returns {Promise<Object>} API response ({ success, data })
1889
2361
  */
1890
2362
  async gateCheck(params = {}) {
1891
2363
  const address = (params.address || "").toString();
1892
- if (!address || !/^0x[a-fA-F0-9]{40}$/i.test(address)) {
2364
+ if (!validateUniversalAddress(address, params.chain)) {
1893
2365
  throw new ValidationError("Valid address is required");
1894
2366
  }
1895
2367
  const qs = new URLSearchParams();
@@ -1924,6 +2396,8 @@ ${bytes.length}`;
1924
2396
  setIfPresent("sinceDays", params.sinceDays);
1925
2397
  setIfPresent("since", params.since);
1926
2398
  setIfPresent("limit", params.limit);
2399
+ setBoolIfPresent("includePrivate", params.includePrivate);
2400
+ setBoolIfPresent("includeQHashes", params.includeQHashes);
1927
2401
  setIfPresent("referenceType", params.referenceType);
1928
2402
  setIfPresent("referenceId", params.referenceId);
1929
2403
  setIfPresent("tag", params.tag);
@@ -1944,7 +2418,40 @@ ${bytes.length}`;
1944
2418
  setIfPresent("primaryWalletAddress", params.primaryWalletAddress);
1945
2419
  setIfPresent("secondaryWalletAddress", params.secondaryWalletAddress);
1946
2420
  setIfPresent("verificationMethod", params.verificationMethod);
1947
- const response = await this._makeRequest("GET", `/api/v1/proofs/gate/check?${qs.toString()}`);
2421
+ let headersOverride = null;
2422
+ if (params.includePrivate === true) {
2423
+ const provided = params.privateAuth && typeof params.privateAuth === "object" ? params.privateAuth : null;
2424
+ let auth = provided;
2425
+ if (!auth) {
2426
+ const walletCandidate = params.wallet || this._getDefaultBrowserWallet();
2427
+ if (walletCandidate) {
2428
+ auth = await this._buildPrivateGateAuth({
2429
+ address,
2430
+ wallet: walletCandidate,
2431
+ chain: params.chain,
2432
+ signatureMethod: params.signatureMethod
2433
+ });
2434
+ }
2435
+ }
2436
+ if (!auth) {
2437
+ } else {
2438
+ const normalizedAuthWallet = this._normalizeIdentity(auth.walletAddress);
2439
+ const normalizedAddress = this._normalizeIdentity(address);
2440
+ if (!normalizedAuthWallet || normalizedAuthWallet !== normalizedAddress) {
2441
+ throw new ValidationError("privateAuth.walletAddress must match address when includePrivate=true");
2442
+ }
2443
+ const authChain = typeof auth.chain === "string" && auth.chain.includes(":") ? auth.chain.trim() : null;
2444
+ const authSignatureMethod = typeof auth.signatureMethod === "string" && auth.signatureMethod.trim() ? auth.signatureMethod.trim() : null;
2445
+ headersOverride = {
2446
+ "x-wallet-address": String(auth.walletAddress),
2447
+ "x-signature": String(auth.signature),
2448
+ "x-signed-timestamp": String(auth.signedTimestamp),
2449
+ ...authChain ? { "x-chain": authChain } : {},
2450
+ ...authSignatureMethod ? { "x-signature-method": authSignatureMethod } : {}
2451
+ };
2452
+ }
2453
+ }
2454
+ const response = await this._makeRequest("GET", `/api/v1/proofs/check?${qs.toString()}`, null, headersOverride);
1948
2455
  if (!response.success) {
1949
2456
  throw new ApiError(`Gate check failed: ${response.error?.message || "Unknown error"}`, response.error);
1950
2457
  }
@@ -1968,7 +2475,7 @@ ${bytes.length}`;
1968
2475
  * Supports verifier-specific:
1969
2476
  * - NFT/Token: 'contractAddress', 'tokenId', 'chainId', 'ownerAddress', 'minBalance'
1970
2477
  * - DNS: 'domain', 'walletAddress'
1971
- * - Wallet-link: 'primaryWalletAddress', 'secondaryWalletAddress', 'chainId'
2478
+ * - Wallet-link: 'primaryWalletAddress', 'secondaryWalletAddress', 'chain', 'signatureMethod'
1972
2479
  * - Contract-ownership: 'contractAddress', 'chainId', 'owner', 'verificationMethod'
1973
2480
  * Note: contentHash matching uses approximation in SDK; for exact SHA-256 matching, use backend API
1974
2481
  * @param {Array} [params.proofs] - Pre-fetched proofs (skip API call)
@@ -1985,7 +2492,7 @@ ${bytes.length}`;
1985
2492
  */
1986
2493
  async checkGate(params) {
1987
2494
  const { walletAddress, requirements, proofs: preloadedProofs } = params;
1988
- if (!walletAddress || !/^0x[a-fA-F0-9]{40}$/i.test(walletAddress)) {
2495
+ if (!validateUniversalAddress(walletAddress)) {
1989
2496
  throw new ValidationError("Valid walletAddress is required");
1990
2497
  }
1991
2498
  if (!Array.isArray(requirements) || requirements.length === 0) {
@@ -2179,16 +2686,20 @@ ${bytes.length}`;
2179
2686
  * @private
2180
2687
  */
2181
2688
  _formatResponse(response) {
2182
- const qHash = response?.data?.qHash || response?.qHash || response?.data?.resource?.qHash || response?.data?.id;
2689
+ const proofId = response?.data?.proofId || response?.proofId || response?.data?.resource?.proofId || response?.data?.qHash || response?.qHash || response?.data?.resource?.qHash || response?.data?.id;
2690
+ const qHash = response?.data?.qHash || response?.qHash || response?.data?.resource?.qHash || proofId || response?.data?.id;
2691
+ const finalProofId = proofId || qHash || null;
2692
+ const finalQHash = qHash || proofId || finalProofId;
2183
2693
  const status = response?.data?.status || response?.status || response?.data?.resource?.status || (response?.success ? "completed" : "unknown");
2184
2694
  return {
2185
2695
  success: response.success,
2186
- qHash,
2696
+ proofId: finalProofId,
2697
+ qHash: finalQHash,
2187
2698
  status,
2188
2699
  data: response.data,
2189
2700
  message: response.message,
2190
2701
  timestamp: Date.now(),
2191
- statusUrl: qHash ? `${this.baseUrl}/api/v1/verification/status/${qHash}` : null
2702
+ statusUrl: finalProofId ? `${this.baseUrl}/api/v1/verification/status/${finalProofId}` : null
2192
2703
  };
2193
2704
  }
2194
2705
  /**
@@ -2232,11 +2743,16 @@ __export(sdk_exports, {
2232
2743
  AuthenticationError: () => AuthenticationError,
2233
2744
  ConfigurationError: () => ConfigurationError,
2234
2745
  DAY: () => DAY,
2746
+ GATE_AGENT_DELEGATION: () => GATE_AGENT_DELEGATION,
2747
+ GATE_AGENT_IDENTITY: () => GATE_AGENT_IDENTITY,
2748
+ GATE_CONTENT_MODERATION: () => GATE_CONTENT_MODERATION,
2235
2749
  GATE_CONTRACT_ADMIN: () => GATE_CONTRACT_ADMIN,
2236
2750
  GATE_DOMAIN_OWNER: () => GATE_DOMAIN_OWNER,
2237
2751
  GATE_LINKED_WALLETS: () => GATE_LINKED_WALLETS,
2238
2752
  GATE_NFT_HOLDER: () => GATE_NFT_HOLDER,
2753
+ GATE_PSEUDONYM: () => GATE_PSEUDONYM,
2239
2754
  GATE_TOKEN_HOLDER: () => GATE_TOKEN_HOLDER,
2755
+ GATE_WALLET_RISK: () => GATE_WALLET_RISK,
2240
2756
  HOUR: () => HOUR,
2241
2757
  MONTH: () => MONTH,
2242
2758
  NEUS_CONSTANTS: () => NEUS_CONSTANTS,
@@ -2264,9 +2780,15 @@ __export(sdk_exports, {
2264
2780
  isSupportedChain: () => isSupportedChain,
2265
2781
  isTerminalStatus: () => isTerminalStatus,
2266
2782
  normalizeAddress: () => normalizeAddress,
2783
+ resolveDID: () => resolveDID,
2784
+ resolveZkPassportConfig: () => resolveZkPassportConfig,
2785
+ signMessage: () => signMessage,
2786
+ standardizeVerificationRequest: () => standardizeVerificationRequest,
2787
+ toHexUtf8: () => toHexUtf8,
2267
2788
  validateQHash: () => validateQHash,
2268
2789
  validateSignatureComponents: () => validateSignatureComponents,
2269
2790
  validateTimestamp: () => validateTimestamp,
2791
+ validateUniversalAddress: () => validateUniversalAddress,
2270
2792
  validateVerifierPayload: () => validateVerifierPayload,
2271
2793
  validateWalletAddress: () => validateWalletAddress,
2272
2794
  withRetry: () => withRetry
@@ -2296,9 +2818,21 @@ var GATE_DOMAIN_OWNER = [
2296
2818
  var GATE_LINKED_WALLETS = [
2297
2819
  { verifierId: "wallet-link" }
2298
2820
  ];
2821
+ var GATE_AGENT_IDENTITY = [
2822
+ { verifierId: "agent-identity" }
2823
+ ];
2299
2824
  var GATE_AGENT_DELEGATION = [
2300
2825
  { verifierId: "agent-delegation", maxAgeMs: 7 * DAY }
2301
2826
  ];
2827
+ var GATE_CONTENT_MODERATION = [
2828
+ { verifierId: "ai-content-moderation" }
2829
+ ];
2830
+ var GATE_WALLET_RISK = [
2831
+ { verifierId: "wallet-risk" }
2832
+ ];
2833
+ var GATE_PSEUDONYM = [
2834
+ { verifierId: "ownership-pseudonym" }
2835
+ ];
2302
2836
  function createGate(requirements) {
2303
2837
  return requirements.map((req) => {
2304
2838
  if (typeof req === "string") {
@@ -2334,11 +2868,16 @@ var sdk_default = {
2334
2868
  AuthenticationError,
2335
2869
  ConfigurationError,
2336
2870
  DAY,
2871
+ GATE_AGENT_DELEGATION,
2872
+ GATE_AGENT_IDENTITY,
2873
+ GATE_CONTENT_MODERATION,
2337
2874
  GATE_CONTRACT_ADMIN,
2338
2875
  GATE_DOMAIN_OWNER,
2339
2876
  GATE_LINKED_WALLETS,
2340
2877
  GATE_NFT_HOLDER,
2878
+ GATE_PSEUDONYM,
2341
2879
  GATE_TOKEN_HOLDER,
2880
+ GATE_WALLET_RISK,
2342
2881
  HOUR,
2343
2882
  MONTH,
2344
2883
  NEUS_CONSTANTS,
@@ -2365,9 +2904,15 @@ var sdk_default = {
2365
2904
  isSupportedChain,
2366
2905
  isTerminalStatus,
2367
2906
  normalizeAddress,
2907
+ resolveDID,
2908
+ resolveZkPassportConfig,
2909
+ signMessage,
2910
+ standardizeVerificationRequest,
2911
+ toHexUtf8,
2368
2912
  validateQHash,
2369
2913
  validateSignatureComponents,
2370
2914
  validateTimestamp,
2915
+ validateUniversalAddress,
2371
2916
  validateVerifierPayload,
2372
2917
  validateWalletAddress,
2373
2918
  withRetry