@neus/sdk 1.0.2 → 1.0.4

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,21 +168,75 @@ 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) return "";
185
+ let zeroes = 0;
186
+ while (zeroes < source.length && source[zeroes] === 0) {
187
+ zeroes++;
188
+ }
189
+ const iFactor = Math.log(256) / Math.log(58);
190
+ const size = (source.length - zeroes) * iFactor + 1 >>> 0;
191
+ const b58 = new Uint8Array(size);
192
+ let length = 0;
193
+ for (let i = zeroes; i < source.length; i++) {
194
+ let carry = source[i];
195
+ let j = 0;
196
+ for (let k = size - 1; (carry !== 0 || j < length) && k >= 0; k--, j++) {
197
+ carry += 256 * b58[k];
198
+ b58[k] = carry % 58;
199
+ carry = carry / 58 | 0;
200
+ }
201
+ length = j;
202
+ }
203
+ let it = size - length;
204
+ while (it < size && b58[it] === 0) {
205
+ it++;
206
+ }
207
+ let out = BASE58_ALPHABET[0].repeat(zeroes);
208
+ for (; it < size; it++) {
209
+ out += BASE58_ALPHABET[b58[it]];
210
+ }
211
+ return out;
212
+ }
169
213
  function deterministicStringify(obj) {
170
214
  if (obj === null || obj === void 0) {
171
215
  return JSON.stringify(obj);
172
216
  }
173
217
  if (typeof obj !== "object") {
218
+ if (typeof obj === "string") return JSON.stringify(obj.normalize("NFC"));
174
219
  return JSON.stringify(obj);
175
220
  }
176
221
  if (Array.isArray(obj)) {
177
- return "[" + obj.map((item) => deterministicStringify(item)).join(",") + "]";
222
+ return `[${obj.map((item) => item === void 0 ? "null" : deterministicStringify(item)).join(",")}]`;
178
223
  }
179
- const sortedKeys = Object.keys(obj).sort();
224
+ const sortedKeys = Object.keys(obj).filter((k) => obj[k] !== void 0).sort();
180
225
  const pairs = sortedKeys.map(
181
- (key) => JSON.stringify(key) + ":" + deterministicStringify(obj[key])
226
+ (key) => `${JSON.stringify(key)}:${deterministicStringify(obj[key])}`
182
227
  );
183
- return "{" + pairs.join(",") + "}";
228
+ return `{${pairs.join(",")}}`;
229
+ }
230
+ function chainLineForPortableProofSigner(chain, chainId) {
231
+ if (typeof chain === "string" && chain.length > 0) {
232
+ const m = chain.match(/^eip155:(\d+)$/);
233
+ if (m) return Number(m[1]);
234
+ return chain;
235
+ }
236
+ if (typeof chainId === "number" && Number.isFinite(chainId) && chainId > 0) {
237
+ return chainId;
238
+ }
239
+ throw new SDKError("chainId is required (or provide chain for universal mode)", "INVALID_CHAIN_CONTEXT");
184
240
  }
