vesant-sdk 1.1.0 → 1.2.0

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.
Files changed (53) hide show
  1. package/dist/{types-DgNbBnEH.d.ts → client-BIfLMfuC.d.mts} +274 -2
  2. package/dist/{types-DGbuL8c0.d.mts → client-BWp5FI3x.d.ts} +274 -2
  3. package/dist/compliance/index.d.mts +9 -4
  4. package/dist/compliance/index.d.ts +9 -4
  5. package/dist/compliance/index.js +297 -2
  6. package/dist/compliance/index.js.map +1 -1
  7. package/dist/compliance/index.mjs +297 -2
  8. package/dist/compliance/index.mjs.map +1 -1
  9. package/dist/geolocation/index.d.mts +3 -5
  10. package/dist/geolocation/index.d.ts +3 -5
  11. package/dist/geolocation/index.js +310 -250
  12. package/dist/geolocation/index.js.map +1 -1
  13. package/dist/geolocation/index.mjs +310 -250
  14. package/dist/geolocation/index.mjs.map +1 -1
  15. package/dist/index.d.mts +5 -7
  16. package/dist/index.d.ts +5 -7
  17. package/dist/index.js +322 -251
  18. package/dist/index.js.map +1 -1
  19. package/dist/index.mjs +322 -251
  20. package/dist/index.mjs.map +1 -1
  21. package/dist/kyc/core.d.mts +2 -3
  22. package/dist/kyc/core.d.ts +2 -3
  23. package/dist/kyc/core.js +1 -1
  24. package/dist/kyc/core.js.map +1 -1
  25. package/dist/kyc/core.mjs +1 -1
  26. package/dist/kyc/core.mjs.map +1 -1
  27. package/dist/kyc/index.d.mts +2 -3
  28. package/dist/kyc/index.d.ts +2 -3
  29. package/dist/kyc/index.js +1 -1
  30. package/dist/kyc/index.js.map +1 -1
  31. package/dist/kyc/index.mjs +1 -1
  32. package/dist/kyc/index.mjs.map +1 -1
  33. package/dist/react.d.mts +3 -5
  34. package/dist/react.d.ts +3 -5
  35. package/dist/react.js +29 -3
  36. package/dist/react.js.map +1 -1
  37. package/dist/react.mjs +29 -3
  38. package/dist/react.mjs.map +1 -1
  39. package/dist/risk-profile/index.d.mts +4 -5
  40. package/dist/risk-profile/index.d.ts +4 -5
  41. package/dist/risk-profile/index.js +1 -1
  42. package/dist/risk-profile/index.js.map +1 -1
  43. package/dist/risk-profile/index.mjs +1 -1
  44. package/dist/risk-profile/index.mjs.map +1 -1
  45. package/dist/{types-DBGM-bFB.d.mts → types-BpKxSXGF.d.mts} +50 -1
  46. package/dist/{types-DBGM-bFB.d.ts → types-BpKxSXGF.d.ts} +50 -1
  47. package/dist/{types-BQTkTvNp.d.mts → types-DKCQN4C5.d.mts} +1 -1
  48. package/dist/{types-BF8mYH2W.d.ts → types-DfHLp_tz.d.ts} +1 -1
  49. package/package.json +1 -1
  50. package/dist/client-B7YzKVEm.d.mts +0 -52
  51. package/dist/client-BaNLT2Df.d.ts +0 -52
  52. package/dist/client-VKJg2GGT.d.mts +0 -253
  53. package/dist/client-hXdrPhA4.d.ts +0 -253
@@ -84,7 +84,7 @@ function createConsoleLogger() {
84
84
  }
85
85
 
86
86
  // src/core/version.ts
87
- var SDK_VERSION = "1.1.0";
87
+ var SDK_VERSION = "1.2.0";
88
88
 
89
89
  // src/core/client.ts
90
90
  var BaseClient = class {
@@ -309,6 +309,256 @@ var BaseClient = class {
309
309
  }
310
310
  };
311
311
 
