vesant-sdk 1.7.0 → 1.7.1-dev.0520b46

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 (75) hide show
  1. package/dist/{client-B0qhE2kr.d.mts → client-5q4whhGu.d.mts} +2 -2
  2. package/dist/{client-DF7hlMEz.d.ts → client-BaUekQT8.d.ts} +96 -52
  3. package/dist/{client-DtH2RLuy.d.ts → client-DUHC-68_.d.ts} +2 -2
  4. package/dist/{client-DrjgZoH_.d.mts → client-XDEhh9VN.d.mts} +96 -52
  5. package/dist/{client-BolQlL5e.d.mts → client-q9fN8Hhf.d.mts} +103 -1
  6. package/dist/{client-BolQlL5e.d.ts → client-q9fN8Hhf.d.ts} +103 -1
  7. package/dist/compliance/index.d.mts +3 -3
  8. package/dist/compliance/index.d.ts +3 -3
  9. package/dist/compliance/index.js +218 -90
  10. package/dist/compliance/index.js.map +1 -1
  11. package/dist/compliance/index.mjs +218 -90
  12. package/dist/compliance/index.mjs.map +1 -1
  13. package/dist/decisions/index.d.mts +1 -1
  14. package/dist/decisions/index.d.ts +1 -1
  15. package/dist/decisions/index.js +69 -8
  16. package/dist/decisions/index.js.map +1 -1
  17. package/dist/decisions/index.mjs +69 -8
  18. package/dist/decisions/index.mjs.map +1 -1
  19. package/dist/geolocation/index.d.mts +68 -7
  20. package/dist/geolocation/index.d.ts +68 -7
  21. package/dist/geolocation/index.js +223 -90
  22. package/dist/geolocation/index.js.map +1 -1
  23. package/dist/geolocation/index.mjs +220 -91
  24. package/dist/geolocation/index.mjs.map +1 -1
  25. package/dist/index-C3zUKydT.d.mts +264 -0
  26. package/dist/index-DSDgS09k.d.ts +264 -0
  27. package/dist/index.d.mts +27 -10
  28. package/dist/index.d.ts +27 -10
  29. package/dist/index.js +418 -126
  30. package/dist/index.js.map +1 -1
  31. package/dist/index.mjs +409 -127
  32. package/dist/index.mjs.map +1 -1
  33. package/dist/kyc/core.d.mts +2 -2
  34. package/dist/kyc/core.d.ts +2 -2
  35. package/dist/kyc/core.js +102 -21
  36. package/dist/kyc/core.js.map +1 -1
  37. package/dist/kyc/core.mjs +102 -22
  38. package/dist/kyc/core.mjs.map +1 -1
  39. package/dist/kyc/index.d.mts +154 -30
  40. package/dist/kyc/index.d.ts +154 -30
  41. package/dist/kyc/index.js +102 -21
  42. package/dist/kyc/index.js.map +1 -1
  43. package/dist/kyc/index.mjs +102 -22
  44. package/dist/kyc/index.mjs.map +1 -1
  45. package/dist/react.d.mts +14 -3
  46. package/dist/react.d.ts +14 -3
  47. package/dist/react.js +317 -68
  48. package/dist/react.js.map +1 -1
  49. package/dist/react.mjs +317 -68
  50. package/dist/react.mjs.map +1 -1
  51. package/dist/risk-profile/index.d.mts +1 -1
  52. package/dist/risk-profile/index.d.ts +1 -1
  53. package/dist/risk-profile/index.js +69 -8
  54. package/dist/risk-profile/index.js.map +1 -1
  55. package/dist/risk-profile/index.mjs +69 -8
  56. package/dist/risk-profile/index.mjs.map +1 -1
  57. package/dist/scores/index.d.mts +1 -1
  58. package/dist/scores/index.d.ts +1 -1
  59. package/dist/scores/index.js +69 -8
  60. package/dist/scores/index.js.map +1 -1
  61. package/dist/scores/index.mjs +69 -8
  62. package/dist/scores/index.mjs.map +1 -1
  63. package/dist/tax/index.d.mts +2 -2
  64. package/dist/tax/index.d.ts +2 -2
  65. package/dist/tax/index.js +74 -10
  66. package/dist/tax/index.js.map +1 -1
  67. package/dist/tax/index.mjs +74 -10
  68. package/dist/tax/index.mjs.map +1 -1
  69. package/dist/webhooks/index.d.mts +2 -189
  70. package/dist/webhooks/index.d.ts +2 -189
  71. package/dist/webhooks/index.js +85 -21
  72. package/dist/webhooks/index.js.map +1 -1
  73. package/dist/webhooks/index.mjs +85 -22
  74. package/dist/webhooks/index.mjs.map +1 -1
  75. package/package.json +4 -1
