@gearbox-protocol/sdk 13.0.0-next.21 → 13.0.0-next.23

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.
@@ -33,7 +33,6 @@ var import_v300 = require("../../abi/v300.js");
33
33
  var import_base = require("../base/index.js");
34
34
  var import_chains = require("../chain/chains.js");
35
35
  var import_constants = require("../constants/index.js");
36
- var import_market = require("../market/index.js");
37
36
  var import_router = require("../router/index.js");
38
37
  var import_sdk_legacy = require("../sdk-legacy/index.js");
39
38
  var import_utils = require("../utils/index.js");
@@ -42,6 +41,7 @@ const COMPRESSORS = {
42
41
  [import_chains.chains.Mainnet.id]: "0x36F3d0Bb73CBC2E94fE24dF0f26a689409cF9023",
43
42
  [import_chains.chains.Monad.id]: "0x36F3d0Bb73CBC2E94fE24dF0f26a689409cF9023"
44
43
  };
44
+ const INVESTORS = new import_utils.AddressMap([], "investors");
45
45
  function getWithdrawalCompressorAddress(chainId) {
46
46
  return COMPRESSORS[chainId];
47
47
  }
@@ -103,6 +103,23 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
103
103
  });
104
104
  return cad;
105
105
  }
106
+ /**
107
+ * Returns credit account data for a single account with the investor address resolved.
108
+ * Loads CA via getCreditAccountData; for KYC underlyings fetches the investor from the KYC factory's getInvestor(creditAccount), otherwise uses the account owner.
109
+ * @param account - Credit account address
110
+ * @param blockNumber - Optional block number for the read
111
+ * @returns CreditAccountDataWithInvestor (CA data + investor address), or undefined if the account is not found
112
+ */
113
+ async getCreditAccountDataWithInvestor(account, blockNumber) {
114
+ const ca = await this.getCreditAccountData(account, blockNumber);
115
+ if (!ca) return ca;
116
+ const marketSuite = this.sdk.marketRegister.findByCreditManager(
117
+ ca.creditManager
118
+ );
119
+ const factory = await marketSuite.getKYCFactory();
120
+ const investor = factory ? await factory.getInvestor(ca.creditAccount, true) : void 0;
121
+ return { ...ca, investor: investor ?? ca.owner };
122
+ }
106
123
  /**
107
124
  * Methods to get all credit accounts with some optional filtering
108
125
  * Performs all necessary price feed updates under the hood
@@ -111,7 +128,7 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
111
128
  * @param blockNumber
112
129
  * @returns returned credit accounts are sorted by health factor in ascending order
113
130
  */
