vesant-sdk 1.5.2 → 1.6.1

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 (65) hide show
  1. package/dist/{client-BZxzOidG.d.mts → client-DW1Xiz6a.d.mts} +4 -2
  2. package/dist/{client-B8pFrXx_.d.ts → client-eLbtPRkh.d.ts} +4 -2
  3. package/dist/{client-CIon-bGS.d.mts → client-ePzhQKp9.d.mts} +2 -0
  4. package/dist/{client-CIon-bGS.d.ts → client-ePzhQKp9.d.ts} +2 -0
  5. package/dist/compliance/index.d.mts +18 -5
  6. package/dist/compliance/index.d.ts +18 -5
  7. package/dist/compliance/index.js +222 -42
  8. package/dist/compliance/index.js.map +1 -1
  9. package/dist/compliance/index.mjs +222 -42
  10. package/dist/compliance/index.mjs.map +1 -1
  11. package/dist/decisions/index.d.mts +1 -1
  12. package/dist/decisions/index.d.ts +1 -1
  13. package/dist/decisions/index.js +14 -1
  14. package/dist/decisions/index.js.map +1 -1
  15. package/dist/decisions/index.mjs +14 -1
  16. package/dist/decisions/index.mjs.map +1 -1
  17. package/dist/geolocation/index.d.mts +3 -3
  18. package/dist/geolocation/index.d.ts +3 -3
  19. package/dist/geolocation/index.js +14 -1
  20. package/dist/geolocation/index.js.map +1 -1
  21. package/dist/geolocation/index.mjs +14 -1
  22. package/dist/geolocation/index.mjs.map +1 -1
  23. package/dist/index.d.mts +6 -376
  24. package/dist/index.d.ts +6 -376
  25. package/dist/index.js +289 -251
  26. package/dist/index.js.map +1 -1
  27. package/dist/index.mjs +289 -251
  28. package/dist/index.mjs.map +1 -1
  29. package/dist/kyc/core.d.mts +1 -1
  30. package/dist/kyc/core.d.ts +1 -1
  31. package/dist/kyc/core.js +14 -1
  32. package/dist/kyc/core.js.map +1 -1
  33. package/dist/kyc/core.mjs +14 -1
  34. package/dist/kyc/core.mjs.map +1 -1
  35. package/dist/kyc/index.d.mts +1 -1
  36. package/dist/kyc/index.d.ts +1 -1
  37. package/dist/kyc/index.js +14 -1
  38. package/dist/kyc/index.js.map +1 -1
  39. package/dist/kyc/index.mjs +14 -1
  40. package/dist/kyc/index.mjs.map +1 -1
  41. package/dist/react.d.mts +2 -2
  42. package/dist/react.d.ts +2 -2
  43. package/dist/react.js +1 -1
  44. package/dist/react.js.map +1 -1
  45. package/dist/react.mjs +1 -1
  46. package/dist/react.mjs.map +1 -1
  47. package/dist/risk-profile/index.d.mts +1 -1
  48. package/dist/risk-profile/index.d.ts +1 -1
  49. package/dist/risk-profile/index.js +14 -1
  50. package/dist/risk-profile/index.js.map +1 -1
  51. package/dist/risk-profile/index.mjs +14 -1
  52. package/dist/risk-profile/index.mjs.map +1 -1
  53. package/dist/scores/index.d.mts +1 -1
  54. package/dist/scores/index.d.ts +1 -1
  55. package/dist/scores/index.js +14 -1
  56. package/dist/scores/index.js.map +1 -1
  57. package/dist/scores/index.mjs +14 -1
  58. package/dist/scores/index.mjs.map +1 -1
  59. package/dist/tax/index.d.mts +256 -0
  60. package/dist/tax/index.d.ts +256 -0
  61. package/dist/tax/index.js +652 -0
  62. package/dist/tax/index.js.map +1 -0
  63. package/dist/tax/index.mjs +650 -0
  64. package/dist/tax/index.mjs.map +1 -0
  65. package/package.json +1 -1
@@ -224,7 +224,7 @@ function createConsoleLogger() {
224
224
  }
225
225
 
226
226
  // src/core/version.ts