@@ -1,5 +1,18 @@
1
1
  'use strict';
2
2
 
3
+ // src/core/auth.ts
4
+ var StaticApiKeyProvider = class {
5
+ constructor(apiKey) {
6
+ this.apiKey = apiKey;
7
+ }
8
+ async getCredential() {
9
+ return this.apiKey ? { scheme: "Bearer", token: this.apiKey } : null;
10
+ }
11
+ canRefresh() {
12
+ return false;
13
+ }
14
+ };
15
+
3
16
  // src/core/errors.ts
4
17
  var VesantError = class _VesantError extends Error {
5
18
  constructor(message, code, statusCode, details) {
@@ -216,7 +229,7 @@ function createConsoleLogger() {
216
229
  }
217
230
 
218
231
  // src/core/version.ts
219
- var SDK_VERSION = "1.7.0";
232
+ var SDK_VERSION = "1.7.1";
220
233
 
221
234
  // src/shared/browser-utils.ts
222
235
  function generateUUID() {
@@ -298,6 +311,12 @@ var BaseClient = class {
298
311
  if (!config.tenantId?.trim()) {
299
312
  throw new ValidationError("tenantId is required and must be a non-empty string", ["tenantId"]);
300
313
  }
314
+ if (typeof fetch === "undefined") {
315
+ throw new VesantError(
316
+ "The Vesant SDK requires a global fetch (Node.js >= 18). Upgrade Node or provide a fetch polyfill.",
317
+ "RUNTIME_UNSUPPORTED"
318
+ );
319
+ }
301
320
  this.interceptors = config.interceptors || [];
302
321
  this.logger = config.logger || createConsoleLogger();
303
322
  let environment = config.environment;
@@ -316,11 +335,12 @@ var BaseClient = class {
316
335
  environment,
317
336
  headers: config.headers || {},
318
337
  timeout: config.timeout || 1e4,
319
- retries: config.retries || 3,
338
+ retries: config.retries ?? 3,
320
339
  debug: config.debug || false,
321
340
  interceptors: this.interceptors,
322
341
  logger: this.logger
323
342
  };
343
+ this.authProvider = config.authProvider ?? (apiKey ? new StaticApiKeyProvider(apiKey) : void 0);
324
344
  if (config.circuitBreaker) {
325
345
  this.circuitBreaker = new CircuitBreaker(config.circuitBreaker);
326
346
  }
@@ -328,6 +348,19 @@ var BaseClient = class {
328
348
  this.rateLimitTracker = new RateLimitTracker();
329
349
  }
330
350
  }
351
+ /**
352
+ * Resolve the Idempotency-Key for a request. Mutating methods (POST/PUT/PATCH)
353
+ * get the caller-supplied key or a freshly minted UUID; non-mutating methods get
354
+ * none. requestWithRetry resolves this once and injects it so every retry reuses
355
+ * one key (letting the server dedup replays); a direct request() resolves per call.
356
+ */
357
+ resolveIdempotencyKey(method, requestOptions) {
358
+ const isMutating = ["POST", "PUT", "PATCH"].includes((method || "GET").toUpperCase());
359
+ if (!isMutating) {
360
+ return void 0;
361
+ }
362
+ return requestOptions?.idempotencyKey ?? generateUUID();
363
+ }
331
364
  /**
332
365
  * Make an HTTP request with timeout and error handling
333
366
  */
@@ -353,15 +386,20 @@ var BaseClient = class {
353
386
  ...this.config.headers,
354
387
  ...options.headers || {}
355
388
  };
356
- if (this.config.apiKey) {
357
- headers["Authorization"] = `Bearer ${this.config.apiKey}`;
389
+ const credential = await this.authProvider?.getCredential({
390
+ tenantId: this.config.tenantId,
391
+ requestId
392
+ });
393
+ if (credential) {
394
+ headers["Authorization"] = `${credential.scheme ?? "Bearer"} ${credential.token}`;
358
395
  }
359
396
  if (this.config.environment === "sandbox") {
360
397
  headers["X-Sandbox"] = "true";
361
398
  }
362
399
  const method = (options.method || "GET").toUpperCase();
363
- if (["POST", "PUT", "PATCH"].includes(method)) {
364
- headers["Idempotency-Key"] = requestOptions?.idempotencyKey || generateUUID();
400
+ const idempotencyKey = this.resolveIdempotencyKey(method, requestOptions);
401
+ if (idempotencyKey) {
402
+ headers["Idempotency-Key"] = idempotencyKey;
365
403
  }
366
404
  const controller = new AbortController();
367
405
  const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
@@ -382,10 +420,28 @@ var BaseClient = class {
382
420
  if (this.config.debug) {
383
421
  this.logger.debug(`${finalOptions.method || "GET"} ${endpoint}`);
384
422
  }
385
- const response = await fetch(url, {
423
+ let response = await fetch(url, {
386
424
  ...finalOptions,
387
425
  signal: controller.signal
388
426
  });
427
+ if (response.status === 401 && this.authProvider?.canRefresh?.()) {
428
+ const refreshed = await this.authProvider.getCredential({
429
+ tenantId: this.config.tenantId,
430
+ requestId,
431
+ forceRefresh: true
432
+ });
433
+ if (refreshed) {
434
+ this.config.onCredentialRotated?.({ reason: "unauthorized" });
435
+ finalOptions = {
436
+ ...finalOptions,
437
+ headers: {
438
+ ...finalOptions.headers,
439
+ Authorization: `${refreshed.scheme ?? "Bearer"} ${refreshed.token}`
440
+ }
441
+ };
442
+ response = await fetch(url, { ...finalOptions, signal: controller.signal });
443
+ }
444
+ }
389
445
  clearTimeout(timeoutId);
390
446
  if (this.rateLimitTracker) {
391
447
  this.rateLimitTracker.updateFromHeaders(response.headers);
@@ -474,9 +530,11 @@ var BaseClient = class {
474
530
  */
475
531
  async requestWithRetry(endpoint, options = {}, serviceURL, retries = this.config.retries, requestOptions) {
476
532
  let lastError;
533
+ const idempotencyKey = this.resolveIdempotencyKey(options.method || "GET", requestOptions);
534
+ const attemptOptions = idempotencyKey ? { ...requestOptions, idempotencyKey } : requestOptions;
477
535
  for (let attempt = 0; attempt <= retries; attempt++) {
478
536
  try {
479
- return await this.request(endpoint, options, serviceURL, requestOptions);
537
+ return await this.request(endpoint, options, serviceURL, attemptOptions);
480
538
  } catch (error) {
481
539
  lastError = error instanceof Error ? error : new Error("Unknown error");
482
540
  if (requestOptions?.signal?.aborted) {
@@ -573,6 +631,9 @@ var BaseClient = class {
573
631
  if (config.interceptors) {
574
632
  this.interceptors = config.interceptors;
575
633
  }
634
+ if (config.authProvider !== void 0 || config.apiKey !== void 0) {
635
+ this.authProvider = this.config.authProvider ?? (this.config.apiKey ? new StaticApiKeyProvider(this.config.apiKey) : void 0);
636
+ }
576
637
  }
577
638
  /**
578
639
  * Get current configuration (readonly)
@@ -600,27 +661,63 @@ var BaseClient = class {
600
661
  }
601
662
  };
602
663
 
603
- // src/geolocation/ciphertext.ts
604
- var CIPHER_TEXT_EXPIRY_MINUTES = 5;
605
- async function computeHMAC(key, message) {
606
- if (typeof globalThis.crypto !== "undefined" && globalThis.crypto.subtle) {
607
- const encoder = new TextEncoder();
608
- const keyData = encoder.encode(key);
609
- const msgData = encoder.encode(message);
610
- const cryptoKey = await globalThis.crypto.subtle.importKey(
611
- "raw",
612
- keyData,
613
- { name: "HMAC", hash: "SHA-256" },
614
- false,
615
- ["sign"]
616
- );
617
- const signature = await globalThis.crypto.subtle.sign("HMAC", cryptoKey, msgData);
618
- const bytes = new Uint8Array(signature);
619
- return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
664
+ // src/geolocation/integrity.ts
665
+ var isNil = (v) => v === null || v === void 0;
666
+ function assessGpsIntegrity(input, opts = {}) {
667
+ const flags = [];
668
+ const now = opts.now ?? (() => Date.now());
669
+ const maxAgeMs = opts.maxAgeMs ?? 6e4;
670
+ const minAccuracy = opts.minAccuracyMeters ?? 1;
671
+ const { accuracy, altitude, altitudeAccuracy, heading, speed, timestamp } = input;
672
+ if (isNil(accuracy)) {
673
+ flags.push("accuracy_missing");
674
+ } else if (accuracy === 0) {
675
+ flags.push("accuracy_zero");
676
+ } else if (accuracy < minAccuracy) {
677
+ flags.push("accuracy_implausibly_small");
678
+ }
679
+ const hasMotion = !isNil(heading) || !isNil(speed);
680
+ if (hasMotion && (isNil(accuracy) || accuracy === 0)) {
681
+ flags.push("motion_without_accuracy");
682
+ }
683
+ if (!isNil(altitude) && isNil(altitudeAccuracy)) {
684
+ flags.push("altitude_without_accuracy");
685
+ }
686
+ if (timestamp !== void 0 && now() - timestamp > maxAgeMs) {
687
+ flags.push("stale_timestamp");
620
688
  }
621
- const { createHmac } = await import('crypto');
622
- return createHmac("sha256", key).update(message).digest("hex");
689
+ if (opts.permissionState === "denied" || opts.permissionState === "prompt") {
690
+ flags.push(`permission_${opts.permissionState}`);
691
+ }
692
+ return { suspicious: flags.length > 0, flags };
623
693
  }
694
+ function gpsIntegrityInputFromPosition(position) {
695
+ const c = position.coords;
696
+ return {
697
+ latitude: c.latitude,
698
+ longitude: c.longitude,
699
+ accuracy: c.accuracy,
700
+ altitude: c.altitude,
701
+ altitudeAccuracy: c.altitudeAccuracy,
702
+ heading: c.heading,
703
+ speed: c.speed,
704
+ timestamp: position.timestamp
705
+ };
706
+ }
707
+ async function probeGeolocationPermission() {
708
+ try {
709
+ if (typeof navigator === "undefined" || !navigator.permissions?.query) {
710
+ return "unavailable";
711
+ }
712
+ const status = await navigator.permissions.query({ name: "geolocation" });
713
+ return status.state;
714
+ } catch {
715
+ return "unavailable";
716
+ }
717
+ }
718
+
719
+ // src/geolocation/ciphertext.ts
720
+ var CIPHER_TEXT_EXPIRY_MINUTES = 5;
624
721
  function getWebGLInfo() {
625
722
  if (typeof document === "undefined") return null;
626
723
  try {
@@ -652,6 +749,7 @@ async function requestGPSLocation(timeout = 1e4, highAccuracy = true) {
652
749
  if (typeof navigator === "undefined" || !navigator.geolocation) {
653
750
  return null;
654
751
  }
752
+ const permissionState = await probeGeolocationPermission();
655
753
  return new Promise((resolve) => {
656
754
  navigator.geolocation.getCurrentPosition(
657
755
  (position) => {
@@ -668,6 +766,7 @@ async function requestGPSLocation(timeout = 1e4, highAccuracy = true) {
668
766
  resolve(null);
669
767
  return;
670
768
  }
769
+ const { flags } = assessGpsIntegrity(gpsIntegrityInputFromPosition(position), { permissionState });
671
770
  resolve({
672
771
  latitude,
673
772
  longitude,
@@ -676,7 +775,8 @@ async function requestGPSLocation(timeout = 1e4, highAccuracy = true) {
676
775
  altitude_accuracy: position.coords.altitudeAccuracy ?? void 0,
677
776
  heading: position.coords.heading ?? void 0,
678
777
  speed: position.coords.speed ?? void 0,
679
- timestamp: position.timestamp
778
+ timestamp: position.timestamp,
779
+ integrity_flags: flags.length ? flags : void 0
680
780
  });
681
781
  },
682
782
  () => {
@@ -743,6 +843,9 @@ async function generateCipherText(options, config) {
743
843
  );
744
844
  if (location) {
745
845
  locationData = location;
846
+ if (location.integrity_flags?.length) {
847
+ warnings.push(`GPS integrity flags (advisory): ${location.integrity_flags.join(", ")}`);
848
+ }
746
849
  } else if (gpsRequiredByConfig) {
747
850
  throw new VesantError(
748
851
  `GPS location is required for ${options.reason} by tenant configuration, but GPS was not available or permission was denied`,
@@ -772,15 +875,7 @@ async function generateCipherText(options, config) {
772
875
  };
773
876
  const encoded = encodePayload(payload);
774
877
  const timestamp = now.getTime().toString(36);
775
- let cipherText;
776
- const hmacKey = options.signingKey || options.apiKey;
777
- if (hmacKey) {
778
- const message = `02.${timestamp}.${encoded}`;
779
- const hmac = await computeHMAC(hmacKey, message);
780
- cipherText = `${message}.${hmac}`;
781
- } else {
782
- cipherText = `01.${timestamp}.${encoded}`;
783
- }
878
+ const cipherText = `01.${timestamp}.${encoded}`;
784
879
  return {
785
880
  cipherText,
786
881
  locationCaptured: !!locationData,
@@ -789,6 +884,7 @@ async function generateCipherText(options, config) {
789
884
  expiresAt: expiry.toISOString()
790
885
  };
791
886
  }
887
+ var collectDeviceSignals = generateCipherText;
792
888
  function decodeCipherText(cipherText) {
793
889
  try {
794
890
  const parts = cipherText.split(".");
@@ -816,6 +912,7 @@ function isCipherTextExpired(cipherText) {
816
912
  }
817
913
 
818
914
  // src/geolocation/client.ts
915
+ var DEFAULT_GPS_CONFIG_TTL_MS = 5 * 60 * 1e3;
819
916
  var GeolocationClient = class extends BaseClient {
820
917
  constructor(config) {
821
918
  const baseConfig = {
@@ -831,6 +928,8 @@ var GeolocationClient = class extends BaseClient {
831
928
  environment: config.environment
832
929
  };
833
930
  super(baseConfig);
931
+ this.gpsConfigCache = null;
932
+ this.gpsConfigTtlMs = config.gpsConfigTtlMs ?? DEFAULT_GPS_CONFIG_TTL_MS;
834
933
  }
835
934
  // ============================================================================
836
935
  // IP Verification & Compliance
@@ -862,8 +961,8 @@ var GeolocationClient = class extends BaseClient {
862
961
  * ```
863
962
  */
864
963
  async verifyIP(request, requestOptions) {
865
- if (!request.ip_address?.trim()) {
866
- throw new ValidationError("ip_address is required and must be a non-empty string", ["ip_address"]);
964
+ if (request.ip_address !== void 0 && !request.ip_address.trim()) {
965
+ throw new ValidationError("ip_address, when provided, must be a non-empty string", ["ip_address"]);
867
966
  }
868
967
  return this.requestWithRetry("/api/v1/geo/verify", {
869
968
  method: "POST",
@@ -916,37 +1015,85 @@ var GeolocationClient = class extends BaseClient {
916
1015
  * ```
917
1016
  */
918
1017
  async getGPSConfig(requestOptions) {
919
- const config = await this.requestWithRetry("/api/v1/geo/config", void 0, void 0, void 0, requestOptions);
920
- if (config.signing_key) {
921
- this.cachedSigningKey = config.signing_key;
1018
+ const cached = this.gpsConfigCache;
1019
+ if (cached && cached.expiresAt > Date.now()) {
1020
+ return cached.value;
922
1021
  }
923
- return config;
1022
+ return this.refreshGPSConfig(requestOptions);
924
1023
  }
925
1024
  /**
926
- * Fetch the signing key from the dedicated authenticated endpoint.
1025
+ * Re-read the tenant's GPS requirement configuration, ignoring any copy held
1026
+ * from an earlier read.
927
1027
  *
928
- * Falls back to getGPSConfig() for backward compatibility with older servers
929
- * that don't expose `/api/v1/geo/signing-key`.
1028
+ * These requirements are edited in the compliance console while your
1029
+ * application is running. `getGPSConfig` reuses a fetched copy for a short
1030
+ * period so a long-lived session does not call the API on every event; call
1031
+ * this when you need a change to take effect immediately — for example right
1032
+ * after an administrator saves new settings.
930
1033
  *
931
- * @returns The signing key string, or undefined if unavailable
1034
+ * @returns The current GPS requirement config per event type
1035
+ *
1036
+ * @example
1037
+ * ```typescript
1038
+ * const config = await client.refreshGPSConfig();
1039
+ * if (config.require_gps.login) {
1040
+ * // GPS is now required for login
1041
+ * }
1042
+ * ```
1043
+ */
1044
+ async refreshGPSConfig(requestOptions) {
1045
+ const value = await this.requestWithRetry(
1046
+ "/api/v1/geo/config",
1047
+ void 0,
1048
+ void 0,
1049
+ void 0,
1050
+ requestOptions
1051
+ );
1052
+ this.gpsConfigCache = { value, expiresAt: Date.now() + this.gpsConfigTtlMs };
1053
+ return value;
1054
+ }
1055
+ /**
1056
+ * Mint a short-lived, single-use device-signals nonce.
1057
+ *
1058
+ * The nonce is bound to the tenant, user, and event type and is consumed
1059
+ * server-side during validation, so a captured device-signals envelope cannot
1060
+ * be replayed. `validateCipherText` mints and attaches one automatically; call
1061
+ * this directly only if you manage the nonce yourself.
1062
+ *
1063
+ * @param userId - User ID the nonce is bound to
1064
+ * @param eventType - Event type the nonce is bound to (login, registration, ...)
1065
+ * @returns The nonce and its expiry
1066
+ */
1067
+ async fetchSignalsNonce(userId, eventType, requestOptions) {
1068
+ if (!userId?.trim()) {
1069
+ throw new ValidationError("userId is required and must be a non-empty string", ["userId"]);
1070
+ }
1071
+ const request = { user_id: userId, event_type: eventType };
1072
+ return this.request(
1073
+ "/api/v1/geo/signals-token",
1074
+ {
1075
+ method: "POST",
1076
+ body: JSON.stringify(request)
1077
+ },
1078
+ void 0,
1079
+ requestOptions
1080
+ );
1081
+ }
1082
+ /**
1083
+ * Best-effort nonce mint for validation. Returns undefined if minting fails —
1084
+ * the server is the sole authority and blocks when a nonce is required, so this
1085
+ * never downgrades security on the client's say-so.
932
1086
  */
933
- async fetchSigningKey(requestOptions) {
1087
+ async resolveSignalsNonce(userId, eventType, requestOptions) {
934
1088
  try {
935
- const response = await this.requestWithRetry(
936
- "/api/v1/geo/signing-key",
937
- void 0,
938
- void 0,
939
- void 0,
940
- requestOptions
1089
+ const { nonce } = await this.fetchSignalsNonce(userId, eventType, requestOptions);
1090
+ return nonce;
1091
+ } catch (err) {
1092
+ this.logger.warn(
1093
+ `Failed to mint device-signals nonce; proceeding without it: ${err instanceof Error ? err.message : String(err)}`
941
1094
  );
942
- if (response.signing_key) {
943
- this.cachedSigningKey = response.signing_key;
944
- return response.signing_key;
945
- }
946
- } catch {
1095
+ return void 0;
947
1096
  }
948
- const config = await this.getGPSConfig(requestOptions);
949
- return config.signing_key;
950
1097
  }
951
1098
  // ============================================================================
952
1099
  // CipherText Validation
@@ -999,12 +1146,14 @@ var GeolocationClient = class extends BaseClient {
999
1146
  if (!userId?.trim()) {
1000
1147
  throw new ValidationError("userId is required and must be a non-empty string", ["userId"]);
1001
1148
  }
1149
+ const nonce = await this.resolveSignalsNonce(userId, eventType, requestOptions);
1002
1150
  const request = {
1003
1151
  cipher_text: cipherText,
1004
1152
  user_id: userId,
1005
1153
  event_type: eventType,
1006
1154
  expected_ip: expectedIP,
1007
- customer_data: customerData
1155
+ customer_data: customerData,
1156
+ nonce
1008
1157
  };
1009
1158
  return this.requestWithRetry(
1010
1159
  "/api/v1/geo/validate-ciphertext",
@@ -1213,20 +1362,12 @@ var GeolocationClient = class extends BaseClient {
1213
1362
  *
1214
1363
  * @example
1215
1364
  * ```typescript
1216
- * // Using GPS (preferred)
1365
+ * // GPS (the web SDK is GPS + IP only; the server handles the IP fallback)
1217
1366
  * const result = await client.captureLocation(token, {
1218
1367
  * latitude: 37.7749,
1219
1368
  * longitude: -122.4194,
1220
1369
  * accuracy: 10
1221
1370
  * });
1222
- *
1223
- * // Using WiFi positioning (fallback)
1224
- * const result = await client.captureLocation(token, {
1225
- * wifi_networks: [
1226
- * { macAddress: "00:11:22:33:44:55", signalStrength: -50 },
1227
- * { macAddress: "AA:BB:CC:DD:EE:FF", signalStrength: -70 }
1228
- * ]
1229
- * });
1230
1371
  * ```
1231
1372
  */
1232
1373
  async captureLocation(token, capture, requestOptions) {
@@ -1239,34 +1380,22 @@ var GeolocationClient = class extends BaseClient {
1239
1380
  // CipherText Generation
1240
1381
  // ============================================================================
1241
1382
  /**
1242
- * Generate a signed cipherText containing device and location data.
1383
+ * Generate a device-signals envelope containing device and location data,
1384
+ * validated by the server.
1243
1385
  *
1244
- * Automatically passes the client's API key for HMAC signing (v02 format).
1245
- * If no API key is configured, falls back to unsigned v01 format.
1246
- *
1247
- * @param options - Options for cipherText generation
1386
+ * @param options - Options for envelope generation
1248
1387
  * @param gpsConfig - Optional GPS config (from getGPSConfig)
1249
- * @returns CipherText result with the signed string
1388
+ * @returns The device-signals envelope result
1250
1389
  *
1251
1390
  * @example
1252
1391
  * ```typescript
1253
1392
  * const result = await client.generateCipherText({ reason: 'login' });
1254
- * console.log(result.cipherText); // v02 signed cipherText
1393
+ * console.log(result.cipherText); // device-signals envelope
1255
1394
  * ```
1256
1395
  */
1257
1396
  async generateCipherText(options, gpsConfig) {
1258
- let signingKey = this.cachedSigningKey;
1259
- let resolvedGpsConfig = gpsConfig;
1260
- if (!signingKey) {
1261
- signingKey = await this.fetchSigningKey();
1262
- }
1263
- if (!resolvedGpsConfig) {
1264
- resolvedGpsConfig = await this.getGPSConfig();
1265
- }
1266
- return generateCipherText(
1267
- { ...options, signingKey: signingKey || void 0 },
1268
- resolvedGpsConfig
1269
- );
1397
+ const resolvedGpsConfig = gpsConfig ?? await this.getGPSConfig();
1398
+ return generateCipherText(options, resolvedGpsConfig);
1270
1399
  }
1271
1400
  // ============================================================================
1272
1401
  // Utility Methods (inherited from BaseClient: healthCheck, updateConfig, getConfig, buildQueryString)
@@ -1274,8 +1403,12 @@ var GeolocationClient = class extends BaseClient {
1274
1403
  };
1275
1404
 
1276
1405
  exports.GeolocationClient = GeolocationClient;
1406
+ exports.assessGpsIntegrity = assessGpsIntegrity;
1407
+ exports.collectDeviceSignals = collectDeviceSignals;
1277
1408
  exports.decodeCipherText = decodeCipherText;
1278
1409
  exports.generateCipherText = generateCipherText;
1410
+ exports.gpsIntegrityInputFromPosition = gpsIntegrityInputFromPosition;
1279
1411
  exports.isCipherTextExpired = isCipherTextExpired;
1412
+ exports.probeGeolocationPermission = probeGeolocationPermission;
1280
1413
  //# sourceMappingURL=index.js.map
1281
1414
  //# sourceMappingURL=index.js.map