312
+ // src/shared/browser-utils.ts
313
+ function generateUUID() {
314
+ if (typeof crypto !== "undefined" && crypto.randomUUID) {
315
+ return crypto.randomUUID();
316
+ }
317
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
318
+ const r = Math.random() * 16 | 0;
319
+ const v = c === "x" ? r : r & 3 | 8;
320
+ return v.toString(16);
321
+ });
322
+ }
323
+ function generateDeviceId() {
324
+ if (typeof window === "undefined" || typeof localStorage === "undefined") {
325
+ return generateUUID();
326
+ }
327
+ const storageKey = "cgs_device_id";
328
+ let deviceId = localStorage.getItem(storageKey);
329
+ if (!deviceId) {
330
+ deviceId = generateUUID();
331
+ localStorage.setItem(storageKey, deviceId);
332
+ }
333
+ return deviceId;
334
+ }
335
+ function getBrowserInfo() {
336
+ if (typeof navigator === "undefined") {
337
+ return { browser: "unknown", browser_version: "", os: "unknown", os_version: "" };
338
+ }
339
+ const ua = navigator.userAgent;
340
+ let browser = "unknown";
341
+ let browserVersion = "";
342
+ let os = "unknown";
343
+ let osVersion = "";
344
+ if (ua.includes("Firefox/")) {
345
+ browser = "Firefox";
346
+ browserVersion = ua.match(/Firefox\/([\d.]+)/)?.[1] || "";
347
+ } else if (ua.includes("Edg/")) {
348
+ browser = "Edge";
349
+ browserVersion = ua.match(/Edg\/([\d.]+)/)?.[1] || "";
350
+ } else if (ua.includes("Chrome/")) {
351
+ browser = "Chrome";
352
+ browserVersion = ua.match(/Chrome\/([\d.]+)/)?.[1] || "";
353
+ } else if (ua.includes("Safari/") && !ua.includes("Chrome")) {
354
+ browser = "Safari";
355
+ browserVersion = ua.match(/Version\/([\d.]+)/)?.[1] || "";
356
+ } else if (ua.includes("Opera") || ua.includes("OPR/")) {
357
+ browser = "Opera";
358
+ browserVersion = ua.match(/(?:Opera|OPR)\/([\d.]+)/)?.[1] || "";
359
+ }
360
+ if (ua.includes("Windows")) {
361
+ os = "Windows";
362
+ if (ua.includes("Windows NT 10.0")) osVersion = "10";
363
+ else if (ua.includes("Windows NT 6.3")) osVersion = "8.1";
364
+ else if (ua.includes("Windows NT 6.2")) osVersion = "8";
365
+ else if (ua.includes("Windows NT 6.1")) osVersion = "7";
366
+ } else if (ua.includes("Mac OS X")) {
367
+ os = "macOS";
368
+ osVersion = ua.match(/Mac OS X ([\d_]+)/)?.[1]?.replace(/_/g, ".") || "";
369
+ } else if (ua.includes("Linux")) {
370
+ os = "Linux";
371
+ } else if (ua.includes("Android")) {
372
+ os = "Android";
373
+ osVersion = ua.match(/Android ([\d.]+)/)?.[1] || "";
374
+ } else if (ua.includes("iOS") || ua.includes("iPhone") || ua.includes("iPad")) {
375
+ os = "iOS";
376
+ osVersion = ua.match(/OS ([\d_]+)/)?.[1]?.replace(/_/g, ".") || "";
377
+ }
378
+ return { browser, browser_version: browserVersion, os, os_version: osVersion };
379
+ }
380
+
381
+ // src/geolocation/ciphertext.ts
382
+ var CIPHER_TEXT_EXPIRY_MINUTES = 5;
383
+ async function computeHMAC(key, message) {
384
+ if (typeof globalThis.crypto !== "undefined" && globalThis.crypto.subtle) {
385
+ const encoder = new TextEncoder();
386
+ const keyData = encoder.encode(key);
387
+ const msgData = encoder.encode(message);
388
+ const cryptoKey = await globalThis.crypto.subtle.importKey(
389
+ "raw",
390
+ keyData,
391
+ { name: "HMAC", hash: "SHA-256" },
392
+ false,
393
+ ["sign"]
394
+ );
395
+ const signature = await globalThis.crypto.subtle.sign("HMAC", cryptoKey, msgData);
396
+ const bytes = new Uint8Array(signature);
397
+ return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
398
+ }
399
+ const { createHmac } = await import('crypto');
400
+ return createHmac("sha256", key).update(message).digest("hex");
401
+ }
402
+ function getWebGLInfo() {
403
+ if (typeof document === "undefined") return null;
404
+ try {
405
+ const canvas = document.createElement("canvas");
406
+ const gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
407
+ if (!gl) return null;
408
+ const debugInfo = gl.getExtension("WEBGL_debug_renderer_info");
409
+ if (!debugInfo) return null;
410
+ return {
411
+ vendor: gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL) || "",
412
+ renderer: gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL) || ""
413
+ };
414
+ } catch {
415
+ return null;
416
+ }
417
+ }
418
+ function getNetworkInfo() {
419
+ if (typeof navigator === "undefined") return void 0;
420
+ const connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
421
+ if (!connection) return void 0;
422
+ return {
423
+ effective_type: connection.effectiveType,
424
+ downlink: connection.downlink,
425
+ rtt: connection.rtt,
426
+ save_data: connection.saveData
427
+ };
428
+ }
429
+ async function requestGPSLocation(timeout = 1e4, highAccuracy = true) {
430
+ if (typeof navigator === "undefined" || !navigator.geolocation) {
431
+ return null;
432
+ }
433
+ return new Promise((resolve) => {
434
+ navigator.geolocation.getCurrentPosition(
435
+ (position) => {
436
+ const { latitude, longitude, accuracy } = position.coords;
437
+ if (latitude < -90 || latitude > 90) {
438
+ resolve(null);
439
+ return;
440
+ }
441
+ if (longitude < -180 || longitude > 180) {
442
+ resolve(null);
443
+ return;
444
+ }
445
+ if (accuracy !== null && accuracy !== void 0 && accuracy <= 0) {
446
+ resolve(null);
447
+ return;
448
+ }
449
+ resolve({
450
+ latitude,
451
+ longitude,
452
+ accuracy,
453
+ altitude: position.coords.altitude ?? void 0,
454
+ altitude_accuracy: position.coords.altitudeAccuracy ?? void 0,
455
+ heading: position.coords.heading ?? void 0,
456
+ speed: position.coords.speed ?? void 0,
457
+ timestamp: position.timestamp
458
+ });
459
+ },
460
+ () => {
461
+ resolve(null);
462
+ },
463
+ {
464
+ enableHighAccuracy: highAccuracy,
465
+ timeout,
466
+ maximumAge: 0
467
+ }
468
+ );
469
+ });
470
+ }
471
+ function collectDeviceData(includeWebGL) {
472
+ const browserInfo = getBrowserInfo();
473
+ const webglInfo = includeWebGL ? getWebGLInfo() : null;
474
+ return {
475
+ device_id: generateDeviceId(),
476
+ user_agent: typeof navigator !== "undefined" ? navigator.userAgent : "",
477
+ platform: typeof navigator !== "undefined" ? navigator.platform : "",
478
+ browser: browserInfo.browser,
479
+ browser_version: browserInfo.browser_version,
480
+ os: browserInfo.os,
481
+ os_version: browserInfo.os_version,
482
+ screen_resolution: typeof screen !== "undefined" ? `${screen.width}x${screen.height}` : void 0,
483
+ language: typeof navigator !== "undefined" ? navigator.language : void 0,
484
+ timezone: Intl?.DateTimeFormat?.()?.resolvedOptions?.()?.timeZone,
485
+ color_depth: typeof screen !== "undefined" ? screen.colorDepth : void 0,
486
+ hardware_concurrency: typeof navigator !== "undefined" ? navigator.hardwareConcurrency : void 0,
487
+ device_memory: typeof navigator !== "undefined" ? navigator.deviceMemory : void 0,
488
+ touch_support: typeof navigator !== "undefined" ? navigator.maxTouchPoints > 0 : void 0,
489
+ webgl_vendor: webglInfo?.vendor,
490
+ webgl_renderer: webglInfo?.renderer
491
+ };
492
+ }
493
+ function encodePayload(payload) {
494
+ const json = JSON.stringify(payload);
495
+ if (typeof btoa !== "undefined") {
496
+ return btoa(unescape(encodeURIComponent(json)));
497
+ } else if (typeof Buffer !== "undefined") {
498
+ return Buffer.from(json, "utf-8").toString("base64");
499
+ }
500
+ throw new Error("No base64 encoding method available");
501
+ }
502
+ async function generateCipherText(options, config) {
503
+ const warnings = [];
504
+ let requestLocation = options.requestLocation ?? false;
505
+ if (config?.require_gps) {
506
+ const reason = options.reason;
507
+ if (reason === "login" && config.require_gps.login || reason === "registration" && config.require_gps.registration || reason === "transaction" && config.require_gps.transaction) {
508
+ requestLocation = true;
509
+ }
510
+ }
511
+ const deviceData = collectDeviceData(options.includeWebGL !== false);
512
+ let locationData;
513
+ if (requestLocation) {
514
+ const location = await requestGPSLocation(
515
+ options.locationTimeout || 1e4,
516
+ options.highAccuracy !== false
517
+ );
518
+ if (location) {
519
+ locationData = location;
520
+ } else {
521
+ warnings.push("GPS location not available or permission denied");
522
+ }
523
+ }
524
+ let networkData;
525
+ if (options.includeNetworkInfo !== false) {
526
+ networkData = getNetworkInfo();
527
+ }
528
+ const now = /* @__PURE__ */ new Date();
529
+ const expiry = new Date(now.getTime() + CIPHER_TEXT_EXPIRY_MINUTES * 60 * 1e3);
530
+ const payload = {
531
+ device: deviceData,
532
+ location: locationData,
533
+ network: networkData,
534
+ metadata: {
535
+ collected_at: now.toISOString(),
536
+ sdk_version: SDK_VERSION,
537
+ collection_reason: options.reason,
538
+ page_url: typeof window !== "undefined" ? window.location.href : void 0,
539
+ referrer: typeof document !== "undefined" ? document.referrer || void 0 : void 0
540
+ }
541
+ };
542
+ const encoded = encodePayload(payload);
543
+ const timestamp = now.getTime().toString(36);
544
+ let cipherText;
545
+ const hmacKey = options.signingKey || options.apiKey;
546
+ if (hmacKey) {
547
+ const message = `02.${timestamp}.${encoded}`;
548
+ const hmac = await computeHMAC(hmacKey, message);
549
+ cipherText = `${message}.${hmac}`;
550
+ } else {
551
+ cipherText = `01.${timestamp}.${encoded}`;
552
+ }
553
+ return {
554
+ cipherText,
555
+ locationCaptured: !!locationData,
556
+ warnings: warnings.length > 0 ? warnings : void 0,
557
+ generatedAt: now.toISOString(),
558
+ expiresAt: expiry.toISOString()
559
+ };
560
+ }
561
+
312
562
  // src/geolocation/client.ts
