vesant-sdk 1.6.6-next.ac58d2b → 1.7.0-dev.059da4f

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 (72) hide show
  1. package/README.md +4 -4
  2. package/dist/client-C3DCmGe9.d.ts +436 -0
  3. package/dist/{client-D6PE3pcB.d.mts → client-DMIRx7Tu.d.mts} +4 -2
  4. package/dist/{client-DPtiuQvW.d.ts → client-DoMSYMMR.d.ts} +4 -2
  5. package/dist/client-ZNdnpWe7.d.mts +436 -0
  6. package/dist/compliance/index.d.mts +25 -429
  7. package/dist/compliance/index.d.ts +25 -429
  8. package/dist/compliance/index.js +181 -79
  9. package/dist/compliance/index.js.map +1 -1
  10. package/dist/compliance/index.mjs +181 -80
  11. package/dist/compliance/index.mjs.map +1 -1
  12. package/dist/decisions/index.d.mts +1 -1
  13. package/dist/decisions/index.d.ts +1 -1
  14. package/dist/decisions/index.js +1 -1
  15. package/dist/decisions/index.js.map +1 -1
  16. package/dist/decisions/index.mjs +1 -1
  17. package/dist/decisions/index.mjs.map +1 -1
  18. package/dist/geolocation/index.d.mts +3 -3
  19. package/dist/geolocation/index.d.ts +3 -3
  20. package/dist/geolocation/index.js +2 -1
  21. package/dist/geolocation/index.js.map +1 -1
  22. package/dist/geolocation/index.mjs +2 -1
  23. package/dist/geolocation/index.mjs.map +1 -1
  24. package/dist/index.d.mts +9 -8
  25. package/dist/index.d.ts +9 -8
  26. package/dist/index.js +269 -93
  27. package/dist/index.js.map +1 -1
  28. package/dist/index.mjs +268 -94
  29. package/dist/index.mjs.map +1 -1
  30. package/dist/kyc/core.d.mts +3 -3
  31. package/dist/kyc/core.d.ts +3 -3
  32. package/dist/kyc/core.js +77 -15
  33. package/dist/kyc/core.js.map +1 -1
  34. package/dist/kyc/core.mjs +77 -16
  35. package/dist/kyc/core.mjs.map +1 -1
  36. package/dist/kyc/index.d.mts +267 -26
  37. package/dist/kyc/index.d.ts +267 -26
  38. package/dist/kyc/index.js +77 -15
  39. package/dist/kyc/index.js.map +1 -1
  40. package/dist/kyc/index.mjs +77 -16
  41. package/dist/kyc/index.mjs.map +1 -1
  42. package/dist/react.d.mts +45 -8
  43. package/dist/react.d.ts +45 -8
  44. package/dist/react.js +874 -272
  45. package/dist/react.js.map +1 -1
  46. package/dist/react.mjs +873 -271
  47. package/dist/react.mjs.map +1 -1
  48. package/dist/risk-profile/index.d.mts +3 -3
  49. package/dist/risk-profile/index.d.ts +3 -3
  50. package/dist/risk-profile/index.js +1 -1
  51. package/dist/risk-profile/index.js.map +1 -1
  52. package/dist/risk-profile/index.mjs +1 -1
  53. package/dist/risk-profile/index.mjs.map +1 -1
  54. package/dist/scores/index.d.mts +1 -1
  55. package/dist/scores/index.d.ts +1 -1
  56. package/dist/scores/index.js +1 -1
  57. package/dist/scores/index.js.map +1 -1
  58. package/dist/scores/index.mjs +1 -1
  59. package/dist/scores/index.mjs.map +1 -1
  60. package/dist/tax/index.d.mts +41 -1
  61. package/dist/tax/index.d.ts +41 -1
  62. package/dist/tax/index.js +13 -1
  63. package/dist/tax/index.js.map +1 -1
  64. package/dist/tax/index.mjs +13 -1
  65. package/dist/tax/index.mjs.map +1 -1
  66. package/dist/{types-DGDVnogO.d.mts → types-BOFaMQxI.d.mts} +2 -2
  67. package/dist/{types-B4Ezqo7V.d.mts → types-CBQRNL-l.d.mts} +14 -1
  68. package/dist/{types-B4Ezqo7V.d.ts → types-CBQRNL-l.d.ts} +14 -1
  69. package/dist/{types-_YQdS3Ax.d.ts → types-UGyDl1fd.d.ts} +2 -2
  70. package/dist/webhooks/index.d.mts +12 -4
  71. package/dist/webhooks/index.d.ts +12 -4
  72. package/package.json +1 -1
