@neus/sdk 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cjs/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
@@ -120,6 +127,50 @@ var ValidationError = class extends SDKError {
120
127
  };
121
128
 
122
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
+ }
123
174
  function deterministicStringify(obj) {
124
175
  if (obj === null || obj === void 0) {
125
176
  return JSON.stringify(obj);
@@ -178,6 +229,29 @@ function validateWalletAddress(address) {
178
229
  }
179
230
  return /^0x[a-fA-F0-9]{40}$/.test(address);
180
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
+ }
181
255
  function validateTimestamp(timestamp, maxAgeMs = 5 * 60 * 1e3) {
182
256
  if (!timestamp || typeof timestamp !== "number") {
183
257
  return false;
@@ -199,7 +273,7 @@ function createVerificationData(content, owner, reference = null) {
199
273
  };
200
274
  return {
201
275
  content,
202
- owner: owner.toLowerCase(),
276
+ owner: validateWalletAddress(owner) ? owner.toLowerCase() : owner,
203
277
  reference: reference || {
204
278
  // Must be a valid backend enum value; 'content' is not supported.
205
279
  type: "other",
@@ -224,6 +298,261 @@ function deriveDid(address, chainIdOrChain) {
224
298
  return `did:pkh:eip155:${chainContext}:${address.toLowerCase()}`;
225
299
  }
226
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
+ }
227
556
  function isTerminalStatus(status) {
228
557
  if (!status || typeof status !== "string")
229
558
  return false;
@@ -510,7 +839,7 @@ function validateVerifierPayload(verifierId, data) {
510
839
  result.missing.push(key);
511
840
  });
512
841
  if (!("ownerAddress" in data)) {
513
- result.warnings.push("ownerAddress omitted (most deployments default to the signed walletAddress)");
842
+ result.warnings.push("ownerAddress omitted (defaults to the signed walletAddress)");
514
843
  }
515
844
  } else if (id === "token-holding") {
516
845
  ["contractAddress", "minBalance", "chainId"].forEach((key) => {
@@ -518,7 +847,7 @@ function validateVerifierPayload(verifierId, data) {
518
847
  result.missing.push(key);
519
848
  });
520
849
  if (!("ownerAddress" in data)) {
521
- result.warnings.push("ownerAddress omitted (most deployments default to the signed walletAddress)");
850
+ result.warnings.push("ownerAddress omitted (defaults to the signed walletAddress)");
522
851
  }
523
852
  } else if (id === "ownership-basic") {
524
853
  if (!("owner" in data))
@@ -672,9 +1001,15 @@ function validateSignatureComponents({ walletAddress, signature, signedTimestamp
672
1001
  isSupportedChain,
673
1002
  isTerminalStatus,
674
1003
  normalizeAddress,
1004
+ resolveDID,
1005
+ resolveZkPassportConfig,
1006
+ signMessage,
1007
+ standardizeVerificationRequest,
1008
+ toHexUtf8,
675
1009
  validateQHash,
676
1010
  validateSignatureComponents,
677
1011
  validateTimestamp,
1012
+ validateUniversalAddress,
678
1013
  validateVerifierPayload,
679
1014
  validateWalletAddress,
680
1015
  withRetry