@neus/sdk 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +150 -140
- package/cjs/client.cjs +634 -223
- package/cjs/errors.cjs +1 -0
- package/cjs/gates.cjs +1 -0
- package/cjs/index.cjs +840 -236
- package/cjs/utils.cjs +408 -12
- package/client.js +502 -244
- package/index.js +75 -64
- package/neus-logo.svg +3 -0
- package/package.json +9 -5
- package/types.d.ts +379 -82
- package/utils.js +443 -14
- 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 +284 -59
- package/widgets/verify-gate/index.js +13 -13
package/cjs/utils.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;
|
|
@@ -44,9 +45,15 @@ __export(utils_exports, {
|
|
|
44
45
|
isSupportedChain: () => isSupportedChain,
|
|
45
46
|
isTerminalStatus: () => isTerminalStatus,
|
|
46
47
|
normalizeAddress: () => normalizeAddress,
|
|
48
|
+
resolveDID: () => resolveDID,
|
|
49
|
+
resolveZkPassportConfig: () => resolveZkPassportConfig,
|
|
50
|
+
signMessage: () => signMessage,
|
|
51
|
+
standardizeVerificationRequest: () => standardizeVerificationRequest,
|
|
52
|
+
toHexUtf8: () => toHexUtf8,
|
|
47
53
|
validateQHash: () => validateQHash,
|
|
48
54
|
validateSignatureComponents: () => validateSignatureComponents,
|
|
49
55
|
validateTimestamp: () => validateTimestamp,
|
|
56
|
+
validateUniversalAddress: () => validateUniversalAddress,
|
|
50
57
|
validateVerifierPayload: () => validateVerifierPayload,
|
|
51
58
|
validateWalletAddress: () => validateWalletAddress,
|
|
52
59
|
withRetry: () => withRetry
|
|
@@ -75,8 +82,95 @@ var SDKError = class _SDKError extends Error {
|
|
|
75
82
|
};
|
|
76
83
|
}
|
|
77
84
|
};
|
|
85
|
+
var ApiError = class _ApiError extends SDKError {
|
|
86
|
+
constructor(message, statusCode = 500, code = "API_ERROR", response = null) {
|
|
87
|
+
super(message, code);
|
|
88
|
+
this.name = "ApiError";
|
|
89
|
+
this.statusCode = statusCode;
|
|
90
|
+
this.response = response;
|
|
91
|
+
this.isClientError = statusCode >= 400 && statusCode < 500;
|
|
92
|
+
this.isServerError = statusCode >= 500;
|
|
93
|
+
this.isRetryable = this.isServerError || statusCode === 429;
|
|
94
|
+
}
|
|
95
|
+
static fromResponse(response, responseData) {
|
|
96
|
+
const statusCode = response.status;
|
|
97
|
+
const message = responseData?.error?.message || responseData?.message || `API request failed with status ${statusCode}`;
|
|
98
|
+
const code = responseData?.error?.code || "API_ERROR";
|
|
99
|
+
return new _ApiError(message, statusCode, code, responseData);
|
|
100
|
+
}
|
|
101
|
+
toJSON() {
|
|
102
|
+
return {
|
|
103
|
+
...super.toJSON(),
|
|
104
|
+
statusCode: this.statusCode,
|
|
105
|
+
isClientError: this.isClientError,
|
|
106
|
+
isServerError: this.isServerError,
|
|
107
|
+
isRetryable: this.isRetryable
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
var ValidationError = class extends SDKError {
|
|
112
|
+
constructor(message, field = null, value = null) {
|
|
113
|
+
super(message, "VALIDATION_ERROR");
|
|
114
|
+
this.name = "ValidationError";
|
|
115
|
+
this.field = field;
|
|
116
|
+
this.value = value;
|
|
117
|
+
this.isRetryable = false;
|
|
118
|
+
}
|
|
119
|
+
toJSON() {
|
|
120
|
+
return {
|
|
121
|
+
...super.toJSON(),
|
|
122
|
+
field: this.field,
|
|
123
|
+
value: this.value,
|
|
124
|
+
isRetryable: this.isRetryable
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
};
|
|
78
128
|
|
|
79
129
|
// utils.js
|
|
130
|
+
var BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
131
|
+
function encodeBase58Bytes(input) {
|
|
132
|
+
let source;
|
|
133
|
+
if (input instanceof Uint8Array) {
|
|
134
|
+
source = input;
|
|
135
|
+
} else if (input instanceof ArrayBuffer) {
|
|
136
|
+
source = new Uint8Array(input);
|
|
137
|
+
} else if (ArrayBuffer.isView(input)) {
|
|
138
|
+
source = new Uint8Array(input.buffer, input.byteOffset, input.byteLength);
|
|
139
|
+
} else if (typeof Buffer !== "undefined" && typeof Buffer.isBuffer === "function" && Buffer.isBuffer(input)) {
|
|
140
|
+
source = new Uint8Array(input);
|
|
141
|
+
} else {
|
|
142
|
+
throw new SDKError("Unsupported non-EVM signature byte format", "INVALID_SIGNATURE_FORMAT");
|
|
143
|
+
}
|
|
144
|
+
if (source.length === 0)
|
|
145
|
+
return "";
|
|
146
|
+
let zeroes = 0;
|
|
147
|
+
while (zeroes < source.length && source[zeroes] === 0) {
|
|
148
|
+
zeroes++;
|
|
149
|
+
}
|
|
150
|
+
const iFactor = Math.log(256) / Math.log(58);
|
|
151
|
+
const size = (source.length - zeroes) * iFactor + 1 >>> 0;
|
|
152
|
+
const b58 = new Uint8Array(size);
|
|
153
|
+
let length = 0;
|
|
154
|
+
for (let i = zeroes; i < source.length; i++) {
|
|
155
|
+
let carry = source[i];
|
|
156
|
+
let j = 0;
|
|
157
|
+
for (let k = size - 1; (carry !== 0 || j < length) && k >= 0; k--, j++) {
|
|
158
|
+
carry += 256 * b58[k];
|
|
159
|
+
b58[k] = carry % 58;
|
|
160
|
+
carry = carry / 58 | 0;
|
|
161
|
+
}
|
|
162
|
+
length = j;
|
|
163
|
+
}
|
|
164
|
+
let it = size - length;
|
|
165
|
+
while (it < size && b58[it] === 0) {
|
|
166
|
+
it++;
|
|
167
|
+
}
|
|
168
|
+
let out = BASE58_ALPHABET[0].repeat(zeroes);
|
|
169
|
+
for (; it < size; it++) {
|
|
170
|
+
out += BASE58_ALPHABET[b58[it]];
|
|
171
|
+
}
|
|
172
|
+
return out;
|
|
173
|
+
}
|
|
80
174
|
function deterministicStringify(obj) {
|
|
81
175
|
if (obj === null || obj === void 0) {
|
|
82
176
|
return JSON.stringify(obj);
|
|
@@ -108,7 +202,7 @@ function constructVerificationMessage({ walletAddress, signedTimestamp, data, ve
|
|
|
108
202
|
}
|
|
109
203
|
const chainContext = typeof chain === "string" && chain.length > 0 ? chain : chainId;
|
|
110
204
|
if (!chainContext) {
|
|
111
|
-
throw new SDKError("chainId is required (or provide chain for
|
|
205
|
+
throw new SDKError("chainId is required (or provide chain for universal mode)", "INVALID_CHAIN_CONTEXT");
|
|
112
206
|
}
|
|
113
207
|
if (chainContext === chainId && typeof chainId !== "number") {
|
|
114
208
|
throw new SDKError("chainId must be a number when provided", "INVALID_CHAIN_ID");
|
|
@@ -135,6 +229,29 @@ function validateWalletAddress(address) {
|
|
|
135
229
|
}
|
|
136
230
|
return /^0x[a-fA-F0-9]{40}$/.test(address);
|
|
137
231
|
}
|
|
232
|
+
function validateUniversalAddress(address, chain) {
|
|
233
|
+
if (!address || typeof address !== "string")
|
|
234
|
+
return false;
|
|
235
|
+
const value = address.trim();
|
|
236
|
+
if (!value)
|
|
237
|
+
return false;
|
|
238
|
+
const chainRef = typeof chain === "string" ? chain.trim().toLowerCase() : "";
|
|
239
|
+
const namespace = chainRef.includes(":") ? chainRef.split(":")[0] : "";
|
|
240
|
+
if (validateWalletAddress(value))
|
|
241
|
+
return true;
|
|
242
|
+
if (namespace === "eip155")
|
|
243
|
+
return false;
|
|
244
|
+
if (namespace === "solana") {
|
|
245
|
+
return /^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(value);
|
|
246
|
+
}
|
|
247
|
+
if (namespace === "bip122") {
|
|
248
|
+
return /^(bc1|tb1|bcrt1)[a-z0-9]{11,87}$/.test(value.toLowerCase()) || /^[13mn2][a-km-zA-HJ-NP-Z1-9]{25,62}$/.test(value);
|
|
249
|
+
}
|
|
250
|
+
if (namespace === "near") {
|
|
251
|
+
return /^[a-z0-9._-]{2,64}$/.test(value);
|
|
252
|
+
}
|
|
253
|
+
return /^[A-Za-z0-9][A-Za-z0-9._:-]{1,127}$/.test(value);
|
|
254
|
+
}
|
|
138
255
|
function validateTimestamp(timestamp, maxAgeMs = 5 * 60 * 1e3) {
|
|
139
256
|
if (!timestamp || typeof timestamp !== "number") {
|
|
140
257
|
return false;
|
|
@@ -156,7 +273,7 @@ function createVerificationData(content, owner, reference = null) {
|
|
|
156
273
|
};
|
|
157
274
|
return {
|
|
158
275
|
content,
|
|
159
|
-
owner: owner.toLowerCase(),
|
|
276
|
+
owner: validateWalletAddress(owner) ? owner.toLowerCase() : owner,
|
|
160
277
|
reference: reference || {
|
|
161
278
|
// Must be a valid backend enum value; 'content' is not supported.
|
|
162
279
|
type: "other",
|
|
@@ -181,6 +298,261 @@ function deriveDid(address, chainIdOrChain) {
|
|
|
181
298
|
return `did:pkh:eip155:${chainContext}:${address.toLowerCase()}`;
|
|
182
299
|
}
|
|
183
300
|
}
|
|
301
|
+
async function resolveDID(params, options = {}) {
|
|
302
|
+
const endpointPath = options.endpoint || "/api/v1/profile/did/resolve";
|
|
303
|
+
const apiUrl = typeof options.apiUrl === "string" ? options.apiUrl.trim() : "";
|
|
304
|
+
const resolveEndpoint = (path) => {
|
|
305
|
+
if (!path || typeof path !== "string")
|
|
306
|
+
return null;
|
|
307
|
+
const trimmedPath = path.trim();
|
|
308
|
+
if (!trimmedPath)
|
|
309
|
+
return null;
|
|
310
|
+
if (/^https?:\/\//i.test(trimmedPath))
|
|
311
|
+
return trimmedPath;
|
|
312
|
+
if (trimmedPath.startsWith("/")) {
|
|
313
|
+
if (!apiUrl)
|
|
314
|
+
return trimmedPath;
|
|
315
|
+
try {
|
|
316
|
+
return new URL(trimmedPath, apiUrl.endsWith("/") ? apiUrl : `${apiUrl}/`).toString();
|
|
317
|
+
} catch {
|
|
318
|
+
return null;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
const base = apiUrl || NEUS_CONSTANTS.API_BASE_URL;
|
|
322
|
+
if (!base || typeof base !== "string")
|
|
323
|
+
return null;
|
|
324
|
+
try {
|
|
325
|
+
return new URL(trimmedPath, base.endsWith("/") ? base : `${base}/`).toString();
|
|
326
|
+
} catch {
|
|
327
|
+
return null;
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
const endpoint = resolveEndpoint(endpointPath);
|
|
331
|
+
if (!endpoint) {
|
|
332
|
+
throw new SDKError("resolveDID requires a valid endpoint", "INVALID_ENDPOINT");
|
|
333
|
+
}
|
|
334
|
+
const payload = {
|
|
335
|
+
walletAddress: params?.walletAddress,
|
|
336
|
+
chainId: params?.chainId,
|
|
337
|
+
chain: params?.chain
|
|
338
|
+
};
|
|
339
|
+
const isRelative = endpoint.startsWith("/") || !/^https?:\/\//i.test(endpoint);
|
|
340
|
+
const credentialsMode = options.credentials !== void 0 ? options.credentials : isRelative ? "same-origin" : "omit";
|
|
341
|
+
try {
|
|
342
|
+
const response = await fetch(endpoint, {
|
|
343
|
+
method: "POST",
|
|
344
|
+
headers: {
|
|
345
|
+
"Content-Type": "application/json",
|
|
346
|
+
Accept: "application/json",
|
|
347
|
+
...options.headers || {}
|
|
348
|
+
},
|
|
349
|
+
body: JSON.stringify(payload),
|
|
350
|
+
credentials: credentialsMode
|
|
351
|
+
});
|
|
352
|
+
const json = await response.json().catch(() => null);
|
|
353
|
+
if (!response.ok) {
|
|
354
|
+
const msg = json?.error?.message || json?.error || json?.message || "DID resolution failed";
|
|
355
|
+
throw new SDKError(msg, "DID_RESOLVE_FAILED", json);
|
|
356
|
+
}
|
|
357
|
+
const did = json?.data?.did || json?.did;
|
|
358
|
+
if (!did || typeof did !== "string") {
|
|
359
|
+
throw new SDKError("DID resolution missing DID", "DID_RESOLVE_MISSING", json);
|
|
360
|
+
}
|
|
361
|
+
return { did, data: json?.data || null, raw: json };
|
|
362
|
+
} catch (error) {
|
|
363
|
+
if (error instanceof SDKError)
|
|
364
|
+
throw error;
|
|
365
|
+
throw new SDKError(`DID resolution failed: ${error?.message || error}`, "DID_RESOLVE_FAILED");
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
async function standardizeVerificationRequest(params, options = {}) {
|
|
369
|
+
const endpointPath = options.endpoint || "/api/v1/verification/standardize";
|
|
370
|
+
const apiUrl = typeof options.apiUrl === "string" ? options.apiUrl.trim() : "";
|
|
371
|
+
const resolveEndpoint = (path) => {
|
|
372
|
+
if (!path || typeof path !== "string")
|
|
373
|
+
return null;
|
|
374
|
+
const trimmedPath = path.trim();
|
|
375
|
+
if (!trimmedPath)
|
|
376
|
+
return null;
|
|
377
|
+
if (/^https?:\/\//i.test(trimmedPath))
|
|
378
|
+
return trimmedPath;
|
|
379
|
+
if (trimmedPath.startsWith("/")) {
|
|
380
|
+
if (!apiUrl)
|
|
381
|
+
return trimmedPath;
|
|
382
|
+
try {
|
|
383
|
+
return new URL(trimmedPath, apiUrl.endsWith("/") ? apiUrl : `${apiUrl}/`).toString();
|
|
384
|
+
} catch {
|
|
385
|
+
return null;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
const base = apiUrl || NEUS_CONSTANTS.API_BASE_URL;
|
|
389
|
+
if (!base || typeof base !== "string")
|
|
390
|
+
return null;
|
|
391
|
+
try {
|
|
392
|
+
return new URL(trimmedPath, base.endsWith("/") ? base : `${base}/`).toString();
|
|
393
|
+
} catch {
|
|
394
|
+
return null;
|
|
395
|
+
}
|
|
396
|
+
};
|
|
397
|
+
const endpoint = resolveEndpoint(endpointPath);
|
|
398
|
+
if (!endpoint) {
|
|
399
|
+
throw new SDKError("standardizeVerificationRequest requires a valid endpoint", "INVALID_ENDPOINT");
|
|
400
|
+
}
|
|
401
|
+
const isRelative = endpoint.startsWith("/") || !/^https?:\/\//i.test(endpoint);
|
|
402
|
+
const credentialsMode = options.credentials !== void 0 ? options.credentials : isRelative ? "same-origin" : "omit";
|
|
403
|
+
try {
|
|
404
|
+
const response = await fetch(endpoint, {
|
|
405
|
+
method: "POST",
|
|
406
|
+
headers: {
|
|
407
|
+
"Content-Type": "application/json",
|
|
408
|
+
Accept: "application/json",
|
|
409
|
+
...options.headers || {}
|
|
410
|
+
},
|
|
411
|
+
body: JSON.stringify(params || {}),
|
|
412
|
+
credentials: credentialsMode
|
|
413
|
+
});
|
|
414
|
+
const json = await response.json().catch(() => null);
|
|
415
|
+
if (!response.ok) {
|
|
416
|
+
const msg = json?.error?.message || json?.error || json?.message || "Standardize request failed";
|
|
417
|
+
throw new SDKError(msg, "STANDARDIZE_FAILED", json);
|
|
418
|
+
}
|
|
419
|
+
return json?.data || json;
|
|
420
|
+
} catch (error) {
|
|
421
|
+
if (error instanceof SDKError)
|
|
422
|
+
throw error;
|
|
423
|
+
throw new SDKError(`Standardize request failed: ${error?.message || error}`, "STANDARDIZE_FAILED");
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
function resolveZkPassportConfig(overrides = {}) {
|
|
427
|
+
const defaults = {
|
|
428
|
+
provider: "zkpassport",
|
|
429
|
+
scope: "basic_kyc",
|
|
430
|
+
checkSanctions: true,
|
|
431
|
+
requireFaceMatch: true,
|
|
432
|
+
faceMatchMode: "strict"
|
|
433
|
+
};
|
|
434
|
+
return {
|
|
435
|
+
...defaults,
|
|
436
|
+
...overrides && typeof overrides === "object" ? overrides : {}
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
function toHexUtf8(value) {
|
|
440
|
+
const input = typeof value === "string" ? value : String(value || "");
|
|
441
|
+
const bytes = new TextEncoder().encode(input);
|
|
442
|
+
return `0x${Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("")}`;
|
|
443
|
+
}
|
|
444
|
+
async function signMessage({ provider, message, walletAddress, chain } = {}) {
|
|
445
|
+
const msg = typeof message === "string" ? message : String(message || "");
|
|
446
|
+
if (!msg) {
|
|
447
|
+
throw new SDKError("signMessage: message is required", "INVALID_ARGUMENT");
|
|
448
|
+
}
|
|
449
|
+
const resolvedProvider = provider || (typeof window !== "undefined" && window?.ethereum ? window.ethereum : null);
|
|
450
|
+
if (!resolvedProvider) {
|
|
451
|
+
throw new SDKError("signMessage: provider is required", "SIGNER_UNAVAILABLE");
|
|
452
|
+
}
|
|
453
|
+
const chainStr = typeof chain === "string" && chain.trim().length > 0 ? chain.trim() : "eip155";
|
|
454
|
+
const namespace = chainStr.includes(":") ? chainStr.split(":")[0] || "eip155" : "eip155";
|
|
455
|
+
const resolveAddress = async () => {
|
|
456
|
+
if (typeof walletAddress === "string" && walletAddress.trim().length > 0)
|
|
457
|
+
return walletAddress;
|
|
458
|
+
if (namespace === "solana") {
|
|
459
|
+
if (resolvedProvider?.publicKey && typeof resolvedProvider.publicKey.toBase58 === "function") {
|
|
460
|
+
const pk = resolvedProvider.publicKey.toBase58();
|
|
461
|
+
if (typeof pk === "string" && pk)
|
|
462
|
+
return pk;
|
|
463
|
+
}
|
|
464
|
+
if (typeof resolvedProvider.getAddress === "function") {
|
|
465
|
+
const addr = await resolvedProvider.getAddress().catch(() => null);
|
|
466
|
+
if (typeof addr === "string" && addr)
|
|
467
|
+
return addr;
|
|
468
|
+
}
|
|
469
|
+
if (typeof resolvedProvider.address === "string" && resolvedProvider.address)
|
|
470
|
+
return resolvedProvider.address;
|
|
471
|
+
return null;
|
|
472
|
+
}
|
|
473
|
+
if (typeof resolvedProvider.address === "string" && resolvedProvider.address)
|
|
474
|
+
return resolvedProvider.address;
|
|
475
|
+
if (typeof resolvedProvider.getAddress === "function")
|
|
476
|
+
return await resolvedProvider.getAddress();
|
|
477
|
+
if (typeof resolvedProvider.request === "function") {
|
|
478
|
+
let accounts = await resolvedProvider.request({ method: "eth_accounts" }).catch(() => []);
|
|
479
|
+
if (!Array.isArray(accounts) || accounts.length === 0) {
|
|
480
|
+
accounts = await resolvedProvider.request({ method: "eth_requestAccounts" }).catch(() => []);
|
|
481
|
+
}
|
|
482
|
+
if (Array.isArray(accounts) && accounts[0])
|
|
483
|
+
return accounts[0];
|
|
484
|
+
}
|
|
485
|
+
return null;
|
|
486
|
+
};
|
|
487
|
+
if (namespace !== "eip155") {
|
|
488
|
+
if (typeof resolvedProvider.signMessage === "function") {
|
|
489
|
+
const encoded = typeof msg === "string" ? new TextEncoder().encode(msg) : msg;
|
|
490
|
+
const result = await resolvedProvider.signMessage(encoded);
|
|
491
|
+
if (typeof result === "string" && result)
|
|
492
|
+
return result;
|
|
493
|
+
if (result instanceof Uint8Array)
|
|
494
|
+
return encodeBase58Bytes(result);
|
|
495
|
+
if (result instanceof ArrayBuffer)
|
|
496
|
+
return encodeBase58Bytes(new Uint8Array(result));
|
|
497
|
+
if (ArrayBuffer.isView(result))
|
|
498
|
+
return encodeBase58Bytes(result);
|
|
499
|
+
if (typeof Buffer !== "undefined" && typeof Buffer.isBuffer === "function" && Buffer.isBuffer(result))
|
|
500
|
+
return encodeBase58Bytes(result);
|
|
501
|
+
}
|
|
502
|
+
throw new SDKError("Non-EVM signing requires provider.signMessage", "SIGNER_UNAVAILABLE");
|
|
503
|
+
}
|
|
504
|
+
const address = await resolveAddress();
|
|
505
|
+
if (typeof resolvedProvider.request === "function" && address) {
|
|
506
|
+
let firstPersonalSignError = null;
|
|
507
|
+
try {
|
|
508
|
+
const sig = await resolvedProvider.request({ method: "personal_sign", params: [msg, address] });
|
|
509
|
+
if (typeof sig === "string" && sig)
|
|
510
|
+
return sig;
|
|
511
|
+
} catch (error) {
|
|
512
|
+
firstPersonalSignError = error;
|
|
513
|
+
}
|
|
514
|
+
let secondPersonalSignError = null;
|
|
515
|
+
try {
|
|
516
|
+
const sig = await resolvedProvider.request({ method: "personal_sign", params: [address, msg] });
|
|
517
|
+
if (typeof sig === "string" && sig)
|
|
518
|
+
return sig;
|
|
519
|
+
} catch (error) {
|
|
520
|
+
secondPersonalSignError = error;
|
|
521
|
+
const signatureErrorMessage = String(
|
|
522
|
+
error?.message || error?.reason || firstPersonalSignError?.message || firstPersonalSignError?.reason || ""
|
|
523
|
+
).toLowerCase();
|
|
524
|
+
const needsHex = /byte|bytes|invalid byte sequence|encoding|non-hex/i.test(signatureErrorMessage);
|
|
525
|
+
if (needsHex) {
|
|
526
|
+
try {
|
|
527
|
+
const hexMsg = toHexUtf8(msg);
|
|
528
|
+
const sig = await resolvedProvider.request({ method: "personal_sign", params: [hexMsg, address] });
|
|
529
|
+
if (typeof sig === "string" && sig)
|
|
530
|
+
return sig;
|
|
531
|
+
} catch {
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
try {
|
|
536
|
+
const sig = await resolvedProvider.request({ method: "eth_sign", params: [address, msg] });
|
|
537
|
+
if (typeof sig === "string" && sig)
|
|
538
|
+
return sig;
|
|
539
|
+
} catch {
|
|
540
|
+
}
|
|
541
|
+
if (secondPersonalSignError || firstPersonalSignError) {
|
|
542
|
+
const lastError = secondPersonalSignError || firstPersonalSignError;
|
|
543
|
+
const isUserRejection = [4001, "ACTION_REJECTED"].includes(lastError?.code);
|
|
544
|
+
if (isUserRejection) {
|
|
545
|
+
throw lastError;
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
if (typeof resolvedProvider.signMessage === "function") {
|
|
550
|
+
const result = await resolvedProvider.signMessage(msg);
|
|
551
|
+
if (typeof result === "string" && result)
|
|
552
|
+
return result;
|
|
553
|
+
}
|
|
554
|
+
throw new SDKError("Unable to sign message with provided wallet/provider", "SIGNER_UNAVAILABLE");
|
|
555
|
+
}
|
|
184
556
|
function isTerminalStatus(status) {
|
|
185
557
|
if (!status || typeof status !== "string")
|
|
186
558
|
return false;
|
|
@@ -384,10 +756,24 @@ var StatusPoller = class {
|
|
|
384
756
|
}
|
|
385
757
|
setTimeout(pollAttempt, this.currentInterval);
|
|
386
758
|
} catch (error) {
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
759
|
+
if (error instanceof ValidationError) {
|
|
760
|
+
reject(error);
|
|
761
|
+
return;
|
|
762
|
+
}
|
|
763
|
+
if (error instanceof ApiError && error.statusCode === 429 || error?.isRetryable === true) {
|
|
764
|
+
if (this.options.exponentialBackoff) {
|
|
765
|
+
const next = Math.min(this.currentInterval * 2, this.options.maxInterval);
|
|
766
|
+
const jitter = next * (0.5 + Math.random() * 0.5);
|
|
767
|
+
this.currentInterval = Math.max(250, Math.floor(jitter));
|
|
768
|
+
}
|
|
769
|
+
if (this.attempt >= this.options.maxAttempts) {
|
|
770
|
+
reject(new SDKError("Verification polling timeout", "POLLING_TIMEOUT"));
|
|
771
|
+
return;
|
|
772
|
+
}
|
|
773
|
+
setTimeout(pollAttempt, this.currentInterval);
|
|
774
|
+
return;
|
|
775
|
+
}
|
|
776
|
+
reject(new SDKError(`Polling failed: ${error.message}`, "POLLING_ERROR"));
|
|
391
777
|
}
|
|
392
778
|
};
|
|
393
779
|
pollAttempt();
|
|
@@ -453,7 +839,7 @@ function validateVerifierPayload(verifierId, data) {
|
|
|
453
839
|
result.missing.push(key);
|
|
454
840
|
});
|
|
455
841
|
if (!("ownerAddress" in data)) {
|
|
456
|
-
result.warnings.push("ownerAddress omitted (
|
|
842
|
+
result.warnings.push("ownerAddress omitted (defaults to the signed walletAddress)");
|
|
457
843
|
}
|
|
458
844
|
} else if (id === "token-holding") {
|
|
459
845
|
["contractAddress", "minBalance", "chainId"].forEach((key) => {
|
|
@@ -461,13 +847,17 @@ function validateVerifierPayload(verifierId, data) {
|
|
|
461
847
|
result.missing.push(key);
|
|
462
848
|
});
|
|
463
849
|
if (!("ownerAddress" in data)) {
|
|
464
|
-
result.warnings.push("ownerAddress omitted (
|
|
850
|
+
result.warnings.push("ownerAddress omitted (defaults to the signed walletAddress)");
|
|
465
851
|
}
|
|
466
852
|
} else if (id === "ownership-basic") {
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
853
|
+
if (!("owner" in data))
|
|
854
|
+
result.missing.push("owner");
|
|
855
|
+
const hasContent = typeof data.content === "string" && data.content.length > 0;
|
|
856
|
+
const hasContentHash = typeof data.contentHash === "string" && data.contentHash.length > 0;
|
|
857
|
+
const hasRefId = typeof data.reference?.id === "string" && data.reference.id.length > 0;
|
|
858
|
+
if (!hasContent && !hasContentHash && !hasRefId) {
|
|
859
|
+
result.missing.push("content (or contentHash or reference.id)");
|
|
860
|
+
}
|
|
471
861
|
}
|
|
472
862
|
if (result.missing.length > 0) {
|
|
473
863
|
result.valid = false;
|
|
@@ -611,9 +1001,15 @@ function validateSignatureComponents({ walletAddress, signature, signedTimestamp
|
|
|
611
1001
|
isSupportedChain,
|
|
612
1002
|
isTerminalStatus,
|
|
613
1003
|
normalizeAddress,
|
|
1004
|
+
resolveDID,
|
|
1005
|
+
resolveZkPassportConfig,
|
|
1006
|
+
signMessage,
|
|
1007
|
+
standardizeVerificationRequest,
|
|
1008
|
+
toHexUtf8,
|
|
614
1009
|
validateQHash,
|
|
615
1010
|
validateSignatureComponents,
|
|
616
1011
|
validateTimestamp,
|
|
1012
|
+
validateUniversalAddress,
|
|
617
1013
|
validateVerifierPayload,
|
|
618
1014
|
validateWalletAddress,
|
|
619
1015
|
withRetry
|