@incodetech/core 0.0.0-dev-20260409-a38d5e8 → 0.0.0-dev-20260409-09dfd52
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.
- package/dist/BrowserStorageProvider-CXaS5Ooj.esm.js +55 -0
- package/dist/{OpenViduRecordingProvider-Bn2meybK.esm.js → OpenViduRecordingProvider-D_cVAwYQ.esm.js} +1 -1
- package/dist/{WasmUtilProvider-BpZSvZbg.esm.js → WasmUtilProvider-mWSXzp7b.esm.js} +1 -1
- package/dist/{addressSearch-DOFI7lwy.esm.js → addressSearch-C26OZIx0.esm.js} +4 -4
- package/dist/antifraud.d.ts +1 -1
- package/dist/antifraud.esm.js +4 -37
- package/dist/antifraudStateMachine-B74mO8vr.esm.js +39 -0
- package/dist/authentication.d.ts +11 -11
- package/dist/authentication.esm.js +22 -19
- package/dist/authenticationManager-BBQHippG.esm.js +67 -0
- package/dist/{authenticationManager-C2mk36yK.d.ts → authenticationManager-DOTo1EYF.d.ts} +2 -2
- package/dist/{authenticationManager-C7dL_avf.esm.js → authenticationStateMachine-DCJ0ArAt.esm.js} +7 -67
- package/dist/{backCameraStream-tabTmwDS.esm.js → backCameraStream-D9g2wyil.esm.js} +3 -3
- package/dist/camera.d.ts +1 -1
- package/dist/camera.esm.js +3 -3
- package/dist/consent.d.ts +55 -55
- package/dist/consent.esm.js +4 -149
- package/dist/consentStateMachine-DIdJXJW0.esm.js +151 -0
- package/dist/cross-document-data-match.d.ts +1 -1
- package/dist/cross-document-data-match.esm.js +4 -4
- package/dist/curp-validation.d.ts +5 -5
- package/dist/curp-validation.esm.js +4 -417
- package/dist/curpValidationStateMachine-Dp5WB6__.esm.js +419 -0
- package/dist/{deepsightLoader-Cj6SyUQ-.esm.js → deepsightLoader-CaULV07H.esm.js} +10 -10
- package/dist/{deepsightService-ByD6uIs7.d.ts → deepsightService-S-tU77m-.d.ts} +2 -2
- package/dist/{deepsightService-BjgXl5hs.esm.js → deepsightService-rPGLH8Xp.esm.js} +5 -5
- package/dist/device.esm.js +3 -3
- package/dist/document-capture.d.ts +80 -78
- package/dist/document-capture.esm.js +8 -403
- package/dist/document-upload.d.ts +53 -53
- package/dist/document-upload.esm.js +7 -7
- package/dist/documentCaptureStateMachine-ByYOCKz5.esm.js +403 -0
- package/dist/ekyb.d.ts +3 -3
- package/dist/ekyb.esm.js +10 -655
- package/dist/ekybStateMachine-DRku_YmR.esm.js +653 -0
- package/dist/ekyc.d.ts +3 -3
- package/dist/ekyc.esm.js +6 -10614
- package/dist/ekycStateMachine-CSWaaWVl.esm.js +10615 -0
- package/dist/email.d.ts +3 -3
- package/dist/email.esm.js +6 -5
- package/dist/{emailManager-CU_hzrsl.d.ts → emailManager-D6CHM2QO.d.ts} +4 -3
- package/dist/emailManager-DByjyeY8.esm.js +238 -0
- package/dist/{emailManager-_9R4vm6g.esm.js → emailStateMachine-BoIkeCw5.esm.js} +6 -239
- package/dist/{events-DlHrOIRc.esm.js → events-W91zLpx4.esm.js} +5 -1
- package/dist/events.esm.js +2 -2
- package/dist/extensibility.d.ts +15 -15
- package/dist/extensibility.esm.js +33 -26
- package/dist/face-match.d.ts +7 -6
- package/dist/face-match.esm.js +8 -129
- package/dist/faceCaptureManagerFactory-Bspg2Tyf.esm.js +117 -0
- package/dist/{faceCaptureManagerFactory-Da_-ohdg.d.ts → faceCaptureManagerFactory-P2yy30KU.d.ts} +8 -8
- package/dist/{faceCaptureSetup-CaVWkjvE.esm.js → faceCaptureSetup-CQevz86q.esm.js} +5 -119
- package/dist/faceMatchStateMachine-CLterVEC.esm.js +127 -0
- package/dist/flow.d.ts +8 -13
- package/dist/flow.esm.js +10 -29
- package/dist/{flowCompletionService-B5JemmC6.esm.js → flowCompletionService-DZSDUXus.esm.js} +2 -2
- package/dist/{flowServices-p22wrYPf.esm.js → flowServices-YATk0fgY.esm.js} +3 -3
- package/dist/geolocation.d.ts +7 -6
- package/dist/geolocation.esm.js +7 -105
- package/dist/geolocationStateMachine-CRRUCl9K.esm.js +105 -0
- package/dist/{getDeviceClass-DEzz4cmY.esm.js → getDeviceClass-DBF-ExLR.esm.js} +1 -1
- package/dist/government-validation.d.ts +2 -2
- package/dist/government-validation.esm.js +5 -269
- package/dist/governmentValidationStateMachine-C_iPX9VE.esm.js +271 -0
- package/dist/http.esm.js +1 -1
- package/dist/id.d.ts +10 -10
- package/dist/id.esm.js +22 -20
- package/dist/idCaptureManager-CJfatzuY.esm.js +335 -0
- package/dist/{idCaptureManager-CV08v1e3.d.ts → idCaptureManager-CbZvdr9y.d.ts} +7 -7
- package/dist/{idCaptureManager-dyZzKv8L.esm.js → idCaptureStateMachine-gf-Q9piu.esm.js} +17 -346
- package/dist/index.d.ts +2 -2
- package/dist/index.esm.js +8 -8
- package/dist/{lib-Bavz2qmt.esm.js → lib-BzVJ-zxG.esm.js} +1 -1
- package/dist/mandatory-consent.d.ts +55 -55
- package/dist/mandatory-consent.esm.js +4 -124
- package/dist/mandatoryConsentStateMachine-BZNBJ1fK.esm.js +126 -0
- package/dist/{openviduLazy-vhrVZCr_.esm.js → openviduLazy-CLg_-u0m.esm.js} +2 -2
- package/dist/openviduLazy-rFXBtZVZ.esm.js +3 -0
- package/dist/{permissionServices-Cskq32Yd.esm.js → permissionServices-Cisv73eQ.esm.js} +2 -2
- package/dist/phone.d.ts +3 -3
- package/dist/phone.esm.js +6 -5
- package/dist/phoneManager-DhC4obPF.esm.js +258 -0
- package/dist/{phoneManager-ulJuGvJ8.d.ts → phoneManager-Zwr-qCnC.d.ts} +2 -2
- package/dist/{phoneManager-DerdUfd4.esm.js → phoneStateMachine-Cc_w4tC0.esm.js} +5 -258
- package/dist/{recordingService-483wQ6kR.esm.js → recordingService-CCfxUY7-.esm.js} +14 -68
- package/dist/redirect-to-mobile.d.ts +2 -2
- package/dist/redirect-to-mobile.esm.js +5 -247
- package/dist/redirectToMobileStateMachine-vOe27Ufw.esm.js +249 -0
- package/dist/runChildModule-DVC4JEjp.esm.js +27 -0
- package/dist/selfie.d.ts +11 -11
- package/dist/selfie.esm.js +22 -19
- package/dist/selfieManager-CorEST5h.esm.js +60 -0
- package/dist/{selfieManager-DCRP7X75.d.ts → selfieManager-DNwfxieF.d.ts} +2 -2
- package/dist/selfieStateMachine-3b19ON1z.esm.js +56 -0
- package/dist/{session-CUh77zj3.esm.js → session-B_rKSRql.esm.js} +4 -4
- package/dist/session.d.ts +1 -1
- package/dist/session.esm.js +6 -6
- package/dist/{setup-DpHakxsC.d.ts → setup-BYqwVLiv.d.ts} +1 -1
- package/dist/{setup-XpxfZgKn.esm.js → setup-DLvhsDol.esm.js} +6 -5
- package/dist/signature.d.ts +4 -3
- package/dist/signature.esm.js +6 -189
- package/dist/signatureStateMachine-CU92zCXU.esm.js +189 -0
- package/dist/{stats-DHDoqSBV.esm.js → stats-gFD2351t.esm.js} +1 -1
- package/dist/stats.esm.js +2 -2
- package/dist/{types-2OPf1pyv.d.ts → types-CYJ0Ish6.d.ts} +1 -1
- package/dist/types-CjsEZRcz.d.ts +35 -0
- package/dist/{types-CVJVQ7fp.d.ts → types-DU8HmI5U.d.ts} +1 -1
- package/dist/wasm.d.ts +2 -2
- package/dist/wasm.esm.js +8 -8
- package/dist/workflow.d.ts +813 -0
- package/dist/workflow.esm.js +600 -0
- package/package.json +7 -3
- package/dist/openviduLazy-BIPHozOu.esm.js +0 -3
- package/dist/selfieManager-DeOcNel4.esm.js +0 -110
- /package/dist/{Actor-Ba71-_30.d.ts → Actor-DbWH1K6E.d.ts} +0 -0
- /package/dist/{BaseWasmProvider-D-s_6M5H.esm.js → BaseWasmProvider-DoYDYH1z.esm.js} +0 -0
- /package/dist/{BrowserEnvironmentProvider-DaHeLJQw.esm.js → BrowserEnvironmentProvider-BtKLxTx4.esm.js} +0 -0
- /package/dist/{BrowserTimerProvider-BhD2MlHg.esm.js → BrowserTimerProvider-v7bpbrAk.esm.js} +0 -0
- /package/dist/{ITimerCapability-oixwa6nj.esm.js → ITimerCapability-BZO_FsCo.esm.js} +0 -0
- /package/dist/{Manager-BN2g_I8W.d.ts → Manager-DcPMRgTm.d.ts} +0 -0
- /package/dist/{MotionSensorProvider-CodM3e0E.esm.js → MotionSensorProvider-D90R4qwV.esm.js} +0 -0
- /package/dist/{StateMachine-BoJsfMvg.d.ts → StateMachine-BBuIgsHT.d.ts} +0 -0
- /package/dist/{api-DzpnV6O7.esm.js → api-aa9Mx20l.esm.js} +0 -0
- /package/dist/{browserSimulation-B4ubb2OL.esm.js → browserSimulation-DFqGKQAD.esm.js} +0 -0
- /package/dist/{camera-1eeGnAaL.d.ts → camera-DATT31my.d.ts} +0 -0
- /package/dist/{camera-DmkFpf5N.esm.js → camera-DpPQS_-5.esm.js} +0 -0
- /package/dist/{chunk-DsxENsBR.esm.js → chunk-YGHKo4MY.esm.js} +0 -0
- /package/dist/{displayErrors-BZLX7idb.d.ts → displayErrors-xrg0ejaS.d.ts} +0 -0
- /package/dist/{flowCompletionService-D-3YCHyO.d.ts → flowCompletionService-gxt5reFV.d.ts} +0 -0
- /package/dist/{getBrowser-Dtyt9J_h.esm.js → getBrowser-DCcD7H-M.esm.js} +0 -0
- /package/dist/{platform-Dv7a2fv-.esm.js → platform-DctkySJU.esm.js} +0 -0
- /package/dist/{types-D_QfFKxT.d.ts → types-CIjb0FKu.d.ts} +0 -0
- /package/dist/{warmup-CIj_wEV_.d.ts → warmup-Ckb1hN85.d.ts} +0 -0
- /package/dist/{xstate.esm-Bv55-lJ4.esm.js → xstate.esm-B7FPE6br.esm.js} +0 -0
package/dist/ekyb.esm.js
CHANGED
|
@@ -1,659 +1,14 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import "./session-
|
|
4
|
-
import "./BrowserEnvironmentProvider-
|
|
5
|
-
import "./browserSimulation-
|
|
6
|
-
import { a as createActor,
|
|
7
|
-
import { a as
|
|
8
|
-
import
|
|
9
|
-
import "./
|
|
1
|
+
import "./api-aa9Mx20l.esm.js";
|
|
2
|
+
import { n as eventModuleNames, o as createManagerInstrumentation } from "./events-W91zLpx4.esm.js";
|
|
3
|
+
import "./session-B_rKSRql.esm.js";
|
|
4
|
+
import "./BrowserEnvironmentProvider-BtKLxTx4.esm.js";
|
|
5
|
+
import "./browserSimulation-DFqGKQAD.esm.js";
|
|
6
|
+
import { a as createActor, o as createManager } from "./xstate.esm-B7FPE6br.esm.js";
|
|
7
|
+
import { a as SUPPORTED_COUNTRIES, i as DEV_ONLY_COUNTRIES, n as computeDisplayErrors, o as isSupportedCountry, r as ALL_COUNTRIES, t as ekybMachine } from "./ekybStateMachine-DRku_YmR.esm.js";
|
|
8
|
+
import "./addressSearch-C26OZIx0.esm.js";
|
|
9
|
+
import "./flowServices-YATk0fgY.esm.js";
|
|
10
|
+
import "./BrowserTimerProvider-v7bpbrAk.esm.js";
|
|
10
11
|
|
|
11
|
-
//#region src/modules/ekyb/ekybConstants.ts
|
|
12
|
-
const UBO_INPUT_LIMIT = 8;
|
|
13
|
-
/**
|
|
14
|
-
* Countries available in all environments.
|
|
15
|
-
* Sorted alphabetically by display name.
|
|
16
|
-
*/
|
|
17
|
-
const SUPPORTED_COUNTRIES = [
|
|
18
|
-
"BR",
|
|
19
|
-
"CN",
|
|
20
|
-
"FR",
|
|
21
|
-
"DE",
|
|
22
|
-
"IL",
|
|
23
|
-
"IT",
|
|
24
|
-
"MX",
|
|
25
|
-
"ES",
|
|
26
|
-
"GB",
|
|
27
|
-
"US"
|
|
28
|
-
];
|
|
29
|
-
/**
|
|
30
|
-
* Additional countries available only in dev/staging environments.
|
|
31
|
-
*/
|
|
32
|
-
const DEV_ONLY_COUNTRIES = [
|
|
33
|
-
"CM",
|
|
34
|
-
"KE",
|
|
35
|
-
"NG"
|
|
36
|
-
];
|
|
37
|
-
/**
|
|
38
|
-
* Union of all recognized country codes (prod + dev).
|
|
39
|
-
*/
|
|
40
|
-
const ALL_COUNTRIES = [...SUPPORTED_COUNTRIES, ...DEV_ONLY_COUNTRIES];
|
|
41
|
-
const ALL_COUNTRIES_SET = new Set(ALL_COUNTRIES);
|
|
42
|
-
function isSupportedCountry(code) {
|
|
43
|
-
return ALL_COUNTRIES_SET.has(code);
|
|
44
|
-
}
|
|
45
|
-
const FIELD_ORDER = [
|
|
46
|
-
"name-user_input",
|
|
47
|
-
"taxId-user_input",
|
|
48
|
-
"street-user_input",
|
|
49
|
-
"houseNo-user_input",
|
|
50
|
-
"address2-user_input",
|
|
51
|
-
"city-user_input",
|
|
52
|
-
"state-user_input",
|
|
53
|
-
"postalCode-user_input"
|
|
54
|
-
];
|
|
55
|
-
const FIELD_NAME_MAPPING = {
|
|
56
|
-
"name-user_input": "businessName",
|
|
57
|
-
"street-user_input": "street",
|
|
58
|
-
"houseNo-user_input": "houseNo",
|
|
59
|
-
"address2-user_input": "addressLine2",
|
|
60
|
-
"city-user_input": "city",
|
|
61
|
-
"state-user_input": "state",
|
|
62
|
-
"postalCode-user_input": "postalCode",
|
|
63
|
-
"taxId-user_input": "taxId"
|
|
64
|
-
};
|
|
65
|
-
const COUNTRIES_WITH_CNPJ_VALIDATION = ["BR"];
|
|
66
|
-
const COUNTRIES_WITH_SPECIAL_TAX_ID_RULES = [
|
|
67
|
-
"NG",
|
|
68
|
-
"CM",
|
|
69
|
-
"KE"
|
|
70
|
-
];
|
|
71
|
-
const BUSINESS_NAME_OPTIONAL_COUNTRIES = [];
|
|
72
|
-
const ADDRESS_FULLY_OPTIONAL_COUNTRIES = [
|
|
73
|
-
"BR",
|
|
74
|
-
"GB",
|
|
75
|
-
"FR"
|
|
76
|
-
];
|
|
77
|
-
const ADDRESS_FIELDS = [
|
|
78
|
-
"street",
|
|
79
|
-
"houseNo",
|
|
80
|
-
"addressLine2",
|
|
81
|
-
"city",
|
|
82
|
-
"state",
|
|
83
|
-
"postalCode"
|
|
84
|
-
];
|
|
85
|
-
const ALL_COUNTRIES_OPTIONAL_FIELDS = ["ubo"];
|
|
86
|
-
|
|
87
|
-
//#endregion
|
|
88
|
-
//#region src/modules/ekyb/ekybValidators.ts
|
|
89
|
-
const CNPJ_FORMATTED_LENGTH = 18;
|
|
90
|
-
const CNPJ_CLEAN_LENGTH = 14;
|
|
91
|
-
const INVALID_CNPJ_PATTERNS = [
|
|
92
|
-
"00000000000000",
|
|
93
|
-
"11111111111111",
|
|
94
|
-
"22222222222222",
|
|
95
|
-
"33333333333333",
|
|
96
|
-
"44444444444444",
|
|
97
|
-
"55555555555555",
|
|
98
|
-
"66666666666666",
|
|
99
|
-
"77777777777777",
|
|
100
|
-
"88888888888888",
|
|
101
|
-
"99999999999999"
|
|
102
|
-
];
|
|
103
|
-
const CNPJ_FIRST_DIGIT_FACTORS = [
|
|
104
|
-
5,
|
|
105
|
-
4,
|
|
106
|
-
3,
|
|
107
|
-
2,
|
|
108
|
-
9,
|
|
109
|
-
8,
|
|
110
|
-
7,
|
|
111
|
-
6,
|
|
112
|
-
5,
|
|
113
|
-
4,
|
|
114
|
-
3,
|
|
115
|
-
2
|
|
116
|
-
];
|
|
117
|
-
const CNPJ_SECOND_DIGIT_FACTORS = [
|
|
118
|
-
6,
|
|
119
|
-
5,
|
|
120
|
-
4,
|
|
121
|
-
3,
|
|
122
|
-
2,
|
|
123
|
-
9,
|
|
124
|
-
8,
|
|
125
|
-
7,
|
|
126
|
-
6,
|
|
127
|
-
5,
|
|
128
|
-
4,
|
|
129
|
-
3,
|
|
130
|
-
2
|
|
131
|
-
];
|
|
132
|
-
function cleanCnpjString(cnpj) {
|
|
133
|
-
return cnpj.replace(/\./g, "").replace(/\//g, "").replace(/-/g, "");
|
|
134
|
-
}
|
|
135
|
-
function calculateVerificationDigit(cnpjString, factors) {
|
|
136
|
-
let digit = 11 - factors.reduce((acc, factor, index) => acc + Number.parseInt(cnpjString.charAt(index), 10) * factor, 0) % 11;
|
|
137
|
-
if (digit >= 10) digit = 0;
|
|
138
|
-
return digit.toString();
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* Validates a Brazilian CNPJ number (14-digit checksum).
|
|
142
|
-
* Accepts formatted (00.000.000/0000-00) or unformatted input.
|
|
143
|
-
*/
|
|
144
|
-
function validateCNPJ(cnpjInput) {
|
|
145
|
-
if (!cnpjInput || typeof cnpjInput !== "string") return false;
|
|
146
|
-
let cnpj = cnpjInput.trim();
|
|
147
|
-
if (cnpj.length === CNPJ_FORMATTED_LENGTH) cnpj = cleanCnpjString(cnpj);
|
|
148
|
-
if (cnpj.length !== CNPJ_CLEAN_LENGTH) return false;
|
|
149
|
-
if (!/^\d+$/.test(cnpj)) return false;
|
|
150
|
-
if (INVALID_CNPJ_PATTERNS.includes(cnpj)) return false;
|
|
151
|
-
const first = calculateVerificationDigit(cnpj, CNPJ_FIRST_DIGIT_FACTORS);
|
|
152
|
-
if (cnpj.charAt(12) !== first) return false;
|
|
153
|
-
const second = calculateVerificationDigit(cnpj, CNPJ_SECOND_DIGIT_FACTORS);
|
|
154
|
-
if (cnpj.charAt(13) !== second) return false;
|
|
155
|
-
return true;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
//#endregion
|
|
159
|
-
//#region src/modules/ekyb/ekybUtils.ts
|
|
160
|
-
/** Sorts modules based on a custom order; items not in order maintain relative position */
|
|
161
|
-
function sortModulesByOrder(modules, customOrder) {
|
|
162
|
-
return [...modules].sort((a, b) => {
|
|
163
|
-
const indexA = customOrder.indexOf(a);
|
|
164
|
-
const indexB = customOrder.indexOf(b);
|
|
165
|
-
if (indexA !== -1 && indexB !== -1) return indexA - indexB;
|
|
166
|
-
if (indexA !== -1) return -1;
|
|
167
|
-
if (indexB !== -1) return 1;
|
|
168
|
-
return 0;
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
/** Determines if a field is optional for the given country */
|
|
172
|
-
function isFieldOptional(fieldName, countryCode) {
|
|
173
|
-
if (ALL_COUNTRIES_OPTIONAL_FIELDS.includes(fieldName)) return true;
|
|
174
|
-
if (fieldName === "businessName") return BUSINESS_NAME_OPTIONAL_COUNTRIES.includes(countryCode);
|
|
175
|
-
if (fieldName === "addressLine2") return true;
|
|
176
|
-
if (ADDRESS_FIELDS.includes(fieldName)) return false;
|
|
177
|
-
if (fieldName === "taxId") return false;
|
|
178
|
-
return false;
|
|
179
|
-
}
|
|
180
|
-
/** Checks if at least one address field has a non-empty value */
|
|
181
|
-
function hasAtLeastOneAddressField(formData) {
|
|
182
|
-
return ADDRESS_FIELDS.some((field) => {
|
|
183
|
-
const value = formData[field];
|
|
184
|
-
return value !== void 0 && value.trim() !== "";
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
/** Returns false for countries where address is fully optional */
|
|
188
|
-
function requiresAddressValidation(countryCode) {
|
|
189
|
-
return !ADDRESS_FULLY_OPTIONAL_COUNTRIES.includes(countryCode);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
//#endregion
|
|
193
|
-
//#region src/modules/ekyb/ekybActions.ts
|
|
194
|
-
const REQUIRED_ERROR_KEYS = new Set(["ekyb.error.requiredField"]);
|
|
195
|
-
const UBO_FIELD_LABELS = {
|
|
196
|
-
name: "ekyb.uboName",
|
|
197
|
-
surname: "ekyb.uboSurname"
|
|
198
|
-
};
|
|
199
|
-
function buildEkybFields(verificationFields, country, _hasUbos) {
|
|
200
|
-
let modules = verificationFields.filter((f) => f !== "ubos-user_input" && !f.startsWith("socure"));
|
|
201
|
-
if (country === "GB") modules = modules.filter((m) => m !== "state-user_input");
|
|
202
|
-
if (country === "MX") modules = modules.filter((m) => {
|
|
203
|
-
if (m === "ubos-user_input") return false;
|
|
204
|
-
const fieldName = FIELD_NAME_MAPPING[m] ?? m;
|
|
205
|
-
if (ADDRESS_FIELDS.includes(fieldName) && fieldName !== "postalCode") return false;
|
|
206
|
-
return true;
|
|
207
|
-
});
|
|
208
|
-
return sortModulesByOrder(modules, FIELD_ORDER).map((moduleName) => {
|
|
209
|
-
const fieldName = FIELD_NAME_MAPPING[moduleName] ?? moduleName;
|
|
210
|
-
const optional = isFieldOptional(fieldName, country);
|
|
211
|
-
const def = {
|
|
212
|
-
name: fieldName,
|
|
213
|
-
type: "text",
|
|
214
|
-
label: `ekyb.${fieldName}`,
|
|
215
|
-
required: !optional
|
|
216
|
-
};
|
|
217
|
-
if (fieldName === "taxId") {
|
|
218
|
-
def.required = true;
|
|
219
|
-
if (country === "CN") def.label = "verification.labels.prcId";
|
|
220
|
-
if (country === "BR") def.displayLabel = "CPF";
|
|
221
|
-
}
|
|
222
|
-
if (fieldName === "postalCode") def.maxLength = getPostalCodeMaxLength(country);
|
|
223
|
-
if (fieldName === "state" && country === "US") {
|
|
224
|
-
def.type = "dropdown";
|
|
225
|
-
def.options = usStateOptions;
|
|
226
|
-
def.placeholder = "verification.placeholder.state";
|
|
227
|
-
}
|
|
228
|
-
return def;
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
function getDefaultVerificationFields(config) {
|
|
232
|
-
if (config.verificationFields && config.verificationFields.length > 0) return config.verificationFields;
|
|
233
|
-
const fields = [];
|
|
234
|
-
if (config.checkBusinessName !== false) fields.push("name-user_input");
|
|
235
|
-
if (config.checkAddress !== false) fields.push("street-user_input", "houseNo-user_input", "address2-user_input", "city-user_input", "state-user_input", "postalCode-user_input");
|
|
236
|
-
if (config.checkTaxId !== false) fields.push("taxId-user_input");
|
|
237
|
-
if (config.checkUniqueBeneficialOwner !== false) fields.push("ubos-user_input");
|
|
238
|
-
return fields;
|
|
239
|
-
}
|
|
240
|
-
function validateEkybField(name, value, required, country) {
|
|
241
|
-
const val = (value ?? "").trim();
|
|
242
|
-
if (required && !val) return "ekyb.error.requiredField";
|
|
243
|
-
if (name === "taxId") {
|
|
244
|
-
if (COUNTRIES_WITH_CNPJ_VALIDATION.includes(country)) {
|
|
245
|
-
if (val && !validateCNPJ(val)) return "ekyb.error.invalidTaxId";
|
|
246
|
-
}
|
|
247
|
-
if (COUNTRIES_WITH_SPECIAL_TAX_ID_RULES.includes(country) && !val) return;
|
|
248
|
-
}
|
|
249
|
-
if (name === "postalCode" && val) {
|
|
250
|
-
if (!validatePostalCode(val, country)) return getPostalCodeErrorKey(country);
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
function computeEkybValidation(fields, values, country, ubos, hasUbos) {
|
|
254
|
-
const errors = {};
|
|
255
|
-
for (const field of fields) {
|
|
256
|
-
const val = values[field.name];
|
|
257
|
-
const err = validateEkybField(field.name, val, field.required, country);
|
|
258
|
-
if (err) errors[field.name] = err;
|
|
259
|
-
}
|
|
260
|
-
if (requiresAddressValidation(country)) {
|
|
261
|
-
const addressValues = {};
|
|
262
|
-
for (const f of ADDRESS_FIELDS) addressValues[f] = values[f];
|
|
263
|
-
if (!hasAtLeastOneAddressField(addressValues)) {
|
|
264
|
-
const requiredAddressFields = fields.filter((f) => ADDRESS_FIELDS.includes(f.name) && f.required);
|
|
265
|
-
for (const f of requiredAddressFields) if (!errors[f.name] && !(values[f.name] ?? "").trim()) errors[f.name] = "ekyb.error.requiredField";
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
if (hasUbos) for (let i = 0; i < ubos.length; i++) {
|
|
269
|
-
const isDefault = i === 0;
|
|
270
|
-
const hasAnyValue = ubos[i].name.trim() !== "" || ubos[i].surname.trim() !== "";
|
|
271
|
-
if (isDefault || hasAnyValue) {
|
|
272
|
-
if (!ubos[i].name.trim()) errors[`ubo-${i}-name`] = "ekyb.error.requiredField";
|
|
273
|
-
if (!ubos[i].surname.trim()) errors[`ubo-${i}-surname`] = "ekyb.error.requiredField";
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
return {
|
|
277
|
-
errors,
|
|
278
|
-
isValid: Object.keys(errors).length === 0
|
|
279
|
-
};
|
|
280
|
-
}
|
|
281
|
-
function computeDisplayErrors(errors, touched, submitAttempted, country, fields) {
|
|
282
|
-
const display = {};
|
|
283
|
-
const errorParams = {};
|
|
284
|
-
const fieldLabelMap = new Map(fields?.map((f) => [f.name, f.displayLabel ?? f.label]));
|
|
285
|
-
for (const [field, err] of Object.entries(errors)) {
|
|
286
|
-
const isRequiredErr = REQUIRED_ERROR_KEYS.has(err);
|
|
287
|
-
if (isRequiredErr && (submitAttempted || touched[field])) {
|
|
288
|
-
display[field] = DYNAMIC_REQUIRED_KEY;
|
|
289
|
-
const label = fieldLabelMap.get(field);
|
|
290
|
-
if (label) errorParams[field] = { fieldName: label };
|
|
291
|
-
else {
|
|
292
|
-
const uboMatch = field.match(/^ubo-\d+-(name|surname)$/);
|
|
293
|
-
if (uboMatch) errorParams[field] = { fieldName: UBO_FIELD_LABELS[uboMatch[1]] ?? field };
|
|
294
|
-
}
|
|
295
|
-
} else if (!isRequiredErr && touched[field]) display[field] = err;
|
|
296
|
-
if (display[field] && field === "postalCode" && POSTAL_CODE_FORMAT_ERROR_KEYS.has(err)) {
|
|
297
|
-
const fixedLen = FIXED_DIGIT_POSTAL_CODE_LENGTH[country];
|
|
298
|
-
if (fixedLen !== void 0) errorParams[field] = {
|
|
299
|
-
...errorParams[field] ?? {},
|
|
300
|
-
length: fixedLen
|
|
301
|
-
};
|
|
302
|
-
else {
|
|
303
|
-
let maxLen = getPostalCodeMaxLength(country);
|
|
304
|
-
if (country === "US" || country === "BR") maxLen = maxLen - 1;
|
|
305
|
-
errorParams[field] = {
|
|
306
|
-
...errorParams[field] ?? {},
|
|
307
|
-
maxLength: maxLen
|
|
308
|
-
};
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
return {
|
|
313
|
-
displayErrors: display,
|
|
314
|
-
errorParams
|
|
315
|
-
};
|
|
316
|
-
}
|
|
317
|
-
function processEkybFieldValue(name, value, country) {
|
|
318
|
-
if (name === "postalCode") return formatPostalCode(value, country);
|
|
319
|
-
return value;
|
|
320
|
-
}
|
|
321
|
-
function buildEkybSubmitPayload(ctx) {
|
|
322
|
-
const uboNames = ctx.ubos.filter((u) => u.name.trim() || u.surname.trim()).map((u) => `${u.name.trim()} ${u.surname.trim()}`.trim());
|
|
323
|
-
const payload = {
|
|
324
|
-
country: ctx.country,
|
|
325
|
-
plugins: ["ekyb"],
|
|
326
|
-
uboNames
|
|
327
|
-
};
|
|
328
|
-
for (const field of ctx.fields) {
|
|
329
|
-
const val = ctx.values[field.name];
|
|
330
|
-
if (val !== void 0 && val !== "") payload[field.name] = val;
|
|
331
|
-
}
|
|
332
|
-
return payload;
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
//#endregion
|
|
336
|
-
//#region src/modules/ekyb/ekybGuards.ts
|
|
337
|
-
const hasFlowIdGuard = ({ context }) => !!context.config.flowId;
|
|
338
|
-
const isValidGuard = ({ context }) => context.isValid;
|
|
339
|
-
const canAddUboGuard = ({ context }) => context.canAddUbo;
|
|
340
|
-
const isValidUboIndexGuard = ({ context, event }) => {
|
|
341
|
-
const { index } = event;
|
|
342
|
-
return Number.isInteger(index) && index >= 0 && index < context.ubos.length;
|
|
343
|
-
};
|
|
344
|
-
const isSupportedCountryGuard = ({ event }) => {
|
|
345
|
-
const { country } = event;
|
|
346
|
-
return isSupportedCountry(country);
|
|
347
|
-
};
|
|
348
|
-
|
|
349
|
-
//#endregion
|
|
350
|
-
//#region src/modules/ekyb/ekybServices.ts
|
|
351
|
-
/** Fetches the onboarding flow and extracts the EKYB module configuration */
|
|
352
|
-
async function fetchEkybModuleConfig(signal) {
|
|
353
|
-
const ekybModule = (await getFlow(signal)).flowModules.find((m) => m.key === "EKYB");
|
|
354
|
-
if (!ekybModule) throw new Error("EKYB module not found in flow configuration");
|
|
355
|
-
return ekybModule.configuration;
|
|
356
|
-
}
|
|
357
|
-
/** Submits eKYB business verification */
|
|
358
|
-
async function submitEkyb(data, signal) {
|
|
359
|
-
const res = await api.post(endpoints.ekybSubmit, data, { signal });
|
|
360
|
-
if (!res.ok) throw new Error(`POST ${endpoints.ekybSubmit} failed: ${res.status} ${res.statusText}`);
|
|
361
|
-
return res.data;
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
//#endregion
|
|
365
|
-
//#region src/modules/ekyb/ekybActors.ts
|
|
366
|
-
const fetchEkybModuleConfigActor = fromPromise(async ({ signal }) => fetchEkybModuleConfig(signal));
|
|
367
|
-
const submitEkybActor = fromPromise(async ({ input, signal }) => submitEkyb(input, signal));
|
|
368
|
-
|
|
369
|
-
//#endregion
|
|
370
|
-
//#region src/modules/ekyb/ekybStateMachine.ts
|
|
371
|
-
const ekybMachine = setup({
|
|
372
|
-
types: {
|
|
373
|
-
context: {},
|
|
374
|
-
events: {},
|
|
375
|
-
input: {}
|
|
376
|
-
},
|
|
377
|
-
actors: {
|
|
378
|
-
fetchEkybModuleConfig: fetchEkybModuleConfigActor,
|
|
379
|
-
submitEkyb: submitEkybActor,
|
|
380
|
-
debounceSearch: debounceSearchActor
|
|
381
|
-
},
|
|
382
|
-
actions: {
|
|
383
|
-
applyFetchedConfig: assign(({ event }) => {
|
|
384
|
-
const fetched = event.output;
|
|
385
|
-
const config = {
|
|
386
|
-
checkBusinessName: fetched.checkBusinessName,
|
|
387
|
-
checkAddress: fetched.checkAddress,
|
|
388
|
-
checkTaxId: fetched.checkTaxId,
|
|
389
|
-
checkUniqueBeneficialOwner: fetched.checkUniqueBeneficialOwner
|
|
390
|
-
};
|
|
391
|
-
const country = "US";
|
|
392
|
-
const vFields = getDefaultVerificationFields(config);
|
|
393
|
-
const hasUbos = config.checkUniqueBeneficialOwner !== false && vFields.includes("ubos-user_input");
|
|
394
|
-
const fields = buildEkybFields(vFields, country, hasUbos);
|
|
395
|
-
const values = { country };
|
|
396
|
-
const ubos = hasUbos ? [{
|
|
397
|
-
id: "ubo-1",
|
|
398
|
-
name: "",
|
|
399
|
-
surname: ""
|
|
400
|
-
}] : [];
|
|
401
|
-
const { errors, isValid } = computeEkybValidation(fields, values, country, ubos, hasUbos);
|
|
402
|
-
return {
|
|
403
|
-
config,
|
|
404
|
-
country,
|
|
405
|
-
availableCountries: ALL_COUNTRIES,
|
|
406
|
-
fields,
|
|
407
|
-
values,
|
|
408
|
-
errors,
|
|
409
|
-
isValid,
|
|
410
|
-
ubos,
|
|
411
|
-
canAddUbo: hasUbos,
|
|
412
|
-
hasUbos,
|
|
413
|
-
submitAttempted: false,
|
|
414
|
-
addressSuggestions: [],
|
|
415
|
-
_nextUboId: 2,
|
|
416
|
-
_searchQuery: ""
|
|
417
|
-
};
|
|
418
|
-
}),
|
|
419
|
-
setCountry: assign(({ context, event }) => {
|
|
420
|
-
const { country } = event;
|
|
421
|
-
const vFields = getDefaultVerificationFields(context.config);
|
|
422
|
-
const hasUbos = context.config.checkUniqueBeneficialOwner !== false && vFields.includes("ubos-user_input") && country !== "MX";
|
|
423
|
-
const fields = buildEkybFields(vFields, country, hasUbos);
|
|
424
|
-
let nextId = context._nextUboId;
|
|
425
|
-
let ubos;
|
|
426
|
-
if (hasUbos) if (context.ubos.length > 0) ubos = context.ubos;
|
|
427
|
-
else {
|
|
428
|
-
ubos = [{
|
|
429
|
-
id: `ubo-${nextId}`,
|
|
430
|
-
name: "",
|
|
431
|
-
surname: ""
|
|
432
|
-
}];
|
|
433
|
-
nextId += 1;
|
|
434
|
-
}
|
|
435
|
-
else ubos = [];
|
|
436
|
-
const newValues = {
|
|
437
|
-
...context.values,
|
|
438
|
-
country,
|
|
439
|
-
state: ""
|
|
440
|
-
};
|
|
441
|
-
const { errors, isValid } = computeEkybValidation(fields, newValues, country, ubos, hasUbos);
|
|
442
|
-
return {
|
|
443
|
-
country,
|
|
444
|
-
fields,
|
|
445
|
-
values: newValues,
|
|
446
|
-
errors,
|
|
447
|
-
isValid,
|
|
448
|
-
ubos,
|
|
449
|
-
canAddUbo: hasUbos && ubos.length < UBO_INPUT_LIMIT,
|
|
450
|
-
hasUbos,
|
|
451
|
-
_nextUboId: nextId
|
|
452
|
-
};
|
|
453
|
-
}),
|
|
454
|
-
updateField: assign(({ context, event }) => {
|
|
455
|
-
const { name, value } = event;
|
|
456
|
-
const processed = processEkybFieldValue(name, value, context.country);
|
|
457
|
-
const newValues = {
|
|
458
|
-
...context.values,
|
|
459
|
-
[name]: processed
|
|
460
|
-
};
|
|
461
|
-
const { errors, isValid } = computeEkybValidation(context.fields, newValues, context.country, context.ubos, context.hasUbos);
|
|
462
|
-
return {
|
|
463
|
-
values: newValues,
|
|
464
|
-
errors,
|
|
465
|
-
isValid
|
|
466
|
-
};
|
|
467
|
-
}),
|
|
468
|
-
addUbo: assign(({ context }) => {
|
|
469
|
-
const newId = context._nextUboId;
|
|
470
|
-
const ubos = [...context.ubos, {
|
|
471
|
-
id: `ubo-${newId}`,
|
|
472
|
-
name: "",
|
|
473
|
-
surname: ""
|
|
474
|
-
}];
|
|
475
|
-
const canAddUbo = ubos.length < UBO_INPUT_LIMIT;
|
|
476
|
-
const { errors, isValid } = computeEkybValidation(context.fields, context.values, context.country, ubos, context.hasUbos);
|
|
477
|
-
return {
|
|
478
|
-
ubos,
|
|
479
|
-
canAddUbo,
|
|
480
|
-
errors,
|
|
481
|
-
isValid,
|
|
482
|
-
_nextUboId: newId + 1
|
|
483
|
-
};
|
|
484
|
-
}),
|
|
485
|
-
removeUbo: assign(({ context, event }) => {
|
|
486
|
-
const { index } = event;
|
|
487
|
-
const ubos = context.ubos.filter((_, i) => i !== index);
|
|
488
|
-
const canAddUbo = ubos.length < UBO_INPUT_LIMIT;
|
|
489
|
-
const { errors, isValid } = computeEkybValidation(context.fields, context.values, context.country, ubos, context.hasUbos);
|
|
490
|
-
return {
|
|
491
|
-
ubos,
|
|
492
|
-
canAddUbo,
|
|
493
|
-
errors,
|
|
494
|
-
isValid
|
|
495
|
-
};
|
|
496
|
-
}),
|
|
497
|
-
setUboField: assign(({ context, event }) => {
|
|
498
|
-
const { index, field, value } = event;
|
|
499
|
-
const ubos = context.ubos.map((ubo, i) => i === index ? {
|
|
500
|
-
...ubo,
|
|
501
|
-
[field]: value
|
|
502
|
-
} : ubo);
|
|
503
|
-
const { errors, isValid } = computeEkybValidation(context.fields, context.values, context.country, ubos, context.hasUbos);
|
|
504
|
-
return {
|
|
505
|
-
ubos,
|
|
506
|
-
errors,
|
|
507
|
-
isValid
|
|
508
|
-
};
|
|
509
|
-
}),
|
|
510
|
-
setErrorMessage: assign(({ event }) => ({ errorMessage: String(event.error ?? "verification.error") })),
|
|
511
|
-
clearErrorMessage: assign({ errorMessage: () => "" }),
|
|
512
|
-
markSubmitAttempted: assign({ submitAttempted: () => true }),
|
|
513
|
-
fillAddressFields: assign(({ context, event }) => {
|
|
514
|
-
const { suggestion } = event;
|
|
515
|
-
const activeFields = new Set(context.fields.map((f) => f.name));
|
|
516
|
-
const { values: newValues } = fillFromSuggestion(context.values, {}, suggestion, activeFields);
|
|
517
|
-
const { errors, isValid } = computeEkybValidation(context.fields, newValues, context.country, context.ubos, context.hasUbos);
|
|
518
|
-
return {
|
|
519
|
-
values: newValues,
|
|
520
|
-
addressSuggestions: [],
|
|
521
|
-
errors,
|
|
522
|
-
isValid
|
|
523
|
-
};
|
|
524
|
-
}),
|
|
525
|
-
setAddressSuggestions: assign(({ event }) => ({ addressSuggestions: event.suggestions }))
|
|
526
|
-
},
|
|
527
|
-
guards: {
|
|
528
|
-
hasFlowId: hasFlowIdGuard,
|
|
529
|
-
isValid: isValidGuard,
|
|
530
|
-
canAddUbo: canAddUboGuard,
|
|
531
|
-
isValidUboIndex: isValidUboIndexGuard,
|
|
532
|
-
isSupportedCountry: isSupportedCountryGuard
|
|
533
|
-
}
|
|
534
|
-
}).createMachine({
|
|
535
|
-
id: "ekyb",
|
|
536
|
-
initial: "idle",
|
|
537
|
-
context: ({ input }) => {
|
|
538
|
-
const country = "US";
|
|
539
|
-
const vFields = getDefaultVerificationFields(input.config);
|
|
540
|
-
const hasUbos = input.config.checkUniqueBeneficialOwner !== false && vFields.includes("ubos-user_input");
|
|
541
|
-
const fields = buildEkybFields(vFields, country, hasUbos);
|
|
542
|
-
const values = { country };
|
|
543
|
-
const ubos = hasUbos ? [{
|
|
544
|
-
id: "ubo-1",
|
|
545
|
-
name: "",
|
|
546
|
-
surname: ""
|
|
547
|
-
}] : [];
|
|
548
|
-
const { errors, isValid } = computeEkybValidation(fields, values, country, ubos, hasUbos);
|
|
549
|
-
return {
|
|
550
|
-
config: input.config,
|
|
551
|
-
country,
|
|
552
|
-
availableCountries: ALL_COUNTRIES,
|
|
553
|
-
fields,
|
|
554
|
-
values,
|
|
555
|
-
errors,
|
|
556
|
-
isValid,
|
|
557
|
-
ubos,
|
|
558
|
-
canAddUbo: hasUbos,
|
|
559
|
-
hasUbos,
|
|
560
|
-
errorMessage: "",
|
|
561
|
-
submitAttempted: false,
|
|
562
|
-
addressSuggestions: [],
|
|
563
|
-
_nextUboId: 2,
|
|
564
|
-
_searchQuery: ""
|
|
565
|
-
};
|
|
566
|
-
},
|
|
567
|
-
states: {
|
|
568
|
-
idle: { on: { LOAD: [{
|
|
569
|
-
target: "loading",
|
|
570
|
-
guard: "hasFlowId"
|
|
571
|
-
}, { target: "form" }] } },
|
|
572
|
-
loading: { invoke: {
|
|
573
|
-
id: "fetchEkybModuleConfig",
|
|
574
|
-
src: "fetchEkybModuleConfig",
|
|
575
|
-
onDone: {
|
|
576
|
-
target: "form",
|
|
577
|
-
actions: "applyFetchedConfig"
|
|
578
|
-
},
|
|
579
|
-
onError: "form"
|
|
580
|
-
} },
|
|
581
|
-
form: {
|
|
582
|
-
initial: "idle",
|
|
583
|
-
states: {
|
|
584
|
-
idle: {},
|
|
585
|
-
searching: {
|
|
586
|
-
invoke: {
|
|
587
|
-
id: "debounceSearch",
|
|
588
|
-
src: "debounceSearch",
|
|
589
|
-
input: ({ context }) => ({ query: context._searchQuery })
|
|
590
|
-
},
|
|
591
|
-
on: { RESULTS: {
|
|
592
|
-
target: "idle",
|
|
593
|
-
actions: "setAddressSuggestions"
|
|
594
|
-
} }
|
|
595
|
-
}
|
|
596
|
-
},
|
|
597
|
-
on: {
|
|
598
|
-
SET_COUNTRY: {
|
|
599
|
-
guard: "isSupportedCountry",
|
|
600
|
-
actions: "setCountry"
|
|
601
|
-
},
|
|
602
|
-
SET_FIELD: { actions: "updateField" },
|
|
603
|
-
SEARCH_ADDRESS: {
|
|
604
|
-
target: ".searching",
|
|
605
|
-
actions: assign(({ event }) => ({
|
|
606
|
-
_searchQuery: event.query,
|
|
607
|
-
addressSuggestions: []
|
|
608
|
-
}))
|
|
609
|
-
},
|
|
610
|
-
SELECT_ADDRESS: {
|
|
611
|
-
target: ".idle",
|
|
612
|
-
actions: "fillAddressFields"
|
|
613
|
-
},
|
|
614
|
-
ADD_UBO: {
|
|
615
|
-
guard: "canAddUbo",
|
|
616
|
-
actions: "addUbo"
|
|
617
|
-
},
|
|
618
|
-
REMOVE_UBO: {
|
|
619
|
-
guard: "isValidUboIndex",
|
|
620
|
-
actions: "removeUbo"
|
|
621
|
-
},
|
|
622
|
-
SET_UBO_FIELD: {
|
|
623
|
-
guard: "isValidUboIndex",
|
|
624
|
-
actions: "setUboField"
|
|
625
|
-
},
|
|
626
|
-
SUBMIT: [{
|
|
627
|
-
target: "submitting",
|
|
628
|
-
guard: "isValid"
|
|
629
|
-
}, { actions: "markSubmitAttempted" }],
|
|
630
|
-
CLOSE: { target: "closed" }
|
|
631
|
-
}
|
|
632
|
-
},
|
|
633
|
-
submitting: { invoke: {
|
|
634
|
-
id: "submitEkyb",
|
|
635
|
-
src: "submitEkyb",
|
|
636
|
-
input: ({ context }) => buildEkybSubmitPayload(context),
|
|
637
|
-
onDone: { target: "success" },
|
|
638
|
-
onError: {
|
|
639
|
-
target: "error",
|
|
640
|
-
actions: "setErrorMessage"
|
|
641
|
-
}
|
|
642
|
-
} },
|
|
643
|
-
success: { after: { 3e3: "finished" } },
|
|
644
|
-
error: { on: {
|
|
645
|
-
RETRY: {
|
|
646
|
-
target: "form",
|
|
647
|
-
actions: "clearErrorMessage"
|
|
648
|
-
},
|
|
649
|
-
CLOSE: { target: "closed" }
|
|
650
|
-
} },
|
|
651
|
-
finished: { type: "final" },
|
|
652
|
-
closed: { type: "final" }
|
|
653
|
-
}
|
|
654
|
-
});
|
|
655
|
-
|
|
656
|
-
//#endregion
|
|
657
12
|
//#region src/modules/ekyb/ekybActor.ts
|
|
658
13
|
/**
|
|
659
14
|
* Creates and starts an eKYB actor.
|