185
241
  function constructVerificationMessage({ walletAddress, signedTimestamp, data, verifierIds, chainId, chain }) {
186
242
  if (!walletAddress || typeof walletAddress !== "string") {
@@ -195,28 +251,28 @@ function constructVerificationMessage({ walletAddress, signedTimestamp, data, ve
195
251
  if (!Array.isArray(verifierIds) || verifierIds.length === 0) {
196
252
  throw new SDKError("verifierIds is required and must be a non-empty array", "INVALID_VERIFIER_IDS");
197
253
  }
198
- const chainContext = typeof chain === "string" && chain.length > 0 ? chain : chainId;
199
- if (!chainContext) {
254
+ if ((typeof chain !== "string" || !chain.length) && !(typeof chainId === "number" && chainId > 0)) {
200
255
  throw new SDKError("chainId is required (or provide chain for universal mode)", "INVALID_CHAIN_CONTEXT");
201
256
  }
202
- if (chainContext === chainId && typeof chainId !== "number") {
203
- throw new SDKError("chainId must be a number when provided", "INVALID_CHAIN_ID");
204
- }
205
- if (chainContext === chain && (typeof chain !== "string" || !chain.includes(":"))) {
257
+ if (typeof chain === "string" && chain.length > 0 && !chain.includes(":")) {
206
258
  throw new SDKError('chain must be a "namespace:reference" string', "INVALID_CHAIN");
207
259
  }
260
+ if ((!chain || !chain.length) && typeof chainId !== "number") {
261
+ throw new SDKError("chainId must be a number when provided", "INVALID_CHAIN_ID");
262
+ }
263
+ const chainLine = chainLineForPortableProofSigner(chain, chainId);
208
264
  const namespace = typeof chain === "string" && chain.includes(":") ? chain.split(":")[0] : "eip155";
209
265
  const normalizedWalletAddress = namespace === "eip155" ? walletAddress.toLowerCase() : walletAddress;
210
266
  const dataString = deterministicStringify(data);
211
267
  const messageComponents = [
212
- "NEUS Verification Request",
268
+ PORTABLE_PROOF_SIGNER_HEADER,
213
269
  `Wallet: ${normalizedWalletAddress}`,
214
- `Chain: ${chainContext}`,
270
+ `Chain: ${chainLine}`,
215
271
  `Verifiers: ${verifierIds.join(",")}`,
216
272
  `Data: ${dataString}`,
217
273
  `Timestamp: ${signedTimestamp}`
218
274
  ];
219
- return messageComponents.join("\n");
275
+ return messageComponents.join("\n").normalize("NFC");
220
276
  }
221
277
  function validateWalletAddress(address) {
222
278
  if (!address || typeof address !== "string") {
@@ -224,6 +280,25 @@ function validateWalletAddress(address) {
224
280
  }
225
281
  return /^0x[a-fA-F0-9]{40}$/.test(address);
226
282
  }
283
+ function validateUniversalAddress(address, chain) {
284
+ if (!address || typeof address !== "string") return false;
285
+ const value = address.trim();
286
+ if (!value) return false;
287
+ const chainRef = typeof chain === "string" ? chain.trim().toLowerCase() : "";
288
+ const namespace = chainRef.includes(":") ? chainRef.split(":")[0] : "";
289
+ if (validateWalletAddress(value)) return true;
290
+ if (namespace === "eip155") return false;
291
+ if (namespace === "solana") {
292
+ return /^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(value);
293
+ }
294
+ if (namespace === "bip122") {
295
+ return /^(bc1|tb1|bcrt1)[a-z0-9]{11,87}$/.test(value.toLowerCase()) || /^[13mn2][a-km-zA-HJ-NP-Z1-9]{25,62}$/.test(value);
296
+ }
297
+ if (namespace === "near") {
298
+ return /^[a-z0-9._-]{2,64}$/.test(value);
299
+ }
300
+ return /^[A-Za-z0-9][A-Za-z0-9._:-]{1,127}$/.test(value);
301
+ }
227
302
  function validateTimestamp(timestamp, maxAgeMs = 5 * 60 * 1e3) {
228
303
  if (!timestamp || typeof timestamp !== "number") {
229
304
  return false;
@@ -245,7 +320,7 @@ function createVerificationData(content, owner, reference = null) {
245
320
  };
246
321
  return {
247
322
  content,
248
- owner: owner.toLowerCase(),
323
+ owner: validateWalletAddress(owner) ? owner.toLowerCase() : owner,
249
324
  reference: reference || {
250
325
  // Must be a valid backend enum value; 'content' is not supported.
251
326
  type: "other",
@@ -270,9 +345,234 @@ function deriveDid(address, chainIdOrChain) {
270
345
  return `did:pkh:eip155:${chainContext}:${address.toLowerCase()}`;
271
346
  }
272
347
  }
348
+ async function resolveDID(params, options = {}) {
349
+ const endpointPath = options.endpoint || "/api/v1/profile/did/resolve";
350
+ const apiUrl = typeof options.apiUrl === "string" ? options.apiUrl.trim() : "";
351
+ const resolveEndpoint = (path) => {
352
+ if (!path || typeof path !== "string") return null;
353
+ const trimmedPath = path.trim();
354
+ if (!trimmedPath) return null;
355
+ if (/^https?:\/\//i.test(trimmedPath)) return trimmedPath;
356
+ if (trimmedPath.startsWith("/")) {
357
+ if (!apiUrl) return trimmedPath;
358
+ try {
359
+ return new URL(trimmedPath, apiUrl.endsWith("/") ? apiUrl : `${apiUrl}/`).toString();
360
+ } catch {
361
+ return null;
362
+ }
363
+ }
364
+ const base = apiUrl || NEUS_CONSTANTS.API_BASE_URL;
365
+ if (!base || typeof base !== "string") return null;
366
+ try {
367
+ return new URL(trimmedPath, base.endsWith("/") ? base : `${base}/`).toString();
368
+ } catch {
369
+ return null;
370
+ }
371
+ };
372
+ const endpoint = resolveEndpoint(endpointPath);
373
+ if (!endpoint) {
374
+ throw new SDKError("resolveDID requires a valid endpoint", "INVALID_ENDPOINT");
375
+ }
376
+ const payload = {
377
+ walletAddress: params?.walletAddress,
378
+ chainId: params?.chainId,
379
+ chain: params?.chain
380
+ };
381
+ const isRelative = endpoint.startsWith("/") || !/^https?:\/\//i.test(endpoint);
382
+ const credentialsMode = options.credentials !== void 0 ? options.credentials : isRelative ? "same-origin" : "omit";
383
+ try {
384
+ const response = await fetch(endpoint, {
385
+ method: "POST",
386
+ headers: {
387
+ "Content-Type": "application/json",
388
+ Accept: "application/json",
389
+ ...options.headers || {}
390
+ },
391
+ body: JSON.stringify(payload),
392
+ credentials: credentialsMode
393
+ });
394
+ const json = await response.json().catch(() => null);
395
+ if (!response.ok) {
396
+ const msg = json?.error?.message || json?.error || json?.message || "DID resolution failed";
397
+ throw new SDKError(msg, "DID_RESOLVE_FAILED", json);
398
+ }
399
+ const did = json?.data?.did || json?.did;
400
+ if (!did || typeof did !== "string") {
401
+ throw new SDKError("DID resolution missing DID", "DID_RESOLVE_MISSING", json);
402
+ }
403
+ return { did, data: json?.data || null, raw: json };
404
+ } catch (error) {
405
+ if (error instanceof SDKError) throw error;
406
+ throw new SDKError(`DID resolution failed: ${error?.message || error}`, "DID_RESOLVE_FAILED");
407
+ }
408
+ }
409
+ async function standardizeVerificationRequest(params, options = {}) {
410
+ const endpointPath = options.endpoint || "/api/v1/verification/standardize";
411
+ const apiUrl = typeof options.apiUrl === "string" ? options.apiUrl.trim() : "";
412
+ const resolveEndpoint = (path) => {
413
+ if (!path || typeof path !== "string") return null;
414
+ const trimmedPath = path.trim();
415
+ if (!trimmedPath) return null;
416
+ if (/^https?:\/\//i.test(trimmedPath)) return trimmedPath;
417
+ if (trimmedPath.startsWith("/")) {
418
+ if (!apiUrl) return trimmedPath;
419
+ try {
420
+ return new URL(trimmedPath, apiUrl.endsWith("/") ? apiUrl : `${apiUrl}/`).toString();
421
+ } catch {
422
+ return null;
423
+ }
424
+ }
425
+ const base = apiUrl || NEUS_CONSTANTS.API_BASE_URL;
426
+ if (!base || typeof base !== "string") return null;
427
+ try {
428
+ return new URL(trimmedPath, base.endsWith("/") ? base : `${base}/`).toString();
429
+ } catch {
430
+ return null;
431
+ }
432
+ };
433
+ const endpoint = resolveEndpoint(endpointPath);
434
+ if (!endpoint) {
435
+ throw new SDKError("standardizeVerificationRequest requires a valid endpoint", "INVALID_ENDPOINT");
436
+ }
437
+ const isRelative = endpoint.startsWith("/") || !/^https?:\/\//i.test(endpoint);
438
+ const credentialsMode = options.credentials !== void 0 ? options.credentials : isRelative ? "same-origin" : "omit";
439
+ try {
440
+ const response = await fetch(endpoint, {
441
+ method: "POST",
442
+ headers: {
443
+ "Content-Type": "application/json",
444
+ Accept: "application/json",
445
+ ...options.headers || {}
446
+ },
447
+ body: JSON.stringify(params || {}),
448
+ credentials: credentialsMode
449
+ });
450
+ const json = await response.json().catch(() => null);
451
+ if (!response.ok) {
452
+ const msg = json?.error?.message || json?.error || json?.message || "Standardize request failed";
453
+ throw new SDKError(msg, "STANDARDIZE_FAILED", json);
454
+ }
455
+ return json?.data || json;
456
+ } catch (error) {
457
+ if (error instanceof SDKError) throw error;
458
+ throw new SDKError(`Standardize request failed: ${error?.message || error}`, "STANDARDIZE_FAILED");
459
+ }
460
+ }
461
+ function resolveZkPassportConfig(overrides = {}) {
462
+ const defaults = {
463
+ provider: "zkpassport",
464
+ scope: "basic_kyc",
465
+ checkSanctions: true,
466
+ requireFaceMatch: true,
467
+ faceMatchMode: "strict"
468
+ };
469
+ return {
470
+ ...defaults,
471
+ ...overrides && typeof overrides === "object" ? overrides : {}
472
+ };
473
+ }
474
+ function toHexUtf8(value) {
475
+ const input = typeof value === "string" ? value : String(value || "");
476
+ const bytes = new TextEncoder().encode(input);
477
+ return `0x${Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("")}`;
478
+ }
479
+ async function signMessage({ provider, message, walletAddress, chain } = {}) {
480
+ const msg = typeof message === "string" ? message : String(message || "");
481
+ if (!msg) {
482
+ throw new SDKError("signMessage: message is required", "INVALID_ARGUMENT");
483
+ }
484
+ const resolvedProvider = provider || (typeof window !== "undefined" && window?.ethereum ? window.ethereum : null);
485
+ if (!resolvedProvider) {
486
+ throw new SDKError("signMessage: provider is required", "SIGNER_UNAVAILABLE");
487
+ }
488
+ const chainStr = typeof chain === "string" && chain.trim().length > 0 ? chain.trim() : "eip155";
489
+ const namespace = chainStr.includes(":") ? chainStr.split(":")[0] || "eip155" : "eip155";
490
+ const resolveAddress = async () => {
491
+ if (typeof walletAddress === "string" && walletAddress.trim().length > 0) return walletAddress;
492
+ if (namespace === "solana") {
493
+ if (resolvedProvider?.publicKey && typeof resolvedProvider.publicKey.toBase58 === "function") {
494
+ const pk = resolvedProvider.publicKey.toBase58();
495
+ if (typeof pk === "string" && pk) return pk;
496
+ }
497
+ if (typeof resolvedProvider.getAddress === "function") {
498
+ const addr = await resolvedProvider.getAddress().catch(() => null);
499
+ if (typeof addr === "string" && addr) return addr;
500
+ }
501
+ if (typeof resolvedProvider.address === "string" && resolvedProvider.address) return resolvedProvider.address;
502
+ return null;
503
+ }
504
+ if (typeof resolvedProvider.address === "string" && resolvedProvider.address) return resolvedProvider.address;
505
+ if (typeof resolvedProvider.getAddress === "function") return resolvedProvider.getAddress();
506
+ if (typeof resolvedProvider.request === "function") {
507
+ let accounts = await resolvedProvider.request({ method: "eth_accounts" }).catch(() => []);
508
+ if (!Array.isArray(accounts) || accounts.length === 0) {
509
+ accounts = await resolvedProvider.request({ method: "eth_requestAccounts" }).catch(() => []);
510
+ }
511
+ if (Array.isArray(accounts) && accounts[0]) return accounts[0];
512
+ }
513
+ return null;
514
+ };
515
+ if (namespace !== "eip155") {
516
+ if (typeof resolvedProvider.signMessage === "function") {
517
+ const encoded = typeof msg === "string" ? new TextEncoder().encode(msg) : msg;
518
+ const result = await resolvedProvider.signMessage(encoded);
519
+ if (typeof result === "string" && result) return result;
520
+ if (result instanceof Uint8Array) return encodeBase58Bytes(result);
521
+ if (result instanceof ArrayBuffer) return encodeBase58Bytes(new Uint8Array(result));
522
+ if (ArrayBuffer.isView(result)) return encodeBase58Bytes(result);
523
+ if (typeof Buffer !== "undefined" && typeof Buffer.isBuffer === "function" && Buffer.isBuffer(result)) return encodeBase58Bytes(result);
524
+ }
525
+ throw new SDKError("Non-EVM signing requires provider.signMessage", "SIGNER_UNAVAILABLE");
526
+ }
527
+ const address = await resolveAddress();
528
+ if (typeof resolvedProvider.request === "function" && address) {
529
+ let firstPersonalSignError = null;
530
+ try {
531
+ const sig = await resolvedProvider.request({ method: "personal_sign", params: [msg, address] });
532
+ if (typeof sig === "string" && sig) return sig;
533
+ } catch (error) {
534
+ firstPersonalSignError = error;
535
+ }
536
+ let secondPersonalSignError = null;
537
+ try {
538
+ const sig = await resolvedProvider.request({ method: "personal_sign", params: [address, msg] });
539
+ if (typeof sig === "string" && sig) return sig;
540
+ } catch (error) {
541
+ secondPersonalSignError = error;
542
+ const signatureErrorMessage = String(
543
+ error?.message || error?.reason || firstPersonalSignError?.message || firstPersonalSignError?.reason || ""
544
+ ).toLowerCase();
545
+ const needsHex = /byte|bytes|invalid byte sequence|encoding|non-hex/i.test(signatureErrorMessage);
546
+ if (needsHex) {
547
+ try {
548
+ const hexMsg = toHexUtf8(msg);
549
+ const sig = await resolvedProvider.request({ method: "personal_sign", params: [hexMsg, address] });
550
+ if (typeof sig === "string" && sig) return sig;
551
+ } catch {
552
+ }
553
+ }
554
+ }
555
+ try {
556
+ const sig = await resolvedProvider.request({ method: "eth_sign", params: [address, msg] });
557
+ if (typeof sig === "string" && sig) return sig;
558
+ } catch {
559
+ }
560
+ if (secondPersonalSignError || firstPersonalSignError) {
561
+ const lastError = secondPersonalSignError || firstPersonalSignError;
562
+ const isUserRejection = [4001, "ACTION_REJECTED"].includes(lastError?.code);
563
+ if (isUserRejection) {
564
+ throw lastError;
565
+ }
566
+ }
567
+ }
568
+ if (typeof resolvedProvider.signMessage === "function") {
569
+ const result = await resolvedProvider.signMessage(msg);
570
+ if (typeof result === "string" && result) return result;
571
+ }
572
+ throw new SDKError("Unable to sign message with provided wallet/provider", "SIGNER_UNAVAILABLE");
573
+ }
273
574
  function isTerminalStatus(status) {
274
- if (!status || typeof status !== "string")
275
- return false;
575
+ if (!status || typeof status !== "string") return false;
276
576
  const successStates = [
277
577
  "verified",
278
578
  "verified_no_verifiers",
@@ -293,8 +593,7 @@ function isTerminalStatus(status) {
293
593
  return successStates.includes(status) || failureStates.includes(status);
294
594
  }
295
595
  function isSuccessStatus(status) {
296
- if (!status || typeof status !== "string")
297
- return false;
596
+ if (!status || typeof status !== "string") return false;
298
597
  const successStates = [
299
598
  "verified",
300
599
  "verified_no_verifiers",
@@ -305,8 +604,7 @@ function isSuccessStatus(status) {
305
604
  return successStates.includes(status);
306
605
  }
307
606
  function isFailureStatus(status) {
308
- if (!status || typeof status !== "string")
309
- return false;
607
+ if (!status || typeof status !== "string") return false;
310
608
  const failureStates = [
311
609
  "rejected",
312
610
  "rejected_verifier_failure",
@@ -457,23 +755,20 @@ function validateVerifierPayload(verifierId, data) {
457
755
  const id = verifierId.replace(/@\d+$/, "");
458
756
  if (id === "nft-ownership") {
459
757
  ["contractAddress", "tokenId", "chainId"].forEach((key) => {
460
- if (!(key in data))
461
- result.missing.push(key);
758
+ if (!(key in data)) result.missing.push(key);
462
759
  });
463
760
  if (!("ownerAddress" in data)) {
464
- result.warnings.push("ownerAddress omitted (most deployments default to the signed walletAddress)");
761
+ result.warnings.push("ownerAddress omitted (defaults to the signed walletAddress)");
465
762
  }
466
763
  } else if (id === "token-holding") {
467
764
  ["contractAddress", "minBalance", "chainId"].forEach((key) => {
468
- if (!(key in data))
469
- result.missing.push(key);
765
+ if (!(key in data)) result.missing.push(key);
470
766
  });
471
767
  if (!("ownerAddress" in data)) {
472
- result.warnings.push("ownerAddress omitted (most deployments default to the signed walletAddress)");
768
+ result.warnings.push("ownerAddress omitted (defaults to the signed walletAddress)");
473
769
  }
474
770
  } else if (id === "ownership-basic") {
475
- if (!("owner" in data))
476
- result.missing.push("owner");
771
+ if (!("owner" in data)) result.missing.push("owner");
477
772
  const hasContent = typeof data.content === "string" && data.content.length > 0;
478
773
  const hasContentHash = typeof data.contentHash === "string" && data.contentHash.length > 0;
479
774
  const hasRefId = typeof data.reference?.id === "string" && data.reference.id.length > 0;
@@ -537,8 +832,7 @@ async function withRetry(fn, options = {}) {
537
832
  return await fn();
538
833
  } catch (error) {
539
834
  lastError = error;
540
- if (attempt === maxAttempts)
541
- break;
835
+ if (attempt === maxAttempts) break;
542
836
  const delayMs = Math.min(
543
837
  baseDelay * Math.pow(backoffFactor, attempt - 1),
544
838
  maxDelay
@@ -606,10 +900,73 @@ function validateSignatureComponents({ walletAddress, signature, signedTimestamp
606
900
  }
607
901
  return result;
608
902
  }
609
- var StatusPoller, NEUS_CONSTANTS;
903
+ function toAgentDelegationMaxSpend(humanAmount, decimals) {
904
+ if (humanAmount === void 0 || humanAmount === null) {
905
+ throw new ValidationError("humanAmount is required", "humanAmount", humanAmount);
906
+ }
907
+ const s0 = String(humanAmount).trim();
908
+ if (!s0) {
909
+ throw new ValidationError("humanAmount must be non-empty", "humanAmount", humanAmount);
910
+ }
911
+ if (s0.startsWith("-") || s0.startsWith("+")) {
912
+ throw new ValidationError("humanAmount must be non-negative", "humanAmount", humanAmount);
913
+ }
914
+ const d = Number(decimals);
915
+ if (!Number.isInteger(d) || d < 0 || d > 78) {
916
+ throw new ValidationError("decimalPlaces must be an integer from 0 to 78", "decimals", decimals);
917
+ }
918
+ if (!/^(?:\d+\.?\d*|\.\d+)$/.test(s0)) {
919
+ throw new ValidationError(
920
+ 'humanAmount must be a decimal string (e.g. "100" or "100.50")',
921
+ "humanAmount",
922
+ humanAmount
923
+ );
924
+ }
925
+ const dot = s0.indexOf(".");
926
+ const intPart = dot === -1 ? s0 : s0.slice(0, dot);
927
+ const fracRaw = dot === -1 ? "" : s0.slice(dot + 1);
928
+ const intNormalized = intPart === "" ? "0" : (() => {
929
+ const s = intPart.replace(/^0+/, "");
930
+ return s === "" ? "0" : s;
931
+ })();
932
+ if (!/^\d+$/.test(intNormalized)) {
933
+ throw new ValidationError("humanAmount has an invalid integer part", "humanAmount", humanAmount);
934
+ }
935
+ if (fracRaw && !/^\d*$/.test(fracRaw)) {
936
+ throw new ValidationError("humanAmount has an invalid fractional part", "humanAmount", humanAmount);
937
+ }
938
+ const fracPadded = `${fracRaw}${"0".repeat(d)}`.slice(0, d);
939
+ const base = BigInt(10) ** BigInt(d);
940
+ const value = BigInt(intNormalized) * base + BigInt(fracPadded || "0");
941
+ const out = value.toString();
942
+ if (out.length > 78) {
943
+ throw new ValidationError("maxSpend exceeds 78-digit limit after conversion", "humanAmount", humanAmount);
944
+ }
945
+ return out;
946
+ }
947
+ function getHostedCheckoutUrl(opts = {}) {
948
+ const base = typeof opts.baseUrl === "string" && opts.baseUrl.trim() ? opts.baseUrl.replace(/\/+$/, "") : DEFAULT_HOSTED_VERIFY_URL;
949
+ const params = new URLSearchParams();
950
+ if (opts.gateId) params.set("gateId", String(opts.gateId));
951
+ if (opts.returnUrl) params.set("returnUrl", String(opts.returnUrl));
952
+ if (Array.isArray(opts.verifiers) && opts.verifiers.length > 0) {
953
+ params.set("verifiers", opts.verifiers.filter(Boolean).join(","));
954
+ }
955
+ if (opts.preset) params.set("preset", String(opts.preset));
956
+ if (opts.mode) params.set("mode", String(opts.mode));
957
+ if (opts.intent) params.set("intent", String(opts.intent));
958
+ if (opts.origin) params.set("origin", String(opts.origin));
959
+ if (opts.oauthProvider) params.set("oauthProvider", String(opts.oauthProvider));
960
+ const qs = params.toString();
961
+ return qs ? `${base}?${qs}` : base;
962
+ }
963
+ var PORTABLE_PROOF_SIGNER_HEADER, BASE58_ALPHABET, StatusPoller, NEUS_CONSTANTS, DEFAULT_HOSTED_VERIFY_URL;
610
964
  var init_utils = __esm({
611
965
  "utils.js"() {
966
+ "use strict";
612
967
  init_errors();
968
+ PORTABLE_PROOF_SIGNER_HEADER = "Portable Proof Verification Request";
969
+ BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
613
970
  StatusPoller = class {
614
971
  constructor(client, qHash, options = {}) {
615
972
  this.client = client;
@@ -632,7 +989,7 @@ var init_utils = __esm({
632
989
  const pollAttempt = async () => {
633
990
  try {
634
991
  this.attempt++;
635
- const response = await this.client.getStatus(this.qHash);
992
+ const response = await this.client.getProof(this.qHash);
636
993
  if (isTerminalStatus(response.status)) {
637
994
  resolve(response);
638
995
  return;
@@ -677,7 +1034,7 @@ var init_utils = __esm({
677
1034
  }
678
1035
  };
679
1036
  NEUS_CONSTANTS = {
680
- // Hub chain (where all verifications occur)
1037
+ /** Default EVM chain id for NEUS protocol signing context (`HUB_CHAIN_ID` name kept for compatibility). */
681
1038
  HUB_CHAIN_ID: 84532,
682
1039
  // Supported target chains for cross-chain propagation
683
1040
  TESTNET_CHAINS: [
@@ -705,6 +1062,7 @@ var init_utils = __esm({
705
1062
  "token-holding"
706
1063
  ]
707
1064
  };
1065
+ DEFAULT_HOSTED_VERIFY_URL = "https://neus.network/verify";
708
1066
  }
709
1067
  });
710
1068
 
@@ -712,25 +1070,40 @@ var init_utils = __esm({
712
1070
  var client_exports = {};
713
1071
  __export(client_exports, {
714
1072
  NeusClient: () => NeusClient,
1073
+ PORTABLE_PROOF_SIGNER_HEADER: () => PORTABLE_PROOF_SIGNER_HEADER,
715
1074
  constructVerificationMessage: () => constructVerificationMessage
716
1075
  });
717
- var validateVerifierData, NeusClient;
1076
+ var FALLBACK_PUBLIC_VERIFIER_CATALOG, EVM_ADDRESS_RE, validateVerifierData, NeusClient;
718
1077
  var init_client = __esm({
719
1078
  "client.js"() {
1079
+ "use strict";
720
1080
  init_errors();
721
1081
  init_utils();
1082
+ FALLBACK_PUBLIC_VERIFIER_CATALOG = {
1083
+ "ownership-basic": { supportsDirectApi: true },
1084
+ "ownership-pseudonym": { supportsDirectApi: true },
1085
+ "ownership-dns-txt": { supportsDirectApi: true },
1086
+ "ownership-social": { supportsDirectApi: false },
1087
+ "ownership-org-oauth": { supportsDirectApi: false },
1088
+ "contract-ownership": { supportsDirectApi: true },
1089
+ "nft-ownership": { supportsDirectApi: true },
1090
+ "token-holding": { supportsDirectApi: true },
1091
+ "wallet-link": { supportsDirectApi: true },
1092
+ "wallet-risk": { supportsDirectApi: true },
1093
+ "proof-of-human": { supportsDirectApi: false },
1094
+ "agent-identity": { supportsDirectApi: true },
1095
+ "agent-delegation": { supportsDirectApi: true },
1096
+ "ai-content-moderation": { supportsDirectApi: true }
1097
+ };
1098
+ EVM_ADDRESS_RE = /^0x[a-fA-F0-9]{40}$/;
722
1099
  validateVerifierData = (verifierId, data) => {
723
1100
  if (!data || typeof data !== "object") {
724
1101
  return { valid: false, error: "Data object is required" };
725
1102
  }
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
1103
  switch (verifierId) {
731
1104
  case "ownership-basic":
732
- if (!data.owner || !validateWalletAddress(data.owner)) {
733
- return { valid: false, error: "owner (wallet address) is required" };
1105
+ if (!data.owner || !validateUniversalAddress(data.owner, typeof data.chain === "string" ? data.chain : void 0)) {
1106
+ return { valid: false, error: "owner (universal wallet address) is required" };
734
1107
  }
735
1108
  if (data.content !== void 0 && data.content !== null) {
736
1109
  if (typeof data.content !== "string") {
@@ -856,17 +1229,20 @@ var init_client = __esm({
856
1229
  }
857
1230
  break;
858
1231
  case "wallet-link":
859
- if (!data.primaryWalletAddress || !validateWalletAddress(data.primaryWalletAddress)) {
1232
+ if (!data.primaryWalletAddress || !validateUniversalAddress(data.primaryWalletAddress, data.chain)) {
860
1233
  return { valid: false, error: "primaryWalletAddress is required" };
861
1234
  }
862
- if (!data.secondaryWalletAddress || !validateWalletAddress(data.secondaryWalletAddress)) {
1235
+ if (!data.secondaryWalletAddress || !validateUniversalAddress(data.secondaryWalletAddress, data.chain)) {
863
1236
  return { valid: false, error: "secondaryWalletAddress is required" };
864
1237
  }
865
1238
  if (!data.signature || typeof data.signature !== "string") {
866
1239
  return { valid: false, error: "signature is required (signed by secondary wallet)" };
867
1240
  }
868
- if (typeof data.chainId !== "number") {
869
- return { valid: false, error: "chainId is required" };
1241
+ if (typeof data.chain !== "string" || !/^[a-z0-9]+:[^\s]+$/.test(data.chain)) {
1242
+ return { valid: false, error: "chain is required (namespace:reference)" };
1243
+ }
1244
+ if (typeof data.signatureMethod !== "string" || !data.signatureMethod.trim()) {
1245
+ return { valid: false, error: "signatureMethod is required" };
870
1246
  }
871
1247
  if (typeof data.signedTimestamp !== "number") {
872
1248
  return { valid: false, error: "signedTimestamp is required" };
@@ -937,7 +1313,10 @@ var init_client = __esm({
937
1313
  const maxBytes = 50 * 1024;
938
1314
  const bytes = typeof TextEncoder !== "undefined" ? new TextEncoder().encode(data.content).length : String(data.content).length;
939
1315
  if (bytes > maxBytes) {
940
- return { valid: false, error: `content exceeds ${maxBytes} bytes limit for ai-content-moderation verifier (text)` };
1316
+ return {
1317
+ valid: false,
1318
+ error: `content exceeds ${maxBytes} bytes limit for ai-content-moderation verifier (text)`
1319
+ };
941
1320
  }
942
1321
  } catch {
943
1322
  }
@@ -961,7 +1340,7 @@ var init_client = __esm({
961
1340
  }
962
1341
  break;
963
1342
  case "wallet-risk":
964
- if (data.walletAddress && !validateWalletAddress(data.walletAddress)) {
1343
+ if (data.walletAddress && !validateUniversalAddress(data.walletAddress, data.chain)) {
965
1344
  return { valid: false, error: "Invalid walletAddress" };
966
1345
  }
967
1346
  break;
@@ -993,6 +1372,21 @@ var init_client = __esm({
993
1372
  if (typeof this.config.apiKey === "string" && this.config.apiKey.trim().length > 0) {
994
1373
  this.defaultHeaders["Authorization"] = `Bearer ${this.config.apiKey.trim()}`;
995
1374
  }
1375
+ if (typeof this.config.appId === "string" && this.config.appId.trim().length > 0) {
1376
+ this.defaultHeaders["X-Neus-App"] = this.config.appId.trim();
1377
+ }
1378
+ if (typeof this.config.paymentSignature === "string" && this.config.paymentSignature.trim().length > 0) {
1379
+ this.defaultHeaders["PAYMENT-SIGNATURE"] = this.config.paymentSignature.trim();
1380
+ }
1381
+ if (this.config.extraHeaders && typeof this.config.extraHeaders === "object") {
1382
+ for (const [k, v] of Object.entries(this.config.extraHeaders)) {
1383
+ if (!k || v === void 0 || v === null) continue;
1384
+ const key = String(k).trim();
1385
+ const value = String(v).trim();
1386
+ if (!key || !value) continue;
1387
+ this.defaultHeaders[key] = value;
1388
+ }
1389
+ }
996
1390
  try {
997
1391
  if (typeof window !== "undefined" && window.location && window.location.origin) {
998
1392
  this.defaultHeaders["X-Client-Origin"] = window.location.origin;
@@ -1000,87 +1394,183 @@ var init_client = __esm({
1000
1394
  } catch {
1001
1395
  }
1002
1396
  }
1003
- // ============================================================================
1004
- // CORE VERIFICATION METHODS
1005
- // ============================================================================
1397
+ _getHubChainId() {
1398
+ const configured = Number(this.config?.hubChainId);
1399
+ if (Number.isFinite(configured) && configured > 0) return Math.floor(configured);
1400
+ return NEUS_CONSTANTS.HUB_CHAIN_ID;
1401
+ }
1402
+ _normalizeIdentity(value) {
1403
+ let raw = String(value || "").trim();
1404
+ if (!raw) return "";
1405
+ const didMatch = raw.match(/^did:pkh:([^:]+):([^:]+):(.+)$/i);
1406
+ if (didMatch && didMatch[3]) {
1407
+ raw = String(didMatch[3]).trim();
1408
+ }
1409
+ return EVM_ADDRESS_RE.test(raw) ? raw.toLowerCase() : raw;
1410
+ }
1411
+ _inferChainForAddress(address, explicitChain) {
1412
+ if (typeof explicitChain === "string" && explicitChain.includes(":")) return explicitChain.trim();
1413
+ const raw = String(address || "").trim();
1414
+ const didMatch = raw.match(/^did:pkh:([^:]+):([^:]+):(.+)$/i);
1415
+ if (didMatch && didMatch[1] && didMatch[2]) {
1416
+ return `${didMatch[1]}:${didMatch[2]}`;
1417
+ }
1418
+ if (EVM_ADDRESS_RE.test(raw)) {
1419
+ return `eip155:${this._getHubChainId()}`;
1420
+ }
1421
+ return "solana:mainnet";
1422
+ }
1423
+ async _resolveWalletSigner(wallet) {
1424
+ if (!wallet) {
1425
+ throw new ConfigurationError("No wallet provider available");
1426
+ }
1427
+ if (wallet.address) {
1428
+ return { signerWalletAddress: wallet.address, provider: wallet };
1429
+ }
1430
+ if (wallet.publicKey && typeof wallet.publicKey.toBase58 === "function") {
1431
+ return { signerWalletAddress: wallet.publicKey.toBase58(), provider: wallet };
1432
+ }
1433
+ if (typeof wallet.getAddress === "function") {
1434
+ const signerWalletAddress = await wallet.getAddress().catch(() => null);
1435
+ return { signerWalletAddress, provider: wallet };
1436
+ }
1437
+ if (wallet.selectedAddress || wallet.request) {
1438
+ const provider = wallet;
1439
+ if (wallet.selectedAddress) {
1440
+ return { signerWalletAddress: wallet.selectedAddress, provider };
1441
+ }
1442
+ const accounts = await provider.request({ method: "eth_accounts" });
1443
+ if (!accounts || accounts.length === 0) {
1444
+ throw new ConfigurationError("No wallet accounts available");
1445
+ }
1446
+ return { signerWalletAddress: accounts[0], provider };
1447
+ }
1448
+ throw new ConfigurationError("Invalid wallet provider");
1449
+ }
1450
+ _getDefaultBrowserWallet() {
1451
+ if (typeof window === "undefined") return null;
1452
+ return window.ethereum || window.solana || window.phantom && window.phantom.solana || null;
1453
+ }
1454
+ async _buildPrivateGateAuth({ address, wallet, chain, signatureMethod } = {}) {
1455
+ const providerWallet = wallet || this._getDefaultBrowserWallet();
1456
+ const { signerWalletAddress, provider } = await this._resolveWalletSigner(providerWallet);
1457
+ if (!signerWalletAddress || typeof signerWalletAddress !== "string") {
1458
+ throw new ConfigurationError("No wallet accounts available");
1459
+ }
1460
+ const normalizedSigner = this._normalizeIdentity(signerWalletAddress);
1461
+ const normalizedAddress = this._normalizeIdentity(address);
1462
+ if (!normalizedSigner || normalizedSigner !== normalizedAddress) {
1463
+ throw new ValidationError("wallet must match address when includePrivate=true");
1464
+ }
1465
+ const signerIsEvm = EVM_ADDRESS_RE.test(normalizedSigner);
1466
+ const resolvedChain = this._inferChainForAddress(normalizedSigner, chain);
1467
+ const resolvedSignatureMethod = typeof signatureMethod === "string" && signatureMethod.trim() ? signatureMethod.trim() : signerIsEvm ? "eip191" : "ed25519";
1468
+ const signedTimestamp = Date.now();
1469
+ const message = constructVerificationMessage({
1470
+ walletAddress: signerWalletAddress,
1471
+ signedTimestamp,
1472
+ data: { action: "gate_check_private_proofs", walletAddress: normalizedAddress },
1473
+ verifierIds: ["ownership-basic"],
1474
+ ...signerIsEvm ? { chainId: this._getHubChainId() } : { chain: resolvedChain }
1475
+ });
1476
+ let signature;
1477
+ try {
1478
+ signature = await signMessage({
1479
+ provider,
1480
+ message,
1481
+ walletAddress: signerWalletAddress,
1482
+ ...signerIsEvm ? {} : { chain: resolvedChain }
1483
+ });
1484
+ } catch (error) {
1485
+ if (error.code === 4001) {
1486
+ throw new ValidationError("User rejected signature request");
1487
+ }
1488
+ throw new ValidationError(`Failed to sign message: ${error.message}`);
1489
+ }
1490
+ return {
1491
+ walletAddress: signerWalletAddress,
1492
+ signature,
1493
+ signedTimestamp,
1494
+ ...signerIsEvm ? {} : { chain: resolvedChain, signatureMethod: resolvedSignatureMethod }
1495
+ };
1496
+ }
1497
+ async createGatePrivateAuth(params = {}) {
1498
+ const address = (params.address || "").toString();
1499
+ if (!validateUniversalAddress(address, params.chain)) {
1500
+ throw new ValidationError("Valid address is required");
1501
+ }
1502
+ return this._buildPrivateGateAuth({
1503
+ address,
1504
+ wallet: params.wallet,
1505
+ chain: params.chain,
1506
+ signatureMethod: params.signatureMethod
1507
+ });
1508
+ }
1006
1509
  /**
1007
- * VERIFY - Standard verification (auto or manual)
1008
- *
1009
- * Create proofs with complete control over the verification process.
1010
- * If signature and walletAddress are omitted but verifier/content are provided,
1011
- * this method performs the wallet flow inline (no aliases, no secondary methods).
1012
- *
1510
+ * Create a verification proof.
1511
+ *
1512
+ * Supports two paths:
1513
+ * - **Auto:** Supply `verifier`, `content`, and/or `data` with an optional
1514
+ * `wallet` provider. The SDK performs signing in the client.
1515
+ * - **Manual:** Supply pre-signed `verifierIds`, `data`, `walletAddress`,
1516
+ * `signature`, and `signedTimestamp`.
1517
+ *
1013
1518
  * @param {Object} params - Verification parameters
1519
+ * @param {string} [params.verifier] - Verifier ID (auto path, e.g. 'ownership-basic')
1520
+ * @param {string} [params.content] - Content to verify (auto path)
1521
+ * @param {Object} [params.data] - Structured verification data
1522
+ * @param {Object} [params.wallet] - Wallet provider (auto path)
1523
+ * @param {Object} [params.options] - Additional options
1014
1524
  * @param {Array<string>} [params.verifierIds] - Array of verifier IDs (manual path)
1015
- * @param {Object} [params.data] - Verification data object (manual path)
1016
1525
  * @param {string} [params.walletAddress] - Wallet address that signed the request (manual path)
1017
1526
  * @param {string} [params.signature] - EIP-191 signature (manual path)
1018
1527
  * @param {number} [params.signedTimestamp] - Unix timestamp when signature was created (manual path)
1019
- * @param {number} [params.chainId] - Chain ID for verification context (optional, managed by protocol)
1020
- * @param {Object} [params.options] - Additional options
1021
- * @param {string} [params.verifier] - Verifier ID (auto path)
1022
- * @param {string} [params.content] - Content/description (auto path)
1023
- * @param {Object} [params.wallet] - Optional injected wallet/provider (auto path)
1024
- * @returns {Promise<Object>} Verification result with qHash
1025
- *
1528
+ * @param {number} [params.chainId] - EVM signing-context hint; when omitted, resolved to the NEUS protocol primary chain for signing
1529
+ * @returns {Promise<Object>} Verification result with proofId
1530
+ *
1531
+ * @example
1532
+ * // Auto path
1533
+ * const proof = await client.verify({
1534
+ * verifier: 'ownership-basic',
1535
+ * content: 'Hello World',
1536
+ * wallet: window.ethereum
1537
+ * });
1538
+ *
1026
1539
  * @example
1540
+ * // Manual path
1027
1541
  * const proof = await client.verify({
1028
1542
  * verifierIds: ['ownership-basic'],
1029
- * data: {
1030
- * content: "My content",
1031
- * owner: walletAddress, // or ownerAddress for nft-ownership/token-holding
1032
- * reference: { type: 'other', id: 'my-unique-identifier' }
1033
- * },
1543
+ * data: { content: "My content", owner: walletAddress },
1034
1544
  * walletAddress: '0x...',
1035
1545
  * signature: '0x...',
1036
1546
  * signedTimestamp: Date.now(),
1037
1547
  * options: { targetChains: [421614, 11155111] }
1038
1548
  * });
1039
1549
  */
1040
- /**
1041
- * Create a verification proof
1042
- *
1043
- * @param {Object} params - Verification parameters
1044
- * @param {string} [params.verifier] - Verifier ID (e.g., 'ownership-basic')
1045
- * @param {string} [params.content] - Content to verify
1046
- * @param {Object} [params.data] - Structured verification data
1047
- * @param {Object} [params.wallet] - Wallet provider
1048
- * @param {Object} [params.options] - Additional options
1049
- * @returns {Promise<Object>} Verification result with qHash
1050
- *
1051
- * @example
1052
- * // Simple ownership proof
1053
- * const proof = await client.verify({
1054
- * verifier: 'ownership-basic',
1055
- * content: 'Hello World',
1056
- * wallet: window.ethereum
1057
- * });
1058
- */
1059
1550
  async verify(params) {
1060
1551
  if ((!params?.signature || !params?.walletAddress) && (params?.verifier || params?.content || params?.data)) {
1061
1552
  const { content, verifier = "ownership-basic", data: data2 = null, wallet = null, options: options2 = {} } = params;
1062
1553
  if (verifier === "ownership-basic" && !data2 && (!content || typeof content !== "string")) {
1063
1554
  throw new ValidationError("content is required and must be a string (or use data param with owner + reference)");
1064
1555
  }
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
- ];
1556
+ let verifierCatalog = FALLBACK_PUBLIC_VERIFIER_CATALOG;
1557
+ try {
1558
+ const discovered = await this.getVerifierCatalog();
1559
+ if (discovered && discovered.metadata && Object.keys(discovered.metadata).length > 0) {
1560
+ verifierCatalog = discovered.metadata;
1561
+ }
1562
+ } catch {
1563
+ }
1564
+ const validVerifiers = Object.keys(verifierCatalog);
1081
1565
  if (!validVerifiers.includes(verifier)) {
1082
1566
  throw new ValidationError(`Invalid verifier '${verifier}'. Must be one of: ${validVerifiers.join(", ")}.`);
1083
1567
  }
1568
+ if (verifierCatalog?.[verifier]?.supportsDirectApi === false) {
1569
+ const hostedCheckoutUrl = options2?.hostedCheckoutUrl || "https://neus.network/verify";
1570
+ throw new ValidationError(
1571
+ `${verifier} requires hosted interactive checkout. Use VerifyGate or redirect to ${hostedCheckoutUrl}.`
1572
+ );
1573
+ }
1084
1574
  const requiresDataParam = [
1085
1575
  "ownership-dns-txt",
1086
1576
  "wallet-link",
@@ -1098,8 +1588,12 @@ var init_client = __esm({
1098
1588
  }
1099
1589
  let walletAddress2, provider;
1100
1590
  if (wallet) {
1101
- walletAddress2 = wallet.address || wallet.selectedAddress;
1591
+ walletAddress2 = wallet.address || wallet.selectedAddress || wallet.walletAddress || (typeof wallet.getAddress === "function" ? await wallet.getAddress() : null);
1102
1592
  provider = wallet.provider || wallet;
1593
+ if (!walletAddress2 && provider && typeof provider.request === "function") {
1594
+ const accounts = await provider.request({ method: "eth_accounts" });
1595
+ walletAddress2 = Array.isArray(accounts) ? accounts[0] : null;
1596
+ }
1103
1597
  } else {
1104
1598
  if (typeof window === "undefined" || !window.ethereum) {
1105
1599
  throw new ConfigurationError("No Web3 wallet detected. Please install MetaMask or provide wallet parameter.");
@@ -1175,14 +1669,18 @@ var init_client = __esm({
1175
1669
  if (!data2?.signature) {
1176
1670
  throw new ValidationError("wallet-link requires signature in data parameter (signed by secondary wallet)");
1177
1671
  }
1178
- if (typeof data2?.chainId !== "number") {
1179
- throw new ValidationError("wallet-link requires chainId (number) in data parameter");
1672
+ if (typeof data2?.chain !== "string" || !/^[a-z0-9]+:[^\s]+$/.test(data2.chain)) {
1673
+ throw new ValidationError("wallet-link requires chain (namespace:reference) in data parameter");
1674
+ }
1675
+ if (typeof data2?.signatureMethod !== "string" || !data2.signatureMethod.trim()) {
1676
+ throw new ValidationError("wallet-link requires signatureMethod in data parameter");
1180
1677
  }
1181
1678
  verificationData = {
1182
1679
  primaryWalletAddress: walletAddress2,
1183
1680
  secondaryWalletAddress: data2.secondaryWalletAddress,
1184
1681
  signature: data2.signature,
1185
- chainId: data2.chainId,
1682
+ chain: data2.chain,
1683
+ signatureMethod: data2.signatureMethod,
1186
1684
  signedTimestamp: data2?.signedTimestamp || Date.now()
1187
1685
  };
1188
1686
  } else if (verifier === "contract-ownership") {
@@ -1208,7 +1706,10 @@ var init_client = __esm({
1208
1706
  ...data2?.agentLabel && { agentLabel: data2.agentLabel },
1209
1707
  ...data2?.agentType && { agentType: data2.agentType },
1210
1708
  ...data2?.description && { description: data2.description },
1211
- ...data2?.capabilities && { capabilities: data2.capabilities }
1709
+ ...data2?.capabilities && { capabilities: data2.capabilities },
1710
+ ...data2?.instructions && { instructions: data2.instructions },
1711
+ ...data2?.skills && { skills: data2.skills },
1712
+ ...data2?.services && { services: data2.services }
1212
1713
  };
1213
1714
  } else if (verifier === "agent-delegation") {
1214
1715
  if (!data2?.agentWallet) {
@@ -1221,7 +1722,11 @@ var init_client = __esm({
1221
1722
  ...data2?.scope && { scope: data2.scope },
1222
1723
  ...data2?.permissions && { permissions: data2.permissions },
1223
1724
  ...data2?.maxSpend && { maxSpend: data2.maxSpend },
1224
- ...data2?.expiresAt && { expiresAt: data2.expiresAt }
1725
+ ...data2?.allowedPaymentTypes && { allowedPaymentTypes: data2.allowedPaymentTypes },
1726
+ ...data2?.receiptDisclosure && { receiptDisclosure: data2.receiptDisclosure },
1727
+ ...data2?.expiresAt && { expiresAt: data2.expiresAt },
1728
+ ...data2?.instructions && { instructions: data2.instructions },
1729
+ ...data2?.skills && { skills: data2.skills }
1225
1730
  };
1226
1731
  } else if (verifier === "ai-content-moderation") {
1227
1732
  if (!data2?.content) {
@@ -1271,48 +1776,41 @@ var init_client = __esm({
1271
1776
  signedTimestamp: signedTimestamp2,
1272
1777
  data: verificationData,
1273
1778
  verifierIds: verifierIds2,
1274
- chainId: NEUS_CONSTANTS.HUB_CHAIN_ID
1779
+ chainId: this._getHubChainId()
1275
1780
  // Protocol-managed chain
1276
1781
  });
1277
1782
  let signature2;
1278
1783
  try {
1279
- const toHexUtf8 = (s) => {
1784
+ const toHexUtf82 = (s) => {
1280
1785
  try {
1281
1786
  const enc = new TextEncoder();
1282
1787
  const bytes = enc.encode(s);
1283
1788
  let hex = "0x";
1284
- for (let i = 0; i < bytes.length; i++)
1285
- hex += bytes[i].toString(16).padStart(2, "0");
1789
+ for (let i = 0; i < bytes.length; i++) hex += bytes[i].toString(16).padStart(2, "0");
1286
1790
  return hex;
1287
1791
  } catch {
1288
1792
  let hex = "0x";
1289
- for (let i = 0; i < s.length; i++)
1290
- hex += s.charCodeAt(i).toString(16).padStart(2, "0");
1793
+ for (let i = 0; i < s.length; i++) hex += s.charCodeAt(i).toString(16).padStart(2, "0");
1291
1794
  return hex;
1292
1795
  }
1293
1796
  };
1294
1797
  const isFarcasterWallet = (() => {
1295
- if (typeof window === "undefined")
1296
- return false;
1798
+ if (typeof window === "undefined") return false;
1297
1799
  try {
1298
1800
  const w = window;
1299
1801
  const fc = w.farcaster;
1300
- if (!fc || !fc.context)
1301
- return false;
1802
+ if (!fc || !fc.context) return false;
1302
1803
  const fcProvider = fc.provider || fc.walletProvider || fc.context && fc.context.walletProvider;
1303
- if (fcProvider === provider)
1304
- return true;
1305
- if (w.mini && w.mini.wallet === provider && fc && fc.context)
1306
- return true;
1307
- if (w.ethereum === provider && fc && fc.context)
1308
- return true;
1804
+ if (fcProvider === provider) return true;
1805
+ if (w.mini && w.mini.wallet === provider && fc && fc.context) return true;
1806
+ if (w.ethereum === provider && fc && fc.context) return true;
1309
1807
  } catch {
1310
1808
  }
1311
1809
  return false;
1312
1810
  })();
1313
1811
  if (isFarcasterWallet) {
1314
1812
  try {
1315
- const hexMsg = toHexUtf8(message);
1813
+ const hexMsg = toHexUtf82(message);
1316
1814
  signature2 = await provider.request({ method: "personal_sign", params: [hexMsg, walletAddress2] });
1317
1815
  } catch (e) {
1318
1816
  }
@@ -1324,7 +1822,8 @@ var init_client = __esm({
1324
1822
  const msg = String(e && (e.message || e.reason) || e || "").toLowerCase();
1325
1823
  const errCode = e && (e.code || e.error && e.error.code) || null;
1326
1824
  const needsHex = /byte|bytes|invalid byte sequence|encoding|non-hex/i.test(msg);
1327
- const methodUnsupported = /method.*not.*supported|unsupported|not implemented|method not found|unknown method|does not support/i.test(msg) || errCode === -32601 || errCode === 4200 || msg.includes("personal_sign") && msg.includes("not") || msg.includes("request method") && msg.includes("not supported");
1825
+ const unsupportedRe = /method.*not.*supported|unsupported|not implemented|method not found|unknown method|does not support/i;
1826
+ const methodUnsupported = unsupportedRe.test(msg) || errCode === -32601 || errCode === 4200 || msg.includes("personal_sign") && msg.includes("not") || msg.includes("request method") && msg.includes("not supported");
1328
1827
  if (methodUnsupported) {
1329
1828
  this._log("personal_sign not supported; attempting eth_sign fallback");
1330
1829
  try {
@@ -1333,35 +1832,30 @@ var init_client = __esm({
1333
1832
  const prefix = `Ethereum Signed Message:
1334
1833
  ${bytes.length}`;
1335
1834
  const full = new Uint8Array(prefix.length + bytes.length);
1336
- for (let i = 0; i < prefix.length; i++)
1337
- full[i] = prefix.charCodeAt(i);
1835
+ for (let i = 0; i < prefix.length; i++) full[i] = prefix.charCodeAt(i);
1338
1836
  full.set(bytes, prefix.length);
1339
1837
  let payloadHex = "0x";
1340
- for (let i = 0; i < full.length; i++)
1341
- payloadHex += full[i].toString(16).padStart(2, "0");
1838
+ for (let i = 0; i < full.length; i++) payloadHex += full[i].toString(16).padStart(2, "0");
1342
1839
  try {
1343
- if (typeof window !== "undefined")
1344
- window.__NEUS_ALLOW_ETH_SIGN__ = true;
1840
+ if (typeof window !== "undefined") window.__NEUS_ALLOW_ETH_SIGN__ = true;
1345
1841
  } catch {
1346
1842
  }
1347
1843
  signature2 = await provider.request({ method: "eth_sign", params: [walletAddress2, payloadHex], neusAllowEthSign: true });
1348
1844
  try {
1349
- if (typeof window !== "undefined")
1350
- delete window.__NEUS_ALLOW_ETH_SIGN__;
1845
+ if (typeof window !== "undefined") delete window.__NEUS_ALLOW_ETH_SIGN__;
1351
1846
  } catch {
1352
1847
  }
1353
1848
  } catch (fallbackErr) {
1354
1849
  this._log("eth_sign fallback failed", { message: fallbackErr?.message || String(fallbackErr) });
1355
1850
  try {
1356
- if (typeof window !== "undefined")
1357
- delete window.__NEUS_ALLOW_ETH_SIGN__;
1851
+ if (typeof window !== "undefined") delete window.__NEUS_ALLOW_ETH_SIGN__;
1358
1852
  } catch {
1359
1853
  }
1360
1854
  throw e;
1361
1855
  }
1362
1856
  } else if (needsHex) {
1363
1857
  this._log("Retrying personal_sign with hex-encoded message");
1364
- const hexMsg = toHexUtf8(message);
1858
+ const hexMsg = toHexUtf82(message);
1365
1859
  signature2 = await provider.request({ method: "personal_sign", params: [hexMsg, walletAddress2] });
1366
1860
  } else {
1367
1861
  throw e;
@@ -1396,8 +1890,7 @@ ${bytes.length}`;
1396
1890
  } = params;
1397
1891
  const resolvedChainId = chainId || (chain ? null : NEUS_CONSTANTS.HUB_CHAIN_ID);
1398
1892
  const normalizeVerifierId = (id) => {
1399
- if (typeof id !== "string")
1400
- return id;
1893
+ if (typeof id !== "string") return id;
1401
1894
  const match = id.match(/^(.*)@\d+$/);
1402
1895
  return match ? match[1] : id;
1403
1896
  };
@@ -1432,10 +1925,9 @@ ${bytes.length}`;
1432
1925
  // Privacy and storage options (defaults)
1433
1926
  privacyLevel: options?.privacyLevel || "private",
1434
1927
  publicDisplay: options?.publicDisplay || false,
1435
- storeOriginalContent: options?.storeOriginalContent || false
1928
+ storeOriginalContent: typeof options?.storeOriginalContent === "boolean" ? options.storeOriginalContent : true
1436
1929
  };
1437
- if (typeof options?.enableIpfs === "boolean")
1438
- optionsPayload.enableIpfs = options.enableIpfs;
1930
+ if (typeof options?.enableIpfs === "boolean") optionsPayload.enableIpfs = options.enableIpfs;
1439
1931
  const requestData = {
1440
1932
  verifierIds: normalizedVerifierIds,
1441
1933
  data,
@@ -1453,96 +1945,94 @@ ${bytes.length}`;
1453
1945
  }
1454
1946
  return this._formatResponse(response);
1455
1947
  }
1456
- // ============================================================================
1457
- // STATUS AND UTILITY METHODS
1458
- // ============================================================================
1459
1948
  /**
1460
- * Get verification status
1949
+ * Get proof record by proof receipt id.
1461
1950
  *
1462
- * @param {string} qHash - Verification ID (qHash or proofId)
1463
- * @returns {Promise<Object>} Verification status and data
1951
+ * @param {string} proofId - Proof receipt ID (0x + 64 hex).
1952
+ * @returns {Promise<Object>} Proof record and verification state
1464
1953
  *
1465
1954
  * @example
1466
- * const result = await client.getStatus('0x...');
1955
+ * const result = await client.getProof('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 getProof(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/proofs/${proofId}`);
1474
1963
  if (!response.success) {
1475
- throw new ApiError(`Failed to get status: ${response.error?.message || "Unknown error"}`, response.error);
1964
+ throw new ApiError(`Failed to get proof: ${response.error?.message || "Unknown error"}`, response.error);
1476
1965
  }
1477
1966
  return this._formatResponse(response);
1478
1967
  }
1479
1968
  /**
1480
- * Get private proof status with wallet signature
1969
+ * Get private proof record with wallet signature
1481
1970
  *
1482
- * @param {string} qHash - Verification ID
1971
+ * @param {string} proofId - Proof receipt ID.
1483
1972
  * @param {Object} wallet - Wallet provider (window.ethereum or ethers Wallet)
1484
- * @returns {Promise<Object>} Private verification status and data
1973
+ * @returns {Promise<Object>} Private proof record and verification state
1485
1974
  *
1486
1975
  * @example
1487
- * // Access private proof
1488
- * const privateData = await client.getPrivateStatus(qHash, window.ethereum);
1976
+ * const privateData = await client.getPrivateProof(proofId, window.ethereum);
1489
1977
  */
1490
- async getPrivateStatus(qHash, wallet = null) {
1491
- if (!qHash || typeof qHash !== "string") {
1492
- throw new ValidationError("qHash is required");
1978
+ async getPrivateProof(proofId, wallet = null) {
1979
+ if (!proofId || typeof proofId !== "string") {
1980
+ throw new ValidationError("proofId is required");
1493
1981
  }
1494
- if (!wallet) {
1495
- if (typeof window === "undefined" || !window.ethereum) {
1496
- throw new ConfigurationError("No wallet provider available");
1982
+ const isPreSignedAuth = wallet && typeof wallet === "object" && typeof wallet.walletAddress === "string" && typeof wallet.signature === "string" && typeof wallet.signedTimestamp === "number";
1983
+ if (isPreSignedAuth) {
1984
+ const auth = wallet;
1985
+ const headers = {
1986
+ "x-wallet-address": String(auth.walletAddress),
1987
+ "x-signature": String(auth.signature),
1988
+ "x-signed-timestamp": String(auth.signedTimestamp),
1989
+ ...typeof auth.chain === "string" && auth.chain.trim() ? { "x-chain": auth.chain.trim() } : {},
1990
+ ...typeof auth.signatureMethod === "string" && auth.signatureMethod.trim() ? { "x-signature-method": auth.signatureMethod.trim() } : {}
1991
+ };
1992
+ const response2 = await this._makeRequest("GET", `/api/v1/proofs/${proofId}`, null, headers);
1993
+ if (!response2.success) {
1994
+ throw new ApiError(
1995
+ `Failed to access private proof: ${response2.error?.message || "Unauthorized"}`,
1996
+ response2.error
1997
+ );
1497
1998
  }
1498
- wallet = window.ethereum;
1999
+ return this._formatResponse(response2);
1499
2000
  }
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");
2001
+ const providerWallet = wallet || this._getDefaultBrowserWallet();
2002
+ const { signerWalletAddress: walletAddress, provider } = await this._resolveWalletSigner(providerWallet);
2003
+ if (!walletAddress || typeof walletAddress !== "string") {
2004
+ throw new ConfigurationError("No wallet accounts available");
1517
2005
  }
2006
+ const signerIsEvm = EVM_ADDRESS_RE.test(this._normalizeIdentity(walletAddress));
2007
+ const chain = this._inferChainForAddress(walletAddress);
2008
+ const signatureMethod = signerIsEvm ? "eip191" : "ed25519";
1518
2009
  const signedTimestamp = Date.now();
1519
2010
  const message = constructVerificationMessage({
1520
2011
  walletAddress,
1521
2012
  signedTimestamp,
1522
- data: { action: "access_private_proof", qHash },
2013
+ data: { action: "access_private_proof", qHash: proofId },
1523
2014
  verifierIds: ["ownership-basic"],
1524
- chainId: NEUS_CONSTANTS.HUB_CHAIN_ID
2015
+ ...signerIsEvm ? { chainId: this._getHubChainId() } : { chain }
1525
2016
  });
1526
2017
  let signature;
1527
2018
  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
- }
2019
+ signature = await signMessage({
2020
+ provider,
2021
+ message,
2022
+ walletAddress,
2023
+ ...signerIsEvm ? {} : { chain }
2024
+ });
1536
2025
  } catch (error) {
1537
2026
  if (error.code === 4001) {
1538
2027
  throw new ValidationError("User rejected signature request");
1539
2028
  }
1540
2029
  throw new ValidationError(`Failed to sign message: ${error.message}`);
1541
2030
  }
1542
- const response = await this._makeRequest("GET", `/api/v1/verification/status/${qHash}`, null, {
2031
+ const response = await this._makeRequest("GET", `/api/v1/proofs/${proofId}`, null, {
1543
2032
  "x-wallet-address": walletAddress,
1544
2033
  "x-signature": signature,
1545
- "x-signed-timestamp": signedTimestamp.toString()
2034
+ "x-signed-timestamp": signedTimestamp.toString(),
2035
+ ...signerIsEvm ? {} : { "x-chain": chain, "x-signature-method": signatureMethod }
1546
2036
  });
1547
2037
  if (!response.success) {
1548
2038
  throw new ApiError(
@@ -1571,27 +2061,39 @@ ${bytes.length}`;
1571
2061
  * @returns {Promise<string[]>} Array of verifier IDs
1572
2062
  */
1573
2063
  async getVerifiers() {
2064
+ const catalog = await this.getVerifierCatalog();
2065
+ return Array.isArray(catalog?.data) ? catalog.data : [];
2066
+ }
2067
+ /**
2068
+ * Get the public verifier catalog with per-verifier capabilities.
2069
+ * @returns {Promise<{data: string[], metadata: Record<string, { supportsDirectApi?: boolean }>, meta?: object}>}
2070
+ */
2071
+ async getVerifierCatalog() {
1574
2072
  const response = await this._makeRequest("GET", "/api/v1/verification/verifiers");
1575
2073
  if (!response.success) {
1576
2074
  throw new ApiError(`Failed to get verifiers: ${response.error?.message || "Unknown error"}`, response.error);
1577
2075
  }
1578
- return Array.isArray(response.data) ? response.data : [];
2076
+ return {
2077
+ data: Array.isArray(response.data) ? response.data : [],
2078
+ metadata: response.metadata && typeof response.metadata === "object" && !Array.isArray(response.metadata) ? response.metadata : {},
2079
+ meta: response.meta && typeof response.meta === "object" && !Array.isArray(response.meta) ? response.meta : {}
2080
+ };
1579
2081
  }
1580
2082
  /**
1581
2083
  * POLL PROOF STATUS - Wait for verification completion
1582
- *
2084
+ *
1583
2085
  * Polls the verification status until it reaches a terminal state (completed or failed).
1584
2086
  * Useful for providing real-time feedback to users during verification.
1585
- *
1586
- * @param {string} qHash - Verification ID to poll
2087
+ *
2088
+ * @param {string} proofId - Proof ID to poll.
1587
2089
  * @param {Object} [options] - Polling options
1588
2090
  * @param {number} [options.interval=5000] - Polling interval in ms
1589
2091
  * @param {number} [options.timeout=120000] - Total timeout in ms
1590
2092
  * @param {Function} [options.onProgress] - Progress callback function
1591
2093
  * @returns {Promise<Object>} Final verification status
1592
- *
2094
+ *
1593
2095
  * @example
1594
- * const finalStatus = await client.pollProofStatus(qHash, {
2096
+ * const finalStatus = await client.pollProofStatus(proofId, {
1595
2097
  * interval: 3000,
1596
2098
  * timeout: 60000,
1597
2099
  * onProgress: (status) => {
@@ -1602,20 +2104,20 @@ ${bytes.length}`;
1602
2104
  * }
1603
2105
  * });
1604
2106
  */
1605
- async pollProofStatus(qHash, options = {}) {
2107
+ async pollProofStatus(proofId, options = {}) {
1606
2108
  const {
1607
2109
  interval = 5e3,
1608
2110
  timeout = 12e4,
1609
2111
  onProgress
1610
2112
  } = options;
1611
- if (!qHash || typeof qHash !== "string") {
1612
- throw new ValidationError("qHash is required");
2113
+ if (!proofId || typeof proofId !== "string") {
2114
+ throw new ValidationError("proofId is required");
1613
2115
  }
1614
2116
  const startTime = Date.now();
1615
2117
  let consecutiveRateLimits = 0;
1616
2118
  while (Date.now() - startTime < timeout) {
1617
2119
  try {
1618
- const status = await this.getStatus(qHash);
2120
+ const status = await this.getProof(proofId);
1619
2121
  consecutiveRateLimits = 0;
1620
2122
  if (onProgress && typeof onProgress === "function") {
1621
2123
  onProgress(status.data || status);
@@ -1648,7 +2150,7 @@ ${bytes.length}`;
1648
2150
  }
1649
2151
  /**
1650
2152
  * DETECT CHAIN ID - Get current wallet chain
1651
- *
2153
+ *
1652
2154
  * @returns {Promise<number>} Current chain ID
1653
2155
  */
1654
2156
  async detectChainId() {
@@ -1663,70 +2165,49 @@ ${bytes.length}`;
1663
2165
  }
1664
2166
  }
1665
2167
  /** Revoke your own proof (owner-signed) */
1666
- async revokeOwnProof(qHash, wallet) {
1667
- if (!qHash || typeof qHash !== "string") {
1668
- throw new ValidationError("qHash is required");
2168
+ async revokeOwnProof(proofId, wallet) {
2169
+ if (!proofId || typeof proofId !== "string") {
2170
+ throw new ValidationError("proofId is required");
2171
+ }
2172
+ const providerWallet = wallet || this._getDefaultBrowserWallet();
2173
+ const { signerWalletAddress: address, provider } = await this._resolveWalletSigner(providerWallet);
2174
+ if (!address || typeof address !== "string") {
2175
+ throw new ConfigurationError("No wallet accounts available");
1669
2176
  }
1670
- const address = wallet?.address || await this._getWalletAddress();
2177
+ const signerIsEvm = EVM_ADDRESS_RE.test(this._normalizeIdentity(address));
2178
+ const chain = this._inferChainForAddress(address);
2179
+ const signatureMethod = signerIsEvm ? "eip191" : "ed25519";
1671
2180
  const signedTimestamp = Date.now();
1672
- const hubChainId = NEUS_CONSTANTS.HUB_CHAIN_ID;
1673
2181
  const message = constructVerificationMessage({
1674
2182
  walletAddress: address,
1675
2183
  signedTimestamp,
1676
- data: { action: "revoke_proof", qHash },
2184
+ data: { action: "revoke_proof", qHash: proofId },
1677
2185
  verifierIds: ["ownership-basic"],
1678
- chainId: hubChainId
2186
+ ...signerIsEvm ? { chainId: this._getHubChainId() } : { chain }
1679
2187
  });
1680
2188
  let signature;
1681
2189
  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
- }
2190
+ signature = await signMessage({
2191
+ provider,
2192
+ message,
2193
+ walletAddress: address,
2194
+ ...signerIsEvm ? {} : { chain }
2195
+ });
1719
2196
  } catch (error) {
1720
2197
  if (error.code === 4001) {
1721
2198
  throw new ValidationError("User rejected revocation signature");
1722
2199
  }
1723
2200
  throw new ValidationError(`Failed to sign revocation: ${error.message}`);
1724
2201
  }
1725
- const res = await fetch(`${this.config.apiUrl}/api/v1/proofs/${qHash}/revoke-self`, {
2202
+ const res = await fetch(`${this.config.apiUrl}/api/v1/proofs/revoke-self/${proofId}`, {
1726
2203
  method: "POST",
1727
- // SECURITY: Do not put proof signatures into Authorization headers.
1728
2204
  headers: { "Content-Type": "application/json" },
1729
- body: JSON.stringify({ walletAddress: address, signature, signedTimestamp })
2205
+ body: JSON.stringify({
2206
+ walletAddress: address,
2207
+ signature,
2208
+ signedTimestamp,
2209
+ ...signerIsEvm ? {} : { chain, signatureMethod }
2210
+ })
1730
2211
  });
1731
2212
  const json = await res.json();
1732
2213
  if (!json.success) {
@@ -1734,18 +2215,16 @@ ${bytes.length}`;
1734
2215
  }
1735
2216
  return true;
1736
2217
  }
1737
- // ============================================================================
1738
- // PROOFS & GATING METHODS
1739
- // ============================================================================
1740
2218
  /**
1741
2219
  * GET PROOFS BY WALLET - Fetch proofs for a wallet address
1742
- *
1743
- * @param {string} walletAddress - Wallet address (0x...) or DID (did:pkh:...)
2220
+ *
2221
+ * @param {string} walletAddress - Wallet identity (EVM/Solana/DID)
1744
2222
  * @param {Object} [options] - Filter options
1745
2223
  * @param {number} [options.limit] - Max results (default: 50; higher limits require owner access)
1746
2224
  * @param {number} [options.offset] - Pagination offset (default: 0)
2225
+ * @param {string} [options.qHash] - Filter to single proof by qHash
1747
2226
  * @returns {Promise<Object>} Proofs result
1748
- *
2227
+ *
1749
2228
  * @example
1750
2229
  * const result = await client.getProofsByWallet('0x...', {
1751
2230
  * limit: 50,
@@ -1759,14 +2238,13 @@ ${bytes.length}`;
1759
2238
  const id = walletAddress.trim();
1760
2239
  const pathId = /^0x[a-fA-F0-9]{40}$/i.test(id) ? id.toLowerCase() : id;
1761
2240
  const qs = [];
1762
- if (options.limit)
1763
- qs.push(`limit=${encodeURIComponent(String(options.limit))}`);
1764
- if (options.offset)
1765
- qs.push(`offset=${encodeURIComponent(String(options.offset))}`);
2241
+ if (options.limit) qs.push(`limit=${encodeURIComponent(String(options.limit))}`);
2242
+ if (options.offset) qs.push(`offset=${encodeURIComponent(String(options.offset))}`);
2243
+ if (options.qHash) qs.push(`qHash=${encodeURIComponent(options.qHash.toLowerCase())}`);
1766
2244
  const query = qs.length ? `?${qs.join("&")}` : "";
1767
2245
  const response = await this._makeRequest(
1768
2246
  "GET",
1769
- `/api/v1/proofs/byWallet/${encodeURIComponent(pathId)}${query}`
2247
+ `/api/v1/proofs/by-wallet/${encodeURIComponent(pathId)}${query}`
1770
2248
  );
1771
2249
  if (!response.success) {
1772
2250
  throw new ApiError(`Failed to get proofs: ${response.error?.message || "Unknown error"}`, response.error);
@@ -1785,10 +2263,11 @@ ${bytes.length}`;
1785
2263
  *
1786
2264
  * Signs an owner-access intent and requests private proofs via signature headers.
1787
2265
  *
1788
- * @param {string} walletAddress - Wallet address (0x...) or DID (did:pkh:...)
2266
+ * @param {string} walletAddress - Wallet identity (EVM/Solana/DID)
1789
2267
  * @param {Object} [options]
1790
2268
  * @param {number} [options.limit] - Max results (server enforces caps)
1791
2269
  * @param {number} [options.offset] - Pagination offset
2270
+ * @param {string} [options.qHash] - Filter to single proof by qHash
1792
2271
  * @param {Object} [wallet] - Optional injected wallet/provider (MetaMask/ethers Wallet)
1793
2272
  */
1794
2273
  async getPrivateProofsByWallet(walletAddress, options = {}, wallet = null) {
@@ -1797,48 +2276,41 @@ ${bytes.length}`;
1797
2276
  }
1798
2277
  const id = walletAddress.trim();
1799
2278
  const pathId = /^0x[a-fA-F0-9]{40}$/i.test(id) ? id.toLowerCase() : id;
2279
+ const requestedIdentity = this._normalizeIdentity(id);
1800
2280
  if (!wallet) {
1801
- if (typeof window === "undefined" || !window.ethereum) {
2281
+ const defaultWallet = this._getDefaultBrowserWallet();
2282
+ if (!defaultWallet) {
1802
2283
  throw new ConfigurationError("No wallet provider available");
1803
2284
  }
1804
- wallet = window.ethereum;
2285
+ wallet = defaultWallet;
1805
2286
  }
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");
2287
+ const { signerWalletAddress, provider } = await this._resolveWalletSigner(wallet);
2288
+ if (!signerWalletAddress || typeof signerWalletAddress !== "string") {
2289
+ throw new ConfigurationError("No wallet accounts available");
1823
2290
  }
2291
+ const normalizedSigner = this._normalizeIdentity(signerWalletAddress);
2292
+ if (!normalizedSigner || normalizedSigner !== requestedIdentity) {
2293
+ throw new ValidationError("wallet must match walletAddress for private proof access");
2294
+ }
2295
+ const signerIsEvm = EVM_ADDRESS_RE.test(normalizedSigner);
2296
+ const chain = this._inferChainForAddress(normalizedSigner, options?.chain);
2297
+ const signatureMethod = typeof options?.signatureMethod === "string" && options.signatureMethod.trim() ? options.signatureMethod.trim() : signerIsEvm ? "eip191" : "ed25519";
1824
2298
  const signedTimestamp = Date.now();
1825
2299
  const message = constructVerificationMessage({
1826
2300
  walletAddress: signerWalletAddress,
1827
2301
  signedTimestamp,
1828
- data: { action: "access_private_proofs_by_wallet", walletAddress: signerWalletAddress.toLowerCase() },
2302
+ data: { action: "access_private_proofs_by_wallet", walletAddress: normalizedSigner },
1829
2303
  verifierIds: ["ownership-basic"],
1830
- chainId: NEUS_CONSTANTS.HUB_CHAIN_ID
2304
+ ...signerIsEvm ? { chainId: this._getHubChainId() } : { chain }
1831
2305
  });
1832
2306
  let signature;
1833
2307
  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
- }
2308
+ signature = await signMessage({
2309
+ provider,
2310
+ message,
2311
+ walletAddress: signerWalletAddress,
2312
+ ...signerIsEvm ? {} : { chain }
2313
+ });
1842
2314
  } catch (error) {
1843
2315
  if (error.code === 4001) {
1844
2316
  throw new ValidationError("User rejected signature request");
@@ -1846,15 +2318,15 @@ ${bytes.length}`;
1846
2318
  throw new ValidationError(`Failed to sign message: ${error.message}`);
1847
2319
  }
1848
2320
  const qs = [];
1849
- if (options.limit)
1850
- qs.push(`limit=${encodeURIComponent(String(options.limit))}`);
1851
- if (options.offset)
1852
- qs.push(`offset=${encodeURIComponent(String(options.offset))}`);
2321
+ if (options.limit) qs.push(`limit=${encodeURIComponent(String(options.limit))}`);
2322
+ if (options.offset) qs.push(`offset=${encodeURIComponent(String(options.offset))}`);
2323
+ if (options.qHash) qs.push(`qHash=${encodeURIComponent(options.qHash.toLowerCase())}`);
1853
2324
  const query = qs.length ? `?${qs.join("&")}` : "";
1854
- const response = await this._makeRequest("GET", `/api/v1/proofs/byWallet/${encodeURIComponent(pathId)}${query}`, null, {
2325
+ const response = await this._makeRequest("GET", `/api/v1/proofs/by-wallet/${encodeURIComponent(pathId)}${query}`, null, {
1855
2326
  "x-wallet-address": signerWalletAddress,
1856
2327
  "x-signature": signature,
1857
- "x-signed-timestamp": signedTimestamp.toString()
2328
+ "x-signed-timestamp": signedTimestamp.toString(),
2329
+ ...signerIsEvm ? {} : { "x-chain": chain, "x-signature-method": signatureMethod }
1858
2330
  });
1859
2331
  if (!response.success) {
1860
2332
  throw new ApiError(`Failed to get proofs: ${response.error?.message || "Unauthorized"}`, response.error);
@@ -1869,51 +2341,52 @@ ${bytes.length}`;
1869
2341
  };
1870
2342
  }
1871
2343
  /**
1872
- * GATE CHECK (API) - Minimal eligibility check
2344
+ * Gate check (HTTP API) minimal eligibility response.
2345
+ *
2346
+ * Calls the gate endpoint and returns a **minimal** yes/no response.
2347
+ * By default this checks **public + unlisted** proofs.
1873
2348
  *
1874
- * Calls the public gate endpoint and returns a **minimal** yes/no response
1875
- * against **public + discoverable** proofs only.
2349
+ * When `includePrivate=true`, this can perform owner-signed private checks
2350
+ * (no full proof payloads returned) by providing a wallet/provider.
1876
2351
  *
1877
- * Prefer this over `checkGate()` for server-side integrations that want the
1878
- * smallest, most stable surface area (and do NOT need full proof payloads).
2352
+ * Prefer this over `checkGate()` when you need the smallest, most stable
2353
+ * response shape and do not need full proof payloads.
1879
2354
  *
1880
2355
  * @param {Object} params - Gate check query params
1881
- * @param {string} params.address - Wallet address to check (0x...)
2356
+ * @param {string} params.address - Wallet identity to check (EVM/Solana/DID)
1882
2357
  * @param {Array<string>|string} [params.verifierIds] - Verifier IDs to match (array or comma-separated)
1883
2358
  * @param {boolean} [params.requireAll] - Require all verifierIds on a single proof
1884
2359
  * @param {number} [params.minCount] - Minimum number of matching proofs
1885
2360
  * @param {number} [params.sinceDays] - Optional time window in days
1886
2361
  * @param {number} [params.since] - Optional unix timestamp in ms (lower bound)
1887
2362
  * @param {number} [params.limit] - Max rows to scan (server may clamp)
2363
+ * @param {boolean} [params.includePrivate] - Include private proofs for owner-authenticated requests
2364
+ * @param {boolean} [params.includeQHashes] - Include matched qHashes in response (minimal IDs only)
2365
+ * @param {Object} [params.wallet] - Optional wallet/provider used to sign includePrivate owner checks
1888
2366
  * @returns {Promise<Object>} API response ({ success, data })
1889
2367
  */
1890
2368
  async gateCheck(params = {}) {
1891
2369
  const address = (params.address || "").toString();
1892
- if (!address || !/^0x[a-fA-F0-9]{40}$/i.test(address)) {
2370
+ if (!validateUniversalAddress(address, params.chain)) {
1893
2371
  throw new ValidationError("Valid address is required");
1894
2372
  }
1895
2373
  const qs = new URLSearchParams();
1896
2374
  qs.set("address", address);
1897
2375
  const setIfPresent = (key, value) => {
1898
- if (value === void 0 || value === null)
1899
- return;
2376
+ if (value === void 0 || value === null) return;
1900
2377
  const str = typeof value === "string" ? value : String(value);
1901
- if (str.length === 0)
1902
- return;
2378
+ if (str.length === 0) return;
1903
2379
  qs.set(key, str);
1904
2380
  };
1905
2381
  const setBoolIfPresent = (key, value) => {
1906
- if (value === void 0 || value === null)
1907
- return;
2382
+ if (value === void 0 || value === null) return;
1908
2383
  qs.set(key, value ? "true" : "false");
1909
2384
  };
1910
2385
  const setCsvIfPresent = (key, value) => {
1911
- if (value === void 0 || value === null)
1912
- return;
2386
+ if (value === void 0 || value === null) return;
1913
2387
  if (Array.isArray(value)) {
1914
2388
  const items = value.map((v) => String(v).trim()).filter(Boolean);
1915
- if (items.length)
1916
- qs.set(key, items.join(","));
2389
+ if (items.length) qs.set(key, items.join(","));
1917
2390
  return;
1918
2391
  }
1919
2392
  setIfPresent(key, value);
@@ -1924,6 +2397,8 @@ ${bytes.length}`;
1924
2397
  setIfPresent("sinceDays", params.sinceDays);
1925
2398
  setIfPresent("since", params.since);
1926
2399
  setIfPresent("limit", params.limit);
2400
+ setBoolIfPresent("includePrivate", params.includePrivate);
2401
+ setBoolIfPresent("includeQHashes", params.includeQHashes);
1927
2402
  setIfPresent("referenceType", params.referenceType);
1928
2403
  setIfPresent("referenceId", params.referenceId);
1929
2404
  setIfPresent("tag", params.tag);
@@ -1937,6 +2412,8 @@ ${bytes.length}`;
1937
2412
  setIfPresent("domain", params.domain);
1938
2413
  setIfPresent("minBalance", params.minBalance);
1939
2414
  setIfPresent("provider", params.provider);
2415
+ setIfPresent("handle", params.handle);
2416
+ setIfPresent("namespace", params.namespace);
1940
2417
  setIfPresent("ownerAddress", params.ownerAddress);
1941
2418
  setIfPresent("riskLevel", params.riskLevel);
1942
2419
  setBoolIfPresent("sanctioned", params.sanctioned);
@@ -1944,18 +2421,57 @@ ${bytes.length}`;
1944
2421
  setIfPresent("primaryWalletAddress", params.primaryWalletAddress);
1945
2422
  setIfPresent("secondaryWalletAddress", params.secondaryWalletAddress);
1946
2423
  setIfPresent("verificationMethod", params.verificationMethod);
1947
- const response = await this._makeRequest("GET", `/api/v1/proofs/gate/check?${qs.toString()}`);
2424
+ let headersOverride = null;
2425
+ if (params.includePrivate === true) {
2426
+ const provided = params.privateAuth && typeof params.privateAuth === "object" ? params.privateAuth : null;
2427
+ let auth = provided;
2428
+ if (!auth) {
2429
+ const walletCandidate = params.wallet || this._getDefaultBrowserWallet();
2430
+ if (walletCandidate) {
2431
+ auth = await this._buildPrivateGateAuth({
2432
+ address,
2433
+ wallet: walletCandidate,
2434
+ chain: params.chain,
2435
+ signatureMethod: params.signatureMethod
2436
+ });
2437
+ }
2438
+ }
2439
+ if (!auth) {
2440
+ } else {
2441
+ const normalizedAuthWallet = this._normalizeIdentity(auth.walletAddress);
2442
+ const normalizedAddress = this._normalizeIdentity(address);
2443
+ if (!normalizedAuthWallet || normalizedAuthWallet !== normalizedAddress) {
2444
+ throw new ValidationError("privateAuth.walletAddress must match address when includePrivate=true");
2445
+ }
2446
+ const authChain = typeof auth.chain === "string" && auth.chain.includes(":") ? auth.chain.trim() : null;
2447
+ const authSignatureMethod = typeof auth.signatureMethod === "string" && auth.signatureMethod.trim() ? auth.signatureMethod.trim() : null;
2448
+ headersOverride = {
2449
+ "x-wallet-address": String(auth.walletAddress),
2450
+ "x-signature": String(auth.signature),
2451
+ "x-signed-timestamp": String(auth.signedTimestamp),
2452
+ ...authChain ? { "x-chain": authChain } : {},
2453
+ ...authSignatureMethod ? { "x-signature-method": authSignatureMethod } : {}
2454
+ };
2455
+ }
2456
+ }
2457
+ const response = await this._makeRequest("GET", `/api/v1/proofs/check?${qs.toString()}`, null, headersOverride);
1948
2458
  if (!response.success) {
1949
2459
  throw new ApiError(`Gate check failed: ${response.error?.message || "Unknown error"}`, response.error);
1950
2460
  }
1951
2461
  return response;
1952
2462
  }
1953
2463
  /**
1954
- * CHECK GATE - Evaluate requirements against existing proofs
1955
- *
2464
+ * CHECK GATE Local preview against proofs you already have in memory or from `getProofsByWallet`.
2465
+ *
2466
+ * **Not authoritative for access control.** For production allow/deny, use {@link NeusClient#gateCheck}
2467
+ * (`GET /api/v1/proofs/check`), which applies the same rules as the NEUS API. This method is useful for
2468
+ * UI previews, offline-ish flows, or when you already fetched proofs and want a quick match without
2469
+ * another round trip — but it can disagree with the server (e.g. `contentHash` matching uses a local
2470
+ * approximation when proof data only has inline `content`; the API uses the standard server-side hash).
2471
+ *
1956
2472
  * Gate-first verification: checks if wallet has valid proofs satisfying requirements.
1957
2473
  * Returns which requirements are missing/expired.
1958
- *
2474
+ *
1959
2475
  * @param {Object} params - Gate check parameters
1960
2476
  * @param {string} params.walletAddress - Target wallet
1961
2477
  * @param {Array<Object>} params.requirements - Array of gate requirements
@@ -1968,12 +2484,12 @@ ${bytes.length}`;
1968
2484
  * Supports verifier-specific:
1969
2485
  * - NFT/Token: 'contractAddress', 'tokenId', 'chainId', 'ownerAddress', 'minBalance'
1970
2486
  * - DNS: 'domain', 'walletAddress'
1971
- * - Wallet-link: 'primaryWalletAddress', 'secondaryWalletAddress', 'chainId'
2487
+ * - Wallet-link: 'primaryWalletAddress', 'secondaryWalletAddress', 'chain', 'signatureMethod'
1972
2488
  * - Contract-ownership: 'contractAddress', 'chainId', 'owner', 'verificationMethod'
1973
2489
  * Note: contentHash matching uses approximation in SDK; for exact SHA-256 matching, use backend API
1974
2490
  * @param {Array} [params.proofs] - Pre-fetched proofs (skip API call)
1975
2491
  * @returns {Promise<Object>} Gate result with satisfied, missing, existing
1976
- *
2492
+ *
1977
2493
  * @example
1978
2494
  * // Basic gate check
1979
2495
  * const result = await client.checkGate({
@@ -1985,7 +2501,7 @@ ${bytes.length}`;
1985
2501
  */
1986
2502
  async checkGate(params) {
1987
2503
  const { walletAddress, requirements, proofs: preloadedProofs } = params;
1988
- if (!walletAddress || !/^0x[a-fA-F0-9]{40}$/i.test(walletAddress)) {
2504
+ if (!validateUniversalAddress(walletAddress)) {
1989
2505
  throw new ValidationError("Valid walletAddress is required");
1990
2506
  }
1991
2507
  if (!Array.isArray(requirements) || requirements.length === 0) {
@@ -2006,20 +2522,20 @@ ${bytes.length}`;
2006
2522
  const verifier = verifiedVerifiers.find(
2007
2523
  (v) => v.verifierId === verifierId && v.verified === true
2008
2524
  );
2009
- if (!verifier)
2010
- return false;
2011
- if (proof.revokedAt)
2012
- return false;
2525
+ if (!verifier) return false;
2526
+ if (proof.revokedAt) return false;
2013
2527
  if (maxAgeMs) {
2014
2528
  const proofTimestamp = proof.createdAt || proof.signedTimestamp || 0;
2015
2529
  const proofAge = now - proofTimestamp;
2016
- if (proofAge > maxAgeMs)
2017
- return false;
2530
+ if (proofAge > maxAgeMs) return false;
2018
2531
  }
2019
2532
  if (match && typeof match === "object") {
2020
2533
  const data = verifier.data || {};
2021
2534
  const input = data.input || {};
2022
- for (const [key, expected] of Object.entries(match)) {
2535
+ const matchObj = Array.isArray(match) ? Object.fromEntries(
2536
+ match.filter((m) => m && m.path && String(m.value ?? "").trim() !== "").map((m) => [String(m.path).trim(), m.value])
2537
+ ) : match;
2538
+ for (const [key, expected] of Object.entries(matchObj)) {
2023
2539
  let actualValue = null;
2024
2540
  if (key.includes(".")) {
2025
2541
  const parts = key.split(".");
@@ -2044,6 +2560,7 @@ ${bytes.length}`;
2044
2560
  actualValue = data.reference?.id || data.content;
2045
2561
  }
2046
2562
  if (actualValue === void 0) {
2563
+ const claims = data.claims || {};
2047
2564
  if (key === "contractAddress") {
2048
2565
  actualValue = input.contractAddress || data.contractAddress;
2049
2566
  } else if (key === "tokenId") {
@@ -2062,6 +2579,22 @@ ${bytes.length}`;
2062
2579
  actualValue = data.verificationMethod;
2063
2580
  } else if (key === "domain") {
2064
2581
  actualValue = data.domain;
2582
+ } else if (key === "handle") {
2583
+ actualValue = data.handle || data.pseudonymId;
2584
+ } else if (key === "namespace") {
2585
+ actualValue = data.namespace !== void 0 && data.namespace !== null && data.namespace !== "" ? data.namespace : "neus";
2586
+ } else if (key === "claims.sanctions_passed") {
2587
+ actualValue = claims.sanctions_passed ?? claims.sanctionsPassed;
2588
+ } else if (key === "claims.age_min") {
2589
+ actualValue = claims.age_min ?? claims.ageMin;
2590
+ } else if (key === "neusPersonhoodId") {
2591
+ actualValue = data.neusPersonhoodId;
2592
+ } else if (key === "riskLevel") {
2593
+ actualValue = data.riskLevel;
2594
+ } else if (key === "sanctioned") {
2595
+ actualValue = data.sanctioned;
2596
+ } else if (key === "poisoned") {
2597
+ actualValue = data.poisoned;
2065
2598
  }
2066
2599
  }
2067
2600
  if (key === "contentHash" && actualValue === void 0 && data.content) {
@@ -2073,7 +2606,7 @@ ${bytes.length}`;
2073
2606
  hash = (hash << 5) - hash + char;
2074
2607
  hash = hash & hash;
2075
2608
  }
2076
- actualValue = "0x" + Math.abs(hash).toString(16).padStart(64, "0").substring(0, 66);
2609
+ actualValue = `0x${Math.abs(hash).toString(16).padStart(64, "0").substring(0, 66)}`;
2077
2610
  } catch {
2078
2611
  actualValue = String(data.content);
2079
2612
  }
@@ -2083,11 +2616,16 @@ ${bytes.length}`;
2083
2616
  if (actualValue === void 0 || actualValue === null) {
2084
2617
  return false;
2085
2618
  }
2619
+ if (typeof actualValue === "boolean" || key && (key.includes("sanctions") || key.includes("sanctioned") || key.includes("poisoned"))) {
2620
+ const bActual = Boolean(actualValue);
2621
+ const bExpected = expected === true || expected === "true" || String(expected).toLowerCase() === "true";
2622
+ if (bActual !== bExpected) return false;
2623
+ continue;
2624
+ }
2086
2625
  if (key === "chainId" || key === "tokenId" && (typeof actualValue === "number" || !isNaN(Number(actualValue)))) {
2087
2626
  normalizedActual = Number(actualValue);
2088
2627
  normalizedExpected = Number(expected);
2089
- if (isNaN(normalizedActual) || isNaN(normalizedExpected))
2090
- return false;
2628
+ if (isNaN(normalizedActual) || isNaN(normalizedExpected)) return false;
2091
2629
  } else if (typeof actualValue === "string" && (actualValue.startsWith("0x") || actualValue.length > 20)) {
2092
2630
  normalizedActual = actualValue.toLowerCase();
2093
2631
  normalizedExpected = typeof expected === "string" ? String(expected).toLowerCase() : expected;
@@ -2116,13 +2654,6 @@ ${bytes.length}`;
2116
2654
  allProofs: proofs
2117
2655
  };
2118
2656
  }
2119
- // ============================================================================
2120
- // PRIVATE UTILITY METHODS
2121
- // ============================================================================
2122
- /**
2123
- * Get connected wallet address
2124
- * @private
2125
- */
2126
2657
  async _getWalletAddress() {
2127
2658
  if (typeof window === "undefined" || !window.ethereum) {
2128
2659
  throw new ConfigurationError("No Web3 wallet detected");
@@ -2133,10 +2664,6 @@ ${bytes.length}`;
2133
2664
  }
2134
2665
  return accounts[0];
2135
2666
  }
2136
- /**
2137
- * Make HTTP request to API
2138
- * @private
2139
- */
2140
2667
  async _makeRequest(method, endpoint, data = null, headersOverride = null) {
2141
2668
  const url = `${this.baseUrl}${endpoint}`;
2142
2669
  const controller = new AbortController();
@@ -2174,27 +2701,23 @@ ${bytes.length}`;
2174
2701
  throw new NetworkError(`Network error: ${error.message}`);
2175
2702
  }
2176
2703
  }
2177
- /**
2178
- * Format API response for consistent structure
2179
- * @private
2180
- */
2181
2704
  _formatResponse(response) {
2182
- const qHash = response?.data?.qHash || response?.qHash || response?.data?.resource?.qHash || response?.data?.id;
2705
+ const proofId = response?.data?.proofId || response?.proofId || response?.data?.resource?.proofId || response?.data?.qHash || response?.qHash || response?.data?.resource?.qHash || response?.data?.id;
2706
+ const qHash = response?.data?.qHash || response?.qHash || response?.data?.resource?.qHash || proofId || response?.data?.id;
2707
+ const finalProofId = proofId || qHash || null;
2708
+ const finalQHash = qHash || proofId || finalProofId;
2183
2709
  const status = response?.data?.status || response?.status || response?.data?.resource?.status || (response?.success ? "completed" : "unknown");
2184
2710
  return {
2185
2711
  success: response.success,
2186
- qHash,
2712
+ proofId: finalProofId,
2713
+ qHash: finalQHash,
2187
2714
  status,
2188
2715
  data: response.data,
2189
2716
  message: response.message,
2190
2717
  timestamp: Date.now(),
2191
- statusUrl: qHash ? `${this.baseUrl}/api/v1/verification/status/${qHash}` : null
2718
+ proofUrl: finalProofId ? `${this.baseUrl}/api/v1/proofs/${finalProofId}` : null
2192
2719
  };
2193
2720
  }
2194
- /**
2195
- * Check if status is terminal (completed or failed)
2196
- * @private
2197
- */
2198
2721
  _isTerminalStatus(status) {
2199
2722
  const terminalStates = [
2200
2723
  "verified",
@@ -2226,22 +2749,29 @@ ${bytes.length}`;
2226
2749
  });
2227
2750
 
2228
2751
  // index.js
2229
- var sdk_exports = {};
2230
- __export(sdk_exports, {
2752
+ var index_exports = {};
2753
+ __export(index_exports, {
2231
2754
  ApiError: () => ApiError,
2232
2755
  AuthenticationError: () => AuthenticationError,
2233
2756
  ConfigurationError: () => ConfigurationError,
2234
2757
  DAY: () => DAY,
2758
+ DEFAULT_HOSTED_VERIFY_URL: () => DEFAULT_HOSTED_VERIFY_URL,
2759
+ GATE_AGENT_DELEGATION: () => GATE_AGENT_DELEGATION,
2760
+ GATE_AGENT_IDENTITY: () => GATE_AGENT_IDENTITY,
2761
+ GATE_CONTENT_MODERATION: () => GATE_CONTENT_MODERATION,
2235
2762
  GATE_CONTRACT_ADMIN: () => GATE_CONTRACT_ADMIN,
2236
2763
  GATE_DOMAIN_OWNER: () => GATE_DOMAIN_OWNER,
2237
2764
  GATE_LINKED_WALLETS: () => GATE_LINKED_WALLETS,
2238
2765
  GATE_NFT_HOLDER: () => GATE_NFT_HOLDER,
2766
+ GATE_PSEUDONYM: () => GATE_PSEUDONYM,
2239
2767
  GATE_TOKEN_HOLDER: () => GATE_TOKEN_HOLDER,
2768
+ GATE_WALLET_RISK: () => GATE_WALLET_RISK,
2240
2769
  HOUR: () => HOUR,
2241
2770
  MONTH: () => MONTH,
2242
2771
  NEUS_CONSTANTS: () => NEUS_CONSTANTS,
2243
2772
  NetworkError: () => NetworkError,
2244
2773
  NeusClient: () => NeusClient,
2774
+ PORTABLE_PROOF_SIGNER_HEADER: () => PORTABLE_PROOF_SIGNER_HEADER,
2245
2775
  SDKError: () => SDKError,
2246
2776
  StatusPoller: () => StatusPoller,
2247
2777
  ValidationError: () => ValidationError,
@@ -2254,24 +2784,32 @@ __export(sdk_exports, {
2254
2784
  constructVerificationMessage: () => constructVerificationMessage,
2255
2785
  createGate: () => createGate,
2256
2786
  createVerificationData: () => createVerificationData,
2257
- default: () => sdk_default,
2787
+ default: () => index_default,
2258
2788
  delay: () => delay,
2259
2789
  deriveDid: () => deriveDid,
2260
2790
  formatTimestamp: () => formatTimestamp,
2261
2791
  formatVerificationStatus: () => formatVerificationStatus,
2792
+ getHostedCheckoutUrl: () => getHostedCheckoutUrl,
2262
2793
  isFailureStatus: () => isFailureStatus,
2263
2794
  isSuccessStatus: () => isSuccessStatus,
2264
2795
  isSupportedChain: () => isSupportedChain,
2265
2796
  isTerminalStatus: () => isTerminalStatus,
2266
2797
  normalizeAddress: () => normalizeAddress,
2798
+ resolveDID: () => resolveDID,
2799
+ resolveZkPassportConfig: () => resolveZkPassportConfig,
2800
+ signMessage: () => signMessage,
2801
+ standardizeVerificationRequest: () => standardizeVerificationRequest,
2802
+ toAgentDelegationMaxSpend: () => toAgentDelegationMaxSpend,
2803
+ toHexUtf8: () => toHexUtf8,
2267
2804
  validateQHash: () => validateQHash,
2268
2805
  validateSignatureComponents: () => validateSignatureComponents,
2269
2806
  validateTimestamp: () => validateTimestamp,
2807
+ validateUniversalAddress: () => validateUniversalAddress,
2270
2808
  validateVerifierPayload: () => validateVerifierPayload,
2271
2809
  validateWalletAddress: () => validateWalletAddress,
2272
2810
  withRetry: () => withRetry
2273
2811
  });
2274
- module.exports = __toCommonJS(sdk_exports);
2812
+ module.exports = __toCommonJS(index_exports);
2275
2813
  init_client();
2276
2814
  init_utils();
2277
2815
 
@@ -2296,9 +2834,21 @@ var GATE_DOMAIN_OWNER = [
2296
2834
  var GATE_LINKED_WALLETS = [
2297
2835
  { verifierId: "wallet-link" }
2298
2836
  ];
2837
+ var GATE_AGENT_IDENTITY = [
2838
+ { verifierId: "agent-identity" }
2839
+ ];
2299
2840
  var GATE_AGENT_DELEGATION = [
2300
2841
  { verifierId: "agent-delegation", maxAgeMs: 7 * DAY }
2301
2842
  ];
2843
+ var GATE_CONTENT_MODERATION = [
2844
+ { verifierId: "ai-content-moderation" }
2845
+ ];
2846
+ var GATE_WALLET_RISK = [
2847
+ { verifierId: "wallet-risk" }
2848
+ ];
2849
+ var GATE_PSEUDONYM = [
2850
+ { verifierId: "ownership-pseudonym" }
2851
+ ];
2302
2852
  function createGate(requirements) {
2303
2853
  return requirements.map((req) => {
2304
2854
  if (typeof req === "string") {
@@ -2324,7 +2874,7 @@ function combineGates(...gates) {
2324
2874
 
2325
2875
  // index.js
2326
2876
  init_errors();
2327
- var sdk_default = {
2877
+ var index_default = {
2328
2878
  NeusClient: () => Promise.resolve().then(() => (init_client(), client_exports)).then((m) => m.NeusClient),
2329
2879
  toString: () => "[neus/sdk]"
2330
2880
  };
@@ -2334,16 +2884,23 @@ var sdk_default = {
2334
2884
  AuthenticationError,
2335
2885
  ConfigurationError,
2336
2886
  DAY,
2887
+ DEFAULT_HOSTED_VERIFY_URL,
2888
+ GATE_AGENT_DELEGATION,
2889
+ GATE_AGENT_IDENTITY,
2890
+ GATE_CONTENT_MODERATION,
2337
2891
  GATE_CONTRACT_ADMIN,
2338
2892
  GATE_DOMAIN_OWNER,
2339
2893
  GATE_LINKED_WALLETS,
2340
2894
  GATE_NFT_HOLDER,
2895
+ GATE_PSEUDONYM,
2341
2896
  GATE_TOKEN_HOLDER,
2897
+ GATE_WALLET_RISK,
2342
2898
  HOUR,
2343
2899
  MONTH,
2344
2900
  NEUS_CONSTANTS,
2345
2901
  NetworkError,
2346
2902
  NeusClient,
2903
+ PORTABLE_PROOF_SIGNER_HEADER,
2347
2904
  SDKError,
2348
2905
  StatusPoller,
2349
2906
  ValidationError,
@@ -2360,14 +2917,22 @@ var sdk_default = {
2360
2917
  deriveDid,
2361
2918
  formatTimestamp,
2362
2919
  formatVerificationStatus,
2920
+ getHostedCheckoutUrl,
2363
2921
  isFailureStatus,
2364
2922
  isSuccessStatus,
2365
2923
  isSupportedChain,
2366
2924
  isTerminalStatus,
2367
2925
  normalizeAddress,
2926
+ resolveDID,
2927
+ resolveZkPassportConfig,
2928
+ signMessage,
2929
+ standardizeVerificationRequest,
2930
+ toAgentDelegationMaxSpend,
2931
+ toHexUtf8,
2368
2932
  validateQHash,
2369
2933
  validateSignatureComponents,
2370
2934
  validateTimestamp,
2935
+ validateUniversalAddress,
2371
2936
  validateVerifierPayload,
2372
2937
  validateWalletAddress,
2373
2938
  withRetry