@mantle-rwa/sdk 0.1.0
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/cjs/client.js +198 -0
- package/dist/cjs/client.js.map +1 -0
- package/dist/cjs/constants/index.js +211 -0
- package/dist/cjs/constants/index.js.map +1 -0
- package/dist/cjs/errors/index.js +218 -0
- package/dist/cjs/errors/index.js.map +1 -0
- package/dist/cjs/index.js +51 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/modules/compliance.js +202 -0
- package/dist/cjs/modules/compliance.js.map +1 -0
- package/dist/cjs/modules/index.js +18 -0
- package/dist/cjs/modules/index.js.map +1 -0
- package/dist/cjs/modules/kyc.js +278 -0
- package/dist/cjs/modules/kyc.js.map +1 -0
- package/dist/cjs/modules/token.js +365 -0
- package/dist/cjs/modules/token.js.map +1 -0
- package/dist/cjs/modules/yield.js +406 -0
- package/dist/cjs/modules/yield.js.map +1 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/types/index.js +20 -0
- package/dist/cjs/types/index.js.map +1 -0
- package/dist/cjs/utils/index.js +206 -0
- package/dist/cjs/utils/index.js.map +1 -0
- package/dist/esm/client.js +194 -0
- package/dist/esm/client.js.map +1 -0
- package/dist/esm/constants/index.js +208 -0
- package/dist/esm/constants/index.js.map +1 -0
- package/dist/esm/errors/index.js +209 -0
- package/dist/esm/errors/index.js.map +1 -0
- package/dist/esm/index.js +17 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/modules/compliance.js +198 -0
- package/dist/esm/modules/compliance.js.map +1 -0
- package/dist/esm/modules/index.js +8 -0
- package/dist/esm/modules/index.js.map +1 -0
- package/dist/esm/modules/kyc.js +273 -0
- package/dist/esm/modules/kyc.js.map +1 -0
- package/dist/esm/modules/token.js +360 -0
- package/dist/esm/modules/token.js.map +1 -0
- package/dist/esm/modules/yield.js +401 -0
- package/dist/esm/modules/yield.js.map +1 -0
- package/dist/esm/types/index.js +17 -0
- package/dist/esm/types/index.js.map +1 -0
- package/dist/esm/utils/index.js +188 -0
- package/dist/esm/utils/index.js.map +1 -0
- package/dist/types/client.d.ts +93 -0
- package/dist/types/client.d.ts.map +1 -0
- package/dist/types/constants/index.d.ts +83 -0
- package/dist/types/constants/index.d.ts.map +1 -0
- package/dist/types/errors/index.d.ts +83 -0
- package/dist/types/errors/index.d.ts.map +1 -0
- package/dist/types/index.d.ts +13 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/modules/compliance.d.ts +29 -0
- package/dist/types/modules/compliance.d.ts.map +1 -0
- package/dist/types/modules/index.d.ts +8 -0
- package/dist/types/modules/index.d.ts.map +1 -0
- package/dist/types/modules/kyc.d.ts +131 -0
- package/dist/types/modules/kyc.d.ts.map +1 -0
- package/dist/types/modules/token.d.ts +145 -0
- package/dist/types/modules/token.d.ts.map +1 -0
- package/dist/types/modules/yield.d.ts +143 -0
- package/dist/types/modules/yield.d.ts.map +1 -0
- package/dist/types/types/index.d.ts +254 -0
- package/dist/types/types/index.d.ts.map +1 -0
- package/dist/types/utils/index.d.ts +80 -0
- package/dist/types/utils/index.d.ts.map +1 -0
- package/package.json +52 -0
- package/src/client.ts +258 -0
- package/src/constants/index.ts +226 -0
- package/src/errors/index.ts +291 -0
- package/src/index.ts +42 -0
- package/src/modules/compliance.ts +252 -0
- package/src/modules/index.ts +8 -0
- package/src/modules/kyc.ts +446 -0
- package/src/modules/token.ts +488 -0
- package/src/modules/yield.ts +566 -0
- package/src/types/index.ts +326 -0
- package/src/utils/index.ts +240 -0
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KYCModule - Handles KYC registry interactions and provider integrations
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { ethers, type Provider, type Signer } from 'ethers';
|
|
6
|
+
import type {
|
|
7
|
+
InvestorData,
|
|
8
|
+
VerificationSession,
|
|
9
|
+
VerificationResult,
|
|
10
|
+
TransactionResult,
|
|
11
|
+
TransactionOptions,
|
|
12
|
+
AccreditationTier,
|
|
13
|
+
} from '../types';
|
|
14
|
+
import { KYC_REGISTRY_ABI } from '../constants';
|
|
15
|
+
import { RWAError, ErrorCode, parseContractError } from '../errors';
|
|
16
|
+
import {
|
|
17
|
+
isValidAddress,
|
|
18
|
+
normalizeAddress,
|
|
19
|
+
parseEvents,
|
|
20
|
+
createTransactionResult,
|
|
21
|
+
retry,
|
|
22
|
+
estimateGasWithBuffer,
|
|
23
|
+
timestampToDate,
|
|
24
|
+
dateToTimestamp,
|
|
25
|
+
hashIdentityData,
|
|
26
|
+
} from '../utils';
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Interface for KYC providers
|
|
31
|
+
*/
|
|
32
|
+
export interface KYCProvider {
|
|
33
|
+
/** Provider name */
|
|
34
|
+
name: string;
|
|
35
|
+
/** Initiate verification for an investor */
|
|
36
|
+
initiateVerification(investorAddress: string, options?: unknown): Promise<VerificationSession>;
|
|
37
|
+
/** Check verification status */
|
|
38
|
+
checkStatus(sessionId: string): Promise<'pending' | 'in_progress' | 'completed' | 'failed'>;
|
|
39
|
+
/** Get verification result */
|
|
40
|
+
getVerificationResult(sessionId: string): Promise<VerificationResult>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Instance of a connected KYC registry
|
|
45
|
+
*/
|
|
46
|
+
export class KYCRegistryInstance {
|
|
47
|
+
private readonly _contract: ethers.Contract;
|
|
48
|
+
private readonly _retries: number;
|
|
49
|
+
private readonly _retryDelay: number;
|
|
50
|
+
|
|
51
|
+
/** Registry contract address */
|
|
52
|
+
readonly address: string;
|
|
53
|
+
|
|
54
|
+
constructor(
|
|
55
|
+
address: string,
|
|
56
|
+
provider: Provider,
|
|
57
|
+
signer: Signer | null,
|
|
58
|
+
retries: number,
|
|
59
|
+
retryDelay: number
|
|
60
|
+
) {
|
|
61
|
+
this.address = normalizeAddress(address);
|
|
62
|
+
this._retries = retries;
|
|
63
|
+
this._retryDelay = retryDelay;
|
|
64
|
+
|
|
65
|
+
this._contract = new ethers.Contract(
|
|
66
|
+
this.address,
|
|
67
|
+
KYC_REGISTRY_ABI,
|
|
68
|
+
signer || provider
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/*//////////////////////////////////////////////////////////////
|
|
73
|
+
READ FUNCTIONS
|
|
74
|
+
//////////////////////////////////////////////////////////////*/
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Check if an investor is verified
|
|
78
|
+
*/
|
|
79
|
+
async isVerified(investor: string): Promise<boolean> {
|
|
80
|
+
return this._contract.isVerified(normalizeAddress(investor));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Check if an investor is accredited
|
|
85
|
+
*/
|
|
86
|
+
async isAccredited(investor: string): Promise<boolean> {
|
|
87
|
+
return this._contract.isAccredited(normalizeAddress(investor));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Get investor information
|
|
92
|
+
*/
|
|
93
|
+
async getInvestorInfo(investor: string): Promise<InvestorData> {
|
|
94
|
+
const [verified, tier, expiry, identityHash] = await this._contract.getInvestorInfo(
|
|
95
|
+
normalizeAddress(investor)
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
return {
|
|
99
|
+
verified,
|
|
100
|
+
tier: tier as AccreditationTier,
|
|
101
|
+
expiry: timestampToDate(expiry),
|
|
102
|
+
identityHash,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/*//////////////////////////////////////////////////////////////
|
|
107
|
+
WRITE FUNCTIONS
|
|
108
|
+
//////////////////////////////////////////////////////////////*/
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Add an investor to the registry
|
|
112
|
+
*/
|
|
113
|
+
async addInvestor(
|
|
114
|
+
investor: string,
|
|
115
|
+
tier: AccreditationTier,
|
|
116
|
+
expiryDate: Date,
|
|
117
|
+
identityHash: string,
|
|
118
|
+
options?: TransactionOptions
|
|
119
|
+
): Promise<TransactionResult> {
|
|
120
|
+
const investorAddress = normalizeAddress(investor);
|
|
121
|
+
const expiryTimestamp = dateToTimestamp(expiryDate);
|
|
122
|
+
|
|
123
|
+
try {
|
|
124
|
+
const tx = await retry(
|
|
125
|
+
async () => {
|
|
126
|
+
const gasLimit = options?.gasLimit || await estimateGasWithBuffer(
|
|
127
|
+
() => this._contract.addInvestor.estimateGas(
|
|
128
|
+
investorAddress,
|
|
129
|
+
tier,
|
|
130
|
+
expiryTimestamp,
|
|
131
|
+
identityHash
|
|
132
|
+
)
|
|
133
|
+
);
|
|
134
|
+
return this._contract.addInvestor(
|
|
135
|
+
investorAddress,
|
|
136
|
+
tier,
|
|
137
|
+
expiryTimestamp,
|
|
138
|
+
identityHash,
|
|
139
|
+
{ gasLimit }
|
|
140
|
+
);
|
|
141
|
+
},
|
|
142
|
+
{ retries: options?.retries ?? this._retries, delay: options?.retryDelay ?? this._retryDelay }
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
const receipt = await tx.wait();
|
|
146
|
+
const events = parseEvents(receipt, this._contract.interface);
|
|
147
|
+
return createTransactionResult(receipt, events);
|
|
148
|
+
} catch (error) {
|
|
149
|
+
throw parseContractError(error, this.address, 'addInvestor');
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Update an investor's information
|
|
155
|
+
*/
|
|
156
|
+
async updateInvestor(
|
|
157
|
+
investor: string,
|
|
158
|
+
tier: AccreditationTier,
|
|
159
|
+
expiryDate: Date,
|
|
160
|
+
options?: TransactionOptions
|
|
161
|
+
): Promise<TransactionResult> {
|
|
162
|
+
const investorAddress = normalizeAddress(investor);
|
|
163
|
+
const expiryTimestamp = dateToTimestamp(expiryDate);
|
|
164
|
+
|
|
165
|
+
try {
|
|
166
|
+
const tx = await retry(
|
|
167
|
+
async () => {
|
|
168
|
+
const gasLimit = options?.gasLimit || await estimateGasWithBuffer(
|
|
169
|
+
() => this._contract.updateInvestor.estimateGas(
|
|
170
|
+
investorAddress,
|
|
171
|
+
tier,
|
|
172
|
+
expiryTimestamp
|
|
173
|
+
)
|
|
174
|
+
);
|
|
175
|
+
return this._contract.updateInvestor(
|
|
176
|
+
investorAddress,
|
|
177
|
+
tier,
|
|
178
|
+
expiryTimestamp,
|
|
179
|
+
{ gasLimit }
|
|
180
|
+
);
|
|
181
|
+
},
|
|
182
|
+
{ retries: options?.retries ?? this._retries, delay: options?.retryDelay ?? this._retryDelay }
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
const receipt = await tx.wait();
|
|
186
|
+
const events = parseEvents(receipt, this._contract.interface);
|
|
187
|
+
return createTransactionResult(receipt, events);
|
|
188
|
+
} catch (error) {
|
|
189
|
+
throw parseContractError(error, this.address, 'updateInvestor');
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Remove an investor from the registry
|
|
195
|
+
*/
|
|
196
|
+
async removeInvestor(investor: string, options?: TransactionOptions): Promise<TransactionResult> {
|
|
197
|
+
const investorAddress = normalizeAddress(investor);
|
|
198
|
+
|
|
199
|
+
try {
|
|
200
|
+
const tx = await retry(
|
|
201
|
+
async () => {
|
|
202
|
+
const gasLimit = options?.gasLimit || await estimateGasWithBuffer(
|
|
203
|
+
() => this._contract.removeInvestor.estimateGas(investorAddress)
|
|
204
|
+
);
|
|
205
|
+
return this._contract.removeInvestor(investorAddress, { gasLimit });
|
|
206
|
+
},
|
|
207
|
+
{ retries: options?.retries ?? this._retries, delay: options?.retryDelay ?? this._retryDelay }
|
|
208
|
+
);
|
|
209
|
+
|
|
210
|
+
const receipt = await tx.wait();
|
|
211
|
+
const events = parseEvents(receipt, this._contract.interface);
|
|
212
|
+
return createTransactionResult(receipt, events);
|
|
213
|
+
} catch (error) {
|
|
214
|
+
throw parseContractError(error, this.address, 'removeInvestor');
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Batch add investors
|
|
220
|
+
*/
|
|
221
|
+
async batchAddInvestors(
|
|
222
|
+
investors: Array<{
|
|
223
|
+
address: string;
|
|
224
|
+
tier: AccreditationTier;
|
|
225
|
+
expiryDate: Date;
|
|
226
|
+
identityHash: string;
|
|
227
|
+
}>,
|
|
228
|
+
options?: TransactionOptions
|
|
229
|
+
): Promise<TransactionResult> {
|
|
230
|
+
const addresses = investors.map((i) => normalizeAddress(i.address));
|
|
231
|
+
const tiers = investors.map((i) => i.tier);
|
|
232
|
+
const expiries = investors.map((i) => dateToTimestamp(i.expiryDate));
|
|
233
|
+
const hashes = investors.map((i) => i.identityHash);
|
|
234
|
+
|
|
235
|
+
try {
|
|
236
|
+
const tx = await retry(
|
|
237
|
+
async () => {
|
|
238
|
+
const gasLimit = options?.gasLimit || await estimateGasWithBuffer(
|
|
239
|
+
() => this._contract.batchAddInvestors.estimateGas(addresses, tiers, expiries, hashes)
|
|
240
|
+
);
|
|
241
|
+
return this._contract.batchAddInvestors(addresses, tiers, expiries, hashes, { gasLimit });
|
|
242
|
+
},
|
|
243
|
+
{ retries: options?.retries ?? this._retries, delay: options?.retryDelay ?? this._retryDelay }
|
|
244
|
+
);
|
|
245
|
+
|
|
246
|
+
const receipt = await tx.wait();
|
|
247
|
+
const events = parseEvents(receipt, this._contract.interface);
|
|
248
|
+
return createTransactionResult(receipt, events);
|
|
249
|
+
} catch (error) {
|
|
250
|
+
throw parseContractError(error, this.address, 'batchAddInvestors');
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/*//////////////////////////////////////////////////////////////
|
|
255
|
+
EVENT LISTENERS
|
|
256
|
+
//////////////////////////////////////////////////////////////*/
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Listen for InvestorVerified events
|
|
260
|
+
*/
|
|
261
|
+
onInvestorVerified(
|
|
262
|
+
callback: (investor: string, tier: AccreditationTier, expiry: bigint) => void
|
|
263
|
+
): () => void {
|
|
264
|
+
const listener = (investor: string, tier: number, expiry: bigint) => {
|
|
265
|
+
callback(investor, tier as AccreditationTier, expiry);
|
|
266
|
+
};
|
|
267
|
+
this._contract.on('InvestorVerified', listener);
|
|
268
|
+
return () => this._contract.off('InvestorVerified', listener);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Listen for InvestorRemoved events
|
|
273
|
+
*/
|
|
274
|
+
onInvestorRemoved(callback: (investor: string) => void): () => void {
|
|
275
|
+
const listener = (investor: string) => callback(investor);
|
|
276
|
+
this._contract.on('InvestorRemoved', listener);
|
|
277
|
+
return () => this._contract.off('InvestorRemoved', listener);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Listen for InvestorUpdated events
|
|
282
|
+
*/
|
|
283
|
+
onInvestorUpdated(
|
|
284
|
+
callback: (investor: string, newTier: AccreditationTier, newExpiry: bigint) => void
|
|
285
|
+
): () => void {
|
|
286
|
+
const listener = (investor: string, newTier: number, newExpiry: bigint) => {
|
|
287
|
+
callback(investor, newTier as AccreditationTier, newExpiry);
|
|
288
|
+
};
|
|
289
|
+
this._contract.on('InvestorUpdated', listener);
|
|
290
|
+
return () => this._contract.off('InvestorUpdated', listener);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Module for KYC operations
|
|
296
|
+
*/
|
|
297
|
+
export class KYCModule {
|
|
298
|
+
private readonly _provider: Provider;
|
|
299
|
+
private readonly _signer: Signer | null;
|
|
300
|
+
private readonly _retries: number;
|
|
301
|
+
private readonly _retryDelay: number;
|
|
302
|
+
private _kycProvider: KYCProvider | null = null;
|
|
303
|
+
|
|
304
|
+
constructor(provider: Provider, signer: Signer | null, retries: number, retryDelay: number) {
|
|
305
|
+
this._provider = provider;
|
|
306
|
+
this._signer = signer;
|
|
307
|
+
this._retries = retries;
|
|
308
|
+
this._retryDelay = retryDelay;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Connect to an existing KYC registry
|
|
313
|
+
*/
|
|
314
|
+
connect(address: string): KYCRegistryInstance {
|
|
315
|
+
if (!isValidAddress(address)) {
|
|
316
|
+
throw new RWAError(ErrorCode.INVALID_ADDRESS, `Invalid registry address: ${address}`);
|
|
317
|
+
}
|
|
318
|
+
return new KYCRegistryInstance(
|
|
319
|
+
address,
|
|
320
|
+
this._provider,
|
|
321
|
+
this._signer,
|
|
322
|
+
this._retries,
|
|
323
|
+
this._retryDelay
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Set the KYC provider
|
|
329
|
+
*/
|
|
330
|
+
setProvider(provider: 'persona' | 'synaps' | 'jumio' | KYCProvider): void {
|
|
331
|
+
if (typeof provider === 'string') {
|
|
332
|
+
// Create stub provider for built-in providers
|
|
333
|
+
this._kycProvider = this._createBuiltInProvider(provider);
|
|
334
|
+
} else {
|
|
335
|
+
this._kycProvider = provider;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Get the current KYC provider
|
|
341
|
+
*/
|
|
342
|
+
get provider(): KYCProvider | null {
|
|
343
|
+
return this._kycProvider;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Initiate verification for an investor
|
|
348
|
+
*/
|
|
349
|
+
async verifyInvestor(investorAddress: string, options?: unknown): Promise<VerificationSession> {
|
|
350
|
+
if (!this._kycProvider) {
|
|
351
|
+
throw new RWAError(
|
|
352
|
+
ErrorCode.PROVIDER_NOT_CONFIGURED,
|
|
353
|
+
'KYC provider not configured. Call setProvider() first.'
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
return this._kycProvider.initiateVerification(investorAddress, options);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Check accreditation status
|
|
361
|
+
*/
|
|
362
|
+
async checkAccreditation(
|
|
363
|
+
registryAddress: string,
|
|
364
|
+
investorAddress: string
|
|
365
|
+
): Promise<AccreditationTier> {
|
|
366
|
+
const registry = this.connect(registryAddress);
|
|
367
|
+
const info = await registry.getInvestorInfo(investorAddress);
|
|
368
|
+
return info.tier;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Update registry with verification result
|
|
373
|
+
*/
|
|
374
|
+
async updateRegistry(
|
|
375
|
+
registryAddress: string,
|
|
376
|
+
investorAddress: string,
|
|
377
|
+
result: VerificationResult
|
|
378
|
+
): Promise<TransactionResult> {
|
|
379
|
+
const registry = this.connect(registryAddress);
|
|
380
|
+
return registry.addInvestor(
|
|
381
|
+
investorAddress,
|
|
382
|
+
result.tier,
|
|
383
|
+
result.expiryDate,
|
|
384
|
+
result.identityHash
|
|
385
|
+
);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Batch update registry with multiple verification results
|
|
390
|
+
*/
|
|
391
|
+
async batchUpdateRegistry(
|
|
392
|
+
registryAddress: string,
|
|
393
|
+
results: Array<{ address: string; result: VerificationResult }>
|
|
394
|
+
): Promise<TransactionResult> {
|
|
395
|
+
const registry = this.connect(registryAddress);
|
|
396
|
+
const investors = results.map((r) => ({
|
|
397
|
+
address: r.address,
|
|
398
|
+
tier: r.result.tier,
|
|
399
|
+
expiryDate: r.result.expiryDate,
|
|
400
|
+
identityHash: r.result.identityHash,
|
|
401
|
+
}));
|
|
402
|
+
return registry.batchAddInvestors(investors);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Generate identity hash from data
|
|
407
|
+
*/
|
|
408
|
+
generateIdentityHash(data: {
|
|
409
|
+
firstName?: string;
|
|
410
|
+
lastName?: string;
|
|
411
|
+
dateOfBirth?: string;
|
|
412
|
+
documentNumber?: string;
|
|
413
|
+
country?: string;
|
|
414
|
+
}): string {
|
|
415
|
+
return hashIdentityData(data);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* Create a built-in provider stub
|
|
420
|
+
*/
|
|
421
|
+
private _createBuiltInProvider(name: 'persona' | 'synaps' | 'jumio'): KYCProvider {
|
|
422
|
+
return {
|
|
423
|
+
name,
|
|
424
|
+
initiateVerification: async (investorAddress: string) => {
|
|
425
|
+
// Stub implementation - in production, this would call the actual provider API
|
|
426
|
+
return {
|
|
427
|
+
sessionId: `${name}-${Date.now()}-${investorAddress.slice(2, 10)}`,
|
|
428
|
+
provider: name,
|
|
429
|
+
status: 'pending' as const,
|
|
430
|
+
redirectUrl: `https://${name}.com/verify?session=${Date.now()}`,
|
|
431
|
+
};
|
|
432
|
+
},
|
|
433
|
+
checkStatus: async () => {
|
|
434
|
+
// Stub implementation
|
|
435
|
+
return 'pending' as const;
|
|
436
|
+
},
|
|
437
|
+
getVerificationResult: async () => {
|
|
438
|
+
// Stub implementation
|
|
439
|
+
throw new RWAError(
|
|
440
|
+
ErrorCode.PROVIDER_NOT_CONFIGURED,
|
|
441
|
+
`${name} provider integration requires API credentials. Configure the provider with your API keys.`
|
|
442
|
+
);
|
|
443
|
+
},
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
}
|