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