@gearbox-protocol/sdk 14.0.0-next.9 → 14.1.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/dist/cjs/abi/kyc/iDSRegistryService.js +149 -0
  2. package/dist/cjs/abi/kyc/iDSToken.js +71 -0
  3. package/dist/cjs/abi/kyc/iKYCCompressor.js +196 -0
  4. package/dist/cjs/abi/kyc/iKYCFactory.js +122 -0
  5. package/dist/cjs/abi/kyc/iKYCUnderlying.js +401 -0
  6. package/dist/cjs/abi/kyc/iSecuritizeDegenNFT.js +326 -0
  7. package/dist/cjs/abi/kyc/iSecuritizeKYCFactory.js +319 -0
  8. package/dist/cjs/dev/AccountOpener.js +45 -5
  9. package/dist/cjs/rewards/rewards/extra-apy.js +1 -1
  10. package/dist/cjs/sdk/MultichainSDK.js +5 -0
  11. package/dist/cjs/sdk/OnchainSDK.js +55 -6
  12. package/dist/cjs/sdk/accounts/AbstractCreditAccountsService.js +335 -21
  13. package/dist/cjs/sdk/accounts/CreditAccountsServiceV310.js +7 -1
  14. package/dist/cjs/sdk/base/TokensMeta.js +22 -42
  15. package/dist/cjs/sdk/base/token-types.js +9 -0
  16. package/dist/cjs/sdk/chain/chains.js +18 -1
  17. package/dist/cjs/sdk/constants/address-provider.js +3 -0
  18. package/dist/cjs/sdk/market/MarketRegister.js +70 -116
  19. package/dist/cjs/sdk/market/MarketSuite.js +3 -0
  20. package/dist/cjs/sdk/market/index.js +2 -0
  21. package/dist/cjs/sdk/market/kyc/KYCRegistry.js +269 -0
  22. package/dist/cjs/sdk/market/kyc/index.js +26 -0
  23. package/dist/cjs/sdk/market/kyc/securitize/SecuritizeKYCFactory.js +242 -0
  24. package/dist/cjs/sdk/market/kyc/securitize/constants.js +28 -0
  25. package/dist/cjs/sdk/market/kyc/securitize/index.js +26 -0
  26. package/dist/cjs/sdk/market/kyc/securitize/types.js +16 -0
  27. package/dist/cjs/sdk/{accounts/utils.js → market/kyc/types.js} +11 -15
  28. package/dist/cjs/sdk/market/pool/PoolSuite.js +3 -0
  29. package/dist/cjs/sdk/market/pool/PoolV310Contract.js +11 -2
  30. package/dist/cjs/sdk/market/pool/index.js +2 -0
  31. package/dist/cjs/sdk/market/pricefeeds/PriceFeedsRegister.js +3 -3
  32. package/dist/cjs/sdk/options.js +6 -0
  33. package/dist/cjs/sdk/pools/PoolService.js +104 -12
  34. package/dist/cjs/sdk/utils/viem/executeDelegatedMulticalls.js +38 -0
  35. package/dist/cjs/sdk/utils/viem/index.js +2 -4
  36. package/dist/esm/abi/kyc/iDSRegistryService.js +125 -0
  37. package/dist/esm/abi/kyc/iDSToken.js +47 -0
  38. package/dist/esm/abi/kyc/iKYCCompressor.js +172 -0
  39. package/dist/esm/abi/kyc/iKYCFactory.js +98 -0
  40. package/dist/esm/abi/kyc/iKYCUnderlying.js +377 -0
  41. package/dist/esm/abi/kyc/iSecuritizeDegenNFT.js +302 -0
  42. package/dist/esm/abi/kyc/iSecuritizeKYCFactory.js +295 -0
  43. package/dist/esm/dev/AccountOpener.js +47 -6
  44. package/dist/esm/rewards/rewards/extra-apy.js +1 -1
  45. package/dist/esm/sdk/MultichainSDK.js +5 -0
  46. package/dist/esm/sdk/OnchainSDK.js +58 -7
  47. package/dist/esm/sdk/accounts/AbstractCreditAccountsService.js +336 -22
  48. package/dist/esm/sdk/accounts/CreditAccountsServiceV310.js +7 -1
  49. package/dist/esm/sdk/base/TokensMeta.js +22 -44
  50. package/dist/esm/sdk/base/token-types.js +6 -0
  51. package/dist/esm/sdk/chain/chains.js +18 -1
  52. package/dist/esm/sdk/constants/address-provider.js +2 -0
  53. package/dist/esm/sdk/market/MarketRegister.js +74 -118
  54. package/dist/esm/sdk/market/MarketSuite.js +3 -0
  55. package/dist/esm/sdk/market/index.js +1 -0
  56. package/dist/esm/sdk/market/kyc/KYCRegistry.js +253 -0
  57. package/dist/esm/sdk/market/kyc/index.js +3 -0
  58. package/dist/esm/sdk/market/kyc/securitize/SecuritizeKYCFactory.js +218 -0
  59. package/dist/esm/sdk/market/kyc/securitize/constants.js +4 -0
  60. package/dist/esm/sdk/market/kyc/securitize/index.js +3 -0
  61. package/dist/esm/sdk/market/kyc/securitize/types.js +0 -0
  62. package/dist/esm/sdk/market/kyc/types.js +9 -0
  63. package/dist/esm/sdk/market/pool/PoolSuite.js +3 -0
  64. package/dist/esm/sdk/market/pool/PoolV310Contract.js +11 -2
  65. package/dist/esm/sdk/market/pool/index.js +1 -0
  66. package/dist/esm/sdk/market/pricefeeds/PriceFeedsRegister.js +3 -3
  67. package/dist/esm/sdk/options.js +6 -0
  68. package/dist/esm/sdk/pools/PoolService.js +109 -13
  69. package/dist/esm/sdk/utils/viem/executeDelegatedMulticalls.js +14 -0
  70. package/dist/esm/sdk/utils/viem/index.js +1 -2
  71. package/dist/types/abi/kyc/iDSRegistryService.d.ts +191 -0
  72. package/dist/types/abi/kyc/iDSToken.d.ts +67 -0
  73. package/dist/types/abi/kyc/iKYCCompressor.d.ts +228 -0
  74. package/dist/types/abi/kyc/iKYCFactory.d.ts +139 -0
  75. package/dist/types/abi/kyc/iKYCUnderlying.d.ts +548 -0
  76. package/dist/types/abi/kyc/iSecuritizeDegenNFT.d.ts +404 -0
  77. package/dist/types/abi/kyc/iSecuritizeKYCFactory.d.ts +376 -0
  78. package/dist/types/sdk/OnchainSDK.d.ts +19 -1
  79. package/dist/types/sdk/accounts/AbstractCreditAccountsService.d.ts +59 -6
  80. package/dist/types/sdk/accounts/CreditAccountsServiceV310.d.ts +1 -1
  81. package/dist/types/sdk/accounts/types.d.ts +114 -14
  82. package/dist/types/sdk/base/TokensMeta.d.ts +14 -3
  83. package/dist/types/sdk/base/token-types.d.ts +44 -4
  84. package/dist/types/sdk/base/types.d.ts +116 -2
  85. package/dist/types/sdk/chain/chains.d.ts +5 -1
  86. package/dist/types/sdk/constants/address-provider.d.ts +1 -0
  87. package/dist/types/sdk/market/MarketRegister.d.ts +6 -9
  88. package/dist/types/sdk/market/MarketSuite.d.ts +2 -0
  89. package/dist/types/sdk/market/index.d.ts +1 -0
  90. package/dist/types/sdk/market/kyc/KYCRegistry.d.ts +52 -0
  91. package/dist/types/sdk/market/kyc/index.d.ts +3 -0
  92. package/dist/types/sdk/market/kyc/securitize/SecuritizeKYCFactory.d.ts +429 -0
  93. package/dist/types/sdk/market/kyc/securitize/constants.d.ts +1 -0
  94. package/dist/types/sdk/market/kyc/securitize/index.d.ts +3 -0
  95. package/dist/types/sdk/market/kyc/securitize/types.d.ts +136 -0
  96. package/dist/types/sdk/market/kyc/types.d.ts +171 -0
  97. package/dist/types/sdk/market/oracle/PriceOracleBaseContract.d.ts +3 -2
  98. package/dist/types/sdk/market/oracle/types.d.ts +3 -10
  99. package/dist/types/sdk/market/pool/PoolSuite.d.ts +2 -0
  100. package/dist/types/sdk/market/pool/PoolV310Contract.d.ts +6 -2
  101. package/dist/types/sdk/market/pool/index.d.ts +1 -0
  102. package/dist/types/sdk/market/pricefeeds/PriceFeedsRegister.d.ts +1 -1
  103. package/dist/types/sdk/market/types.d.ts +1 -1
  104. package/dist/types/sdk/options.d.ts +1 -0
  105. package/dist/types/sdk/pools/PoolService.d.ts +8 -8
  106. package/dist/types/sdk/pools/types.d.ts +1 -1
  107. package/dist/types/sdk/types/state-human.d.ts +2 -0
  108. package/dist/types/sdk/types/state.d.ts +5 -0
  109. package/dist/types/sdk/utils/viem/executeDelegatedMulticalls.d.ts +28 -0
  110. package/dist/types/sdk/utils/viem/index.d.ts +1 -2
  111. package/package.json +4 -4
  112. package/dist/cjs/sdk/utils/viem/getLogsPaginated.js +0 -62
  113. package/dist/cjs/sdk/utils/viem/getLogsSafe.js +0 -87
  114. package/dist/esm/sdk/accounts/utils.js +0 -14
  115. package/dist/esm/sdk/utils/viem/getLogsPaginated.js +0 -38
  116. package/dist/esm/sdk/utils/viem/getLogsSafe.js +0 -65
  117. package/dist/types/sdk/accounts/utils.d.ts +0 -2
  118. package/dist/types/sdk/utils/viem/getLogsPaginated.d.ts +0 -12
  119. package/dist/types/sdk/utils/viem/getLogsSafe.d.ts +0 -3