313
563
  var GeolocationClient = class extends BaseClient {
314
564
  constructor(config) {
@@ -409,7 +659,11 @@ var GeolocationClient = class extends BaseClient {
409
659
  * ```
410
660
  */
411
661
  async getGPSConfig(requestOptions) {
412
- return this.requestWithRetry("/api/v1/geo/config", void 0, void 0, void 0, requestOptions);
662
+ const config = await this.requestWithRetry("/api/v1/geo/config", void 0, void 0, void 0, requestOptions);
663
+ if (config.signing_key) {
664
+ this.cachedSigningKey = config.signing_key;
665
+ }
666
+ return config;
413
667
  }
414
668
  // ============================================================================
415
669
  // CipherText Validation
@@ -669,6 +923,36 @@ var GeolocationClient = class extends BaseClient {
669
923
  }, void 0, requestOptions);
670
924
  }
671
925
  // ============================================================================
926
+ // CipherText Generation
927
+ // ============================================================================
928
+ /**
929
+ * Generate a signed cipherText containing device and location data.
930
+ *
931
+ * Automatically passes the client's API key for HMAC signing (v02 format).
932
+ * If no API key is configured, falls back to unsigned v01 format.
933
+ *
934
+ * @param options - Options for cipherText generation
935
+ * @param gpsConfig - Optional GPS config (from getGPSConfig)
936
+ * @returns CipherText result with the signed string
937
+ *
938
+ * @example
939
+ * ```typescript
940
+ * const result = await client.generateCipherText({ reason: 'login' });
941
+ * console.log(result.cipherText); // v02 signed cipherText
942
+ * ```
943
+ */
944
+ async generateCipherText(options, gpsConfig) {
945
+ let signingKey = this.cachedSigningKey;
946
+ if (!signingKey) {
947
+ const config = await this.getGPSConfig();
948
+ signingKey = config.signing_key;
949
+ }
950
+ return generateCipherText(
951
+ { ...options, signingKey: signingKey || void 0 },
952
+ gpsConfig
953
+ );
954
+ }
955
+ // ============================================================================
672
956
  // Utility Methods (inherited from BaseClient: healthCheck, updateConfig, getConfig, buildQueryString)
673
957
  // ============================================================================
674
958
  };
@@ -856,6 +1140,17 @@ var ComplianceClient = class {
856
1140
  this.currencyRates = DEFAULT_CURRENCY_RATES;
857
1141
  }
858
1142
  // ============================================================================
1143
+ // Sub-Client Accessors
1144
+ // ============================================================================
1145
+ /** Get the underlying GeolocationClient for direct geolocation API access */
1146
+ getGeolocationClient() {
1147
+ return this.geoClient;
1148
+ }
1149
+ /** Get the underlying RiskProfileClient for direct risk profile API access */
1150
+ getRiskProfileClient() {
1151
+ return this.riskClient;
1152
+ }
1153
+ // ============================================================================
859
1154
  // Main Verification Methods
860
1155
  // ============================================================================
861
1156
  /**