@@ -1,5 +1,80 @@
1
1
  'use strict';
2
2
 
3
+ // src/compliance/block-reasons.ts
4
+ var sdkReasons = {
5
+ // Jurisdiction
6
+ jurisdictionBlocked: (country, countryISO) => ({
7
+ code: "JURISDICTION_BLOCKED",
8
+ message: "Access from a blocked jurisdiction",
9
+ metadata: { country, country_iso: countryISO }
10
+ }),
11
+ jurisdictionNonCompliant: () => ({
12
+ code: "JURISDICTION_NON_COMPLIANT",
13
+ message: "Location does not meet compliance requirements"
14
+ }),
15
+ jurisdictionRegistrationDenied: () => ({
16
+ code: "JURISDICTION_REGISTRATION_DENIED",
17
+ message: "Registration is not permitted in this jurisdiction"
18
+ }),
19
+ jurisdictionRestricted: () => ({
20
+ code: "JURISDICTION_RESTRICTED",
21
+ message: "Access from a restricted jurisdiction"
22
+ }),
23
+ // Risk
24
+ riskCriticalLevel: () => ({
25
+ code: "RISK_CRITICAL_LEVEL",
26
+ message: "Risk assessment reached critical threshold"
27
+ }),
28
+ accountSuspended: () => ({
29
+ code: "RISK_ACCOUNT_SUSPENDED",
30
+ message: "Customer account is suspended"
31
+ }),
32
+ sanctionsMatch: () => ({
33
+ code: "RISK_SANCTIONS_MATCH",
34
+ message: "Customer profile matched against sanctions list"
35
+ }),
36
+ riskHighLocation: () => ({
37
+ code: "RISK_HIGH_LOCATION",
38
+ message: "High-risk geographic location"
39
+ }),
40
+ riskHighCustomer: () => ({
41
+ code: "RISK_HIGH_CUSTOMER",
42
+ message: "Customer flagged as high risk"
43
+ }),
44
+ // Device
45
+ ciphertextInvalid: () => ({
46
+ code: "DEVICE_CIPHERTEXT_INVALID",
47
+ message: "Device verification payload failed validation"
48
+ }),
49
+ gpsIPMismatch: () => ({
50
+ code: "DEVICE_GPS_IP_MISMATCH",
51
+ message: "GPS location does not match IP-derived location"
52
+ }),
53
+ gpsRequired: () => ({
54
+ code: "DEVICE_GPS_REQUIRED",
55
+ message: "GPS verification is required but was not provided"
56
+ }),
57
+ // Transaction
58
+ transactionHighAmount: (amount, currency, threshold) => ({
59
+ code: "TRANSACTION_HIGH_AMOUNT",
60
+ message: "Transaction amount exceeds high-value threshold",
61
+ metadata: { amount, currency, threshold }
62
+ }),
63
+ transactionElevatedAmount: (amount, currency, threshold) => ({
64
+ code: "TRANSACTION_ELEVATED_AMOUNT",
65
+ message: "Transaction amount exceeds elevated-value threshold",
66
+ metadata: { amount, currency, threshold }
67
+ }),
68
+ transactionJurisdictionLimit: () => ({
69
+ code: "TRANSACTION_JURISDICTION_LIMIT",
70
+ message: "Transaction amount exceeds jurisdiction limit"
71
+ }),
72
+ anonymizationDetected: () => ({
73
+ code: "NETWORK_ANONYMIZER_DETECTED",
74
+ message: "Anonymization tool detected"
75
+ })
76
+ };
77
+
3
78
  // src/core/errors.ts