114
- async getCreditAccounts(options, blockNumber) {
131
+ async getCreditAccounts(options, blockNumber, priceUpdate) {
115
132
  const {
116
133
  creditManager,
117
134
  includeZeroDebt = false,
@@ -133,7 +150,7 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
133
150
  maxHealthFactor,
134
151
  reverting: false
135
152
  };
136
- const { txs: priceUpdateTxs } = await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(
153
+ const { txs: priceUpdateTxs } = priceUpdate ?? await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(
137
154
  ignoreReservePrices ? { main: true } : void 0
138
155
  );
139
156
  const allCAs = [];
@@ -162,6 +179,75 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
162
179
  );
163
180
  return allCAs.sort((a, b) => Number(a.healthFactor - b.healthFactor));
164
181
  }
182
+ /**
183
+ * Returns all credit accounts matching the filter, with investor set on each item.
184
+ * Delegates to getCreditAccounts; when options.owner is set, also loads KYC credit accounts for that owner and merges them into the list. Result is sorted by health factor ascending.
185
+ * @param options - Filter options (owner, creditManager, health factor, etc.)
186
+ * @param blockNumber - Optional block number for the read
187
+ * @returns Array of credit accounts (with investor field), sorted by health factor ascending
188
+ */
189
+ async getCreditAccountsWithInvestor(options, blockNumber) {
190
+ const { owner, ignoreReservePrices = false } = options ?? {};
191
+ const priceUpdate = await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(
192
+ ignoreReservePrices ? { main: true } : void 0
193
+ );
194
+ const { txs: priceUpdateTxs } = priceUpdate;
195
+ const [common, kyc] = await Promise.all([
196
+ this.getCreditAccounts(options, blockNumber),
197
+ owner ? this.getKYCCreditAccountsOfOwner(owner, priceUpdateTxs, blockNumber) : void 0
198
+ ]);
199
+ const allCAs = common.map(
200
+ (ca) => ({
201
+ ...ca,
202
+ investor: owner || ca.owner
203
+ })
204
+ );
205
+ allCAs.push(...kyc || []);
206
+ return allCAs.sort((a, b) => Number(a.healthFactor - b.healthFactor));
207
+ }
208
+ async getKYCCreditAccountsOfOwner(owner, priceUpdateTxs, blockNumber) {
209
+ const suites = this.marketConfigurators.map((mc) => {
210
+ const suite = this.sdk.marketRegister.markets.find(
211
+ (m) => m.configurator.address === mc
212
+ );
213
+ return suite;
214
+ });
215
+ const kycCAAddresses = await this.getKYCCaOfInvestor(owner, suites);
216
+ const kycCAs = await this.loadSpecifiedAccounts(
217
+ kycCAAddresses,
218
+ priceUpdateTxs,
219
+ blockNumber
220
+ );
221
+ return kycCAs.map((ca) => ({
222
+ ...ca,
223
+ investor: owner
224
+ }));
225
+ }
226
+ /**
227
+ * Loads credit account data for the given addresses using simulateWithPriceUpdates.
228
+ * Applies the provided price update txs before reading, so returned data is consistent with up-to-date prices.
229
+ * @param accounts - Credit account addresses to load
230
+ * @param priceUpdateTxs - Price feed update txs to simulate before the read (e.g. from generatePriceFeedsUpdateTxs)
231
+ * @param blockNumber - Optional block number for the read
232
+ * @returns Array of CreditAccountData in the same order as accounts (throws if any getCreditAccountData call reverts)
233
+ */
234
+ async loadSpecifiedAccounts(accounts, priceUpdateTxs, blockNumber) {
235
+ if (accounts.length === 0) return [];
236
+ const list = await (0, import_viem2.simulateWithPriceUpdates)(this.client, {
237
+ priceUpdates: priceUpdateTxs,
238
+ contracts: accounts.map(
239
+ (account) => ({
240
+ abi: import_creditAccountCompressor.creditAccountCompressorAbi,
241
+ address: this.#compressor,
242
+ functionName: "getCreditAccountData",
243
+ args: [account]
244
+ })
245
+ ),
246
+ blockNumber,
247
+ gas: this.sdk.gasLimit
248
+ });
249
+ return list;
250
+ }
165
251
  /**
166
252
  * Method to get all claimable rewards for credit account (ex. stkUSDS SKY rewards)
167
253
  Assosiates rewards by adapter + stakedPhantomToken
@@ -394,6 +480,13 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
394
480
  closePath
395
481
  }) {
396
482
  const cm = this.sdk.marketRegister.findCreditManager(ca.creditManager);
483
+ await this.sdk.tokensMeta.loadTokenData(cm.underlying);
484
+ const underlying = this.sdk.tokensMeta.mustGet(cm.underlying);
485
+ if (this.sdk.tokensMeta.isKYCUnderlying(underlying)) {
486
+ throw new Error(
487
+ "closeCreditAccount is not supported for KYC underlying credit accounts"
488
+ );
489
+ }
397
490
  const routerCloseResult = closePath || await this.sdk.routerFor(ca).findBestClosePath({
398
491
  creditAccount: ca,
399
492
  creditManager: cm.creditManager,
@@ -796,10 +889,9 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
796
889
  async getApprovalAddress(options) {
797
890
  const { creditManager } = options;
798
891
  const suite = this.sdk.marketRegister.findCreditManager(creditManager);
799
- await this.sdk.tokensMeta.loadTokenData(suite.underlying);
800
- const underlying = this.sdk.tokensMeta.mustGet(suite.underlying);
801
- if (this.sdk.tokensMeta.isKYCUnderlying(underlying)) {
802
- const factory = new import_market.SecuritizeKYCFactory(this.sdk, underlying.kycFactory);
892
+ const marketSuite = this.sdk.marketRegister.findByPool(suite.pool);
893
+ const factory = await marketSuite.getKYCFactory();
894
+ if (factory) {
803
895
  if ("creditAccount" in options) {
804
896
  return factory.getWallet(options.creditAccount);
805
897
  }
@@ -955,6 +1047,99 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
955
1047
  );
956
1048
  return resp;
957
1049
  }
1050
+ /**
1051
+ * Returns multicall entries to redeem (unwrap) KYC ERC-4626 vault shares into underlying for the given credit manager.
1052
+ * Used when withdrawing debt from a KYC market: redeems adapter vault shares so the underlying can be withdrawn.
1053
+ * Only applies when the credit manager's underlying is KYC-gated and has an ERC-4626 adapter configured.
1054
+ * @param amount - Number of vault shares (adapter tokens) to redeem
1055
+ * @param creditManager - Credit manager address
1056
+ * @returns Array of MultiCall to pass to credit facade multicall, or undefined if underlying is not KYC or no adapter is configured
1057
+ */
1058
+ async getKYCUnwrapCalls(amount, creditManager) {
1059
+ const suite = this.sdk.marketRegister.findCreditManager(creditManager);
1060
+ const meta = this.sdk.tokensMeta.mustGet(suite.underlying);
1061
+ if (!this.sdk.tokensMeta.isKYCUnderlying(meta)) {
1062
+ return void 0;
1063
+ }
1064
+ const adapter = suite.creditManager.adapters.get(meta.addr);
1065
+ const adapterAddress = adapter?.address;
1066
+ if (!adapterAddress) {
1067
+ return void 0;
1068
+ }
1069
+ const mc = [
1070
+ {
1071
+ target: adapterAddress,
1072
+ callData: (0, import_viem.encodeFunctionData)({
1073
+ abi: ierc4626AdapterAbi,
1074
+ functionName: "redeem",
1075
+ args: [amount, import_constants.ADDRESS_0X0, import_constants.ADDRESS_0X0]
1076
+ })
1077
+ }
1078
+ ];
1079
+ return mc;
1080
+ }
1081
+ /**
1082
+ * Returns multicall entries to deposit (wrap) underlying into KYC ERC-4626 vault shares for the given credit manager.
1083
+ * Used when adding debt on a KYC market: deposits underlying into the adapter vault so shares are minted on the account.
1084
+ * Only applies when the credit manager's underlying is KYC-gated and has an ERC-4626 adapter configured.
1085
+ * @param amount - Amount of underlying assets to deposit into the vault (in underlying decimals)
1086
+ * @param creditManager - Credit manager address
1087
+ * @returns Array of MultiCall to pass to credit facade multicall, or undefined if underlying is not KYC or no adapter is configured
1088
+ */
1089
+ async getKYCWrapCalls(amount, creditManager) {
1090
+ const suite = this.sdk.marketRegister.findCreditManager(creditManager);
1091
+ const meta = this.sdk.tokensMeta.mustGet(suite.underlying);
1092
+ if (!this.sdk.tokensMeta.isKYCUnderlying(meta)) {
1093
+ return void 0;
1094
+ }
1095
+ const adapter = suite.creditManager.adapters.get(meta.addr);
1096
+ const adapterAddress = adapter?.address;
1097
+ if (!adapterAddress) {
1098
+ return void 0;
1099
+ }
1100
+ const mc = [
1101
+ {
1102
+ target: adapterAddress,
1103
+ callData: (0, import_viem.encodeFunctionData)({
1104
+ abi: ierc4626AdapterAbi,
1105
+ functionName: "deposit",
1106
+ args: [amount, import_constants.ADDRESS_0X0]
1107
+ })
1108
+ }
1109
+ ];
1110
+ return mc;
1111
+ }
1112
+ /**
1113
+ * Returns multicall entries to call redeemDiff on the KYC ERC-4626 adapter for the given credit manager.
1114
+ * Redeems the leftover vault shares (e.g. after repaying debt) so the account does not hold excess KYC vault tokens.
1115
+ * Only applies when the credit manager's underlying is KYC-gated and has an ERC-4626 adapter configured.
1116
+ * @param amount - Leftover vault share amount to redeem (in adapter/vault decimals)
1117
+ * @param creditManager - Credit manager address
1118
+ * @returns Array of MultiCall to pass to credit facade multicall, or undefined if underlying is not KYC or no adapter is configured
1119
+ */
1120
+ async getRedeemDiffCalls(amount, creditManager) {
1121
+ const suite = this.sdk.marketRegister.findCreditManager(creditManager);
1122
+ const meta = this.sdk.tokensMeta.mustGet(suite.underlying);
1123
+ if (!this.sdk.tokensMeta.isKYCUnderlying(meta)) {
1124
+ return void 0;
1125
+ }
1126
+ const adapter = suite.creditManager.adapters.get(meta.addr);
1127
+ const adapterAddress = adapter?.address;
1128
+ if (!adapterAddress) {
1129
+ return void 0;
1130
+ }
1131
+ const mc = [
1132
+ {
1133
+ target: adapterAddress,
1134
+ callData: (0, import_viem.encodeFunctionData)({
1135
+ abi: ierc4626AdapterAbi,
1136
+ functionName: "redeemDiff",
1137
+ args: [amount]
1138
+ })
1139
+ }
1140
+ ];
1141
+ return mc;
1142
+ }
958
1143
  /**
959
1144
  * Returns raw txs that are needed to update all price feeds so that all credit accounts (possibly from different markets) compute
960
1145
  *
@@ -1221,10 +1406,9 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
1221
1406
  * @returns
1222
1407
  */
1223
1408
  async openCreditAccountTx(suite, to, calls, referralCode) {
1224
- await this.sdk.tokensMeta.loadTokenData(suite.underlying);
1225
- const underlying = this.sdk.tokensMeta.mustGet(suite.underlying);
1226
- if (this.sdk.tokensMeta.isKYCUnderlying(underlying)) {
1227
- const factory = new import_market.SecuritizeKYCFactory(this.sdk, underlying.kycFactory);
1409
+ const marketSuite = this.sdk.marketRegister.findByPool(suite.pool);
1410
+ const factory = await marketSuite.getKYCFactory();
1411
+ if (factory) {
1228
1412
  const tokensToRegister = await factory.getDSTokens();
1229
1413
  return factory.openCreditAccount(
1230
1414
  suite.creditManager.address,
@@ -1242,11 +1426,12 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
1242
1426
  * @returns
1243
1427
  */
1244
1428
  async multicallTx(suite, creditAccount, calls) {
1245
- await this.sdk.tokensMeta.loadTokenData(suite.underlying);
1246
- const underlying = this.sdk.tokensMeta.mustGet(suite.underlying);
1247
- if (this.sdk.tokensMeta.isKYCUnderlying(underlying)) {
1429
+ const marketSuite = this.sdk.marketRegister.findByCreditManager(
1430
+ suite.creditManager.address
1431
+ );
1432
+ const factory = await marketSuite.getKYCFactory();
1433
+ if (factory) {
1248
1434
  const tokensToRegister = [];
1249
- const factory = new import_market.SecuritizeKYCFactory(this.sdk, underlying.kycFactory);
1250
1435
  return factory.multicall(creditAccount, calls, tokensToRegister);
1251
1436
  }
1252
1437
  return suite.creditFacade.multicall(creditAccount, calls);
@@ -1260,16 +1445,128 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
1260
1445
  * @returns
1261
1446
  */
1262
1447
  async closeCreditAccountTx(suite, creditAccount, calls, operation) {
1263
- await this.sdk.tokensMeta.loadTokenData(suite.underlying);
1264
- const underlying = this.sdk.tokensMeta.mustGet(suite.underlying);
1265
- if (this.sdk.tokensMeta.isKYCUnderlying(underlying)) {
1266
- throw new Error(
1267
- "KYC underlying is not supported for close credit account"
1268
- );
1448
+ const marketSuite = this.sdk.marketRegister.findByCreditManager(
1449
+ suite.creditManager.address
1450
+ );
1451
+ const factory = await marketSuite.getKYCFactory();
1452
+ if (operation === "close") {
1453
+ if (factory) {
1454
+ throw new Error(
1455
+ "CloseOptions=close is not supported for KYC underlying credit accounts"
1456
+ );
1457
+ }
1458
+ return suite.creditFacade.closeCreditAccount(creditAccount, calls);
1269
1459
  }
1270
- return operation === "close" ? suite.creditFacade.closeCreditAccount(creditAccount, calls) : suite.creditFacade.multicall(creditAccount, calls);
1460
+ if (factory) {
1461
+ const tokensToRegister = [];
1462
+ return factory.multicall(creditAccount, calls, tokensToRegister);
1463
+ }
1464
+ return suite.creditFacade.multicall(creditAccount, calls);
1465
+ }
1466
+ /**
1467
+ * Returns all KYC credit account addresses for an investor across the given market suites.
1468
+ * Resolves KYC factory per suite, then multicalls each factory's getCreditAccounts(investor).
1469
+ * @param investor - Owner address to query
1470
+ * @param suites - Market suites (KYC factories are resolved for each; undefined entries are skipped)
1471
+ * @returns Flat array of credit account addresses from all KYC markets
1472
+ */
1473
+ async getKYCCaOfInvestor(investor, suites) {
1474
+ if (suites.length === 0 || investor === import_constants.ADDRESS_0X0) return [];
1475
+ const factories = await Promise.all(
1476
+ suites.map((suite) => suite ? suite.getKYCFactory() : void 0)
1477
+ );
1478
+ const safeFactories = factories.reduce(
1479
+ (acc, v) => {
1480
+ if (v) {
1481
+ acc.push(v);
1482
+ }
1483
+ return acc;
1484
+ },
1485
+ []
1486
+ );
1487
+ const allResp = await this.client.multicall({
1488
+ contracts: [
1489
+ ...safeFactories.map((factory) => {
1490
+ return {
1491
+ abi: factory.abi,
1492
+ address: factory.address,
1493
+ functionName: "getCreditAccounts",
1494
+ args: [investor]
1495
+ };
1496
+ })
1497
+ ],
1498
+ allowFailure: true,
1499
+ batchSize: 0
1500
+ });
1501
+ const caLists = safeFactories.reduce((acc, _, index) => {
1502
+ const response = allResp[index];
1503
+ acc.push(...response.result || []);
1504
+ return acc;
1505
+ }, []);
1506
+ return caLists;
1271
1507
  }
1272
1508
  }
1509
+ const ierc4626AdapterAbi = [
1510
+ {
1511
+ inputs: [
1512
+ { name: "assets", type: "uint256", internalType: "uint256" },
1513
+ { name: "receiver", type: "address", internalType: "address" }
1514
+ ],
1515
+ name: "deposit",
1516
+ outputs: [{ name: "useSafePrices", type: "bool", internalType: "bool" }],
1517
+ stateMutability: "nonpayable",
1518
+ type: "function"
1519
+ },
1520
+ {
1521
+ inputs: [
1522
+ { name: "shares", type: "uint256", internalType: "uint256" },
1523
+ { name: "receiver", type: "address", internalType: "address" },
1524
+ { name: "owner", type: "address", internalType: "address" }
1525
+ ],
1526
+ name: "redeem",
1527
+ outputs: [{ name: "useSafePrices", type: "bool", internalType: "bool" }],
1528
+ stateMutability: "nonpayable",
1529
+ type: "function"
1530
+ },
1531
+ {
1532
+ inputs: [
1533
+ {
1534
+ name: "leftoverAmount",
1535
+ type: "uint256",
1536
+ internalType: "uint256"
1537
+ }
1538
+ ],
1539
+ name: "redeemDiff",
1540
+ outputs: [
1541
+ {
1542
+ name: "useSafePrices",
1543
+ type: "bool",
1544
+ internalType: "bool"
1545
+ }
1546
+ ],
1547
+ stateMutability: "nonpayable",
1548
+ type: "function"
1549
+ },
1550
+ {
1551
+ inputs: [
1552
+ {
1553
+ name: "leftoverAmount",
1554
+ type: "uint256",
1555
+ internalType: "uint256"
1556
+ }
1557
+ ],
1558
+ name: "depositDiff",
1559
+ outputs: [
1560
+ {
1561
+ name: "useSafePrices",
1562
+ type: "bool",
1563
+ internalType: "bool"
1564
+ }
1565
+ ],
1566
+ stateMutability: "nonpayable",
1567
+ type: "function"
1568
+ }
1569
+ ];
1273
1570
  // Annotate the CommonJS export names for ESM import in node:
1274
1571
  0 && (module.exports = {
1275
1572
  AbstractCreditAccountService,
@@ -113,11 +113,13 @@ class CreditAccountServiceV310 extends import_AbstractCreditAccountsService.Abst
113
113
  creditAccount: ca,
114
114
  permits,
115
115
  to,
116
- tokensToClaim
116
+ tokensToClaim,
117
+ calls: wrapCalls = []
117
118
  }) {
118
119
  const cm = this.sdk.marketRegister.findCreditManager(ca.creditManager);
119
120
  const addCollateral = collateralAssets.filter((a) => a.balance > 0);
120
121
  const router = this.sdk.routerFor(ca);
122
+ const unwrapCalls = await this.getRedeemDiffCalls(1n, ca.creditManager) ?? [];
121
123
  const claimPath = await router.findClaimAllRewards({
122
124
  calls: [],
123
125
  tokensToClaim,
@@ -130,8 +132,10 @@ class CreditAccountServiceV310 extends import_AbstractCreditAccountsService.Abst
130
132
  const calls = [
131
133
  ...operation === "close" ? [] : priceUpdates,
132
134
  ...this.prepareAddCollateral(ca.creditFacade, addCollateral, permits),
135
+ ...wrapCalls,
133
136
  ...this.prepareDisableQuotas(ca),
134
137
  ...this.prepareDecreaseDebt(ca),
138
+ ...unwrapCalls,
135
139
  ...claimPath.calls,
136
140
  ...this.prepareDisableTokens(ca),
137
141
  ...assetsToWithdraw.map(
@@ -81,7 +81,8 @@ const chains = {
81
81
  "0x601067eba24bb5b558a184fc082525637e96a42d": "Gami Labs"
82
82
  },
83
83
  testMarketConfigurators: {
84
- "0x99df7330bf42d596af2e9d9836d4fc2077c574aa": "M11 Credit"
84
+ "0x99df7330bf42d596af2e9d9836d4fc2077c574aa": "M11 Credit",
85
+ "0xE0527dE5908B3fc2e054B7eEE0DeF6c9965AbF24": "Securitize"
85
86
  },
86
87
  isPublic: true,
87
88
  wellKnownToken: {
@@ -23,8 +23,10 @@ __export(SecuritizeKYCFactory_exports, {
23
23
  module.exports = __toCommonJS(SecuritizeKYCFactory_exports);
24
24
  var import_iSecuritizeKYCFactory = require("../../../abi/310/iSecuritizeKYCFactory.js");
25
25
  var import_base = require("../../base/index.js");
26
+ var import__ = require("../../index.js");
26
27
  const abi = import_iSecuritizeKYCFactory.iSecuritizeKYCFactoryAbi;
27
28
  class SecuritizeKYCFactory extends import_base.BaseContract {
29
+ investorCache;
28
30
  constructor(options, address) {
29
31
  super(options, {
30
32
  addr: address,
@@ -41,6 +43,24 @@ class SecuritizeKYCFactory extends import_base.BaseContract {
41
43
  async getWallet(creditAccount) {
42
44
  return this.contract.read.getWallet([creditAccount]);
43
45
  }
46
+ /**
47
+ * Returns the investor address for a credit account.
48
+ * @param creditAccount - Credit account address
49
+ * @param fromCache - If true, use and update an in-memory cache (creditAccount -> investor). On cache miss, loads from contract and stores the result for future calls.
50
+ */
51
+ async getInvestor(creditAccount, fromCache) {
52
+ if (fromCache && this.investorCache?.has(creditAccount)) {
53
+ return this.investorCache.get(creditAccount);
54
+ }
55
+ const investor = await this.contract.read.getInvestor([creditAccount]);
56
+ if (fromCache) {
57
+ if (!this.investorCache) {
58
+ this.investorCache = new import__.AddressMap();
59
+ }
60
+ this.investorCache.upsert(creditAccount, investor);
61
+ }
62
+ return investor;
63
+ }
44
64
  async getDSTokens() {
45
65
  const tokens = await this.contract.read.getDSTokens();
46
66
  return [...tokens];
@@ -38,6 +38,7 @@ class CreditAccountData_Legacy {
38
38
  underlying;
39
39
  expirationDate;
40
40
  version;
41
+ investor;
41
42
  enabledTokensMask;
42
43
  healthFactor;
43
44
  baseBorrowRateWithoutFee;
@@ -67,6 +68,7 @@ class CreditAccountData_Legacy {
67
68
  this.underlying = payload.underlying.toLowerCase();
68
69
  this.expirationDate = Number(payload.expirationDate);
69
70
  this.version = Number(payload.cfVersion);
71
+ this.investor = payload.investor.toLowerCase();
70
72
  this.healthFactor = Number(
71
73
  (payload.healthFactor || 0n) * import_constants.PERCENTAGE_FACTOR / import_constants.WAD
72
74
  );