227
- var SDK_VERSION = "1.5.2";
227
+ var SDK_VERSION = "1.6.1";
228
228
 
229
229
  // src/shared/browser-utils.ts
230
230
  function generateUUID() {
@@ -398,6 +398,19 @@ var BaseClient = class {
398
398
  if (this.rateLimitTracker) {
399
399
  this.rateLimitTracker.updateFromHeaders(response.headers);
400
400
  }
401
+ if (requestOptions?.responseType === "arraybuffer") {
402
+ if (!response.ok) {
403
+ let errData = {};
404
+ try {
405
+ errData = await response.json();
406
+ } catch {
407
+ }
408
+ this.handleErrorResponse(response.status, errData, requestId);
409
+ }
410
+ this.circuitBreaker?.onSuccess();
411
+ const buffer = await response.arrayBuffer();
412
+ return buffer;
413
+ }
401
414
  let data;
402
415
  try {
403
416
  data = await response.json();
@@ -1440,17 +1453,34 @@ var ComplianceClient = class {
1440
1453
  const startTime = Date.now();
1441
1454
  this.validateRegistrationRequest(request);
1442
1455
  let geoVerification = null;
1456
+ let cipherTextResult;
1443
1457
  try {
1444
1458
  if (this.config.debug) {
1445
1459
  this.logger.debug("Starting registration verification", { customerId: request.customerId });
1446
1460
  }
1447
- geoVerification = await this.geoClient.verifyIP({
1448
- ip_address: request.ipAddress,
1449
- user_id: request.customerId,
1450
- event_type: "registration",
1451
- device_fingerprint: request.deviceFingerprint
1452
- }, requestOptions);
1453
- const blockReasons = this.evaluateRegistrationBlock(geoVerification);
1461
+ const customerData = request.cipherText ? {
1462
+ full_name: request.fullName,
1463
+ email: request.emailAddress,
1464
+ phone: request.phoneNumber,
1465
+ date_of_birth: request.dateOfBirth
1466
+ } : void 0;
1467
+ [cipherTextResult, geoVerification] = await Promise.all([
1468
+ this.executeCipherTextValidation(
1469
+ request.cipherText,
1470
+ request.customerId,
1471
+ "registration",
1472
+ request.ipAddress,
1473
+ customerData,
1474
+ requestOptions
1475
+ ),
1476
+ this.geoClient.verifyIP({
1477
+ ip_address: request.ipAddress,
1478
+ user_id: request.customerId,
1479
+ event_type: "registration",
1480
+ device_fingerprint: request.deviceFingerprint
1481
+ }, requestOptions)
1482
+ ]);
1483
+ const blockReasons = this.evaluateRegistrationBlock(geoVerification, cipherTextResult);
1454
1484
  if (blockReasons.length > 0) {
1455
1485
  if (this.config.debug) {
1456
1486
  this.logger.debug("Registration blocked at geo stage", { blockReasons });
@@ -1462,7 +1492,8 @@ var ComplianceClient = class {
1462
1492
  requiresKYC: false,
1463
1493
  requiresEDD: false,
1464
1494
  blockReasons,
1465
- processingTime: Date.now() - startTime
1495
+ processingTime: Date.now() - startTime,
1496
+ cipherTextValidation: cipherTextResult
1466
1497
  };
1467
1498
  }
1468
1499
  const profile = await this.riskClient.createProfile({
@@ -1497,7 +1528,8 @@ var ComplianceClient = class {
1497
1528
  requiresKYC,
1498
1529
  requiresEDD,
1499
1530
  blockReasons: [],
1500
- processingTime: Date.now() - startTime
1531
+ processingTime: Date.now() - startTime,
1532
+ cipherTextValidation: cipherTextResult
1501
1533
  };
1502
1534
  } catch (error) {
1503
1535
  if (this.config.debug) {
@@ -1525,7 +1557,7 @@ var ComplianceClient = class {
1525
1557
  * @param geoVerification - Geolocation verification result
1526
1558
  * @returns Array of block reasons (empty if allowed)
1527
1559
  */
1528
- evaluateRegistrationBlock(geoVerification) {
1560
+ evaluateRegistrationBlock(geoVerification, cipherTextResult) {
1529
1561
  const blockReasons = [];
1530
1562
  if (geoVerification.is_blocked) {
1531
1563
  blockReasons.push(...geoVerification.risk_reasons);
@@ -1559,6 +1591,20 @@ var ComplianceClient = class {
1559
1591
  blockReasons.push("critical_risk_level");
1560
1592
  }
1561
1593
  }
1594
+ if (cipherTextResult) {
1595
+ if (!cipherTextResult.valid) {
1596
+ blockReasons.push("ciphertext_validation_failed");
1597
+ }
1598
+ if (cipherTextResult.risk?.is_blocked) {
1599
+ blockReasons.push(...cipherTextResult.risk.block_reasons || []);
1600
+ }
1601
+ if (cipherTextResult.risk?.location_mismatch) {
1602
+ blockReasons.push("gps_ip_location_mismatch");
1603
+ }
1604
+ }
1605
+ if (geoVerification.gps_required && !cipherTextResult) {
1606
+ blockReasons.push("gps_verification_required");
1607
+ }
1562
1608
  return [...new Set(blockReasons)];
1563
1609
  }
1564
1610
  /**
@@ -1689,7 +1735,15 @@ var ComplianceClient = class {
1689
1735
  if (this.config.debug) {
1690
1736
  this.logger.debug("Starting login verification", { customerId: request.customerId });
1691
1737
  }
1692
- const [geoVerification, profileResult] = await Promise.all([
1738
+ const [cipherTextResult, geoVerification, profileResult] = await Promise.all([
1739
+ this.executeCipherTextValidation(
1740
+ request.cipherText,
1741
+ request.customerId,
1742
+ "login",
1743
+ request.ipAddress,
1744
+ void 0,
1745
+ requestOptions
1746
+ ),
1693
1747
  this.geoClient.verifyIP({
1694
1748
  ip_address: request.ipAddress,
1695
1749
  user_id: request.customerId,
@@ -1698,10 +1752,23 @@ var ComplianceClient = class {
1698
1752
  }, requestOptions),
1699
1753
  this.riskClient.getProfile(request.customerId, requestOptions).catch(() => null)
1700
1754
  ]);
1755
+ const loginBlockReasons = this.getBlockReasons(geoVerification, profileResult, cipherTextResult);
1756
+ const isBlocked = !geoVerification.is_compliant || geoVerification.is_blocked || !!cipherTextResult?.risk?.is_blocked || cipherTextResult?.valid === false || geoVerification.gps_required && !cipherTextResult;
1757
+ if (isBlocked && !profileResult) {
1758
+ return {
1759
+ allowed: false,
1760
+ geolocation: geoVerification,
1761
+ profile: null,
1762
+ requiresStepUp: false,
1763
+ blockReasons: loginBlockReasons,
1764
+ processingTime: Date.now() - startTime,
1765
+ cipherTextValidation: cipherTextResult
1766
+ };
1767
+ }
1701
1768
  let profile;
1702
1769
  if (profileResult) {
1703
1770
  profile = profileResult;
1704
- if (this.shouldUpdateProfile(profile, geoVerification.location.city)) {
1771
+ if (!isBlocked && this.shouldUpdateProfile(profile, geoVerification.location.city)) {
1705
1772
  profile = await this.riskClient.updateProfile(profile.id, {
1706
1773
  last_recorded_activity: (/* @__PURE__ */ new Date()).toISOString(),
1707
1774
  location: `${geoVerification.location.city}, ${geoVerification.location.country}`,
@@ -1714,15 +1781,15 @@ var ComplianceClient = class {
1714
1781
  }
1715
1782
  profile = await this.createProfileFromGeo(request.customerId, geoVerification);
1716
1783
  }
1717
- const isAllowed = geoVerification.is_compliant && !geoVerification.is_blocked && profile.customer_status !== "suspended";
1718
- const requiresStepUp = geoVerification.risk_level === "high" || geoVerification.risk_level === "critical";
1784
+ const requiresStepUp = geoVerification.risk_level === "high" || geoVerification.risk_level === "critical" || cipherTextResult?.risk?.location_mismatch === true;
1719
1785
  return {
1720
- allowed: isAllowed,
1786
+ allowed: !isBlocked && profile.customer_status !== "suspended",
1721
1787
  geolocation: geoVerification,
1722
1788
  profile,
1723
1789
  requiresStepUp,
1724
- blockReasons: this.getBlockReasons(geoVerification, profile),
1725
- processingTime: Date.now() - startTime
1790
+ blockReasons: isBlocked || profile.customer_status === "suspended" ? this.getBlockReasons(geoVerification, profile, cipherTextResult) : [],
1791
+ processingTime: Date.now() - startTime,
1792
+ cipherTextValidation: cipherTextResult
1726
1793
  };
1727
1794
  } catch (error) {
1728
1795
  throw new ComplianceError("Login verification failed", error instanceof Error ? error.message : void 0);
@@ -1769,27 +1836,58 @@ var ComplianceClient = class {
1769
1836
  currency: request.currency
1770
1837
  });
1771
1838
  }
1772
- const [geoVerification, profile] = await Promise.all([
1839
+ const [cipherTextResult, geoVerification, profileResult] = await Promise.all([
1840
+ this.executeCipherTextValidation(
1841
+ request.cipherText,
1842
+ request.customerId,
1843
+ "transaction",
1844
+ request.ipAddress,
1845
+ void 0,
1846
+ requestOptions
1847
+ ),
1773
1848
  this.geoClient.verifyIP({
1774
1849
  ip_address: request.ipAddress,
1775
1850
  user_id: request.customerId,
1776
1851
  event_type: "transaction",
1777
1852
  device_fingerprint: request.deviceFingerprint
1778
1853
  }, requestOptions),
1779
- this.riskClient.getProfile(request.customerId, requestOptions)
1854
+ this.riskClient.getProfile(request.customerId, requestOptions).catch(() => null)
1780
1855
  ]);
1856
+ const geoBlocked = !geoVerification.is_compliant || geoVerification.is_blocked || !!cipherTextResult?.risk?.is_blocked || cipherTextResult?.valid === false || geoVerification.gps_required && !cipherTextResult;
1857
+ if (geoBlocked && !profileResult) {
1858
+ return {
1859
+ allowed: false,
1860
+ geolocation: geoVerification,
1861
+ profile: null,
1862
+ transactionRisk: { score: 0, level: "low", factors: [], allowed: false, requiresManualReview: false },
1863
+ requiresApproval: false,
1864
+ blockReasons: this.getTransactionBlockReasons(
1865
+ geoVerification,
1866
+ { score: 0, level: "low", factors: [], allowed: false, requiresManualReview: false },
1867
+ true,
1868
+ cipherTextResult
1869
+ ),
1870
+ processingTime: Date.now() - startTime,
1871
+ cipherTextValidation: cipherTextResult
1872
+ };
1873
+ }
1874
+ if (!profileResult) {
1875
+ throw new ComplianceError("Customer profile not found", request.customerId);
1876
+ }
1877
+ const profile = profileResult;
1781
1878
  const transactionRisk = this.calculateTransactionRisk(
1782
1879
  request.amount,
1783
1880
  request.currency,
1784
1881
  geoVerification,
1785
- profile
1882
+ profile,
1883
+ cipherTextResult
1786
1884
  );
1787
1885
  const jurisdictionAllowed = this.checkJurisdictionLimits(
1788
1886
  request.amount,
1789
1887
  request.currency,
1790
1888
  geoVerification.jurisdiction
1791
1889
  );
1792
- const isAllowed = geoVerification.is_compliant && !geoVerification.is_blocked && jurisdictionAllowed && transactionRisk.allowed;
1890
+ const isAllowed = !geoBlocked && jurisdictionAllowed && transactionRisk.allowed && profile.customer_status !== "suspended";
1793
1891
  return {
1794
1892
  allowed: isAllowed,
1795
1893
  geolocation: geoVerification,
@@ -1799,9 +1897,11 @@ var ComplianceClient = class {
1799
1897
  blockReasons: this.getTransactionBlockReasons(
1800
1898
  geoVerification,
1801
1899
  transactionRisk,
1802
- jurisdictionAllowed
1900
+ jurisdictionAllowed,
1901
+ cipherTextResult
1803
1902
  ),
1804
- processingTime: Date.now() - startTime
1903
+ processingTime: Date.now() - startTime,
1904
+ cipherTextValidation: cipherTextResult
1805
1905
  };
1806
1906
  } catch (error) {
1807
1907
  throw new ComplianceError("Transaction verification failed", error instanceof Error ? error.message : void 0);
@@ -1816,12 +1916,22 @@ var ComplianceClient = class {
1816
1916
  async verifyEvent(request, requestOptions) {
1817
1917
  const startTime = Date.now();
1818
1918
  this.validateEventRequest(request);
1819
- const geoVerification = await this.geoClient.verifyIP({
1820
- ip_address: request.ipAddress,
1821
- user_id: request.customerId,
1822
- event_type: request.eventType,
1823
- device_fingerprint: request.deviceFingerprint
1824
- }, requestOptions);
1919
+ const [cipherTextResult, geoVerification] = await Promise.all([
1920
+ this.executeCipherTextValidation(
1921
+ request.cipherText,
1922
+ request.customerId,
1923
+ request.eventType,
1924
+ request.ipAddress,
1925
+ void 0,
1926
+ requestOptions
1927
+ ),
1928
+ this.geoClient.verifyIP({
1929
+ ip_address: request.ipAddress,
1930
+ user_id: request.customerId,
1931
+ event_type: request.eventType,
1932
+ device_fingerprint: request.deviceFingerprint
1933
+ }, requestOptions)
1934
+ ]);
1825
1935
  if (this.config.autoCreateProfiles) {
1826
1936
  try {
1827
1937
  const profile = await this.riskClient.getProfile(request.customerId, requestOptions);
@@ -1834,11 +1944,26 @@ var ComplianceClient = class {
1834
1944
  }
1835
1945
  }
1836
1946
  }
1947
+ const cipherTextBlocked = cipherTextResult ? !cipherTextResult.valid || cipherTextResult.risk?.is_blocked === true : false;
1948
+ const blockReasons = [...geoVerification.risk_reasons];
1949
+ if (cipherTextResult) {
1950
+ if (!cipherTextResult.valid) {
1951
+ blockReasons.push("ciphertext_validation_failed");
1952
+ }
1953
+ if (cipherTextResult.risk?.is_blocked) {
1954
+ blockReasons.push(...cipherTextResult.risk.block_reasons || []);
1955
+ }
1956
+ }
1957
+ const gpsBlocked = geoVerification.gps_required && !cipherTextResult;
1958
+ if (gpsBlocked) {
1959
+ blockReasons.push("gps_verification_required");
1960
+ }
1837
1961
  return {
1838
- allowed: geoVerification.is_compliant && !geoVerification.is_blocked,
1962
+ allowed: geoVerification.is_compliant && !geoVerification.is_blocked && !cipherTextBlocked && !gpsBlocked,
1839
1963
  geolocation: geoVerification,
1840
- blockReasons: geoVerification.risk_reasons,
1841
- processingTime: Date.now() - startTime
1964
+ blockReasons: [...new Set(blockReasons)],
1965
+ processingTime: Date.now() - startTime,
1966
+ cipherTextValidation: cipherTextResult
1842
1967
  };
1843
1968
  }
1844
1969
  // ============================================================================
@@ -1867,7 +1992,29 @@ var ComplianceClient = class {
1867
1992
  kyc_status: "pending"
1868
1993
  });
1869
1994
  }
1870
- calculateTransactionRisk(amount, currency, geoVerification, profile) {
1995
+ /**
1996
+ * Execute cipherText validation with graceful degradation.
1997
+ * Returns undefined if cipherText is not provided or validation fails.
1998
+ */
1999
+ async executeCipherTextValidation(cipherText, userId, eventType, ipAddress, customerData, requestOptions) {
2000
+ if (!cipherText) return void 0;
2001
+ try {
2002
+ return await this.geoClient.validateCipherText(
2003
+ cipherText,
2004
+ userId,
2005
+ eventType,
2006
+ ipAddress,
2007
+ customerData,
2008
+ requestOptions
2009
+ );
2010
+ } catch (err) {
2011
+ this.logger.warn("CipherText validation failed, proceeding with IP-only", {
2012
+ error: err instanceof Error ? err.message : "Unknown error"
2013
+ });
2014
+ return void 0;
2015
+ }
2016
+ }
2017
+ calculateTransactionRisk(amount, currency, geoVerification, profile, cipherTextResult) {
1871
2018
  if (!this._currencyRatesCustomized && !this._currencyRatesWarned) {
1872
2019
  this._currencyRatesWarned = true;
1873
2020
  this.logger.warn(
@@ -1900,6 +2047,15 @@ var ComplianceClient = class {
1900
2047
  riskScore += 50;
1901
2048
  factors.push("account_suspended");
1902
2049
  }
2050
+ if (cipherTextResult) {
2051
+ if (cipherTextResult.risk?.location_mismatch) {
2052
+ riskScore += 20;
2053
+ factors.push("gps_ip_location_mismatch");
2054
+ }
2055
+ if (cipherTextResult.risk?.score) {
2056
+ riskScore += cipherTextResult.risk.score * 0.2;
2057
+ }
2058
+ }
1903
2059
  return {
1904
2060
  score: Math.min(riskScore, 100),
1905
2061
  level: this.getRiskLevel(riskScore),
@@ -1925,20 +2081,33 @@ var ComplianceClient = class {
1925
2081
  if (score >= 40) return "medium";
1926
2082
  return "low";
1927
2083
  }
1928
- getBlockReasons(geoVerification, profile) {
2084
+ getBlockReasons(geoVerification, profile, cipherTextResult) {
1929
2085
  const reasons = [];
1930
2086
  if (geoVerification.is_blocked) {
1931
2087
  reasons.push(...geoVerification.risk_reasons);
1932
2088
  }
1933
- if (profile.customer_status === "suspended") {
1934
- reasons.push("account_suspended");
2089
+ if (profile) {
2090
+ if (profile.customer_status === "suspended") {
2091
+ reasons.push("account_suspended");
2092
+ }
2093
+ if (profile.has_sanctions) {
2094
+ reasons.push("sanctions_match");
2095
+ }
2096
+ }
2097
+ if (cipherTextResult) {
2098
+ if (!cipherTextResult.valid) {
2099
+ reasons.push("ciphertext_validation_failed");
2100
+ }
2101
+ if (cipherTextResult.risk?.is_blocked) {
2102
+ reasons.push(...cipherTextResult.risk.block_reasons || []);
2103
+ }
1935
2104
  }
1936
- if (profile.has_sanctions) {
1937
- reasons.push("sanctions_match");
2105
+ if (geoVerification.gps_required && !cipherTextResult) {
2106
+ reasons.push("gps_verification_required");
1938
2107
  }
1939
- return reasons;
2108
+ return [...new Set(reasons)];
1940
2109
  }
1941
- getTransactionBlockReasons(geoVerification, transactionRisk, jurisdictionAllowed) {
2110
+ getTransactionBlockReasons(geoVerification, transactionRisk, jurisdictionAllowed, cipherTextResult) {
1942
2111
  const reasons = [];
1943
2112
  if (!geoVerification.is_compliant) {
1944
2113
  reasons.push("non_compliant_jurisdiction");
@@ -1949,7 +2118,18 @@ var ComplianceClient = class {
1949
2118
  if (!transactionRisk.allowed) {
1950
2119
  reasons.push(...transactionRisk.factors);
1951
2120
  }
1952
- return reasons;
2121
+ if (cipherTextResult) {
2122
+ if (!cipherTextResult.valid) {
2123
+ reasons.push("ciphertext_validation_failed");
2124
+ }
2125
+ if (cipherTextResult.risk?.is_blocked) {
2126
+ reasons.push(...cipherTextResult.risk.block_reasons || []);
2127
+ }
2128
+ }
2129
+ if (geoVerification.gps_required && !cipherTextResult) {
2130
+ reasons.push("gps_verification_required");
2131
+ }
2132
+ return [...new Set(reasons)];
1953
2133
  }
1954
2134
  // ============================================================================
1955
2135
  // Location Request Methods