@@ -65,8 +65,10 @@ const chains = {
65
65
  "0x601067eba24bb5b558a184fc082525637e96a42d": "Gami Labs"
66
66
  },
67
67
  testMarketConfigurators: {
68
- "0x99df7330bf42d596af2e9d9836d4fc2077c574aa": "M11 Credit"
68
+ "0x99df7330bf42d596af2e9d9836d4fc2077c574aa": "M11 Credit",
69
+ "0x610627d8d01a413bdd9b0a0b60070da7dd1e54ad": "Securitize"
69
70
  },
71
+ kycFactories: [],
70
72
  isPublic: true,
71
73
  wellKnownToken: {
72
74
  address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
@@ -84,6 +86,7 @@ const chains = {
84
86
  defaultMarketConfigurators: {
85
87
  "0x01023850b360b88de0d0f84015bbba1eba57fe7e": "Chaos Labs"
86
88
  },
89
+ kycFactories: [],
87
90
  isPublic: true,
88
91
  wellKnownToken: {
89
92
  address: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
@@ -102,6 +105,7 @@ const chains = {
102
105
  "0x2a15969CE5320868eb609680751cF8896DD92De5": "Chaos Labs",
103
106
  "0x9dddd1b9ce0ac8aa0c80e4ec141600b9bf0101c3": "UltraYield"
104
107
  },
108
+ kycFactories: [],
105
109
  isPublic: true,
106
110
  wellKnownToken: {
107
111
  address: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",
@@ -117,6 +121,7 @@ const chains = {
117
121
  ...base,
118
122
  network: "Base",
119
123
  defaultMarketConfigurators: {},
124
+ kycFactories: [],
120
125
  isPublic: false,
121
126
  wellKnownToken: {
122
127
  address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
@@ -133,6 +138,7 @@ const chains = {
133
138
  defaultMarketConfigurators: {
134
139
  "0x8FFDd1F1433674516f83645a768E8900A2A5D076": "Chaos Labs"
135
140
  },
141
+ kycFactories: [],
136
142
  isPublic: true,
137
143
  blockExplorers: {
138
144
  default: {
@@ -154,6 +160,7 @@ const chains = {
154
160
  ...megaeth,
155
161
  network: "MegaETH",
156
162
  defaultMarketConfigurators: {},
163
+ kycFactories: [],
157
164
  isPublic: false,
158
165
  wellKnownToken: {
159
166
  address: "0xFAfDdbb3FC7688494971a79cc65DCa3EF82079E7",
@@ -175,6 +182,7 @@ const chains = {
175
182
  "0x16956912813ab9a38d95730b52a8cf53e860a7c5": "Tulipa",
176
183
  "0x7c6ee1bf9c1eb3ee55bdbdc1e8d0317aab718e0a": "UltraYield"
177
184
  },
185
+ kycFactories: [],
178
186
  isPublic: true,
179
187
  wellKnownToken: {
180
188
  address: "0xe7cd86e13AC4309349F30B3435a9d337750fC82D",
@@ -188,6 +196,7 @@ const chains = {
188
196
  ...berachain,
189
197
  network: "Berachain",
190
198
  defaultMarketConfigurators: {},
199
+ kycFactories: [],
191
200
  isPublic: false,
192
201
  blockExplorers: {
193
202
  default: {
@@ -209,6 +218,7 @@ const chains = {
209
218
  ...avalanche,
210
219
  network: "Avalanche",
211
220
  defaultMarketConfigurators: {},
221
+ kycFactories: [],
212
222
  isPublic: false,
213
223
  wellKnownToken: {
214
224
  address: "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",
@@ -227,6 +237,7 @@ const chains = {
227
237
  "0x92dc4ee43e9b207e16fbf3fd1a6933563c0a0d35": "Re7"
228
238
  },
229
239
  testMarketConfigurators: {},
240
+ kycFactories: [],
230
241
  isPublic: true,
231
242
  wellKnownToken: {
232
243
  address: "0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d",
@@ -241,6 +252,7 @@ const chains = {
241
252
  ...worldchain,
242
253
  network: "WorldChain",
243
254
  defaultMarketConfigurators: {},
255
+ kycFactories: [],
244
256
  isPublic: false,
245
257
  wellKnownToken: {
246
258
  address: "0x79a02482a880bce3f13e09da970dc34db4cd24d1",
@@ -255,6 +267,7 @@ const chains = {
255
267
  defaultMarketConfigurators: {
256
268
  "0x577424f0e6f50db668cc1bc76babb87e36732291": "Re7"
257
269
  },
270
+ kycFactories: [],
258
271
  isPublic: true,
259
272
  wellKnownToken: {
260
273
  address: "0x796Ea11Fa2dD751eD01b53C372fFDB4AAa8f00F9",
@@ -269,6 +282,7 @@ const chains = {
269
282
  defaultMarketConfigurators: {
270
283
  "0xc9961b8a0c763779690577f2c76962c086af2fe3": "Invariant Group"
271
284
  },
285
+ kycFactories: [],
272
286
  isPublic: true,
273
287
  wellKnownToken: {
274
288
  address: "0xad11a8BEb98bbf61dbb1aa0F6d6F2ECD87b35afA",
@@ -288,6 +302,7 @@ const chains = {
288
302
  defaultMarketConfigurators: {
289
303
  "0x25778dbf0e56b7feb8358c4aa2f6f9e19a1c145a": "Re7"
290
304
  },
305
+ kycFactories: [],
291
306
  isPublic: true,
292
307
  wellKnownToken: {
293
308
  address: "0xF242275d3a6527d877f2c927a82D9b057609cc71",
@@ -304,6 +319,7 @@ const chains = {
304
319
  "0xce1cf71a28837daaa7b92d00ca4ef2fd649c2a67": "Hyperithm",
305
320
  "0x9655f82b585b11cee8a05576ed8efcf755cec04b": "TelosC"
306
321
  },
322
+ kycFactories: [],
307
323
  isPublic: true,
308
324
  wellKnownToken: {
309
325
  address: "0x5d72a9d9a9510cd8cbdba12ac62593a58930a948",
@@ -330,6 +346,7 @@ const chains = {
330
346
  defaultMarketConfigurators: {
331
347
  "0x1ca8b92aa7233a9f8f7ba031ac45c878141adff0": "Invariant Group"
332
348
  },
349
+ kycFactories: [],
333
350
  isPublic: true,
334
351
  wellKnownToken: {
335
352
  address: "0x67B302E35Aef5EEE8c32D934F5856869EF428330",
@@ -31,6 +31,7 @@ const AP_WETH_GATEWAY = "WETH_GATEWAY";
31
31
  const AP_WETH_TOKEN = "WETH_TOKEN";
32
32
  const AP_ZAPPER_REGISTER = "ZAPPER_REGISTER";
33
33
  const AP_ZERO_PRICE_FEED = "ZERO_PRICE_FEED";
34
+ const AP_KYC_COMPRESSOR = "GLOBAL::KYC_COMPRESSOR";
34
35
  const ADDRESS_PROVIDER_V310 = "0xF7f0a609BfAb9a0A98786951ef10e5FE26cC1E38";
35
36
  export {
36
37
  ADDRESS_PROVIDER_V310,
@@ -51,6 +52,7 @@ export {
51
52
  AP_GEAR_TOKEN,
52
53
  AP_INFLATION_ATTACK_BLOCKER,
53
54
  AP_INSOLVENCY_CHECKER,
55
+ AP_KYC_COMPRESSOR,
54
56
  AP_MARKET_COMPRESSOR,
55
57
  AP_MARKET_CONFIGURATOR,
56
58
  AP_PARTIAL_LIQUIDATION_BOT,
@@ -4,12 +4,17 @@ import {
4
4
  AP_MARKET_COMPRESSOR,
5
5
  VERSION_RANGE_310
6
6
  } from "../constants/index.js";
7
- import { AddressMap } from "../utils/index.js";
8
- import { simulateWithPriceUpdates } from "../utils/viem/index.js";
7
+ import { AddressMap, AddressSet } from "../utils/index.js";
8
+ import {
9
+ executeDelegatedMulticalls
10
+ } from "../utils/viem/index.js";
9
11
  import { MarketConfiguratorContract } from "./MarketConfiguratorContract.js";
10
12
  import { MarketSuite } from "./MarketSuite.js";
11
13
  import { ZapperRegister } from "./ZapperRegister.js";
12
14
  class MarketRegister extends ZapperRegister {
15
+ /**
16
+ * Mapping pool.address -> MarketSuite
17
+ */
13
18
  #markets = new AddressMap(void 0, "markets");
14
19
  #marketFilter;
15
20
  #marketConfigurators = new AddressMap(
@@ -23,9 +28,7 @@ class MarketRegister extends ZapperRegister {
23
28
  **/
24
29
  constructor(sdk, ignoreMarkets = []) {
25
30
  super(sdk);
26
- this.#ignoreMarkets = new Set(
27
- ignoreMarkets.map((m) => m.toLowerCase())
28
- );
31
+ this.#ignoreMarkets = new AddressSet(ignoreMarkets);
29
32
  }
30
33
  /**
31
34
  * Restores market state from a previously serialized snapshot,
@@ -33,40 +36,41 @@ class MarketRegister extends ZapperRegister {
33
36
  * @param state - Array of market data snapshots.
34
37
  **/
35
38
  hydrate(state) {
36
- this.#markets.clear();
37
39
  const configurators = new Set(state.map((m) => m.configurator));
38
40
  this.#setMarketFilter([...configurators]);
39
- for (const data of state) {
40
- const pool = data.pool.baseParams.addr;
41
- if (this.#ignoreMarkets.has(pool.toLowerCase())) {
42
- this.logger?.debug(
43
- `ignoring market of pool ${pool} (${data.pool.name})`
44
- );
45
- continue;
46
- }
47
- this.#markets.upsert(
48
- data.pool.baseParams.addr,
49
- new MarketSuite(this.sdk, data)
50
- );
51
- }
41
+ this.#setMarkets(state);
52
42
  }
53
43
  /**
54
- * Fetches all markets from the on-chain for the given market configurators.
44
+ * @internal
45
+ * Returns delegated multicalls for loading all markets from the on-chain
46
+ * market compressor. Used by the SDK to compose batched RPC calls.
55
47
  *
56
- * @param marketConfigurators - Addresses of market configurator contracts to query.
57
- * @param ignoreUpdateablePrices - When `true`, skips generating off-chain
58
- * price updates before loading
48
+ * @param configurators - Addresses of market configurator contracts to query.
59
49
  **/
60
- async loadMarkets(marketConfigurators, ignoreUpdateablePrices) {
61
- if (!marketConfigurators.length) {
62
- this.logger?.warn(
63
- "no market configurators provided, skipping loadMarkets"
64
- );
65
- return;
66
- }
67
- await this.#loadMarkets(marketConfigurators, [], ignoreUpdateablePrices);
50
+ getLoadMulticalls(configurators) {
51
+ this.#setMarketFilter(configurators);
52
+ const [marketCompressorAddress] = this.sdk.addressProvider.mustGetLatest(
53
+ AP_MARKET_COMPRESSOR,
54
+ VERSION_RANGE_310
55
+ );
56
+ return [
57
+ {
58
+ call: {
59
+ abi: marketCompressorAbi,
60
+ address: marketCompressorAddress,
61
+ functionName: "getMarkets",
62
+ args: [this.marketFilter]
63
+ },
64
+ onResult: (resp) => {
65
+ this.#setMarkets(resp);
66
+ this.logger?.info(
67
+ `loaded ${this.#markets.size} markets in block ${this.sdk.currentBlock}`
68
+ );
69
+ }
70
+ }
71
+ ];
68
72
  }
69
- #setMarketFilter(configurators, pools = []) {
73
+ #setMarketFilter(configurators) {
70
74
  for (const c of configurators) {
71
75
  this.#marketConfigurators.upsert(
72
76
  c,
@@ -75,7 +79,7 @@ class MarketRegister extends ZapperRegister {
75
79
  }
76
80
  this.#marketFilter = {
77
81
  configurators,
78
- pools,
82
+ pools: [],
79
83
  underlying: ADDRESS_0X0
80
84
  };
81
85
  }
@@ -102,106 +106,45 @@ class MarketRegister extends ZapperRegister {
102
106
  **/
103
107
  async syncState(ignoreUpdateablePrices) {
104
108
  const dirty = this.markets.some((m) => m.dirty) || this.marketConfigurators.some((c) => c.dirty);
109
+ let multicalls;
110
+ let txs = [];
105
111
  if (dirty) {
106
112
  this.logger?.debug(
107
113
  "some markets or market configurators are dirty, reloading everything"
108
114
  );
109
- await this.#loadMarkets(
110
- [...this.marketFilter.configurators],
111
- [...this.marketFilter.pools],
112
- ignoreUpdateablePrices
113
- );
115
+ multicalls = this.getLoadMulticalls([...this.marketFilter.configurators]);
116
+ if (!ignoreUpdateablePrices) {
117
+ const updatables = await this.sdk.priceFeeds.getPartialUpdatablePriceFeeds([
118
+ ...this.marketFilter.configurators
119
+ ]);
120
+ const updates = await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(updatables);
121
+ txs = updates.txs;
122
+ }
114
123
  } else if (!ignoreUpdateablePrices) {
115
- await this.updatePrices();
116
- }
117
- }
118
- async #loadMarkets(configurators, pools, ignoreUpdateablePrices) {
119
- this.#setMarketFilter(configurators, pools);
120
- const [marketCompressorAddress] = this.sdk.addressProvider.mustGetLatest(
121
- AP_MARKET_COMPRESSOR,
122
- VERSION_RANGE_310
123
- );
124
- let txs = [];
125
- if (!ignoreUpdateablePrices) {
126
- const updatables = await this.sdk.priceFeeds.getPartialUpdatablePriceFeeds(
127
- configurators,
128
- pools
129
- );
130
- const updates = await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(updatables);
124
+ multicalls = this.#getOracleSyncMulticalls();
125
+ if (!multicalls.length) {
126
+ return;
127
+ }
128
+ this.logger?.debug(`syncing prices on ${multicalls.length} oracles`);
129
+ const updates = await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs();
131
130
  txs = updates.txs;
132
- }
133
- this.logger?.debug(
134
- { configurators, pools },
135
- `calling getMarkets with ${txs.length} price updates in block ${this.sdk.currentBlock}`
136
- );
137
- let markets = [];
138
- if (txs.length) {
139
- const [resp] = await simulateWithPriceUpdates(this.client, {
140
- priceUpdates: txs,
141
- contracts: [
142
- {
143
- abi: marketCompressorAbi,
144
- address: marketCompressorAddress,
145
- functionName: "getMarkets",
146
- args: [this.marketFilter]
147
- }
148
- ],
149
- blockNumber: this.sdk.currentBlock,
150
- gas: this.sdk.gasLimit
151
- });
152
- markets = resp;
153
131
  } else {
154
- markets = await this.client.readContract({
155
- abi: marketCompressorAbi,
156
- address: marketCompressorAddress,
157
- functionName: "getMarkets",
158
- args: [this.marketFilter],
159
- blockNumber: this.sdk.currentBlock,
160
- // @ts-expect-error
161
- gas: this.sdk.gasLimit
162
- });
163
- }
164
- for (const data of markets) {
165
- const pool = data.pool.baseParams.addr;
166
- if (this.#ignoreMarkets.has(pool.toLowerCase())) {
167
- this.logger?.debug(
168
- `ignoring market of pool ${pool} (${data.pool.name})`
169
- );
170
- continue;
171
- }
172
- this.#markets.upsert(pool, new MarketSuite(this.sdk, data));
132
+ return;
173
133
  }
174
- this.logger?.info(
175
- `loaded ${this.#markets.size} markets in block ${this.sdk.currentBlock}`
176
- );
134
+ await executeDelegatedMulticalls(this.client, multicalls, {
135
+ priceUpdates: txs,
136
+ blockNumber: this.sdk.currentBlock,
137
+ gas: this.sdk.gasLimit
138
+ });
177
139
  }
178
- /**
179
- * Loads new prices and price feeds for given oracles from PriceFeedCompressor, defaults to all oracles
180
- */
181
- async updatePrices(oracles) {
140
+ #getOracleSyncMulticalls(oracles) {
182
141
  const uniqOracles = new AddressMap();
183
142
  for (const m of this.markets) {
184
143
  if (!oracles || oracles.includes(m.priceOracle.address)) {
185
144
  uniqOracles.upsert(m.priceOracle.address, m.priceOracle);
186
145
  }
187
146
  }
188
- const multicalls = uniqOracles.values().map((o) => o.syncStateMulticall());
189
- if (!multicalls.length) {
190
- return;
191
- }
192
- this.logger?.debug(`syncing prices on ${multicalls.length} oracles`);
193
- const { txs } = await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs();
194
- const oraclesStates = await simulateWithPriceUpdates(this.client, {
195
- priceUpdates: txs,
196
- contracts: multicalls.map((mc) => mc.call),
197
- gas: this.sdk.gasLimit,
198
- blockNumber: this.sdk.currentBlock
199
- });
200
- for (let i = 0; i < multicalls.length; i++) {
201
- const handler = multicalls[i].onResult;
202
- const result = oraclesStates[i];
203
- handler(result);
204
- }
147
+ return uniqOracles.values().map((o) => o.syncStateMulticall());
205
148
  }
206
149
  get watchAddresses() {
207
150
  return /* @__PURE__ */ new Set([
@@ -322,6 +265,19 @@ class MarketRegister extends ZapperRegister {
322
265
  get markets() {
323
266
  return this.#markets.values();
324
267
  }
268
+ #setMarkets(markets) {
269
+ this.#markets.clear();
270
+ for (const data of markets) {
271
+ const pool = data.pool.baseParams.addr;
272
+ if (this.#ignoreMarkets.has(pool)) {
273
+ this.logger?.debug(
274
+ `ignoring market of pool ${pool} (${data.pool.name})`
275
+ );
276
+ continue;
277
+ }
278
+ this.#markets.upsert(pool, new MarketSuite(this.sdk, data));
279
+ }
280
+ }
325
281
  }
326
282
  export {
327
283
  MarketRegister
@@ -44,6 +44,9 @@ class MarketSuite extends SDKConstruct {
44
44
  get underlying() {
45
45
  return this.pool.underlying;
46
46
  }
47
+ get kycFactory() {
48
+ return this.pool.kycFactory;
49
+ }
47
50
  get dirty() {
48
51
  return this.configurator.dirty || this.pool.dirty || this.priceOracle.dirty || this.creditManagers.some((cm) => cm.dirty);
49
52
  }
@@ -1,5 +1,6 @@
1
1
  export * from "./adapters/index.js";
2
2
  export * from "./credit/index.js";
3
+ export * from "./kyc/index.js";
3
4
  export * from "./MarketRegister.js";
4
5
  export * from "./MarketSuite.js";
5
6
  export * from "./oracle/index.js";
@@ -0,0 +1,253 @@
1
+ import { decodeAbiParameters } from "viem";
2
+ import { iKYCCompressorAbi } from "../../../abi/kyc/iKYCCompressor.js";
3
+ import {
4
+ KYC_ON_DEMAND_LP_MONOPOLIZED,
5
+ KYC_UNDERLYING_DEFAULT,
6
+ KYC_UNDERLYING_ON_DEMAND,
7
+ SDKConstruct
8
+ } from "../../base/index.js";
9
+ import { AP_KYC_COMPRESSOR, VERSION_RANGE_310 } from "../../constants/index.js";
10
+ import { AddressMap, bytes32ToString } from "../../utils/index.js";
11
+ import {
12
+ KYC_FACTORY_SECURITIZE,
13
+ SecuritizeKYCFactory
14
+ } from "./securitize/index.js";
15
+ class KYCRegistry extends SDKConstruct {
16
+ #state;
17
+ #factories = new AddressMap();
18
+ /**
19
+ * @internal
20
+ *
21
+ * Returns delegated multicalls for loading all KYC underlying tokens from the on-chain KYC compressor.
22
+ * Used by the SDK to compose batched RPC calls.
23
+ *
24
+ * @param configurators - Market configurators to query.
25
+ * @param kycFactories - KYC factory contracts to query.
26
+ */
27
+ getLoadMulticalls(configurators, kycFactories = []) {
28
+ if (!kycFactories.length) return [];
29
+ const [kycCompressorAddress] = this.sdk.addressProvider.mustGetLatest(
30
+ AP_KYC_COMPRESSOR,
31
+ VERSION_RANGE_310
32
+ );
33
+ return [
34
+ {
35
+ call: {
36
+ abi: iKYCCompressorAbi,
37
+ address: kycCompressorAddress,
38
+ functionName: "getKYCMarketsData",
39
+ args: [configurators, kycFactories]
40
+ },
41
+ onResult: (resp) => this.setState(resp)
42
+ }
43
+ ];
44
+ }
45
+ /**
46
+ * Fetches decoded investor data from the on-chain KYC compressor.
47
+ *
48
+ * Each factory produces its own investor data (e.g. registered tokens,
49
+ * cached signatures, EIP-712 messages to sign).
50
+ *
51
+ * @param investor - Investor EOA address.
52
+ * @param factories_ - Optional subset of factory addresses to query.
53
+ * When omitted, all loaded factories are used.
54
+ */
55
+ async getInvestorData(investor, factories_) {
56
+ const [kycCompressorAddress] = this.sdk.addressProvider.mustGetLatest(
57
+ AP_KYC_COMPRESSOR,
58
+ VERSION_RANGE_310
59
+ );
60
+ let factories = this.#factories.values();
61
+ if (factories_?.length) {
62
+ factories = factories_.map((f) => this.#factories.mustGet(f));
63
+ }
64
+ const resp = await this.client.readContract({
65
+ abi: iKYCCompressorAbi,
66
+ address: kycCompressorAddress,
67
+ functionName: "getKYCInvestorData",
68
+ args: [investor, factories.map((f) => f.address)]
69
+ });
70
+ const result = [];
71
+ for (let i = 0; i < factories.length; i++) {
72
+ const factory = factories[i];
73
+ const factoryData = resp[i];
74
+ const investorData = factory.decodeInvestorData(factoryData);
75
+ result.push(investorData);
76
+ }
77
+ return result;
78
+ }
79
+ /** All loaded KYC factory instances. */
80
+ get factories() {
81
+ return this.#factories.values();
82
+ }
83
+ /** Raw KYC compressor response, or `undefined` before attach/hydrate. */
84
+ get state() {
85
+ return this.#state;
86
+ }
87
+ /**
88
+ * Returns a human-readable snapshot of the KYC state.
89
+ */
90
+ stateHuman(raw) {
91
+ return {
92
+ factories: this.factories.map((f) => f.stateHuman(raw))
93
+ };
94
+ }
95
+ /**
96
+ * @internal
97
+ *
98
+ * Replaces the internal state with a new KYC compressor response.
99
+ * Rebuilds token metadata for KYC underlyings and re-instantiates factory
100
+ * wrappers.
101
+ */
102
+ setState(resp) {
103
+ this.#state = resp;
104
+ for (const u of resp?.[0] ?? []) {
105
+ this.#loadUnderlyingTokenData(u);
106
+ }
107
+ this.#factories.clear();
108
+ for (const f of resp?.[1] ?? []) {
109
+ this.#loadKYCFactoryData(f);
110
+ }
111
+ }
112
+ #loadUnderlyingTokenData(u) {
113
+ const contractType = bytes32ToString(u.baseParams.contractType);
114
+ const meta = this.tokensMeta.get(u.baseParams.addr);
115
+ if (!meta) {
116
+ throw new Error(
117
+ `KYC underlying token ${contractType} (${u.baseParams.addr}) not found in tokensMeta`
118
+ );
119
+ }
120
+ switch (contractType) {
121
+ case KYC_UNDERLYING_DEFAULT:
122
+ this.#loadKYCUnderlyingDefault(meta, u);
123
+ break;
124
+ case KYC_UNDERLYING_ON_DEMAND:
125
+ this.#loadKYCUnderlyingOnDemand(meta, u);
126
+ break;
127
+ default:
128
+ if (this.sdk.strictContractTypes) {
129
+ throw new Error(`Unknown KYC underlying type: ${contractType}`);
130
+ }
131
+ this.logger?.warn(`unknown KYC underlying type: ${contractType}`);
132
+ }
133
+ }
134
+ #loadKYCUnderlyingDefault(meta, data) {
135
+ const decoded = decodeAbiParameters(
136
+ [
137
+ { name: "factory", type: "address" },
138
+ { name: "asset", type: "address" }
139
+ ],
140
+ data.baseParams.serializedParams
141
+ );
142
+ this.tokensMeta.upsert(data.baseParams.addr, {
143
+ ...meta,
144
+ contractType: KYC_UNDERLYING_DEFAULT,
145
+ kycFactory: decoded[0],
146
+ asset: decoded[1]
147
+ });
148
+ }
149
+ #loadKYCUnderlyingOnDemand(meta, data) {
150
+ const decoded = decodeAbiParameters(
151
+ [
152
+ { name: "factory", type: "address" },
153
+ { name: "asset", type: "address" },
154
+ { name: "pool", type: "address" },
155
+ { name: "liquidityProvider", type: "address" },
156
+ { name: "marketConfigurator", type: "address" },
157
+ { name: "allowedDepositors", type: "address[]" }
158
+ ],
159
+ data.baseParams.serializedParams
160
+ );
161
+ const lpMeta = this.#getOnDemandLPMeta(data.extraDetails);
162
+ if (decoded[3] !== lpMeta.addr) {
163
+ throw new Error(
164
+ `Liquidity provider mismatch: ${decoded[3]} !== ${lpMeta.addr} for on-demand underlying ${data.baseParams.addr}`
165
+ );
166
+ }
167
+ this.tokensMeta.upsert(data.baseParams.addr, {
168
+ ...meta,
169
+ contractType: KYC_UNDERLYING_ON_DEMAND,
170
+ kycFactory: decoded[0],
171
+ asset: decoded[1],
172
+ pool: decoded[2],
173
+ marketConfigurator: decoded[4],
174
+ allowedDepositors: decoded[5],
175
+ // liquidityProvider: decoded[3],
176
+ liquidityProvider: lpMeta
177
+ });
178
+ }
179
+ #getOnDemandLPMeta(extraDetails) {
180
+ const [decoded] = decodeAbiParameters(
181
+ [
182
+ {
183
+ name: "baseParams",
184
+ type: "tuple",
185
+ components: [
186
+ { name: "addr", type: "address" },
187
+ { name: "version", type: "uint256" },
188
+ { name: "contractType", type: "bytes32" },
189
+ { name: "serializedParams", type: "bytes" }
190
+ ]
191
+ }
192
+ ],
193
+ extraDetails
194
+ );
195
+ const contractType = bytes32ToString(decoded.contractType);
196
+ switch (contractType) {
197
+ case KYC_ON_DEMAND_LP_MONOPOLIZED:
198
+ return this.#getOnDemandLPMonopolizedMeta(
199
+ decoded.addr,
200
+ decoded.version,
201
+ decoded.serializedParams
202
+ );
203
+ default:
204
+ throw new Error(`Unknown on-demand LP contract type: ${contractType}`);
205
+ }
206
+ }
207
+ #getOnDemandLPMonopolizedMeta(addr, version, serializedParams) {
208
+ const [marketConfigurator, depositor, pools] = decodeAbiParameters(
209
+ [
210
+ { name: "marketConfigurator", type: "address" },
211
+ { name: "depositor", type: "address" },
212
+ {
213
+ name: "pools",
214
+ type: "tuple[]",
215
+ components: [
216
+ { name: "pool", type: "address" },
217
+ { name: "wrappedUnderlying", type: "address" },
218
+ { name: "unwrappedUnderlying", type: "address" },
219
+ { name: "depositAllowance", type: "uint256" },
220
+ { name: "claimableAmount", type: "uint256" }
221
+ ]
222
+ }
223
+ ],
224
+ serializedParams
225
+ );
226
+ return {
227
+ addr,
228
+ version,
229
+ contractType: KYC_ON_DEMAND_LP_MONOPOLIZED,
230
+ marketConfigurator,
231
+ depositor,
232
+ pools: [...pools]
233
+ };
234
+ }
235
+ #loadKYCFactoryData(data) {
236
+ const contractType = bytes32ToString(data.baseParams.contractType);
237
+ switch (contractType) {
238
+ case KYC_FACTORY_SECURITIZE:
239
+ this.#factories.upsert(
240
+ data.baseParams.addr,
241
+ new SecuritizeKYCFactory(this.sdk, data)
242
+ );
243
+ break;
244
+ default:
245
+ throw new Error(
246
+ `Unknown KYC factory type: ${contractType} for ${data.baseParams.addr}`
247
+ );
248
+ }
249
+ }
250
+ }
251
+ export {
252
+ KYCRegistry
253
+ };
@@ -0,0 +1,3 @@
1
+ export * from "./KYCRegistry.js";
2
+ export * from "./securitize/index.js";
3
+ export * from "./types.js";