@gearbox-protocol/sdk 14.12.0-next.50 → 14.12.0-next.52

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.
@@ -19,129 +19,18 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
19
19
  var claimDSToken_exports = {};
20
20
  __export(claimDSToken_exports, {
21
21
  claimDSToken: () => claimDSToken,
22
- claimDSTokens: () => claimDSTokens,
23
- registerInvestor: () => registerInvestor
22
+ claimDSTokens: () => claimDSTokens
24
23
  });
25
24
  module.exports = __toCommonJS(claimDSToken_exports);
26
25
  var import_viem = require("viem");
27
26
  var import_accounts = require("viem/accounts");
28
- var import_iDSRegistryService = require("../abi/rwa/iDSRegistryService.js");
29
27
  var import_iDSToken = require("../abi/rwa/iDSToken.js");
30
28
  var import_sdk = require("../sdk/index.js");
31
- async function writeAndWait(anvil, params) {
32
- const hash = await anvil.writeContract(params);
33
- await anvil.mine({ blocks: 1 });
34
- await anvil.waitForTransactionReceipt({
35
- hash,
36
- pollingInterval: 100
37
- });
38
- return hash;
39
- }
40
- async function registerInvestor(props) {
41
- const { claimer, anvil, token, adminPrivateKey, logger } = props;
42
- const account = (0, import_accounts.privateKeyToAccount)(adminPrivateKey);
43
- const registryServiceId = await anvil.readContract({
44
- address: token,
45
- abi: import_iDSToken.iDSTokenAbi,
46
- functionName: "REGISTRY_SERVICE"
47
- });
48
- const registryService = await anvil.readContract({
49
- address: token,
50
- abi: import_iDSToken.iDSTokenAbi,
51
- functionName: "getDSService",
52
- args: [registryServiceId]
53
- });
54
- logger?.debug(`Registry service: ${registryService} (${registryServiceId})`);
55
- const [isRegistered, ACCREDITED, APPROVED] = await anvil.multicall({
56
- contracts: [
57
- {
58
- address: registryService,
59
- abi: import_iDSRegistryService.iDSRegistryServiceAbi,
60
- functionName: "isWallet",
61
- args: [claimer]
62
- },
63
- {
64
- address: registryService,
65
- abi: import_iDSRegistryService.iDSRegistryServiceAbi,
66
- functionName: "ACCREDITED",
67
- args: []
68
- },
69
- {
70
- address: registryService,
71
- abi: import_iDSRegistryService.iDSRegistryServiceAbi,
72
- functionName: "APPROVED",
73
- args: []
74
- }
75
- ],
76
- allowFailure: false
77
- });
78
- if (!isRegistered) {
79
- logger?.debug(
80
- `Claimer ${claimer} is not a registered wallet, registering...`
81
- );
82
- const investorId = `investor-${claimer.toLowerCase()}`;
83
- const investorExists = await anvil.readContract({
84
- address: registryService,
85
- abi: import_iDSRegistryService.iDSRegistryServiceAbi,
86
- functionName: "isInvestor",
87
- args: [investorId]
88
- });
89
- if (!investorExists) {
90
- await writeAndWait(anvil, {
91
- account,
92
- chain: anvil.chain,
93
- address: registryService,
94
- abi: import_iDSRegistryService.iDSRegistryServiceAbi,
95
- functionName: "registerInvestor",
96
- args: [investorId, investorId]
97
- });
98
- logger?.debug(`Registered investor "${investorId}"`);
99
- }
100
- await writeAndWait(anvil, {
101
- account,
102
- chain: anvil.chain,
103
- address: registryService,
104
- abi: import_iDSRegistryService.iDSRegistryServiceAbi,
105
- functionName: "addWallet",
106
- args: [claimer, investorId]
107
- });
108
- logger?.debug(`Added wallet ${claimer} for investor "${investorId}"`);
109
- try {
110
- await writeAndWait(anvil, {
111
- account,
112
- chain: anvil.chain,
113
- address: registryService,
114
- abi: import_iDSRegistryService.iDSRegistryServiceAbi,
115
- functionName: "setCountry",
116
- args: [investorId, "US"]
117
- });
118
- logger?.debug(`Set country for investor "${investorId}" to "US"`);
119
- await writeAndWait(anvil, {
120
- account,
121
- chain: anvil.chain,
122
- address: registryService,
123
- abi: import_iDSRegistryService.iDSRegistryServiceAbi,
124
- functionName: "setAttribute",
125
- args: [
126
- investorId,
127
- ACCREDITED,
128
- BigInt(APPROVED),
129
- import_sdk.MAX_UINT256,
130
- "fake proof"
131
- ]
132
- });
133
- logger?.debug(`Set attributes for investor "${investorId}"`);
134
- } catch (e) {
135
- logger?.error(e);
136
- }
137
- } else {
138
- logger?.debug(`Claimer ${claimer} is already a registered wallet`);
139
- }
140
- }
29
+ var import_kycUtils = require("./kycUtils.js");
141
30
  async function claimDSToken(props) {
142
31
  const {
143
32
  anvil,
144
- claimer,
33
+ investor,
145
34
  adminPrivateKey,
146
35
  token,
147
36
  marketConfigurators,
@@ -173,25 +62,25 @@ async function claimDSToken(props) {
173
62
  throw new Error(`No market found for token ${token}`);
174
63
  }
175
64
  logger?.debug(`${usdAmountProp} USD === ${amount} ${symbol}`);
176
- await registerInvestor({ ...props, logger });
177
- logger?.debug(`Issuing ${amount} tokens to ${claimer}...`);
178
- const mintHash = await writeAndWait(anvil, {
65
+ await (0, import_kycUtils.registerSecuritizeInvestor)({ ...props, logger });
66
+ logger?.debug(`Issuing ${amount} tokens to ${investor}...`);
67
+ const mintHash = await (0, import_kycUtils.writeAndWait)(anvil, {
179
68
  account,
180
69
  chain: anvil.chain,
181
70
  address: token,
182
71
  abi: import_iDSToken.iDSTokenAbi,
183
72
  functionName: "issueTokens",
184
- args: [claimer, amount]
73
+ args: [investor, amount]
185
74
  });
186
75
  logger?.debug(`Done! tx: ${mintHash}`);
187
76
  const balance = await anvil.readContract({
188
77
  address: token,
189
78
  abi: import_viem.erc20Abi,
190
79
  functionName: "balanceOf",
191
- args: [claimer]
80
+ args: [investor]
192
81
  });
193
82
  logger?.debug(
194
- `Balance of ${claimer}: ${sdk.tokensMeta.formatBN(token, balance)}`
83
+ `Balance of ${investor}: ${sdk.tokensMeta.formatBN(token, balance)}`
195
84
  );
196
85
  }
197
86
  async function claimDSTokens(props) {
@@ -203,6 +92,5 @@ async function claimDSTokens(props) {
203
92
  // Annotate the CommonJS export names for ESM import in node:
204
93
  0 && (module.exports = {
205
94
  claimDSToken,
206
- claimDSTokens,
207
- registerInvestor
95
+ claimDSTokens
208
96
  });
@@ -35,6 +35,7 @@ __reExport(dev_exports, require("./EthCallSpy.js"), module.exports);
35
35
  __reExport(dev_exports, require("./isOutOfSyncError.js"), module.exports);
36
36
  __reExport(dev_exports, require("./isRateLimitError.js"), module.exports);
37
37
  __reExport(dev_exports, require("./isTransientError.js"), module.exports);
38
+ __reExport(dev_exports, require("./kycUtils.js"), module.exports);
38
39
  var import_logSplitterTransport = require("./logSplitterTransport.js");
39
40
  __reExport(dev_exports, require("./ltUtils.js"), module.exports);
40
41
  __reExport(dev_exports, require("./migrateFaucet.js"), module.exports);
@@ -63,6 +64,7 @@ __reExport(dev_exports, require("./withdrawalUtils.js"), module.exports);
63
64
  ...require("./isOutOfSyncError.js"),
64
65
  ...require("./isRateLimitError.js"),
65
66
  ...require("./isTransientError.js"),
67
+ ...require("./kycUtils.js"),
66
68
  ...require("./ltUtils.js"),
67
69
  ...require("./migrateFaucet.js"),
68
70
  ...require("./mint/index.js"),
@@ -0,0 +1,388 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var kycUtils_exports = {};
20
+ __export(kycUtils_exports, {
21
+ greenlistMidasGateway: () => greenlistMidasGateway,
22
+ registerMidasInvestor: () => registerMidasInvestor,
23
+ registerRWAInvestor: () => registerRWAInvestor,
24
+ registerSecuritizeInvestor: () => registerSecuritizeInvestor,
25
+ writeAndWait: () => writeAndWait
26
+ });
27
+ module.exports = __toCommonJS(kycUtils_exports);
28
+ var import_viem = require("viem");
29
+ var import_accounts = require("viem/accounts");
30
+ var import_iDSRegistryService = require("../abi/rwa/iDSRegistryService.js");
31
+ var import_iDSToken = require("../abi/rwa/iDSToken.js");
32
+ var import_sdk = require("../sdk/index.js");
33
+ var import_withdrawalAbi = require("./withdrawalAbi.js");
34
+ async function writeAndWait(anvil, params) {
35
+ const hash = await anvil.writeContract(params);
36
+ await anvil.mine({ blocks: 1 });
37
+ await anvil.waitForTransactionReceipt({
38
+ hash,
39
+ pollingInterval: 100
40
+ });
41
+ return hash;
42
+ }
43
+ async function useSecuritizeAdmin(props) {
44
+ const { anvil, adminPrivateKey, admin, logger } = props;
45
+ if (adminPrivateKey) {
46
+ return {
47
+ account: (0, import_accounts.privateKeyToAccount)(adminPrivateKey),
48
+ release: async () => {
49
+ }
50
+ };
51
+ }
52
+ if (!admin) {
53
+ throw new Error(
54
+ "securitize: either adminPrivateKey or admin address is required"
55
+ );
56
+ }
57
+ await anvil.impersonateAccount({ address: admin });
58
+ await anvil.setBalance({ address: admin, value: (0, import_viem.parseEther)("100") });
59
+ logger?.debug(`securitize: impersonating registry admin ${admin}`);
60
+ return {
61
+ account: admin,
62
+ release: async () => {
63
+ await anvil.stopImpersonatingAccount({ address: admin });
64
+ }
65
+ };
66
+ }
67
+ async function registerSecuritizeInvestor(props) {
68
+ const { investor, anvil, token, logger } = props;
69
+ const registryServiceId = await anvil.readContract({
70
+ address: token,
71
+ abi: import_iDSToken.iDSTokenAbi,
72
+ functionName: "REGISTRY_SERVICE"
73
+ });
74
+ const registryService = await anvil.readContract({
75
+ address: token,
76
+ abi: import_iDSToken.iDSTokenAbi,
77
+ functionName: "getDSService",
78
+ args: [registryServiceId]
79
+ });
80
+ logger?.debug(`Registry service: ${registryService} (${registryServiceId})`);
81
+ const [isRegistered, ACCREDITED, APPROVED] = await anvil.multicall({
82
+ contracts: [
83
+ {
84
+ address: registryService,
85
+ abi: import_iDSRegistryService.iDSRegistryServiceAbi,
86
+ functionName: "isWallet",
87
+ args: [investor]
88
+ },
89
+ {
90
+ address: registryService,
91
+ abi: import_iDSRegistryService.iDSRegistryServiceAbi,
92
+ functionName: "ACCREDITED",
93
+ args: []
94
+ },
95
+ {
96
+ address: registryService,
97
+ abi: import_iDSRegistryService.iDSRegistryServiceAbi,
98
+ functionName: "APPROVED",
99
+ args: []
100
+ }
101
+ ],
102
+ allowFailure: false
103
+ });
104
+ if (!isRegistered) {
105
+ logger?.debug(
106
+ `Investor ${investor} is not a registered wallet, registering...`
107
+ );
108
+ const investorId = `investor-${investor.toLowerCase()}`;
109
+ const investorExists = await anvil.readContract({
110
+ address: registryService,
111
+ abi: import_iDSRegistryService.iDSRegistryServiceAbi,
112
+ functionName: "isInvestor",
113
+ args: [investorId]
114
+ });
115
+ const { account, release } = await useSecuritizeAdmin(props);
116
+ try {
117
+ if (!investorExists) {
118
+ await writeAndWait(anvil, {
119
+ account,
120
+ chain: anvil.chain,
121
+ address: registryService,
122
+ abi: import_iDSRegistryService.iDSRegistryServiceAbi,
123
+ functionName: "registerInvestor",
124
+ args: [investorId, investorId]
125
+ });
126
+ logger?.debug(`Registered investor "${investorId}"`);
127
+ }
128
+ await writeAndWait(anvil, {
129
+ account,
130
+ chain: anvil.chain,
131
+ address: registryService,
132
+ abi: import_iDSRegistryService.iDSRegistryServiceAbi,
133
+ functionName: "addWallet",
134
+ args: [investor, investorId]
135
+ });
136
+ logger?.debug(`Added wallet ${investor} for investor "${investorId}"`);
137
+ try {
138
+ await writeAndWait(anvil, {
139
+ account,
140
+ chain: anvil.chain,
141
+ address: registryService,
142
+ abi: import_iDSRegistryService.iDSRegistryServiceAbi,
143
+ functionName: "setCountry",
144
+ args: [investorId, "US"]
145
+ });
146
+ logger?.debug(`Set country for investor "${investorId}" to "US"`);
147
+ await writeAndWait(anvil, {
148
+ account,
149
+ chain: anvil.chain,
150
+ address: registryService,
151
+ abi: import_iDSRegistryService.iDSRegistryServiceAbi,
152
+ functionName: "setAttribute",
153
+ args: [
154
+ investorId,
155
+ ACCREDITED,
156
+ BigInt(APPROVED),
157
+ import_sdk.MAX_UINT256,
158
+ "fake proof"
159
+ ]
160
+ });
161
+ logger?.debug(`Set attributes for investor "${investorId}"`);
162
+ } catch (e) {
163
+ logger?.error(e);
164
+ }
165
+ } finally {
166
+ await release();
167
+ }
168
+ } else {
169
+ logger?.debug(`Investor ${investor} is already a registered wallet`);
170
+ }
171
+ }
172
+ const MIDAS_MODE_PERMISSIONED = 2;
173
+ const iMidasGatewayExtAbi = (0, import_viem.parseAbi)([
174
+ "function greenlistedRole() external view returns (bytes32)"
175
+ ]);
176
+ const iMidasAccessControlAbi = (0, import_viem.parseAbi)([
177
+ "function hasRole(bytes32 role, address account) external view returns (bool)",
178
+ "function getRoleAdmin(bytes32 role) external view returns (bytes32)",
179
+ "function grantRole(bytes32 role, address account) external"
180
+ ]);
181
+ async function registerMidasInvestor(props) {
182
+ const { anvil, investor, admin, logger } = props;
183
+ const gateway = await findMidasGateway(props);
184
+ await greenlistMidasGateway({ anvil, investor, admin, gateway, logger });
185
+ }
186
+ async function greenlistMidasGateway(props) {
187
+ const { anvil, investor, admin, gateway, logger } = props;
188
+ const [accessControl, mode, greenlistedRole] = await anvil.multicall({
189
+ allowFailure: false,
190
+ contracts: [
191
+ {
192
+ address: gateway,
193
+ abi: import_withdrawalAbi.midasGatewayAbi,
194
+ functionName: "accessControl"
195
+ },
196
+ {
197
+ address: gateway,
198
+ abi: import_withdrawalAbi.midasGatewayAbi,
199
+ functionName: "mode"
200
+ },
201
+ {
202
+ address: gateway,
203
+ abi: iMidasGatewayExtAbi,
204
+ functionName: "greenlistedRole"
205
+ }
206
+ ]
207
+ });
208
+ if ((0, import_viem.isAddressEqual)(accessControl, import_viem.zeroAddress)) {
209
+ logger?.debug(
210
+ `midas: gateway ${gateway} is permissionless, nothing to greenlist`
211
+ );
212
+ return;
213
+ }
214
+ const operatorRole = await anvil.readContract({
215
+ address: accessControl,
216
+ abi: iMidasAccessControlAbi,
217
+ functionName: "getRoleAdmin",
218
+ args: [greenlistedRole]
219
+ });
220
+ logger?.debug(
221
+ `midas: gateway ${gateway}, access control ${accessControl}, mode ${mode}, greenlisted role ${greenlistedRole}, operator role ${operatorRole}`
222
+ );
223
+ const grants = [[operatorRole, gateway]];
224
+ if (mode === MIDAS_MODE_PERMISSIONED) {
225
+ grants.push([operatorRole, admin], [greenlistedRole, investor]);
226
+ } else {
227
+ logger?.debug(
228
+ `midas: gateway ${gateway} does not require greenlisted borrowers, only granting the operator role to the gateway`
229
+ );
230
+ }
231
+ const granted = await anvil.multicall({
232
+ allowFailure: false,
233
+ contracts: grants.map(([role, account]) => ({
234
+ address: accessControl,
235
+ abi: iMidasAccessControlAbi,
236
+ functionName: "hasRole",
237
+ args: [role, account]
238
+ }))
239
+ });
240
+ await anvil.impersonateAccount({ address: admin });
241
+ try {
242
+ await anvil.setBalance({ address: admin, value: (0, import_viem.parseEther)("100") });
243
+ for (const [i, [role, account]] of grants.entries()) {
244
+ if (granted[i]) {
245
+ logger?.debug(`midas: ${account} already has role ${role}`);
246
+ continue;
247
+ }
248
+ await writeAndWait(anvil, {
249
+ account: admin,
250
+ chain: anvil.chain,
251
+ address: accessControl,
252
+ abi: iMidasAccessControlAbi,
253
+ functionName: "grantRole",
254
+ args: [role, account]
255
+ });
256
+ logger?.debug(`midas: granted role ${role} to ${account}`);
257
+ }
258
+ } finally {
259
+ await anvil.stopImpersonatingAccount({ address: admin });
260
+ }
261
+ if (mode === MIDAS_MODE_PERMISSIONED) {
262
+ const isGreenlisted = await anvil.readContract({
263
+ address: accessControl,
264
+ abi: iMidasAccessControlAbi,
265
+ functionName: "hasRole",
266
+ args: [greenlistedRole, investor]
267
+ });
268
+ if (!isGreenlisted) {
269
+ throw new Error(`midas: failed to greenlist investor ${investor}`);
270
+ }
271
+ logger?.debug(`midas: investor ${investor} is greenlisted`);
272
+ }
273
+ }
274
+ async function findMidasGateway(props) {
275
+ const { anvil, token, marketConfigurators, logger } = props;
276
+ let sdk = props.sdk;
277
+ if (!sdk) {
278
+ sdk = new import_sdk.OnchainSDK(anvil.chain.network, {
279
+ client: anvil,
280
+ timeout: 12e4
281
+ });
282
+ await sdk.attach({ marketConfigurators });
283
+ }
284
+ const candidates = collectMidasGateways(sdk);
285
+ if (candidates.length === 0) {
286
+ throw new Error("no midas gateway adapters found in loaded markets");
287
+ }
288
+ const mTokens = await anvil.multicall({
289
+ allowFailure: false,
290
+ contracts: candidates.map((address) => ({
291
+ address,
292
+ abi: import_withdrawalAbi.midasGatewayAbi,
293
+ functionName: "mToken"
294
+ }))
295
+ });
296
+ const index = mTokens.findIndex((mToken) => (0, import_viem.isAddressEqual)(mToken, token));
297
+ if (index === -1) {
298
+ throw new Error(`no midas gateway found for token ${token}`);
299
+ }
300
+ logger?.debug(`midas: gateway for ${token} is ${candidates[index]}`);
301
+ return candidates[index];
302
+ }
303
+ function collectMidasGateways(sdk) {
304
+ const gateways = new import_sdk.AddressSet();
305
+ for (const cm of sdk.marketRegister.creditManagers) {
306
+ for (const adapter of cm.creditManager.adapters.values()) {
307
+ if (adapter.contractType === "ADAPTER::MIDAS_GATEWAY") {
308
+ gateways.add(adapter.targetContract);
309
+ }
310
+ }
311
+ }
312
+ return gateways.asArray();
313
+ }
314
+ async function registerRWAInvestor(props) {
315
+ const {
316
+ anvil,
317
+ sdk,
318
+ investor,
319
+ adminPrivateKey,
320
+ securitizeAdmin,
321
+ midasAdmin,
322
+ logger
323
+ } = props;
324
+ const securitizeTokens = [];
325
+ const midasGateways = [];
326
+ const failed = [];
327
+ const dsTokens = new import_sdk.AddressSet(
328
+ sdk.rwa.factories.flatMap((factory) => factory.getTokens())
329
+ );
330
+ if (adminPrivateKey || securitizeAdmin) {
331
+ for (const token of dsTokens) {
332
+ try {
333
+ await registerSecuritizeInvestor({
334
+ anvil,
335
+ investor,
336
+ adminPrivateKey,
337
+ admin: securitizeAdmin,
338
+ token,
339
+ logger
340
+ });
341
+ securitizeTokens.push(token);
342
+ } catch (e) {
343
+ logger?.error(`securitize: failed to register ${investor} in ${token}`);
344
+ logger?.error(e);
345
+ failed.push({ target: token, error: e });
346
+ }
347
+ }
348
+ } else if (dsTokens.size > 0) {
349
+ logger?.warn(
350
+ `securitize: no registry admin, skipping ${dsTokens.size} DSToken(s)`
351
+ );
352
+ }
353
+ const gateways = collectMidasGateways(sdk);
354
+ if (midasAdmin) {
355
+ for (const gateway of gateways) {
356
+ try {
357
+ await greenlistMidasGateway({
358
+ anvil,
359
+ investor,
360
+ admin: midasAdmin,
361
+ gateway,
362
+ logger
363
+ });
364
+ midasGateways.push(gateway);
365
+ } catch (e) {
366
+ logger?.error(`midas: failed to greenlist ${investor} in ${gateway}`);
367
+ logger?.error(e);
368
+ failed.push({ target: gateway, error: e });
369
+ }
370
+ }
371
+ } else if (gateways.length > 0) {
372
+ logger?.warn(
373
+ `midas: no access control admin, skipping ${gateways.length} gateway(s)`
374
+ );
375
+ }
376
+ logger?.debug(
377
+ `${investor} passed KYC on ${securitizeTokens.length} DSToken(s) and ${midasGateways.length} midas gateway(s), ${failed.length} failure(s)`
378
+ );
379
+ return { securitizeTokens, midasGateways, failed };
380
+ }
381
+ // Annotate the CommonJS export names for ESM import in node:
382
+ 0 && (module.exports = {
383
+ greenlistMidasGateway,
384
+ registerMidasInvestor,
385
+ registerRWAInvestor,
386
+ registerSecuritizeInvestor,
387
+ writeAndWait
388
+ });
@@ -2,126 +2,13 @@ import {
2
2
  erc20Abi
3
3
  } from "viem";
4
4
  import { privateKeyToAccount } from "viem/accounts";
5
- import { iDSRegistryServiceAbi } from "../abi/rwa/iDSRegistryService.js";
6
5
  import { iDSTokenAbi } from "../abi/rwa/iDSToken.js";
7
- import {
8
- MAX_UINT256,
9
- OnchainSDK
10
- } from "../sdk/index.js";
11
- async function writeAndWait(anvil, params) {
12
- const hash = await anvil.writeContract(params);
13
- await anvil.mine({ blocks: 1 });
14
- await anvil.waitForTransactionReceipt({
15
- hash,
16
- pollingInterval: 100
17
- });
18
- return hash;
19
- }
20
- async function registerInvestor(props) {
21
- const { claimer, anvil, token, adminPrivateKey, logger } = props;
22
- const account = privateKeyToAccount(adminPrivateKey);
23
- const registryServiceId = await anvil.readContract({
24
- address: token,
25
- abi: iDSTokenAbi,
26
- functionName: "REGISTRY_SERVICE"
27
- });
28
- const registryService = await anvil.readContract({
29
- address: token,
30
- abi: iDSTokenAbi,
31
- functionName: "getDSService",
32
- args: [registryServiceId]
33
- });
34
- logger?.debug(`Registry service: ${registryService} (${registryServiceId})`);
35
- const [isRegistered, ACCREDITED, APPROVED] = await anvil.multicall({
36
- contracts: [
37
- {
38
- address: registryService,
39
- abi: iDSRegistryServiceAbi,
40
- functionName: "isWallet",
41
- args: [claimer]
42
- },
43
- {
44
- address: registryService,
45
- abi: iDSRegistryServiceAbi,
46
- functionName: "ACCREDITED",
47
- args: []
48
- },
49
- {
50
- address: registryService,
51
- abi: iDSRegistryServiceAbi,
52
- functionName: "APPROVED",
53
- args: []
54
- }
55
- ],
56
- allowFailure: false
57
- });
58
- if (!isRegistered) {
59
- logger?.debug(
60
- `Claimer ${claimer} is not a registered wallet, registering...`
61
- );
62
- const investorId = `investor-${claimer.toLowerCase()}`;
63
- const investorExists = await anvil.readContract({
64
- address: registryService,
65
- abi: iDSRegistryServiceAbi,
66
- functionName: "isInvestor",
67
- args: [investorId]
68
- });
69
- if (!investorExists) {
70
- await writeAndWait(anvil, {
71
- account,
72
- chain: anvil.chain,
73
- address: registryService,
74
- abi: iDSRegistryServiceAbi,
75
- functionName: "registerInvestor",
76
- args: [investorId, investorId]
77
- });
78
- logger?.debug(`Registered investor "${investorId}"`);
79
- }
80
- await writeAndWait(anvil, {
81
- account,
82
- chain: anvil.chain,
83
- address: registryService,
84
- abi: iDSRegistryServiceAbi,
85
- functionName: "addWallet",
86
- args: [claimer, investorId]
87
- });
88
- logger?.debug(`Added wallet ${claimer} for investor "${investorId}"`);
89
- try {
90
- await writeAndWait(anvil, {
91
- account,
92
- chain: anvil.chain,
93
- address: registryService,
94
- abi: iDSRegistryServiceAbi,
95
- functionName: "setCountry",
96
- args: [investorId, "US"]
97
- });
98
- logger?.debug(`Set country for investor "${investorId}" to "US"`);
99
- await writeAndWait(anvil, {
100
- account,
101
- chain: anvil.chain,
102
- address: registryService,
103
- abi: iDSRegistryServiceAbi,
104
- functionName: "setAttribute",
105
- args: [
106
- investorId,
107
- ACCREDITED,
108
- BigInt(APPROVED),
109
- MAX_UINT256,
110
- "fake proof"
111
- ]
112
- });
113
- logger?.debug(`Set attributes for investor "${investorId}"`);
114
- } catch (e) {
115
- logger?.error(e);
116
- }
117
- } else {
118
- logger?.debug(`Claimer ${claimer} is already a registered wallet`);
119
- }
120
- }
6
+ import { OnchainSDK } from "../sdk/index.js";
7
+ import { registerSecuritizeInvestor, writeAndWait } from "./kycUtils.js";
121
8
  async function claimDSToken(props) {
122
9
  const {
123
10
  anvil,
124
- claimer,
11
+ investor,
125
12
  adminPrivateKey,
126
13
  token,
127
14
  marketConfigurators,
@@ -153,25 +40,25 @@ async function claimDSToken(props) {
153
40
  throw new Error(`No market found for token ${token}`);
154
41
  }
155
42
  logger?.debug(`${usdAmountProp} USD === ${amount} ${symbol}`);
156
- await registerInvestor({ ...props, logger });
157
- logger?.debug(`Issuing ${amount} tokens to ${claimer}...`);
43
+ await registerSecuritizeInvestor({ ...props, logger });
44
+ logger?.debug(`Issuing ${amount} tokens to ${investor}...`);
158
45
  const mintHash = await writeAndWait(anvil, {
159
46
  account,
160
47
  chain: anvil.chain,
161
48
  address: token,
162
49
  abi: iDSTokenAbi,
163
50
  functionName: "issueTokens",
164
- args: [claimer, amount]
51
+ args: [investor, amount]
165
52
  });
166
53
  logger?.debug(`Done! tx: ${mintHash}`);
167
54
  const balance = await anvil.readContract({
168
55
  address: token,
169
56
  abi: erc20Abi,
170
57
  functionName: "balanceOf",
171
- args: [claimer]
58
+ args: [investor]
172
59
  });
173
60
  logger?.debug(
174
- `Balance of ${claimer}: ${sdk.tokensMeta.formatBN(token, balance)}`
61
+ `Balance of ${investor}: ${sdk.tokensMeta.formatBN(token, balance)}`
175
62
  );
176
63
  }
177
64
  async function claimDSTokens(props) {
@@ -182,6 +69,5 @@ async function claimDSTokens(props) {
182
69
  }
183
70
  export {
184
71
  claimDSToken,
185
- claimDSTokens,
186
- registerInvestor
72
+ claimDSTokens
187
73
  };
@@ -10,6 +10,7 @@ export * from "./EthCallSpy.js";
10
10
  export * from "./isOutOfSyncError.js";
11
11
  export * from "./isRateLimitError.js";
12
12
  export * from "./isTransientError.js";
13
+ export * from "./kycUtils.js";
13
14
  import {
14
15
  isRangeError,
15
16
  logSplitterTransport
@@ -0,0 +1,369 @@
1
+ import {
2
+ isAddressEqual,
3
+ parseAbi,
4
+ parseEther,
5
+ zeroAddress
6
+ } from "viem";
7
+ import { privateKeyToAccount } from "viem/accounts";
8
+ import { iDSRegistryServiceAbi } from "../abi/rwa/iDSRegistryService.js";
9
+ import { iDSTokenAbi } from "../abi/rwa/iDSToken.js";
10
+ import {
11
+ AddressSet,
12
+ MAX_UINT256,
13
+ OnchainSDK
14
+ } from "../sdk/index.js";
15
+ import { midasGatewayAbi } from "./withdrawalAbi.js";
16
+ async function writeAndWait(anvil, params) {
17
+ const hash = await anvil.writeContract(params);
18
+ await anvil.mine({ blocks: 1 });
19
+ await anvil.waitForTransactionReceipt({
20
+ hash,
21
+ pollingInterval: 100
22
+ });
23
+ return hash;
24
+ }
25
+ async function useSecuritizeAdmin(props) {
26
+ const { anvil, adminPrivateKey, admin, logger } = props;
27
+ if (adminPrivateKey) {
28
+ return {
29
+ account: privateKeyToAccount(adminPrivateKey),
30
+ release: async () => {
31
+ }
32
+ };
33
+ }
34
+ if (!admin) {
35
+ throw new Error(
36
+ "securitize: either adminPrivateKey or admin address is required"
37
+ );
38
+ }
39
+ await anvil.impersonateAccount({ address: admin });
40
+ await anvil.setBalance({ address: admin, value: parseEther("100") });
41
+ logger?.debug(`securitize: impersonating registry admin ${admin}`);
42
+ return {
43
+ account: admin,
44
+ release: async () => {
45
+ await anvil.stopImpersonatingAccount({ address: admin });
46
+ }
47
+ };
48
+ }
49
+ async function registerSecuritizeInvestor(props) {
50
+ const { investor, anvil, token, logger } = props;
51
+ const registryServiceId = await anvil.readContract({
52
+ address: token,
53
+ abi: iDSTokenAbi,
54
+ functionName: "REGISTRY_SERVICE"
55
+ });
56
+ const registryService = await anvil.readContract({
57
+ address: token,
58
+ abi: iDSTokenAbi,
59
+ functionName: "getDSService",
60
+ args: [registryServiceId]
61
+ });
62
+ logger?.debug(`Registry service: ${registryService} (${registryServiceId})`);
63
+ const [isRegistered, ACCREDITED, APPROVED] = await anvil.multicall({
64
+ contracts: [
65
+ {
66
+ address: registryService,
67
+ abi: iDSRegistryServiceAbi,
68
+ functionName: "isWallet",
69
+ args: [investor]
70
+ },
71
+ {
72
+ address: registryService,
73
+ abi: iDSRegistryServiceAbi,
74
+ functionName: "ACCREDITED",
75
+ args: []
76
+ },
77
+ {
78
+ address: registryService,
79
+ abi: iDSRegistryServiceAbi,
80
+ functionName: "APPROVED",
81
+ args: []
82
+ }
83
+ ],
84
+ allowFailure: false
85
+ });
86
+ if (!isRegistered) {
87
+ logger?.debug(
88
+ `Investor ${investor} is not a registered wallet, registering...`
89
+ );
90
+ const investorId = `investor-${investor.toLowerCase()}`;
91
+ const investorExists = await anvil.readContract({
92
+ address: registryService,
93
+ abi: iDSRegistryServiceAbi,
94
+ functionName: "isInvestor",
95
+ args: [investorId]
96
+ });
97
+ const { account, release } = await useSecuritizeAdmin(props);
98
+ try {
99
+ if (!investorExists) {
100
+ await writeAndWait(anvil, {
101
+ account,
102
+ chain: anvil.chain,
103
+ address: registryService,
104
+ abi: iDSRegistryServiceAbi,
105
+ functionName: "registerInvestor",
106
+ args: [investorId, investorId]
107
+ });
108
+ logger?.debug(`Registered investor "${investorId}"`);
109
+ }
110
+ await writeAndWait(anvil, {
111
+ account,
112
+ chain: anvil.chain,
113
+ address: registryService,
114
+ abi: iDSRegistryServiceAbi,
115
+ functionName: "addWallet",
116
+ args: [investor, investorId]
117
+ });
118
+ logger?.debug(`Added wallet ${investor} for investor "${investorId}"`);
119
+ try {
120
+ await writeAndWait(anvil, {
121
+ account,
122
+ chain: anvil.chain,
123
+ address: registryService,
124
+ abi: iDSRegistryServiceAbi,
125
+ functionName: "setCountry",
126
+ args: [investorId, "US"]
127
+ });
128
+ logger?.debug(`Set country for investor "${investorId}" to "US"`);
129
+ await writeAndWait(anvil, {
130
+ account,
131
+ chain: anvil.chain,
132
+ address: registryService,
133
+ abi: iDSRegistryServiceAbi,
134
+ functionName: "setAttribute",
135
+ args: [
136
+ investorId,
137
+ ACCREDITED,
138
+ BigInt(APPROVED),
139
+ MAX_UINT256,
140
+ "fake proof"
141
+ ]
142
+ });
143
+ logger?.debug(`Set attributes for investor "${investorId}"`);
144
+ } catch (e) {
145
+ logger?.error(e);
146
+ }
147
+ } finally {
148
+ await release();
149
+ }
150
+ } else {
151
+ logger?.debug(`Investor ${investor} is already a registered wallet`);
152
+ }
153
+ }
154
+ const MIDAS_MODE_PERMISSIONED = 2;
155
+ const iMidasGatewayExtAbi = parseAbi([
156
+ "function greenlistedRole() external view returns (bytes32)"
157
+ ]);
158
+ const iMidasAccessControlAbi = parseAbi([
159
+ "function hasRole(bytes32 role, address account) external view returns (bool)",
160
+ "function getRoleAdmin(bytes32 role) external view returns (bytes32)",
161
+ "function grantRole(bytes32 role, address account) external"
162
+ ]);
163
+ async function registerMidasInvestor(props) {
164
+ const { anvil, investor, admin, logger } = props;
165
+ const gateway = await findMidasGateway(props);
166
+ await greenlistMidasGateway({ anvil, investor, admin, gateway, logger });
167
+ }
168
+ async function greenlistMidasGateway(props) {
169
+ const { anvil, investor, admin, gateway, logger } = props;
170
+ const [accessControl, mode, greenlistedRole] = await anvil.multicall({
171
+ allowFailure: false,
172
+ contracts: [
173
+ {
174
+ address: gateway,
175
+ abi: midasGatewayAbi,
176
+ functionName: "accessControl"
177
+ },
178
+ {
179
+ address: gateway,
180
+ abi: midasGatewayAbi,
181
+ functionName: "mode"
182
+ },
183
+ {
184
+ address: gateway,
185
+ abi: iMidasGatewayExtAbi,
186
+ functionName: "greenlistedRole"
187
+ }
188
+ ]
189
+ });
190
+ if (isAddressEqual(accessControl, zeroAddress)) {
191
+ logger?.debug(
192
+ `midas: gateway ${gateway} is permissionless, nothing to greenlist`
193
+ );
194
+ return;
195
+ }
196
+ const operatorRole = await anvil.readContract({
197
+ address: accessControl,
198
+ abi: iMidasAccessControlAbi,
199
+ functionName: "getRoleAdmin",
200
+ args: [greenlistedRole]
201
+ });
202
+ logger?.debug(
203
+ `midas: gateway ${gateway}, access control ${accessControl}, mode ${mode}, greenlisted role ${greenlistedRole}, operator role ${operatorRole}`
204
+ );
205
+ const grants = [[operatorRole, gateway]];
206
+ if (mode === MIDAS_MODE_PERMISSIONED) {
207
+ grants.push([operatorRole, admin], [greenlistedRole, investor]);
208
+ } else {
209
+ logger?.debug(
210
+ `midas: gateway ${gateway} does not require greenlisted borrowers, only granting the operator role to the gateway`
211
+ );
212
+ }
213
+ const granted = await anvil.multicall({
214
+ allowFailure: false,
215
+ contracts: grants.map(([role, account]) => ({
216
+ address: accessControl,
217
+ abi: iMidasAccessControlAbi,
218
+ functionName: "hasRole",
219
+ args: [role, account]
220
+ }))
221
+ });
222
+ await anvil.impersonateAccount({ address: admin });
223
+ try {
224
+ await anvil.setBalance({ address: admin, value: parseEther("100") });
225
+ for (const [i, [role, account]] of grants.entries()) {
226
+ if (granted[i]) {
227
+ logger?.debug(`midas: ${account} already has role ${role}`);
228
+ continue;
229
+ }
230
+ await writeAndWait(anvil, {
231
+ account: admin,
232
+ chain: anvil.chain,
233
+ address: accessControl,
234
+ abi: iMidasAccessControlAbi,
235
+ functionName: "grantRole",
236
+ args: [role, account]
237
+ });
238
+ logger?.debug(`midas: granted role ${role} to ${account}`);
239
+ }
240
+ } finally {
241
+ await anvil.stopImpersonatingAccount({ address: admin });
242
+ }
243
+ if (mode === MIDAS_MODE_PERMISSIONED) {
244
+ const isGreenlisted = await anvil.readContract({
245
+ address: accessControl,
246
+ abi: iMidasAccessControlAbi,
247
+ functionName: "hasRole",
248
+ args: [greenlistedRole, investor]
249
+ });
250
+ if (!isGreenlisted) {
251
+ throw new Error(`midas: failed to greenlist investor ${investor}`);
252
+ }
253
+ logger?.debug(`midas: investor ${investor} is greenlisted`);
254
+ }
255
+ }
256
+ async function findMidasGateway(props) {
257
+ const { anvil, token, marketConfigurators, logger } = props;
258
+ let sdk = props.sdk;
259
+ if (!sdk) {
260
+ sdk = new OnchainSDK(anvil.chain.network, {
261
+ client: anvil,
262
+ timeout: 12e4
263
+ });
264
+ await sdk.attach({ marketConfigurators });
265
+ }
266
+ const candidates = collectMidasGateways(sdk);
267
+ if (candidates.length === 0) {
268
+ throw new Error("no midas gateway adapters found in loaded markets");
269
+ }
270
+ const mTokens = await anvil.multicall({
271
+ allowFailure: false,
272
+ contracts: candidates.map((address) => ({
273
+ address,
274
+ abi: midasGatewayAbi,
275
+ functionName: "mToken"
276
+ }))
277
+ });
278
+ const index = mTokens.findIndex((mToken) => isAddressEqual(mToken, token));
279
+ if (index === -1) {
280
+ throw new Error(`no midas gateway found for token ${token}`);
281
+ }
282
+ logger?.debug(`midas: gateway for ${token} is ${candidates[index]}`);
283
+ return candidates[index];
284
+ }
285
+ function collectMidasGateways(sdk) {
286
+ const gateways = new AddressSet();
287
+ for (const cm of sdk.marketRegister.creditManagers) {
288
+ for (const adapter of cm.creditManager.adapters.values()) {
289
+ if (adapter.contractType === "ADAPTER::MIDAS_GATEWAY") {
290
+ gateways.add(adapter.targetContract);
291
+ }
292
+ }
293
+ }
294
+ return gateways.asArray();
295
+ }
296
+ async function registerRWAInvestor(props) {
297
+ const {
298
+ anvil,
299
+ sdk,
300
+ investor,
301
+ adminPrivateKey,
302
+ securitizeAdmin,
303
+ midasAdmin,
304
+ logger
305
+ } = props;
306
+ const securitizeTokens = [];
307
+ const midasGateways = [];
308
+ const failed = [];
309
+ const dsTokens = new AddressSet(
310
+ sdk.rwa.factories.flatMap((factory) => factory.getTokens())
311
+ );
312
+ if (adminPrivateKey || securitizeAdmin) {
313
+ for (const token of dsTokens) {
314
+ try {
315
+ await registerSecuritizeInvestor({
316
+ anvil,
317
+ investor,
318
+ adminPrivateKey,
319
+ admin: securitizeAdmin,
320
+ token,
321
+ logger
322
+ });
323
+ securitizeTokens.push(token);
324
+ } catch (e) {
325
+ logger?.error(`securitize: failed to register ${investor} in ${token}`);
326
+ logger?.error(e);
327
+ failed.push({ target: token, error: e });
328
+ }
329
+ }
330
+ } else if (dsTokens.size > 0) {
331
+ logger?.warn(
332
+ `securitize: no registry admin, skipping ${dsTokens.size} DSToken(s)`
333
+ );
334
+ }
335
+ const gateways = collectMidasGateways(sdk);
336
+ if (midasAdmin) {
337
+ for (const gateway of gateways) {
338
+ try {
339
+ await greenlistMidasGateway({
340
+ anvil,
341
+ investor,
342
+ admin: midasAdmin,
343
+ gateway,
344
+ logger
345
+ });
346
+ midasGateways.push(gateway);
347
+ } catch (e) {
348
+ logger?.error(`midas: failed to greenlist ${investor} in ${gateway}`);
349
+ logger?.error(e);
350
+ failed.push({ target: gateway, error: e });
351
+ }
352
+ }
353
+ } else if (gateways.length > 0) {
354
+ logger?.warn(
355
+ `midas: no access control admin, skipping ${gateways.length} gateway(s)`
356
+ );
357
+ }
358
+ logger?.debug(
359
+ `${investor} passed KYC on ${securitizeTokens.length} DSToken(s) and ${midasGateways.length} midas gateway(s), ${failed.length} failure(s)`
360
+ );
361
+ return { securitizeTokens, midasGateways, failed };
362
+ }
363
+ export {
364
+ greenlistMidasGateway,
365
+ registerMidasInvestor,
366
+ registerRWAInvestor,
367
+ registerSecuritizeInvestor,
368
+ writeAndWait
369
+ };
@@ -3,7 +3,7 @@ import { type ILogger } from "../sdk/index.js";
3
3
  import type { AnvilClient } from "./createAnvilClient.js";
4
4
  interface ClaimDSTokenProps {
5
5
  anvil: AnvilClient;
6
- claimer: Address;
6
+ investor: Address;
7
7
  adminPrivateKey: Hex;
8
8
  /**
9
9
  * DSToken addresses
@@ -20,14 +20,13 @@ interface ClaimDSTokenProps {
20
20
  type ClaimDSTokensProps = Omit<ClaimDSTokenProps, "token"> & {
21
21
  tokens: Address[];
22
22
  };
23
- export declare function registerInvestor(props: ClaimDSTokenProps): Promise<void>;
24
23
  export declare function claimDSToken(props: ClaimDSTokenProps): Promise<void>;
25
24
  /**
26
25
  * Helper function to claim DSToken from the faucet.
27
26
  * Works both for MockDStoken and real DSToken connected by securitize-deploy script
28
27
  * @param forkStatus
29
28
  * @param publicClient
30
- * @param claimer
29
+ * @param investor
31
30
  * @returns
32
31
  */
33
32
  export declare function claimDSTokens(props: ClaimDSTokensProps): Promise<void>;
@@ -10,6 +10,7 @@ export * from "./EthCallSpy.js";
10
10
  export * from "./isOutOfSyncError.js";
11
11
  export * from "./isRateLimitError.js";
12
12
  export * from "./isTransientError.js";
13
+ export * from "./kycUtils.js";
13
14
  export { isRangeError, type LogSplitterTransportOptions, logSplitterTransport, } from "./logSplitterTransport.js";
14
15
  export * from "./ltUtils.js";
15
16
  export * from "./migrateFaucet.js";
@@ -0,0 +1,136 @@
1
+ import { type Address, type Hex } from "viem";
2
+ import { type ILogger, OnchainSDK } from "../sdk/index.js";
3
+ import type { AnvilClient } from "./createAnvilClient.js";
4
+ /**
5
+ * Writes to a contract, mines a block and waits for the receipt
6
+ */
7
+ export declare function writeAndWait(anvil: AnvilClient, params: Parameters<AnvilClient["writeContract"]>[0]): Promise<Hex>;
8
+ export interface RegisterSecuritizeInvestorProps {
9
+ anvil: AnvilClient;
10
+ /**
11
+ * Wallet to register in the Securitize DS registry
12
+ */
13
+ investor: Address;
14
+ /**
15
+ * Private key of the DS registry admin, signs the registry writes
16
+ */
17
+ adminPrivateKey?: Hex;
18
+ /**
19
+ * DS registry admin, impersonated on the fork when no private key is given
20
+ */
21
+ admin?: Address;
22
+ /**
23
+ * DSToken address
24
+ */
25
+ token: Address;
26
+ logger?: ILogger;
27
+ }
28
+ /**
29
+ * Registers a wallet as a Securitize investor (fake KYC) in the DS registry
30
+ * service of a DSToken.
31
+ * Works both for MockDSToken and real DSToken connected by securitize-deploy script
32
+ */
33
+ export declare function registerSecuritizeInvestor(props: RegisterSecuritizeInvestorProps): Promise<void>;
34
+ export interface RegisterMidasInvestorProps {
35
+ anvil: AnvilClient;
36
+ /**
37
+ * Investor EOA to greenlist
38
+ */
39
+ investor: Address;
40
+ /**
41
+ * Midas access control admin, impersonated on the fork
42
+ * (MIDAS_ACL_ADMIN in periphery-v3/router-v3 foundry tests)
43
+ */
44
+ admin: Address;
45
+ /**
46
+ * mToken address, the gateway is resolved from it
47
+ */
48
+ token: Address;
49
+ /**
50
+ * Attached SDK, created from `anvil` when omitted
51
+ */
52
+ sdk?: OnchainSDK;
53
+ marketConfigurators?: Address[];
54
+ logger?: ILogger;
55
+ }
56
+ /**
57
+ * Greenlists an investor in Midas access control (fake KYC) on an anvil fork.
58
+ *
59
+ * Replicates the `_grantGreenlistAdmin` / `_grantGreenlist` logic from the
60
+ * foundry tests (periphery-v3's WithdrawalCompressorMidasRWA.t.sol and
61
+ * router-v3's RouterLiveTestMidas.sol) by impersonating the Midas access
62
+ * control admin instead of pranking it.
63
+ */
64
+ export declare function registerMidasInvestor(props: RegisterMidasInvestorProps): Promise<void>;
65
+ export interface GreenlistMidasGatewayProps {
66
+ anvil: AnvilClient;
67
+ /**
68
+ * Investor EOA to greenlist
69
+ */
70
+ investor: Address;
71
+ /**
72
+ * Midas access control admin, impersonated on the fork
73
+ * (MIDAS_ACL_ADMIN in periphery-v3/router-v3 foundry tests)
74
+ */
75
+ admin: Address;
76
+ /**
77
+ * Midas gateway address
78
+ */
79
+ gateway: Address;
80
+ logger?: ILogger;
81
+ }
82
+ /**
83
+ * Greenlists an investor in the access control of a single Midas gateway
84
+ */
85
+ export declare function greenlistMidasGateway(props: GreenlistMidasGatewayProps): Promise<void>;
86
+ export interface RegisterRWAInvestorProps {
87
+ anvil: AnvilClient;
88
+ /**
89
+ * Attached SDK, markets and RWA factories are read from it
90
+ */
91
+ sdk: OnchainSDK;
92
+ /**
93
+ * Wallet to pass the KYC of every RWA token
94
+ */
95
+ investor: Address;
96
+ /**
97
+ * Private key of the Securitize registry admin, DSTokens are skipped when
98
+ * neither this nor `securitizeAdmin` is set
99
+ */
100
+ adminPrivateKey?: Hex;
101
+ /**
102
+ * Securitize registry admin, impersonated on the fork
103
+ */
104
+ securitizeAdmin?: Address;
105
+ /**
106
+ * Midas access control admin, Midas gateways are skipped when omitted
107
+ */
108
+ midasAdmin?: Address;
109
+ logger?: ILogger;
110
+ }
111
+ export interface RWAKycFailure {
112
+ /**
113
+ * DSToken or Midas gateway that failed
114
+ */
115
+ target: Address;
116
+ error: unknown;
117
+ }
118
+ export interface RegisterRWAInvestorResult {
119
+ /**
120
+ * DSTokens the investor was registered in
121
+ */
122
+ securitizeTokens: Address[];
123
+ /**
124
+ * Midas gateways the investor was greenlisted in
125
+ */
126
+ midasGateways: Address[];
127
+ failed: RWAKycFailure[];
128
+ }
129
+ /**
130
+ * Registers a wallet as an investor (fake KYC) in every Securitize DSToken and
131
+ * every Midas gateway of the markets loaded by `sdk`.
132
+ *
133
+ * Failures of a single token or gateway are collected and reported in the
134
+ * result instead of aborting the whole run.
135
+ */
136
+ export declare function registerRWAInvestor(props: RegisterRWAInvestorProps): Promise<RegisterRWAInvestorResult>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gearbox-protocol/sdk",
3
- "version": "14.12.0-next.50",
3
+ "version": "14.12.0-next.52",
4
4
  "description": "Gearbox SDK",
5
5
  "license": "MIT",
6
6
  "repository": {