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