@neus/sdk 1.0.1 → 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);
@@ -197,7 +242,7 @@ function constructVerificationMessage({ walletAddress, signedTimestamp, data, ve
197
242
  }
198
243
  const chainContext = typeof chain === "string" && chain.length > 0 ? chain : chainId;
199
244
  if (!chainContext) {
200
- throw new SDKError("chainId is required (or provide chain for preview mode)", "INVALID_CHAIN_CONTEXT");
245
+ throw new SDKError("chainId is required (or provide chain for universal mode)", "INVALID_CHAIN_CONTEXT");
201
246
  }
202
247
  if (chainContext === chainId && typeof chainId !== "number") {
203
248
  throw new SDKError("chainId must be a number when provided", "INVALID_CHAIN_ID");
@@ -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,13 +792,17 @@ 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
- ["content"].forEach((key) => {
476
- if (!(key in data))
477
- result.missing.push(key);
478
- });
798
+ if (!("owner" in data))
799
+ result.missing.push("owner");
800
+ const hasContent = typeof data.content === "string" && data.content.length > 0;
801
+ const hasContentHash = typeof data.contentHash === "string" && data.contentHash.length > 0;
802
+ const hasRefId = typeof data.reference?.id === "string" && data.reference.id.length > 0;
803
+ if (!hasContent && !hasContentHash && !hasRefId) {
804
+ result.missing.push("content (or contentHash or reference.id)");
805
+ }
479
806
  }
480
807
  if (result.missing.length > 0) {
481
808
  result.valid = false;
@@ -602,10 +929,12 @@ function validateSignatureComponents({ walletAddress, signature, signedTimestamp
602
929
  }
603
930
  return result;
604
931
  }
605
- var StatusPoller, NEUS_CONSTANTS;
932
+ var BASE58_ALPHABET, StatusPoller, NEUS_CONSTANTS;
606
933
  var init_utils = __esm({
607
934
  "utils.js"() {
935
+ "use strict";
608
936
  init_errors();
937
+ BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
609
938
  StatusPoller = class {
610
939
  constructor(client, qHash, options = {}) {
611
940
  this.client = client;
@@ -648,10 +977,24 @@ var init_utils = __esm({
648
977
  }
649
978
  setTimeout(pollAttempt, this.currentInterval);
650
979
  } catch (error) {
651
- reject(new SDKError(
652
- `Polling failed: ${error.message}`,
653
- "POLLING_ERROR"
654
- ));
980
+ if (error instanceof ValidationError) {
981
+ reject(error);
982
+ return;
983
+ }
984
+ if (error instanceof ApiError && error.statusCode === 429 || error?.isRetryable === true) {
985
+ if (this.options.exponentialBackoff) {
986
+ const next = Math.min(this.currentInterval * 2, this.options.maxInterval);
987
+ const jitter = next * (0.5 + Math.random() * 0.5);
988
+ this.currentInterval = Math.max(250, Math.floor(jitter));
989
+ }
990
+ if (this.attempt >= this.options.maxAttempts) {
991
+ reject(new SDKError("Verification polling timeout", "POLLING_TIMEOUT"));
992
+ return;
993
+ }
994
+ setTimeout(pollAttempt, this.currentInterval);
995
+ return;
996
+ }
997
+ reject(new SDKError(`Polling failed: ${error.message}`, "POLLING_ERROR"));
655
998
  }
656
999
  };
657
1000
  pollAttempt();
@@ -696,23 +1039,103 @@ __export(client_exports, {
696
1039
  NeusClient: () => NeusClient,
697
1040
  constructVerificationMessage: () => constructVerificationMessage
698
1041
  });
699
- var validateVerifierData, NeusClient;
1042
+ var FALLBACK_PUBLIC_VERIFIERS, INTERACTIVE_VERIFIERS, EVM_ADDRESS_RE, validateVerifierData, NeusClient;
700
1043
  var init_client = __esm({
701
1044
  "client.js"() {
1045
+ "use strict";
702
1046
  init_errors();
703
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}$/;
704
1070
  validateVerifierData = (verifierId, data) => {
705
1071
  if (!data || typeof data !== "object") {
706
1072
  return { valid: false, error: "Data object is required" };
707
1073
  }
708
- const ownerField = verifierId === "nft-ownership" || verifierId === "token-holding" ? "ownerAddress" : "owner";
709
- if (data[ownerField] && !validateWalletAddress(data[ownerField])) {
710
- return { valid: false, error: `Invalid ${ownerField} address` };
711
- }
712
1074
  switch (verifierId) {
713
1075
  case "ownership-basic":
714
- if (!data.owner || !validateWalletAddress(data.owner)) {
715
- 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" };
1078
+ }
1079
+ if (data.content !== void 0 && data.content !== null) {
1080
+ if (typeof data.content !== "string") {
1081
+ return { valid: false, error: "content must be a string when provided" };
1082
+ }
1083
+ if (data.content.length > 5e4) {
1084
+ return { valid: false, error: "content exceeds 50KB inline limit" };
1085
+ }
1086
+ }
1087
+ if (data.contentHash !== void 0 && data.contentHash !== null) {
1088
+ if (typeof data.contentHash !== "string" || !/^0x[a-fA-F0-9]{64}$/.test(data.contentHash)) {
1089
+ return { valid: false, error: "contentHash must be a 32-byte hex string (0x + 64 hex chars) when provided" };
1090
+ }
1091
+ }
1092
+ if (data.contentType !== void 0 && data.contentType !== null) {
1093
+ if (typeof data.contentType !== "string" || data.contentType.length > 100) {
1094
+ return { valid: false, error: "contentType must be a string (max 100 chars) when provided" };
1095
+ }
1096
+ const base = String(data.contentType).split(";")[0].trim().toLowerCase();
1097
+ if (!base || base.includes(" ") || !base.includes("/")) {
1098
+ return { valid: false, error: "contentType must be a valid MIME type when provided" };
1099
+ }
1100
+ }
1101
+ if (data.provenance !== void 0 && data.provenance !== null) {
1102
+ if (!data.provenance || typeof data.provenance !== "object" || Array.isArray(data.provenance)) {
1103
+ return { valid: false, error: "provenance must be an object when provided" };
1104
+ }
1105
+ const dk = data.provenance.declaredKind;
1106
+ if (dk !== void 0 && dk !== null) {
1107
+ const allowed = ["human", "ai", "mixed", "unknown"];
1108
+ if (typeof dk !== "string" || !allowed.includes(dk)) {
1109
+ return { valid: false, error: `provenance.declaredKind must be one of: ${allowed.join(", ")}` };
1110
+ }
1111
+ }
1112
+ const ai = data.provenance.aiContext;
1113
+ if (ai !== void 0 && ai !== null) {
1114
+ if (typeof ai !== "object" || Array.isArray(ai)) {
1115
+ return { valid: false, error: "provenance.aiContext must be an object when provided" };
1116
+ }
1117
+ if (ai.generatorType !== void 0 && ai.generatorType !== null) {
1118
+ const allowed = ["local", "saas", "agent"];
1119
+ if (typeof ai.generatorType !== "string" || !allowed.includes(ai.generatorType)) {
1120
+ return { valid: false, error: `provenance.aiContext.generatorType must be one of: ${allowed.join(", ")}` };
1121
+ }
1122
+ }
1123
+ if (ai.provider !== void 0 && ai.provider !== null) {
1124
+ if (typeof ai.provider !== "string" || ai.provider.length > 64) {
1125
+ return { valid: false, error: "provenance.aiContext.provider must be a string (max 64 chars) when provided" };
1126
+ }
1127
+ }
1128
+ if (ai.model !== void 0 && ai.model !== null) {
1129
+ if (typeof ai.model !== "string" || ai.model.length > 128) {
1130
+ return { valid: false, error: "provenance.aiContext.model must be a string (max 128 chars) when provided" };
1131
+ }
1132
+ }
1133
+ if (ai.runId !== void 0 && ai.runId !== null) {
1134
+ if (typeof ai.runId !== "string" || ai.runId.length > 128) {
1135
+ return { valid: false, error: "provenance.aiContext.runId must be a string (max 128 chars) when provided" };
1136
+ }
1137
+ }
1138
+ }
716
1139
  }
717
1140
  if (data.reference !== void 0) {
718
1141
  if (!data.reference || typeof data.reference !== "object") {
@@ -777,17 +1200,20 @@ var init_client = __esm({
777
1200
  }
778
1201
  break;
779
1202
  case "wallet-link":
780
- if (!data.primaryWalletAddress || !validateWalletAddress(data.primaryWalletAddress)) {
1203
+ if (!data.primaryWalletAddress || !validateUniversalAddress(data.primaryWalletAddress, data.chain)) {
781
1204
  return { valid: false, error: "primaryWalletAddress is required" };
782
1205
  }
783
- if (!data.secondaryWalletAddress || !validateWalletAddress(data.secondaryWalletAddress)) {
1206
+ if (!data.secondaryWalletAddress || !validateUniversalAddress(data.secondaryWalletAddress, data.chain)) {
784
1207
  return { valid: false, error: "secondaryWalletAddress is required" };
785
1208
  }
786
1209
  if (!data.signature || typeof data.signature !== "string") {
787
1210
  return { valid: false, error: "signature is required (signed by secondary wallet)" };
788
1211
  }
789
- if (typeof data.chainId !== "number") {
790
- 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" };
791
1217
  }
792
1218
  if (typeof data.signedTimestamp !== "number") {
793
1219
  return { valid: false, error: "signedTimestamp is required" };
@@ -852,6 +1278,17 @@ var init_client = __esm({
852
1278
  if (!validTypes.includes(contentType)) {
853
1279
  return { valid: false, error: `contentType must be one of: ${validTypes.join(", ")}` };
854
1280
  }
1281
+ const isTextual = contentType.startsWith("text/") || contentType.includes("markdown");
1282
+ if (isTextual) {
1283
+ try {
1284
+ const maxBytes = 50 * 1024;
1285
+ const bytes = typeof TextEncoder !== "undefined" ? new TextEncoder().encode(data.content).length : String(data.content).length;
1286
+ if (bytes > maxBytes) {
1287
+ return { valid: false, error: `content exceeds ${maxBytes} bytes limit for ai-content-moderation verifier (text)` };
1288
+ }
1289
+ } catch {
1290
+ }
1291
+ }
855
1292
  }
856
1293
  if (data.content.length > 13653334) {
857
1294
  return { valid: false, error: "content exceeds 10MB limit" };
@@ -871,7 +1308,7 @@ var init_client = __esm({
871
1308
  }
872
1309
  break;
873
1310
  case "wallet-risk":
874
- if (data.walletAddress && !validateWalletAddress(data.walletAddress)) {
1311
+ if (data.walletAddress && !validateUniversalAddress(data.walletAddress, data.chain)) {
875
1312
  return { valid: false, error: "Invalid walletAddress" };
876
1313
  }
877
1314
  break;
@@ -903,6 +1340,26 @@ var init_client = __esm({
903
1340
  if (typeof this.config.apiKey === "string" && this.config.apiKey.trim().length > 0) {
904
1341
  this.defaultHeaders["Authorization"] = `Bearer ${this.config.apiKey.trim()}`;
905
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
+ }
906
1363
  try {
907
1364
  if (typeof window !== "undefined" && window.location && window.location.origin) {
908
1365
  this.defaultHeaders["X-Client-Origin"] = window.location.origin;
@@ -910,6 +1367,122 @@ var init_client = __esm({
910
1367
  } catch {
911
1368
  }
912
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
+ }
913
1486
  // ============================================================================
914
1487
  // CORE VERIFICATION METHODS
915
1488
  // ============================================================================
@@ -931,7 +1504,7 @@ var init_client = __esm({
931
1504
  * @param {string} [params.verifier] - Verifier ID (auto path)
932
1505
  * @param {string} [params.content] - Content/description (auto path)
933
1506
  * @param {Object} [params.wallet] - Optional injected wallet/provider (auto path)
934
- * @returns {Promise<Object>} Verification result with qHash
1507
+ * @returns {Promise<Object>} Verification result with proofId (qHash is a deprecated alias)
935
1508
  *
936
1509
  * @example
937
1510
  * const proof = await client.verify({
@@ -939,7 +1512,7 @@ var init_client = __esm({
939
1512
  * data: {
940
1513
  * content: "My content",
941
1514
  * owner: walletAddress, // or ownerAddress for nft-ownership/token-holding
942
- * reference: { type: 'content', id: 'my-unique-identifier' }
1515
+ * reference: { type: 'other', id: 'my-unique-identifier' }
943
1516
  * },
944
1517
  * walletAddress: '0x...',
945
1518
  * signature: '0x...',
@@ -956,7 +1529,7 @@ var init_client = __esm({
956
1529
  * @param {Object} [params.data] - Structured verification data
957
1530
  * @param {Object} [params.wallet] - Wallet provider
958
1531
  * @param {Object} [params.options] - Additional options
959
- * @returns {Promise<Object>} Verification result with qHash
1532
+ * @returns {Promise<Object>} Verification result with proofId (qHash is a deprecated alias)
960
1533
  *
961
1534
  * @example
962
1535
  * // Simple ownership proof
@@ -972,25 +1545,23 @@ var init_client = __esm({
972
1545
  if (verifier === "ownership-basic" && !data2 && (!content || typeof content !== "string")) {
973
1546
  throw new ValidationError("content is required and must be a string (or use data param with owner + reference)");
974
1547
  }
975
- const validVerifiers = [
976
- "ownership-basic",
977
- "ownership-pseudonym",
978
- // Pseudonymous identity (public)
979
- "nft-ownership",
980
- "token-holding",
981
- "ownership-dns-txt",
982
- "wallet-link",
983
- "contract-ownership",
984
- "wallet-risk",
985
- // Wallet risk assessment (public)
986
- // AI & Agent verifiers (ERC-8004 aligned)
987
- "agent-identity",
988
- "agent-delegation",
989
- "ai-content-moderation"
990
- ];
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
+ }
991
1556
  if (!validVerifiers.includes(verifier)) {
992
1557
  throw new ValidationError(`Invalid verifier '${verifier}'. Must be one of: ${validVerifiers.join(", ")}.`);
993
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
+ }
994
1565
  const requiresDataParam = [
995
1566
  "ownership-dns-txt",
996
1567
  "wallet-link",
@@ -1008,8 +1579,12 @@ var init_client = __esm({
1008
1579
  }
1009
1580
  let walletAddress2, provider;
1010
1581
  if (wallet) {
1011
- walletAddress2 = wallet.address || wallet.selectedAddress;
1582
+ walletAddress2 = wallet.address || wallet.selectedAddress || wallet.walletAddress || (typeof wallet.getAddress === "function" ? await wallet.getAddress() : null);
1012
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
+ }
1013
1588
  } else {
1014
1589
  if (typeof window === "undefined" || !window.ethereum) {
1015
1590
  throw new ConfigurationError("No Web3 wallet detected. Please install MetaMask or provide wallet parameter.");
@@ -1027,6 +1602,7 @@ var init_client = __esm({
1027
1602
  reference: data2.reference,
1028
1603
  ...data2.content && { content: data2.content },
1029
1604
  ...data2.contentHash && { contentHash: data2.contentHash },
1605
+ ...data2.contentType && { contentType: data2.contentType },
1030
1606
  ...data2.provenance && { provenance: data2.provenance }
1031
1607
  };
1032
1608
  } else {
@@ -1084,14 +1660,18 @@ var init_client = __esm({
1084
1660
  if (!data2?.signature) {
1085
1661
  throw new ValidationError("wallet-link requires signature in data parameter (signed by secondary wallet)");
1086
1662
  }
1087
- if (typeof data2?.chainId !== "number") {
1088
- 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");
1089
1668
  }
1090
1669
  verificationData = {
1091
1670
  primaryWalletAddress: walletAddress2,
1092
1671
  secondaryWalletAddress: data2.secondaryWalletAddress,
1093
1672
  signature: data2.signature,
1094
- chainId: data2.chainId,
1673
+ chain: data2.chain,
1674
+ signatureMethod: data2.signatureMethod,
1095
1675
  signedTimestamp: data2?.signedTimestamp || Date.now()
1096
1676
  };
1097
1677
  } else if (verifier === "contract-ownership") {
@@ -1180,12 +1760,12 @@ var init_client = __esm({
1180
1760
  signedTimestamp: signedTimestamp2,
1181
1761
  data: verificationData,
1182
1762
  verifierIds: verifierIds2,
1183
- chainId: NEUS_CONSTANTS.HUB_CHAIN_ID
1763
+ chainId: this._getHubChainId()
1184
1764
  // Protocol-managed chain
1185
1765
  });
1186
1766
  let signature2;
1187
1767
  try {
1188
- const toHexUtf8 = (s) => {
1768
+ const toHexUtf82 = (s) => {
1189
1769
  try {
1190
1770
  const enc = new TextEncoder();
1191
1771
  const bytes = enc.encode(s);
@@ -1221,7 +1801,7 @@ var init_client = __esm({
1221
1801
  })();
1222
1802
  if (isFarcasterWallet) {
1223
1803
  try {
1224
- const hexMsg = toHexUtf8(message);
1804
+ const hexMsg = toHexUtf82(message);
1225
1805
  signature2 = await provider.request({ method: "personal_sign", params: [hexMsg, walletAddress2] });
1226
1806
  } catch (e) {
1227
1807
  }
@@ -1270,7 +1850,7 @@ ${bytes.length}`;
1270
1850
  }
1271
1851
  } else if (needsHex) {
1272
1852
  this._log("Retrying personal_sign with hex-encoded message");
1273
- const hexMsg = toHexUtf8(message);
1853
+ const hexMsg = toHexUtf82(message);
1274
1854
  signature2 = await provider.request({ method: "personal_sign", params: [hexMsg, walletAddress2] });
1275
1855
  } else {
1276
1856
  throw e;
@@ -1368,18 +1948,18 @@ ${bytes.length}`;
1368
1948
  /**
1369
1949
  * Get verification status
1370
1950
  *
1371
- * @param {string} qHash - Verification ID (qHash or proofId)
1951
+ * @param {string} proofId - Proof ID (standard). `qHash` is a deprecated alias (same value).
1372
1952
  * @returns {Promise<Object>} Verification status and data
1373
1953
  *
1374
1954
  * @example
1375
1955
  * const result = await client.getStatus('0x...');
1376
1956
  * console.log('Status:', result.status);
1377
1957
  */
1378
- async getStatus(qHash) {
1379
- if (!qHash || typeof qHash !== "string") {
1380
- throw new ValidationError("qHash is required");
1958
+ async getStatus(proofId) {
1959
+ if (!proofId || typeof proofId !== "string") {
1960
+ throw new ValidationError("proofId is required");
1381
1961
  }
1382
- const response = await this._makeRequest("GET", `/api/v1/verification/status/${qHash}`);
1962
+ const response = await this._makeRequest("GET", `/api/v1/verification/status/${proofId}`);
1383
1963
  if (!response.success) {
1384
1964
  throw new ApiError(`Failed to get status: ${response.error?.message || "Unknown error"}`, response.error);
1385
1965
  }
@@ -1388,70 +1968,72 @@ ${bytes.length}`;
1388
1968
  /**
1389
1969
  * Get private proof status with wallet signature
1390
1970
  *
1391
- * @param {string} qHash - Verification ID
1971
+ * @param {string} proofId - Proof ID (standard). `qHash` is a deprecated alias (same value).
1392
1972
  * @param {Object} wallet - Wallet provider (window.ethereum or ethers Wallet)
1393
1973
  * @returns {Promise<Object>} Private verification status and data
1394
1974
  *
1395
1975
  * @example
1396
1976
  * // Access private proof
1397
- * const privateData = await client.getPrivateStatus(qHash, window.ethereum);
1977
+ * const privateData = await client.getPrivateStatus(proofId, window.ethereum);
1398
1978
  */
1399
- async getPrivateStatus(qHash, wallet = null) {
1400
- if (!qHash || typeof qHash !== "string") {
1401
- 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");
1402
1982
  }
1403
- if (!wallet) {
1404
- if (typeof window === "undefined" || !window.ethereum) {
1405
- 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
+ );
1406
1999
  }
1407
- wallet = window.ethereum;
2000
+ return this._formatResponse(response2);
1408
2001
  }
1409
- let walletAddress, provider;
1410
- if (wallet.address) {
1411
- walletAddress = wallet.address;
1412
- provider = wallet;
1413
- } else if (wallet.selectedAddress || wallet.request) {
1414
- provider = wallet;
1415
- if (wallet.selectedAddress) {
1416
- walletAddress = wallet.selectedAddress;
1417
- } else {
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
- walletAddress = accounts[0];
1423
- }
1424
- } else {
1425
- 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");
1426
2006
  }
2007
+ const signerIsEvm = EVM_ADDRESS_RE.test(this._normalizeIdentity(walletAddress));
2008
+ const chain = this._inferChainForAddress(walletAddress);
2009
+ const signatureMethod = signerIsEvm ? "eip191" : "ed25519";
1427
2010
  const signedTimestamp = Date.now();
1428
2011
  const message = constructVerificationMessage({
1429
2012
  walletAddress,
1430
2013
  signedTimestamp,
1431
- data: { action: "access_private_proof", qHash },
2014
+ data: { action: "access_private_proof", qHash: proofId },
1432
2015
  verifierIds: ["ownership-basic"],
1433
- chainId: NEUS_CONSTANTS.HUB_CHAIN_ID
2016
+ ...signerIsEvm ? { chainId: this._getHubChainId() } : { chain }
1434
2017
  });
1435
2018
  let signature;
1436
2019
  try {
1437
- if (provider.signMessage) {
1438
- signature = await provider.signMessage(message);
1439
- } else {
1440
- signature = await provider.request({
1441
- method: "personal_sign",
1442
- params: [message, walletAddress]
1443
- });
1444
- }
2020
+ signature = await signMessage({
2021
+ provider,
2022
+ message,
2023
+ walletAddress,
2024
+ ...signerIsEvm ? {} : { chain }
2025
+ });
1445
2026
  } catch (error) {
1446
2027
  if (error.code === 4001) {
1447
2028
  throw new ValidationError("User rejected signature request");
1448
2029
  }
1449
2030
  throw new ValidationError(`Failed to sign message: ${error.message}`);
1450
2031
  }
1451
- 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, {
1452
2033
  "x-wallet-address": walletAddress,
1453
2034
  "x-signature": signature,
1454
- "x-signed-timestamp": signedTimestamp.toString()
2035
+ "x-signed-timestamp": signedTimestamp.toString(),
2036
+ ...signerIsEvm ? {} : { "x-chain": chain, "x-signature-method": signatureMethod }
1455
2037
  });
1456
2038
  if (!response.success) {
1457
2039
  throw new ApiError(
@@ -1492,7 +2074,7 @@ ${bytes.length}`;
1492
2074
  * Polls the verification status until it reaches a terminal state (completed or failed).
1493
2075
  * Useful for providing real-time feedback to users during verification.
1494
2076
  *
1495
- * @param {string} qHash - Verification ID to poll
2077
+ * @param {string} proofId - Proof ID to poll (standard). `qHash` is a deprecated alias (same value).
1496
2078
  * @param {Object} [options] - Polling options
1497
2079
  * @param {number} [options.interval=5000] - Polling interval in ms
1498
2080
  * @param {number} [options.timeout=120000] - Total timeout in ms
@@ -1500,7 +2082,7 @@ ${bytes.length}`;
1500
2082
  * @returns {Promise<Object>} Final verification status
1501
2083
  *
1502
2084
  * @example
1503
- * const finalStatus = await client.pollProofStatus(qHash, {
2085
+ * const finalStatus = await client.pollProofStatus(proofId, {
1504
2086
  * interval: 3000,
1505
2087
  * timeout: 60000,
1506
2088
  * onProgress: (status) => {
@@ -1511,19 +2093,21 @@ ${bytes.length}`;
1511
2093
  * }
1512
2094
  * });
1513
2095
  */
1514
- async pollProofStatus(qHash, options = {}) {
2096
+ async pollProofStatus(proofId, options = {}) {
1515
2097
  const {
1516
2098
  interval = 5e3,
1517
2099
  timeout = 12e4,
1518
2100
  onProgress
1519
2101
  } = options;
1520
- if (!qHash || typeof qHash !== "string") {
1521
- throw new ValidationError("qHash is required");
2102
+ if (!proofId || typeof proofId !== "string") {
2103
+ throw new ValidationError("proofId is required");
1522
2104
  }
1523
2105
  const startTime = Date.now();
2106
+ let consecutiveRateLimits = 0;
1524
2107
  while (Date.now() - startTime < timeout) {
1525
2108
  try {
1526
- const status = await this.getStatus(qHash);
2109
+ const status = await this.getStatus(proofId);
2110
+ consecutiveRateLimits = 0;
1527
2111
  if (onProgress && typeof onProgress === "function") {
1528
2112
  onProgress(status.data || status);
1529
2113
  }
@@ -1538,7 +2122,17 @@ ${bytes.length}`;
1538
2122
  if (error instanceof ValidationError) {
1539
2123
  throw error;
1540
2124
  }
1541
- await new Promise((resolve) => setTimeout(resolve, interval));
2125
+ let nextDelay = interval;
2126
+ if (error instanceof ApiError && Number(error.statusCode) === 429) {
2127
+ consecutiveRateLimits += 1;
2128
+ const exp = Math.min(6, consecutiveRateLimits);
2129
+ const base = Math.max(500, Number(interval) || 0);
2130
+ const max = 3e4;
2131
+ const backoff = Math.min(max, base * Math.pow(2, exp));
2132
+ const jitter = Math.floor(backoff * (0.5 + Math.random() * 0.5));
2133
+ nextDelay = jitter;
2134
+ }
2135
+ await new Promise((resolve) => setTimeout(resolve, nextDelay));
1542
2136
  }
1543
2137
  }
1544
2138
  throw new NetworkError(`Polling timeout after ${timeout}ms`, "POLLING_TIMEOUT");
@@ -1560,70 +2154,51 @@ ${bytes.length}`;
1560
2154
  }
1561
2155
  }
1562
2156
  /** Revoke your own proof (owner-signed) */
1563
- async revokeOwnProof(qHash, wallet) {
1564
- if (!qHash || typeof qHash !== "string") {
1565
- 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");
1566
2165
  }
1567
- 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";
1568
2169
  const signedTimestamp = Date.now();
1569
- const hubChainId = NEUS_CONSTANTS.HUB_CHAIN_ID;
1570
2170
  const message = constructVerificationMessage({
1571
2171
  walletAddress: address,
1572
2172
  signedTimestamp,
1573
- data: { action: "revoke_proof", qHash },
2173
+ // Keep wire payload key `qHash` for backwards compatibility.
2174
+ data: { action: "revoke_proof", qHash: proofId },
1574
2175
  verifierIds: ["ownership-basic"],
1575
- chainId: hubChainId
2176
+ ...signerIsEvm ? { chainId: this._getHubChainId() } : { chain }
1576
2177
  });
1577
2178
  let signature;
1578
2179
  try {
1579
- const toHexUtf8 = (s) => {
1580
- const enc = new TextEncoder();
1581
- const bytes = enc.encode(s);
1582
- let hex = "0x";
1583
- for (let i = 0; i < bytes.length; i++)
1584
- hex += bytes[i].toString(16).padStart(2, "0");
1585
- return hex;
1586
- };
1587
- const isFarcasterWallet = (() => {
1588
- if (typeof window === "undefined")
1589
- return false;
1590
- try {
1591
- const w = window;
1592
- const fc = w.farcaster;
1593
- if (!fc || !fc.context)
1594
- return false;
1595
- const fcProvider = fc.provider || fc.walletProvider || fc.context && fc.context.walletProvider;
1596
- if (fcProvider === w.ethereum)
1597
- return true;
1598
- if (w.mini && w.mini.wallet === w.ethereum && fc && fc.context)
1599
- return true;
1600
- if (w.ethereum && fc && fc.context)
1601
- return true;
1602
- } catch {
1603
- }
1604
- return false;
1605
- })();
1606
- if (isFarcasterWallet) {
1607
- try {
1608
- const hexMsg = toHexUtf8(message);
1609
- signature = await window.ethereum.request({ method: "personal_sign", params: [hexMsg, address] });
1610
- } catch {
1611
- }
1612
- }
1613
- if (!signature) {
1614
- signature = await window.ethereum.request({ method: "personal_sign", params: [message, address] });
1615
- }
2180
+ signature = await signMessage({
2181
+ provider,
2182
+ message,
2183
+ walletAddress: address,
2184
+ ...signerIsEvm ? {} : { chain }
2185
+ });
1616
2186
  } catch (error) {
1617
2187
  if (error.code === 4001) {
1618
2188
  throw new ValidationError("User rejected revocation signature");
1619
2189
  }
1620
2190
  throw new ValidationError(`Failed to sign revocation: ${error.message}`);
1621
2191
  }
1622
- 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`, {
1623
2193
  method: "POST",
1624
2194
  // SECURITY: Do not put proof signatures into Authorization headers.
1625
2195
  headers: { "Content-Type": "application/json" },
1626
- body: JSON.stringify({ walletAddress: address, signature, signedTimestamp })
2196
+ body: JSON.stringify({
2197
+ walletAddress: address,
2198
+ signature,
2199
+ signedTimestamp,
2200
+ ...signerIsEvm ? {} : { chain, signatureMethod }
2201
+ })
1627
2202
  });
1628
2203
  const json = await res.json();
1629
2204
  if (!json.success) {
@@ -1632,12 +2207,12 @@ ${bytes.length}`;
1632
2207
  return true;
1633
2208
  }
1634
2209
  // ============================================================================
1635
- // GATE & LOOKUP METHODS
2210
+ // PROOFS & GATING METHODS
1636
2211
  // ============================================================================
1637
2212
  /**
1638
2213
  * GET PROOFS BY WALLET - Fetch proofs for a wallet address
1639
2214
  *
1640
- * @param {string} walletAddress - Wallet address (0x...) or DID (did:pkh:...)
2215
+ * @param {string} walletAddress - Wallet identity (EVM/Solana/DID)
1641
2216
  * @param {Object} [options] - Filter options
1642
2217
  * @param {number} [options.limit] - Max results (default: 50; higher limits require owner access)
1643
2218
  * @param {number} [options.offset] - Pagination offset (default: 0)
@@ -1682,7 +2257,7 @@ ${bytes.length}`;
1682
2257
  *
1683
2258
  * Signs an owner-access intent and requests private proofs via signature headers.
1684
2259
  *
1685
- * @param {string} walletAddress - Wallet address (0x...) or DID (did:pkh:...)
2260
+ * @param {string} walletAddress - Wallet identity (EVM/Solana/DID)
1686
2261
  * @param {Object} [options]
1687
2262
  * @param {number} [options.limit] - Max results (server enforces caps)
1688
2263
  * @param {number} [options.offset] - Pagination offset
@@ -1694,48 +2269,41 @@ ${bytes.length}`;
1694
2269
  }
1695
2270
  const id = walletAddress.trim();
1696
2271
  const pathId = /^0x[a-fA-F0-9]{40}$/i.test(id) ? id.toLowerCase() : id;
2272
+ const requestedIdentity = this._normalizeIdentity(id);
1697
2273
  if (!wallet) {
1698
- if (typeof window === "undefined" || !window.ethereum) {
2274
+ const defaultWallet = this._getDefaultBrowserWallet();
2275
+ if (!defaultWallet) {
1699
2276
  throw new ConfigurationError("No wallet provider available");
1700
2277
  }
1701
- wallet = window.ethereum;
2278
+ wallet = defaultWallet;
1702
2279
  }
1703
- let signerWalletAddress, provider;
1704
- if (wallet.address) {
1705
- signerWalletAddress = wallet.address;
1706
- provider = wallet;
1707
- } else if (wallet.selectedAddress || wallet.request) {
1708
- provider = wallet;
1709
- if (wallet.selectedAddress) {
1710
- signerWalletAddress = wallet.selectedAddress;
1711
- } else {
1712
- const accounts = await provider.request({ method: "eth_accounts" });
1713
- if (!accounts || accounts.length === 0) {
1714
- throw new ConfigurationError("No wallet accounts available");
1715
- }
1716
- signerWalletAddress = accounts[0];
1717
- }
1718
- } else {
1719
- 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");
1720
2283
  }
2284
+ const normalizedSigner = this._normalizeIdentity(signerWalletAddress);
2285
+ if (!normalizedSigner || normalizedSigner !== requestedIdentity) {
2286
+ throw new ValidationError("wallet must match walletAddress for private proof access");
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";
1721
2291
  const signedTimestamp = Date.now();
1722
2292
  const message = constructVerificationMessage({
1723
2293
  walletAddress: signerWalletAddress,
1724
2294
  signedTimestamp,
1725
- data: { action: "access_private_proofs_by_wallet", walletAddress: signerWalletAddress.toLowerCase() },
2295
+ data: { action: "access_private_proofs_by_wallet", walletAddress: normalizedSigner },
1726
2296
  verifierIds: ["ownership-basic"],
1727
- chainId: NEUS_CONSTANTS.HUB_CHAIN_ID
2297
+ ...signerIsEvm ? { chainId: this._getHubChainId() } : { chain }
1728
2298
  });
1729
2299
  let signature;
1730
2300
  try {
1731
- if (provider.signMessage) {
1732
- signature = await provider.signMessage(message);
1733
- } else {
1734
- signature = await provider.request({
1735
- method: "personal_sign",
1736
- params: [message, signerWalletAddress]
1737
- });
1738
- }
2301
+ signature = await signMessage({
2302
+ provider,
2303
+ message,
2304
+ walletAddress: signerWalletAddress,
2305
+ ...signerIsEvm ? {} : { chain }
2306
+ });
1739
2307
  } catch (error) {
1740
2308
  if (error.code === 4001) {
1741
2309
  throw new ValidationError("User rejected signature request");
@@ -1751,7 +2319,8 @@ ${bytes.length}`;
1751
2319
  const response = await this._makeRequest("GET", `/api/v1/proofs/byWallet/${encodeURIComponent(pathId)}${query}`, null, {
1752
2320
  "x-wallet-address": signerWalletAddress,
1753
2321
  "x-signature": signature,
1754
- "x-signed-timestamp": signedTimestamp.toString()
2322
+ "x-signed-timestamp": signedTimestamp.toString(),
2323
+ ...signerIsEvm ? {} : { "x-chain": chain, "x-signature-method": signatureMethod }
1755
2324
  });
1756
2325
  if (!response.success) {
1757
2326
  throw new ApiError(`Failed to get proofs: ${response.error?.message || "Unauthorized"}`, response.error);
@@ -1765,68 +2334,34 @@ ${bytes.length}`;
1765
2334
  nextOffset: response.data?.nextOffset ?? null
1766
2335
  };
1767
2336
  }
1768
- /**
1769
- * LOOKUP MODE (API) - Non-persistent server-to-server checks
1770
- *
1771
- * Runs `external_lookup` verifiers without minting/storing a proof.
1772
- * Requires an enterprise API key (server-side only).
1773
- *
1774
- * @param {Object} params
1775
- * @param {string} params.apiKey - Enterprise API key (sk_live_... or sk_test_...)
1776
- * @param {Array<string>} params.verifierIds - Verifiers to run (external_lookup only)
1777
- * @param {string} params.targetWalletAddress - Wallet to evaluate
1778
- * @param {Object} [params.data] - Verifier input data (e.g., contractAddress/tokenId/chainId)
1779
- * @returns {Promise<Object>} API response ({ success, data })
1780
- */
1781
- async lookup(params = {}) {
1782
- const apiKey = (params.apiKey || "").toString().trim();
1783
- if (!apiKey || !(apiKey.startsWith("sk_live_") || apiKey.startsWith("sk_test_"))) {
1784
- throw new ValidationError("lookup requires apiKey (sk_live_* or sk_test_*)");
1785
- }
1786
- const verifierIds = Array.isArray(params.verifierIds) ? params.verifierIds.map((v) => String(v).trim()).filter(Boolean) : [];
1787
- if (verifierIds.length === 0) {
1788
- throw new ValidationError("lookup requires verifierIds (non-empty array)");
1789
- }
1790
- const targetWalletAddress = (params.targetWalletAddress || "").toString().trim();
1791
- if (!targetWalletAddress || !/^0x[a-fA-F0-9]{40}$/i.test(targetWalletAddress)) {
1792
- throw new ValidationError("lookup requires a valid targetWalletAddress (0x...)");
1793
- }
1794
- const body = {
1795
- verifierIds,
1796
- targetWalletAddress,
1797
- data: params.data && typeof params.data === "object" ? params.data : {}
1798
- };
1799
- const response = await this._makeRequest("POST", "/api/v1/verification/lookup", body, {
1800
- Authorization: `Bearer ${apiKey}`
1801
- });
1802
- if (!response.success) {
1803
- throw new ApiError(`Lookup failed: ${response.error?.message || "Unknown error"}`, response.error);
1804
- }
1805
- return response;
1806
- }
1807
2337
  /**
1808
2338
  * GATE CHECK (API) - Minimal eligibility check
1809
2339
  *
1810
- * Calls the public gate endpoint and returns a **minimal** yes/no response
1811
- * 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.
2342
+ *
2343
+ * When `includePrivate=true`, this can perform owner-signed private checks
2344
+ * (no full proof payloads returned) by providing a wallet/provider.
1812
2345
  *
1813
- * Prefer this over `checkGate()` for server-side integrations that want the
2346
+ * Prefer this over `checkGate()` for integrations that want the
1814
2347
  * smallest, most stable surface area (and do NOT need full proof payloads).
1815
2348
  *
1816
2349
  * @param {Object} params - Gate check query params
1817
- * @param {string} params.address - Wallet address to check (0x...)
2350
+ * @param {string} params.address - Wallet identity to check (EVM/Solana/DID)
1818
2351
  * @param {Array<string>|string} [params.verifierIds] - Verifier IDs to match (array or comma-separated)
1819
2352
  * @param {boolean} [params.requireAll] - Require all verifierIds on a single proof
1820
2353
  * @param {number} [params.minCount] - Minimum number of matching proofs
1821
2354
  * @param {number} [params.sinceDays] - Optional time window in days
1822
2355
  * @param {number} [params.since] - Optional unix timestamp in ms (lower bound)
1823
2356
  * @param {number} [params.limit] - Max rows to scan (server may clamp)
1824
- * @param {string} [params.select] - Comma-separated projections (handle,provider,profileUrl,traits.<key>)
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
1825
2360
  * @returns {Promise<Object>} API response ({ success, data })
1826
2361
  */
1827
2362
  async gateCheck(params = {}) {
1828
2363
  const address = (params.address || "").toString();
1829
- if (!address || !/^0x[a-fA-F0-9]{40}$/i.test(address)) {
2364
+ if (!validateUniversalAddress(address, params.chain)) {
1830
2365
  throw new ValidationError("Valid address is required");
1831
2366
  }
1832
2367
  const qs = new URLSearchParams();
@@ -1861,7 +2396,8 @@ ${bytes.length}`;
1861
2396
  setIfPresent("sinceDays", params.sinceDays);
1862
2397
  setIfPresent("since", params.since);
1863
2398
  setIfPresent("limit", params.limit);
1864
- setCsvIfPresent("select", params.select);
2399
+ setBoolIfPresent("includePrivate", params.includePrivate);
2400
+ setBoolIfPresent("includeQHashes", params.includeQHashes);
1865
2401
  setIfPresent("referenceType", params.referenceType);
1866
2402
  setIfPresent("referenceId", params.referenceId);
1867
2403
  setIfPresent("tag", params.tag);
@@ -1875,7 +2411,6 @@ ${bytes.length}`;
1875
2411
  setIfPresent("domain", params.domain);
1876
2412
  setIfPresent("minBalance", params.minBalance);
1877
2413
  setIfPresent("provider", params.provider);
1878
- setIfPresent("handle", params.handle);
1879
2414
  setIfPresent("ownerAddress", params.ownerAddress);
1880
2415
  setIfPresent("riskLevel", params.riskLevel);
1881
2416
  setBoolIfPresent("sanctioned", params.sanctioned);
@@ -1883,9 +2418,40 @@ ${bytes.length}`;
1883
2418
  setIfPresent("primaryWalletAddress", params.primaryWalletAddress);
1884
2419
  setIfPresent("secondaryWalletAddress", params.secondaryWalletAddress);
1885
2420
  setIfPresent("verificationMethod", params.verificationMethod);
1886
- setIfPresent("traitPath", params.traitPath);
1887
- setIfPresent("traitGte", params.traitGte);
1888
- 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);
1889
2455
  if (!response.success) {
1890
2456
  throw new ApiError(`Gate check failed: ${response.error?.message || "Unknown error"}`, response.error);
1891
2457
  }
@@ -1909,7 +2475,7 @@ ${bytes.length}`;
1909
2475
  * Supports verifier-specific:
1910
2476
  * - NFT/Token: 'contractAddress', 'tokenId', 'chainId', 'ownerAddress', 'minBalance'
1911
2477
  * - DNS: 'domain', 'walletAddress'
1912
- * - Wallet-link: 'primaryWalletAddress', 'secondaryWalletAddress', 'chainId'
2478
+ * - Wallet-link: 'primaryWalletAddress', 'secondaryWalletAddress', 'chain', 'signatureMethod'
1913
2479
  * - Contract-ownership: 'contractAddress', 'chainId', 'owner', 'verificationMethod'
1914
2480
  * Note: contentHash matching uses approximation in SDK; for exact SHA-256 matching, use backend API
1915
2481
  * @param {Array} [params.proofs] - Pre-fetched proofs (skip API call)
@@ -1926,7 +2492,7 @@ ${bytes.length}`;
1926
2492
  */
1927
2493
  async checkGate(params) {
1928
2494
  const { walletAddress, requirements, proofs: preloadedProofs } = params;
1929
- if (!walletAddress || !/^0x[a-fA-F0-9]{40}$/i.test(walletAddress)) {
2495
+ if (!validateUniversalAddress(walletAddress)) {
1930
2496
  throw new ValidationError("Valid walletAddress is required");
1931
2497
  }
1932
2498
  if (!Array.isArray(requirements) || requirements.length === 0) {
@@ -2120,16 +2686,20 @@ ${bytes.length}`;
2120
2686
  * @private
2121
2687
  */
2122
2688
  _formatResponse(response) {
2123
- 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;
2124
2693
  const status = response?.data?.status || response?.status || response?.data?.resource?.status || (response?.success ? "completed" : "unknown");
2125
2694
  return {
2126
2695
  success: response.success,
2127
- qHash,
2696
+ proofId: finalProofId,
2697
+ qHash: finalQHash,
2128
2698
  status,
2129
2699
  data: response.data,
2130
2700
  message: response.message,
2131
2701
  timestamp: Date.now(),
2132
- statusUrl: qHash ? `${this.baseUrl}/api/v1/verification/status/${qHash}` : null
2702
+ statusUrl: finalProofId ? `${this.baseUrl}/api/v1/verification/status/${finalProofId}` : null
2133
2703
  };
2134
2704
  }
2135
2705
  /**
@@ -2173,11 +2743,16 @@ __export(sdk_exports, {
2173
2743
  AuthenticationError: () => AuthenticationError,
2174
2744
  ConfigurationError: () => ConfigurationError,
2175
2745
  DAY: () => DAY,
2746
+ GATE_AGENT_DELEGATION: () => GATE_AGENT_DELEGATION,
2747
+ GATE_AGENT_IDENTITY: () => GATE_AGENT_IDENTITY,
2748
+ GATE_CONTENT_MODERATION: () => GATE_CONTENT_MODERATION,
2176
2749
  GATE_CONTRACT_ADMIN: () => GATE_CONTRACT_ADMIN,
2177
2750
  GATE_DOMAIN_OWNER: () => GATE_DOMAIN_OWNER,
2178
2751
  GATE_LINKED_WALLETS: () => GATE_LINKED_WALLETS,
2179
2752
  GATE_NFT_HOLDER: () => GATE_NFT_HOLDER,
2753
+ GATE_PSEUDONYM: () => GATE_PSEUDONYM,
2180
2754
  GATE_TOKEN_HOLDER: () => GATE_TOKEN_HOLDER,
2755
+ GATE_WALLET_RISK: () => GATE_WALLET_RISK,
2181
2756
  HOUR: () => HOUR,
2182
2757
  MONTH: () => MONTH,
2183
2758
  NEUS_CONSTANTS: () => NEUS_CONSTANTS,
@@ -2205,9 +2780,15 @@ __export(sdk_exports, {
2205
2780
  isSupportedChain: () => isSupportedChain,
2206
2781
  isTerminalStatus: () => isTerminalStatus,
2207
2782
  normalizeAddress: () => normalizeAddress,
2783
+ resolveDID: () => resolveDID,
2784
+ resolveZkPassportConfig: () => resolveZkPassportConfig,
2785
+ signMessage: () => signMessage,
2786
+ standardizeVerificationRequest: () => standardizeVerificationRequest,
2787
+ toHexUtf8: () => toHexUtf8,
2208
2788
  validateQHash: () => validateQHash,
2209
2789
  validateSignatureComponents: () => validateSignatureComponents,
2210
2790
  validateTimestamp: () => validateTimestamp,
2791
+ validateUniversalAddress: () => validateUniversalAddress,
2211
2792
  validateVerifierPayload: () => validateVerifierPayload,
2212
2793
  validateWalletAddress: () => validateWalletAddress,
2213
2794
  withRetry: () => withRetry
@@ -2237,9 +2818,21 @@ var GATE_DOMAIN_OWNER = [
2237
2818
  var GATE_LINKED_WALLETS = [
2238
2819
  { verifierId: "wallet-link" }
2239
2820
  ];
2821
+ var GATE_AGENT_IDENTITY = [
2822
+ { verifierId: "agent-identity" }
2823
+ ];
2240
2824
  var GATE_AGENT_DELEGATION = [
2241
2825
  { verifierId: "agent-delegation", maxAgeMs: 7 * DAY }
2242
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
+ ];
2243
2836
  function createGate(requirements) {
2244
2837
  return requirements.map((req) => {
2245
2838
  if (typeof req === "string") {
@@ -2275,11 +2868,16 @@ var sdk_default = {
2275
2868
  AuthenticationError,
2276
2869
  ConfigurationError,
2277
2870
  DAY,
2871
+ GATE_AGENT_DELEGATION,
2872
+ GATE_AGENT_IDENTITY,
2873
+ GATE_CONTENT_MODERATION,
2278
2874
  GATE_CONTRACT_ADMIN,
2279
2875
  GATE_DOMAIN_OWNER,
2280
2876
  GATE_LINKED_WALLETS,
2281
2877
  GATE_NFT_HOLDER,
2878
+ GATE_PSEUDONYM,
2282
2879
  GATE_TOKEN_HOLDER,
2880
+ GATE_WALLET_RISK,
2283
2881
  HOUR,
2284
2882
  MONTH,
2285
2883
  NEUS_CONSTANTS,
@@ -2306,9 +2904,15 @@ var sdk_default = {
2306
2904
  isSupportedChain,
2307
2905
  isTerminalStatus,
2308
2906
  normalizeAddress,
2907
+ resolveDID,
2908
+ resolveZkPassportConfig,
2909
+ signMessage,
2910
+ standardizeVerificationRequest,
2911
+ toHexUtf8,
2309
2912
  validateQHash,
2310
2913
  validateSignatureComponents,
2311
2914
  validateTimestamp,
2915
+ validateUniversalAddress,
2312
2916
  validateVerifierPayload,
2313
2917
  validateWalletAddress,
2314
2918
  withRetry