4
79
  var VesantError = class _VesantError extends Error {
5
80
  constructor(message, code, statusCode, details) {
@@ -224,7 +299,7 @@ function createConsoleLogger() {
224
299
  }
225
300
 
226
301
  // src/core/version.ts
227
- var SDK_VERSION = "1.6.6";
302
+ var SDK_VERSION = "1.7.0";
228
303
 
229
304
  // src/shared/browser-utils.ts
230
305
  function generateUUID() {
@@ -1075,6 +1150,7 @@ var GeolocationClient = class extends BaseClient {
1075
1150
  risk_level: risk.level ?? "low",
1076
1151
  risk_score: risk.score ?? 0,
1077
1152
  risk_reasons: risk.is_blocked && risk.block_reasons ? risk.block_reasons : risk.factors ?? [],
1153
+ risk_reasons_structured: risk.block_reasons_structured ?? [],
1078
1154
  jurisdiction: cipherTextResult.jurisdiction,
1079
1155
  geofence_evaluation: cipherTextResult.geofence_evaluation,
1080
1156
  record_id: cipherTextResult.record_id ?? "",
@@ -1516,10 +1592,10 @@ var ComplianceClient = class {
1516
1592
  device_fingerprint: request.deviceFingerprint
1517
1593
  }, requestOptions);
1518
1594
  }
1519
- const blockReasons = this.evaluateRegistrationBlock(geoVerification, cipherTextResult);
1520
- if (blockReasons.length > 0) {
1595
+ const structuredBlockReasons = this.evaluateRegistrationBlock(geoVerification, cipherTextResult);
1596
+ if (structuredBlockReasons.length > 0) {
1521
1597
  if (this.config.debug) {
1522
- this.logger.debug("Registration blocked at geo stage", { blockReasons });
1598
+ this.logger.debug("Registration blocked at geo stage", { blockReasons: structuredBlockReasons });
1523
1599
  }
1524
1600
  return {
1525
1601
  allowed: false,
@@ -1527,9 +1603,7 @@ var ComplianceClient = class {
1527
1603
  profile: null,
1528
1604
  requiresKYC: false,
1529
1605
  requiresEDD: false,
1530
- blockReasons,
1531
- processingTime: Date.now() - startTime,
1532
- cipherTextValidation: cipherTextResult
1606
+ ...this.buildReasonTail(structuredBlockReasons, startTime, cipherTextResult)
1533
1607
  };
1534
1608
  }
1535
1609
  const profile = await this.riskClient.createProfile({
@@ -1563,9 +1637,7 @@ var ComplianceClient = class {
1563
1637
  profile,
1564
1638
  requiresKYC,
1565
1639
  requiresEDD,
1566
- blockReasons: [],
1567
- processingTime: Date.now() - startTime,
1568
- cipherTextValidation: cipherTextResult
1640
+ ...this.buildReasonTail([], startTime, cipherTextResult)
1569
1641
  };
1570
1642
  } catch (error) {
1571
1643
  if (this.config.debug) {
@@ -1599,52 +1671,62 @@ var ComplianceClient = class {
1599
1671
  evaluateRegistrationBlock(geoVerification, cipherTextResult) {
1600
1672
  const blockReasons = [];
1601
1673
  if (geoVerification.is_blocked) {
1602
- blockReasons.push(...geoVerification.risk_reasons ?? []);
1674
+ blockReasons.push(...geoVerification.risk_reasons_structured ?? []);
1603
1675
  }
1604
1676
  if (!geoVerification.is_compliant) {
1605
- if (!blockReasons.includes("non_compliant_jurisdiction")) {
1606
- blockReasons.push("non_compliant_jurisdiction");
1677
+ if (!blockReasons.some((r) => r.code === "JURISDICTION_NON_COMPLIANT")) {
1678
+ blockReasons.push(sdkReasons.jurisdictionNonCompliant());
1607
1679
  }
1608
1680
  }
1609
1681
  const jurisdiction = geoVerification.jurisdiction;
1610
1682
  if (jurisdiction) {
1611
1683
  if (jurisdiction.allow_registration === false) {
1612
- blockReasons.push("registration_not_allowed_in_jurisdiction");
1684
+ blockReasons.push(sdkReasons.jurisdictionRegistrationDenied());
1613
1685
  }
1614
1686
  if (jurisdiction.status === "blocked" || jurisdiction.status === "sanctioned") {
1615
- if (!blockReasons.includes("blocked_jurisdiction")) {
1616
- blockReasons.push("blocked_jurisdiction");
1687
+ if (!blockReasons.some((r) => r.code === "JURISDICTION_BLOCKED")) {
1688
+ blockReasons.push(sdkReasons.jurisdictionBlocked(jurisdiction.country_name ?? "", jurisdiction.country_iso ?? ""));
1617
1689
  }
1618
1690
  }
1619
1691
  if (jurisdiction.status === "restricted" && jurisdiction.allow_registration === false) {
1620
- if (!blockReasons.includes("restricted_jurisdiction_no_registration")) {
1621
- blockReasons.push("restricted_jurisdiction_no_registration");
1692
+ if (!blockReasons.some((r) => r.code === "JURISDICTION_RESTRICTED")) {
1693
+ blockReasons.push(sdkReasons.jurisdictionRestricted());
1622
1694
  }
1623
1695
  }
1624
1696
  }
1625
1697
  if (geoVerification.geofence_evaluation?.blocked) {
1626
- blockReasons.push(...geoVerification.geofence_evaluation.reasons ?? []);
1698
+ blockReasons.push(
1699
+ ...(geoVerification.geofence_evaluation.reasons ?? []).map((m) => ({
1700
+ code: "JURISDICTION_GEOFENCE_VIOLATION",
1701
+ message: m
1702
+ }))
1703
+ );
1627
1704
  }
1628
1705
  if (geoVerification.risk_level === "critical") {
1629
- if (!blockReasons.includes("critical_risk_level")) {
1630
- blockReasons.push("critical_risk_level");
1706
+ if (!blockReasons.some((r) => r.code === "RISK_CRITICAL_LEVEL")) {
1707
+ blockReasons.push(sdkReasons.riskCriticalLevel());
1631
1708
  }
1632
1709
  }
1633
1710
  if (cipherTextResult) {
1634
1711
  if (!cipherTextResult.valid) {
1635
- blockReasons.push("ciphertext_validation_failed");
1712
+ blockReasons.push(sdkReasons.ciphertextInvalid());
1636
1713
  }
1637
1714
  if (cipherTextResult.risk?.is_blocked) {
1638
- blockReasons.push(...cipherTextResult.risk.block_reasons || []);
1715
+ blockReasons.push(...cipherTextResult.risk.block_reasons_structured ?? []);
1639
1716
  }
1640
1717
  if (cipherTextResult.risk?.location_mismatch) {
1641
- blockReasons.push("gps_ip_location_mismatch");
1718
+ blockReasons.push(sdkReasons.gpsIPMismatch());
1642
1719
  }
1643
1720
  }
1644
1721
  if (geoVerification.gps_required && !cipherTextResult) {
1645
- blockReasons.push("gps_verification_required");
1722
+ blockReasons.push(sdkReasons.gpsRequired());
1646
1723
  }
1647
- return [...new Set(blockReasons)];
1724
+ const seen = /* @__PURE__ */ new Set();
1725
+ return blockReasons.filter((r) => {
1726
+ if (seen.has(r.code)) return false;
1727
+ seen.add(r.code);
1728
+ return true;
1729
+ });
1648
1730
  }
1649
1731
  /**
1650
1732
  * Validate registration request has all required fields
@@ -1815,9 +1897,7 @@ var ComplianceClient = class {
1815
1897
  geolocation: geoVerification,
1816
1898
  profile: null,
1817
1899
  requiresStepUp: false,
1818
- blockReasons: loginBlockReasons,
1819
- processingTime: Date.now() - startTime,
1820
- cipherTextValidation: cipherTextResult
1900
+ ...this.buildReasonTail(loginBlockReasons, startTime, cipherTextResult)
1821
1901
  };
1822
1902
  }
1823
1903
  let profile;
@@ -1837,14 +1917,13 @@ var ComplianceClient = class {
1837
1917
  profile = await this.createProfileFromGeo(request.customerId, geoVerification);
1838
1918
  }
1839
1919
  const requiresStepUp = geoVerification.risk_level === "high" || geoVerification.risk_level === "critical" || cipherTextResult?.risk?.location_mismatch === true;
1920
+ const loginFinalStructured = isBlocked || profile.customer_status === "suspended" ? this.getBlockReasons(geoVerification, profile, cipherTextResult) : [];
1840
1921
  return {
1841
1922
  allowed: !isBlocked && profile.customer_status !== "suspended",
1842
1923
  geolocation: geoVerification,
1843
1924
  profile,
1844
1925
  requiresStepUp,
1845
- blockReasons: isBlocked || profile.customer_status === "suspended" ? this.getBlockReasons(geoVerification, profile, cipherTextResult) : [],
1846
- processingTime: Date.now() - startTime,
1847
- cipherTextValidation: cipherTextResult
1926
+ ...this.buildReasonTail(loginFinalStructured, startTime, cipherTextResult)
1848
1927
  };
1849
1928
  } catch (error) {
1850
1929
  throw new ComplianceError("Login verification failed", error instanceof Error ? error.message : void 0);
@@ -1926,20 +2005,19 @@ var ComplianceClient = class {
1926
2005
  }
1927
2006
  const geoBlocked = !geoVerification.is_compliant || geoVerification.is_blocked || !!cipherTextResult?.risk?.is_blocked || cipherTextResult?.valid === false || geoVerification.gps_required && !cipherTextResult;
1928
2007
  if (geoBlocked && !profileResult) {
2008
+ const earlyStructured = this.getTransactionBlockReasons(
2009
+ geoVerification,
2010
+ { score: 0, level: "low", factors: [], allowed: false, requiresManualReview: false },
2011
+ true,
2012
+ cipherTextResult
2013
+ );
1929
2014
  return {
1930
2015
  allowed: false,
1931
2016
  geolocation: geoVerification,
1932
2017
  profile: null,
1933
2018
  transactionRisk: { score: 0, level: "low", factors: [], allowed: false, requiresManualReview: false },
1934
2019
  requiresApproval: false,
1935
- blockReasons: this.getTransactionBlockReasons(
1936
- geoVerification,
1937
- { score: 0, level: "low", factors: [], allowed: false, requiresManualReview: false },
1938
- true,
1939
- cipherTextResult
1940
- ),
1941
- processingTime: Date.now() - startTime,
1942
- cipherTextValidation: cipherTextResult
2020
+ ...this.buildReasonTail(earlyStructured, startTime, cipherTextResult)
1943
2021
  };
1944
2022
  }
1945
2023
  if (!profileResult) {
@@ -1959,20 +2037,19 @@ var ComplianceClient = class {
1959
2037
  geoVerification.jurisdiction
1960
2038
  );
1961
2039
  const isAllowed = !geoBlocked && jurisdictionAllowed && transactionRisk.allowed && profile.customer_status !== "suspended";
2040
+ const txStructured = this.getTransactionBlockReasons(
2041
+ geoVerification,
2042
+ transactionRisk,
2043
+ jurisdictionAllowed,
2044
+ cipherTextResult
2045
+ );
1962
2046
  return {
1963
2047
  allowed: isAllowed,
1964
2048
  geolocation: geoVerification,
1965
2049
  profile,
1966
2050
  transactionRisk,
1967
2051
  requiresApproval: transactionRisk.requiresManualReview,
1968
- blockReasons: this.getTransactionBlockReasons(
1969
- geoVerification,
1970
- transactionRisk,
1971
- jurisdictionAllowed,
1972
- cipherTextResult
1973
- ),
1974
- processingTime: Date.now() - startTime,
1975
- cipherTextValidation: cipherTextResult
2052
+ ...this.buildReasonTail(txStructured, startTime, cipherTextResult)
1976
2053
  };
1977
2054
  } catch (error) {
1978
2055
  throw new ComplianceError("Transaction verification failed", error instanceof Error ? error.message : void 0);
@@ -2025,30 +2102,42 @@ var ComplianceClient = class {
2025
2102
  }
2026
2103
  }
2027
2104
  const cipherTextBlocked = cipherTextResult ? !cipherTextResult.valid || cipherTextResult.risk?.is_blocked === true : false;
2028
- const blockReasons = [...geoVerification.risk_reasons ?? []];
2105
+ const structuredEventReasons = [...geoVerification.risk_reasons_structured ?? []];
2029
2106
  if (cipherTextResult) {
2030
2107
  if (!cipherTextResult.valid) {
2031
- blockReasons.push("ciphertext_validation_failed");
2108
+ structuredEventReasons.push(sdkReasons.ciphertextInvalid());
2032
2109
  }
2033
2110
  if (cipherTextResult.risk?.is_blocked) {
2034
- blockReasons.push(...cipherTextResult.risk.block_reasons || []);
2111
+ structuredEventReasons.push(...cipherTextResult.risk.block_reasons_structured ?? []);
2035
2112
  }
2036
2113
  }
2037
2114
  const gpsBlocked = geoVerification.gps_required && !cipherTextResult;
2038
2115
  if (gpsBlocked) {
2039
- blockReasons.push("gps_verification_required");
2116
+ structuredEventReasons.push(sdkReasons.gpsRequired());
2040
2117
  }
2118
+ const seen = /* @__PURE__ */ new Set();
2119
+ const dedupedStructured = structuredEventReasons.filter((r) => {
2120
+ if (seen.has(r.code)) return false;
2121
+ seen.add(r.code);
2122
+ return true;
2123
+ });
2041
2124
  return {
2042
2125
  allowed: geoVerification.is_compliant && !geoVerification.is_blocked && !cipherTextBlocked && !gpsBlocked,
2043
2126
  geolocation: geoVerification,
2044
- blockReasons: [...new Set(blockReasons)],
2045
- processingTime: Date.now() - startTime,
2046
- cipherTextValidation: cipherTextResult
2127
+ ...this.buildReasonTail(dedupedStructured, startTime, cipherTextResult)
2047
2128
  };
2048
2129
  }
2049
2130
  // ============================================================================
2050
2131
  // Helper Methods
2051
2132
  // ============================================================================
2133
+ buildReasonTail(structured, startTime, cipherTextResult) {
2134
+ return {
2135
+ blockReasons: structured.map((r) => r.message),
2136
+ blockReasonsStructured: structured,
2137
+ processingTime: Date.now() - startTime,
2138
+ cipherTextValidation: cipherTextResult
2139
+ };
2140
+ }
2052
2141
  shouldUpdateProfile(profile, newCity) {
2053
2142
  return !profile.location || !profile.location.includes(newCity);
2054
2143
  }
@@ -2125,7 +2214,8 @@ var ComplianceClient = class {
2125
2214
  is_blocked: risk.is_blocked,
2126
2215
  risk_level: risk.level,
2127
2216
  risk_score: risk.score,
2128
- risk_reasons: risk.is_blocked && risk.block_reasons ? risk.block_reasons : risk.factors ?? [],
2217
+ risk_reasons: [],
2218
+ risk_reasons_structured: risk.is_blocked && risk.block_reasons_structured ? risk.block_reasons_structured : [],
2129
2219
  jurisdiction: ct.jurisdiction,
2130
2220
  geofence_evaluation: ct.geofence_evaluation,
2131
2221
  record_id: ct.record_id ?? "",
@@ -2140,35 +2230,35 @@ var ComplianceClient = class {
2140
2230
  );
2141
2231
  }
2142
2232
  let riskScore = 0;
2143
- const factors = [];
2233
+ const structuredFactors = [];
2144
2234
  const normalizedAmount = this.normalizeToUSD(amount, currency);
2145
2235
  if (normalizedAmount > 1e4) {
2146
2236
  riskScore += 30;
2147
- factors.push("high_transaction_amount");
2237
+ structuredFactors.push(sdkReasons.transactionHighAmount(normalizedAmount, currency, 1e4));
2148
2238
  } else if (normalizedAmount > 5e3) {
2149
2239
  riskScore += 15;
2150
- factors.push("elevated_transaction_amount");
2240
+ structuredFactors.push(sdkReasons.transactionElevatedAmount(normalizedAmount, currency, 5e3));
2151
2241
  }
2152
2242
  riskScore += geoVerification.risk_score * 0.4;
2153
2243
  if (geoVerification.risk_level === "high" || geoVerification.risk_level === "critical") {
2154
- factors.push("high_risk_location");
2244
+ structuredFactors.push(sdkReasons.riskHighLocation());
2155
2245
  }
2156
2246
  riskScore += profile.risk_score * 0.3;
2157
2247
  if (profile.risk_category === "high" || profile.risk_category === "critical") {
2158
- factors.push("high_risk_customer");
2248
+ structuredFactors.push(sdkReasons.riskHighCustomer());
2159
2249
  }
2160
2250
  if (geoVerification.location.is_vpn || geoVerification.location.is_proxy) {
2161
2251
  riskScore += 20;
2162
- factors.push("anonymization_detected");
2252
+ structuredFactors.push(sdkReasons.anonymizationDetected());
2163
2253
  }
2164
2254
  if (profile.customer_status === "suspended") {
2165
2255
  riskScore += 50;
2166
- factors.push("account_suspended");
2256
+ structuredFactors.push(sdkReasons.accountSuspended());
2167
2257
  }
2168
2258
  if (cipherTextResult) {
2169
2259
  if (cipherTextResult.risk?.location_mismatch) {
2170
2260
  riskScore += 20;
2171
- factors.push("gps_ip_location_mismatch");
2261
+ structuredFactors.push(sdkReasons.gpsIPMismatch());
2172
2262
  }
2173
2263
  if (cipherTextResult.risk?.score) {
2174
2264
  riskScore += cipherTextResult.risk.score * 0.2;
@@ -2177,7 +2267,8 @@ var ComplianceClient = class {
2177
2267
  return {
2178
2268
  score: Math.min(riskScore, 100),
2179
2269
  level: this.getRiskLevel(riskScore),
2180
- factors,
2270
+ factors: structuredFactors.map((r) => r.message),
2271
+ factorsStructured: structuredFactors,
2181
2272
  allowed: riskScore < 70,
2182
2273
  requiresManualReview: riskScore >= 60 && riskScore < 70
2183
2274
  };
@@ -2202,52 +2293,62 @@ var ComplianceClient = class {
2202
2293
  getBlockReasons(geoVerification, profile, cipherTextResult) {
2203
2294
  const reasons = [];
2204
2295
  if (geoVerification.is_blocked) {
2205
- reasons.push(...geoVerification.risk_reasons ?? []);
2296
+ reasons.push(...geoVerification.risk_reasons_structured ?? []);
2206
2297
  }
2207
2298
  if (profile) {
2208
2299
  if (profile.customer_status === "suspended") {
2209
- reasons.push("account_suspended");
2300
+ reasons.push(sdkReasons.accountSuspended());
2210
2301
  }
2211
2302
  if (profile.has_sanctions) {
2212
- reasons.push("sanctions_match");
2303
+ reasons.push(sdkReasons.sanctionsMatch());
2213
2304
  }
2214
2305
  }
2215
2306
  if (cipherTextResult) {
2216
2307
  if (!cipherTextResult.valid) {
2217
- reasons.push("ciphertext_validation_failed");
2308
+ reasons.push(sdkReasons.ciphertextInvalid());
2218
2309
  }
2219
2310
  if (cipherTextResult.risk?.is_blocked) {
2220
- reasons.push(...cipherTextResult.risk.block_reasons || []);
2311
+ reasons.push(...cipherTextResult.risk.block_reasons_structured ?? []);
2221
2312
  }
2222
2313
  }
2223
2314
  if (geoVerification.gps_required && !cipherTextResult) {
2224
- reasons.push("gps_verification_required");
2315
+ reasons.push(sdkReasons.gpsRequired());
2225
2316
  }
2226
- return [...new Set(reasons)];
2317
+ const seen = /* @__PURE__ */ new Set();
2318
+ return reasons.filter((r) => {
2319
+ if (seen.has(r.code)) return false;
2320
+ seen.add(r.code);
2321
+ return true;
2322
+ });
2227
2323
  }
2228
2324
  getTransactionBlockReasons(geoVerification, transactionRisk, jurisdictionAllowed, cipherTextResult) {
2229
2325
  const reasons = [];
2230
2326
  if (!geoVerification.is_compliant) {
2231
- reasons.push("non_compliant_jurisdiction");
2327
+ reasons.push(sdkReasons.jurisdictionNonCompliant());
2232
2328
  }
2233
2329
  if (!jurisdictionAllowed) {
2234
- reasons.push("exceeds_jurisdiction_limit");
2330
+ reasons.push(sdkReasons.transactionJurisdictionLimit());
2235
2331
  }
2236
2332
  if (!transactionRisk.allowed) {
2237
- reasons.push(...transactionRisk.factors);
2333
+ reasons.push(...transactionRisk.factorsStructured ?? []);
2238
2334
  }
2239
2335
  if (cipherTextResult) {
2240
2336
  if (!cipherTextResult.valid) {
2241
- reasons.push("ciphertext_validation_failed");
2337
+ reasons.push(sdkReasons.ciphertextInvalid());
2242
2338
  }
2243
2339
  if (cipherTextResult.risk?.is_blocked) {
2244
- reasons.push(...cipherTextResult.risk.block_reasons || []);
2340
+ reasons.push(...cipherTextResult.risk.block_reasons_structured ?? []);
2245
2341
  }
2246
2342
  }
2247
2343
  if (geoVerification.gps_required && !cipherTextResult) {
2248
- reasons.push("gps_verification_required");
2344
+ reasons.push(sdkReasons.gpsRequired());
2249
2345
  }
2250
- return [...new Set(reasons)];
2346
+ const seen = /* @__PURE__ */ new Set();
2347
+ return reasons.filter((r) => {
2348
+ if (seen.has(r.code)) return false;
2349
+ seen.add(r.code);
2350
+ return true;
2351
+ });
2251
2352
  }
2252
2353
  // ============================================================================
2253
2354
  // Location Request Methods
@@ -2467,5 +2568,6 @@ var ComplianceClient = class {
2467
2568
 
2468
2569
  exports.ComplianceClient = ComplianceClient;
2469
2570
  exports.DEFAULT_CURRENCY_RATES = DEFAULT_CURRENCY_RATES;
2571
+ exports.sdkReasons = sdkReasons;
2470
2572
  //# sourceMappingURL=index.js.map
2471
2573
  //# sourceMappingURL=index.js.map