@gearbox-protocol/sdk 15.1.0-next.1 → 15.1.0-next.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/abi/iExpirable.js +15 -0
- package/dist/cjs/dev/AccountOpener.js +0 -1
- package/dist/cjs/sdk/MultichainSDK.js +3 -4
- package/dist/cjs/sdk/OnchainSDK.js +42 -13
- package/dist/cjs/sdk/accounts/withdrawal-compressor/AbstractWithdrawalCompressorContract.js +29 -18
- package/dist/cjs/sdk/base/TokensMeta.js +78 -27
- package/dist/cjs/sdk/index.js +2 -0
- package/dist/cjs/sdk/market/MarketRegister.js +16 -7
- package/dist/cjs/sdk/market/ZapperRegister.js +56 -25
- package/dist/cjs/sdk/market/rwa/RWARegistry.js +22 -0
- package/dist/cjs/sdk/options.js +1 -5
- package/dist/cjs/sdk/utils/viem/executeMulticallBatches.js +32 -0
- package/dist/cjs/sdk/utils/viem/index.js +2 -0
- package/dist/esm/abi/iExpirable.js +14 -0
- package/dist/esm/dev/AccountOpener.js +1 -2
- package/dist/esm/dev/withdrawalUtils.js +1 -1
- package/dist/esm/plugins/adapters/contracts/ERC4626AdapterContract.js +1 -1
- package/dist/esm/preview/simulate/simulatePoolOperation.js +1 -1
- package/dist/esm/preview/trace/extractTransfers.js +1 -1
- package/dist/esm/sdk/MultichainSDK.js +3 -4
- package/dist/esm/sdk/OnchainSDK.js +42 -13
- package/dist/esm/sdk/accounts/CreditAccountsServiceV310.js +2 -2
- package/dist/esm/sdk/accounts/liquidations/LiquidationsService.js +1 -1
- package/dist/esm/sdk/accounts/withdrawal-compressor/AbstractWithdrawalCompressorContract.js +29 -18
- package/dist/esm/sdk/accounts/withdrawal-compressor/RedemptionLoggerV310Contract.js +1 -1
- package/dist/esm/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV310Contract.js +1 -1
- package/dist/esm/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV311Contract.js +1 -1
- package/dist/esm/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV313Contract.js +1 -1
- package/dist/esm/sdk/base/TokensMeta.js +80 -29
- package/dist/esm/sdk/chain/detectNetwork.js +1 -1
- package/dist/esm/sdk/core/createAddressProvider.js +1 -1
- package/dist/esm/sdk/index.js +2 -1
- package/dist/esm/sdk/market/MarketRegister.js +16 -7
- package/dist/esm/sdk/market/ZapperRegister.js +56 -25
- package/dist/esm/sdk/market/credit/CreditFacadeV310BaseContract.js +1 -1
- package/dist/esm/sdk/market/pool/PoolV310Contract.js +1 -1
- package/dist/esm/sdk/market/rwa/RWARegistry.js +22 -0
- package/dist/esm/sdk/market/zapper/IETHZapperContract.js +1 -1
- package/dist/esm/sdk/market/zapper/ZapperContract.js +1 -1
- package/dist/esm/sdk/options.js +1 -5
- package/dist/esm/sdk/pools/PoolService.js +1 -1
- package/dist/esm/sdk/utils/viem/executeMulticallBatches.js +31 -0
- package/dist/esm/sdk/utils/viem/index.js +2 -1
- package/dist/esm/sdk/utils/viem/simulateWithPriceUpdates.js +1 -1
- package/dist/types/abi/iExpirable.d.ts +14 -0
- package/dist/types/sdk/MultichainSDK.d.ts +0 -5
- package/dist/types/sdk/OnchainSDK.d.ts +1 -5
- package/dist/types/sdk/accounts/withdrawal-compressor/AbstractWithdrawalCompressorContract.d.ts +6 -0
- package/dist/types/sdk/accounts/withdrawal-compressor/types.d.ts +18 -0
- package/dist/types/sdk/base/TokensMeta.d.ts +44 -1
- package/dist/types/sdk/base/index.d.ts +2 -2
- package/dist/types/sdk/base/token-types.d.ts +12 -1
- package/dist/types/sdk/index.d.ts +12 -11
- package/dist/types/sdk/market/MarketRegister.d.ts +7 -3
- package/dist/types/sdk/market/ZapperRegister.d.ts +20 -2
- package/dist/types/sdk/market/index.d.ts +2 -2
- package/dist/types/sdk/market/oracle/PriceOracleBaseContract.d.ts +2 -2
- package/dist/types/sdk/market/oracle/types.d.ts +2 -2
- package/dist/types/sdk/market/rwa/RWARegistry.d.ts +13 -0
- package/dist/types/sdk/market/types.d.ts +5 -1
- package/dist/types/sdk/options.d.ts +0 -1
- package/dist/types/sdk/types/state.d.ts +6 -0
- package/dist/types/sdk/utils/viem/executeMulticallBatches.d.ts +39 -0
- package/dist/types/sdk/utils/viem/index.d.ts +3 -2
- package/package.json +1 -1
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region src/abi/iExpirable.ts
|
|
3
|
+
const iExpirableAbi = [{
|
|
4
|
+
type: "function",
|
|
5
|
+
inputs: [],
|
|
6
|
+
name: "isExpired",
|
|
7
|
+
outputs: [{
|
|
8
|
+
name: "",
|
|
9
|
+
internalType: "bool",
|
|
10
|
+
type: "bool"
|
|
11
|
+
}],
|
|
12
|
+
stateMutability: "view"
|
|
13
|
+
}];
|
|
14
|
+
//#endregion
|
|
15
|
+
exports.iExpirableAbi = iExpirableAbi;
|
|
@@ -87,7 +87,6 @@ var AccountOpener = class extends require_sdk_base_SDKConstruct.SDKConstruct {
|
|
|
87
87
|
depositIntoPools,
|
|
88
88
|
claimFromFaucet
|
|
89
89
|
}, "opening credit accounts");
|
|
90
|
-
await Promise.all([this.sdk.tokensMeta.loadTokenData(), this.sdk.marketRegister.loadZappers()]);
|
|
91
90
|
let deposits = [];
|
|
92
91
|
if (depositIntoPools) try {
|
|
93
92
|
deposits = await this.#depositIntoPools(targets);
|
|
@@ -69,7 +69,6 @@ var MultichainSDK = class {
|
|
|
69
69
|
const perChainOpts = options?.perChain?.[network] ?? {};
|
|
70
70
|
return sdk.attach({
|
|
71
71
|
...perChainOpts,
|
|
72
|
-
loadZappers: perChainOpts.loadZappers ?? options?.loadZappers,
|
|
73
72
|
redstone: {
|
|
74
73
|
...options?.redstone,
|
|
75
74
|
cache: this.#redstoneCache,
|
|
@@ -89,7 +88,7 @@ var MultichainSDK = class {
|
|
|
89
88
|
* state and `allowMissingChains` is not set.
|
|
90
89
|
*/
|
|
91
90
|
hydrate(state, options) {
|
|
92
|
-
if (state.version !==
|
|
91
|
+
if (state.version !== 2) throw new require_sdk_core_errors.SdkStateVersionMismatchError(2, state.version);
|
|
93
92
|
if (options?.redstone) this.#redstoneCache = new require_sdk_market_pricefeeds_updates_PriceUpdatesCache.PriceUpdatesCache({
|
|
94
93
|
ttl: options.redstone.cacheTTL ?? 225e3,
|
|
95
94
|
historical: !!options.redstone.historicTimestamp
|
|
@@ -169,7 +168,7 @@ var MultichainSDK = class {
|
|
|
169
168
|
**/
|
|
170
169
|
get state() {
|
|
171
170
|
return {
|
|
172
|
-
version:
|
|
171
|
+
version: 2,
|
|
173
172
|
chains: [...this.#chains.values()].map((sdk) => sdk.state)
|
|
174
173
|
};
|
|
175
174
|
}
|
|
@@ -179,7 +178,7 @@ var MultichainSDK = class {
|
|
|
179
178
|
*/
|
|
180
179
|
stateHuman(raw) {
|
|
181
180
|
return {
|
|
182
|
-
version:
|
|
181
|
+
version: 2,
|
|
183
182
|
chains: [...this.#chains.values()].map((sdk) => sdk.stateHuman(raw))
|
|
184
183
|
};
|
|
185
184
|
}
|
|
@@ -8,6 +8,7 @@ require("./constants/index.js");
|
|
|
8
8
|
const require_sdk_utils_formatter = require("./utils/formatter.js");
|
|
9
9
|
const require_sdk_utils_toAddress = require("./utils/toAddress.js");
|
|
10
10
|
require("./utils/index.js");
|
|
11
|
+
const require_sdk_utils_viem_executeMulticallBatches = require("./utils/viem/executeMulticallBatches.js");
|
|
11
12
|
const require_sdk_base_ChainContractsRegister = require("./base/ChainContractsRegister.js");
|
|
12
13
|
require("./base/index.js");
|
|
13
14
|
const require_sdk_utils_viem_executeDelegatedMulticalls = require("./utils/viem/executeDelegatedMulticalls.js");
|
|
@@ -41,7 +42,7 @@ let viem = require("viem");
|
|
|
41
42
|
* Serialised state format version, checked during hydration to detect
|
|
42
43
|
* incompatible snapshots.
|
|
43
44
|
**/
|
|
44
|
-
const STATE_VERSION =
|
|
45
|
+
const STATE_VERSION = 2;
|
|
45
46
|
/**
|
|
46
47
|
* @internal
|
|
47
48
|
* Creates a viem `PublicClient` from the given connection options.
|
|
@@ -151,7 +152,7 @@ var OnchainSDK = class extends require_sdk_base_ChainContractsRegister.ChainCont
|
|
|
151
152
|
*/
|
|
152
153
|
async attach(options) {
|
|
153
154
|
if (this.#attached) throw new require_sdk_core_errors.SdkAlreadyAttachedError();
|
|
154
|
-
const { addressProvider = require_sdk_constants_address_provider.ADDRESS_PROVIDER_V310, blockNumber, ignoreUpdateablePrices, ignoreMarkets, marketConfigurators: mcs, redstone
|
|
155
|
+
const { addressProvider = require_sdk_constants_address_provider.ADDRESS_PROVIDER_V310, blockNumber, ignoreUpdateablePrices, ignoreMarkets, marketConfigurators: mcs, redstone } = options ?? {};
|
|
155
156
|
const marketConfigurators = mcs ?? require_sdk_utils_mappers.TypedObjectUtils.keys(this.client.chain.defaultMarketConfigurators);
|
|
156
157
|
const rwaFactories = options?.rwaFactories ?? this.client.chain.rwaFactories;
|
|
157
158
|
this.logger?.info({
|
|
@@ -175,19 +176,15 @@ var OnchainSDK = class extends require_sdk_base_ChainContractsRegister.ChainCont
|
|
|
175
176
|
this.#marketRegister = new require_sdk_market_MarketRegister.MarketRegister(this, ignoreMarkets);
|
|
176
177
|
if (!marketConfigurators.length) this.logger?.warn("no market configurators provided, skipping market loading");
|
|
177
178
|
else {
|
|
179
|
+
const priceUpdates = await this.#getPriceUpdateTxs(marketConfigurators, ignoreUpdateablePrices);
|
|
180
|
+
this.logger?.debug({ configurators: marketConfigurators }, `calling getMarkets with ${priceUpdates.length} price updates in block ${this.currentBlock}`);
|
|
178
181
|
const delegated = [...this.#marketRegister.getLoadMulticalls(marketConfigurators), ...this.#rwa.getLoadMulticalls(marketConfigurators, rwaFactories)];
|
|
179
|
-
let txs = [];
|
|
180
|
-
if (!ignoreUpdateablePrices) {
|
|
181
|
-
const updatables = await this.#priceFeeds.getPartialUpdatablePriceFeeds(marketConfigurators);
|
|
182
|
-
txs = (await this.#priceFeeds.generatePriceFeedsUpdateTxs(updatables)).txs;
|
|
183
|
-
}
|
|
184
|
-
this.logger?.debug({ configurators: marketConfigurators }, `calling getMarkets with ${txs.length} price updates in block ${this.currentBlock}`);
|
|
185
182
|
await require_sdk_utils_viem_executeDelegatedMulticalls.executeDelegatedMulticalls(this.client, delegated, {
|
|
186
|
-
priceUpdates
|
|
183
|
+
priceUpdates,
|
|
187
184
|
blockNumber: this.currentBlock,
|
|
188
185
|
gas: this.gasLimit
|
|
189
186
|
});
|
|
190
|
-
|
|
187
|
+
await this.#warmup();
|
|
191
188
|
}
|
|
192
189
|
const pluginsList = require_sdk_utils_mappers.TypedObjectUtils.entries(this.plugins);
|
|
193
190
|
(await Promise.allSettled(pluginsList.map(([name, plugin]) => {
|
|
@@ -204,6 +201,36 @@ var OnchainSDK = class extends require_sdk_base_ChainContractsRegister.ChainCont
|
|
|
204
201
|
this.#attached = true;
|
|
205
202
|
}
|
|
206
203
|
/**
|
|
204
|
+
* @internal
|
|
205
|
+
* Pass 0 of attach: resolves the price updates that the market reads of
|
|
206
|
+
* pass 1 are simulated with.
|
|
207
|
+
*
|
|
208
|
+
* @param configurators - Market configurators whose feeds are considered.
|
|
209
|
+
* @param ignoreUpdateablePrices - When `true`, no updates are fetched.
|
|
210
|
+
**/
|
|
211
|
+
async #getPriceUpdateTxs(configurators, ignoreUpdateablePrices) {
|
|
212
|
+
if (ignoreUpdateablePrices) return [];
|
|
213
|
+
const updatables = await this.priceFeeds.getPartialUpdatablePriceFeeds(configurators);
|
|
214
|
+
const { txs } = await this.priceFeeds.generatePriceFeedsUpdateTxs(updatables);
|
|
215
|
+
return txs;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* @internal
|
|
219
|
+
* Pass 2 of attach: loads the data that is read synchronously afterwards
|
|
220
|
+
* (zappers, withdrawable assets, extended token data) in a single multicall.
|
|
221
|
+
*
|
|
222
|
+
* Also re-run after a sync that reloaded the markets these caches derive from.
|
|
223
|
+
*
|
|
224
|
+
* @param force - Reload caches that are already populated.
|
|
225
|
+
**/
|
|
226
|
+
async #warmup(force = false) {
|
|
227
|
+
await require_sdk_utils_viem_executeMulticallBatches.executeMulticallBatches(this.client, [
|
|
228
|
+
this.marketRegister.getLoadZappersMulticall(force),
|
|
229
|
+
...this.#withdrawalCompressor ? [this.#withdrawalCompressor.getLoadWithdrawableAssetsMulticall(force)] : [],
|
|
230
|
+
this.tokensMeta.getLoadTokenDataMulticall()
|
|
231
|
+
], { blockNumber: this.currentBlock });
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
207
234
|
* Restores SDK state from a previously serialised {@link GearboxState}
|
|
208
235
|
* snapshot, without making any on-chain calls.
|
|
209
236
|
*
|
|
@@ -215,7 +242,7 @@ var OnchainSDK = class extends require_sdk_base_ChainContractsRegister.ChainCont
|
|
|
215
242
|
*/
|
|
216
243
|
hydrate(state, options) {
|
|
217
244
|
if (this.#attached) throw new require_sdk_core_errors.SdkAlreadyAttachedError();
|
|
218
|
-
if (state.version !==
|
|
245
|
+
if (state.version !== 2) throw new require_sdk_core_errors.SdkStateVersionMismatchError(2, state.version);
|
|
219
246
|
if (state.network !== this.networkType) throw new require_sdk_core_errors.SdkChainMismatchError(this.networkType, state.network);
|
|
220
247
|
const { ignoreMarkets, redstone } = options ?? {};
|
|
221
248
|
this.logger?.info({ networkType: this.networkType }, "hydrating sdk state");
|
|
@@ -229,6 +256,7 @@ var OnchainSDK = class extends require_sdk_base_ChainContractsRegister.ChainCont
|
|
|
229
256
|
this.#rwa = new require_sdk_market_rwa_RWARegistry.RWARegistry(this);
|
|
230
257
|
this.#rwa.setState(state.rwa);
|
|
231
258
|
if (state.withdrawals) this.#withdrawalCompressor?.hydrate(state.withdrawals);
|
|
259
|
+
if (state.tokens) this.tokensMeta.hydrate(state.tokens);
|
|
232
260
|
for (const [name, plugin] of require_sdk_utils_mappers.TypedObjectUtils.entries(this.plugins)) {
|
|
233
261
|
const pluginState = state.plugins[name];
|
|
234
262
|
if (plugin.hydrate && pluginState) {
|
|
@@ -274,13 +302,14 @@ var OnchainSDK = class extends require_sdk_base_ChainContractsRegister.ChainCont
|
|
|
274
302
|
/** Serialisable snapshot of the current SDK state. */
|
|
275
303
|
get state() {
|
|
276
304
|
return {
|
|
277
|
-
version:
|
|
305
|
+
version: 2,
|
|
278
306
|
network: this.networkType,
|
|
279
307
|
chainId: this.chainId,
|
|
280
308
|
currentBlock: this.currentBlock,
|
|
281
309
|
timestamp: this.timestamp,
|
|
282
310
|
addressProvider: this.addressProvider.state,
|
|
283
311
|
...this.marketRegister.state,
|
|
312
|
+
tokens: this.tokensMeta.state,
|
|
284
313
|
rwa: this.#rwa.state,
|
|
285
314
|
withdrawals: this.#withdrawalCompressor?.state,
|
|
286
315
|
plugins: Object.fromEntries(require_sdk_utils_mappers.TypedObjectUtils.entries(this.plugins).map(([name, plugin]) => [name, plugin.loaded ? {
|
|
@@ -339,7 +368,7 @@ var OnchainSDK = class extends require_sdk_base_ChainContractsRegister.ChainCont
|
|
|
339
368
|
}
|
|
340
369
|
this.#currentBlock = blockNumber;
|
|
341
370
|
this.#timestamp = timestamp;
|
|
342
|
-
await this.marketRegister.syncState(ignoreUpdateablePrices);
|
|
371
|
+
if (await this.marketRegister.syncState(ignoreUpdateablePrices, this.#rwa.getSyncMulticalls())) await this.#warmup(true);
|
|
343
372
|
const pluginsList = require_sdk_utils_mappers.TypedObjectUtils.entries(this.plugins);
|
|
344
373
|
(await Promise.allSettled(pluginsList.map(([name, plugin]) => {
|
|
345
374
|
if (plugin.syncState) {
|
|
@@ -4,8 +4,10 @@ require("../../constants/addresses.js");
|
|
|
4
4
|
require("../../constants/index.js");
|
|
5
5
|
const require_sdk_utils_hex = require("../../utils/hex.js");
|
|
6
6
|
require("../../utils/index.js");
|
|
7
|
+
const require_sdk_utils_viem_executeMulticallBatches = require("../../utils/viem/executeMulticallBatches.js");
|
|
7
8
|
const require_sdk_base_BaseContract = require("../../base/BaseContract.js");
|
|
8
9
|
require("../../base/index.js");
|
|
10
|
+
require("../../utils/viem/index.js");
|
|
9
11
|
const require_sdk_accounts_withdrawal_compressor_intent_codec = require("./intent-codec.js");
|
|
10
12
|
let viem = require("viem");
|
|
11
13
|
//#region src/sdk/accounts/withdrawal-compressor/AbstractWithdrawalCompressorContract.ts
|
|
@@ -58,37 +60,46 @@ var AbstractWithdrawalCompressorContract = class extends require_sdk_base_BaseCo
|
|
|
58
60
|
**/
|
|
59
61
|
getWithdrawableAssets(...creditManagers) {
|
|
60
62
|
const cache = this.#withdrawableAssets;
|
|
61
|
-
if (!cache) throw new Error("withdrawable assets are not loaded,
|
|
63
|
+
if (!cache) throw new Error("withdrawable assets are not loaded, check if the sdk was properly attached or hydrated");
|
|
62
64
|
if (creditManagers.length === 0) return cache.values().flat();
|
|
63
65
|
return creditManagers.flatMap((cm) => cache.get(cm) ?? []);
|
|
64
66
|
}
|
|
65
67
|
/**
|
|
66
|
-
* {@inheritDoc IWithdrawalCompressorContract.
|
|
68
|
+
* {@inheritDoc IWithdrawalCompressorContract.getLoadWithdrawableAssetsMulticall}
|
|
67
69
|
**/
|
|
68
|
-
|
|
69
|
-
if (this.#withdrawableAssets && !force) return
|
|
70
|
+
getLoadWithdrawableAssetsMulticall(force) {
|
|
71
|
+
if (this.#withdrawableAssets && !force) return {
|
|
72
|
+
contracts: [],
|
|
73
|
+
onResults: () => {}
|
|
74
|
+
};
|
|
70
75
|
const cms = this.#sdk.marketRegister.creditManagers.map((cm) => cm.creditManager.address);
|
|
71
|
-
|
|
76
|
+
return {
|
|
72
77
|
contracts: cms.map((cm) => ({
|
|
73
78
|
address: this.address,
|
|
74
79
|
abi: this.abi,
|
|
75
80
|
functionName: "getWithdrawableAssets",
|
|
76
81
|
args: [cm]
|
|
77
82
|
})),
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
83
|
+
onResults: (resps) => {
|
|
84
|
+
const cache = new require_sdk_utils_AddressMap.AddressMap(void 0, MAP_LABEL);
|
|
85
|
+
for (let i = 0; i < resps.length; i++) {
|
|
86
|
+
const r = resps[i];
|
|
87
|
+
if (r.status !== "success") {
|
|
88
|
+
this.logger?.warn(`failed to get withdrawable assets of credit manager ${cms[i]}: ${r.error}`);
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
const assets = r.result;
|
|
92
|
+
if (assets.length > 0) cache.upsert(cms[i], assets.map((a) => toWithdrawableAsset(a, cms[i])));
|
|
93
|
+
}
|
|
94
|
+
this.#withdrawableAssets = cache;
|
|
88
95
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* {@inheritDoc IWithdrawalCompressorContract.loadWithdrawableAssets}
|
|
100
|
+
**/
|
|
101
|
+
async loadWithdrawableAssets(force, blockNumber) {
|
|
102
|
+
await require_sdk_utils_viem_executeMulticallBatches.executeMulticallBatches(this.client, [this.getLoadWithdrawableAssetsMulticall(force)], { blockNumber });
|
|
92
103
|
return this.getWithdrawableAssets();
|
|
93
104
|
}
|
|
94
105
|
/**
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_abi_iExpirable = require("../../abi/iExpirable.js");
|
|
2
3
|
const require_abi_iStateSerializer = require("../../abi/iStateSerializer.js");
|
|
3
4
|
const require_abi_iVersion = require("../../abi/iVersion.js");
|
|
4
5
|
const require_sdk_utils_AddressMap = require("../utils/AddressMap.js");
|
|
@@ -7,6 +8,7 @@ const require_sdk_utils_bytes32ToString = require("../utils/bytes32ToString.js")
|
|
|
7
8
|
const require_sdk_chain_chains = require("../chain/chains.js");
|
|
8
9
|
const require_sdk_utils_formatter = require("../utils/formatter.js");
|
|
9
10
|
require("../utils/index.js");
|
|
11
|
+
const require_sdk_utils_viem_executeMulticallBatches = require("../utils/viem/executeMulticallBatches.js");
|
|
10
12
|
//#region src/sdk/base/TokensMeta.ts
|
|
11
13
|
/**
|
|
12
14
|
* Registry of token metadata (symbol, decimals, phantom type) keyed by address.
|
|
@@ -63,7 +65,7 @@ var TokensMeta = class extends require_sdk_utils_AddressMap.AddressMap {
|
|
|
63
65
|
* @returns
|
|
64
66
|
*/
|
|
65
67
|
isPhantomToken(t) {
|
|
66
|
-
if (!this.#tokenDataLoaded.has(t.addr)) throw new Error(`extended token data not loaded for ${t.symbol} (${t.addr})`);
|
|
68
|
+
if (!this.#tokenDataLoaded.has(t.addr)) throw new Error(`extended token data not loaded for ${t.symbol} (${t.addr}), check if the sdk was properly attached or hydrated`);
|
|
67
69
|
return !!t.contractType?.startsWith("PHANTOM_TOKEN::");
|
|
68
70
|
}
|
|
69
71
|
/**
|
|
@@ -168,44 +170,93 @@ var TokensMeta = class extends require_sdk_utils_AddressMap.AddressMap {
|
|
|
168
170
|
return meta;
|
|
169
171
|
}
|
|
170
172
|
/**
|
|
173
|
+
* @internal
|
|
174
|
+
*
|
|
175
|
+
* Returns the multicall batch that loads extended token data (`contractType`
|
|
176
|
+
* and `serialize()`) for the tokens that do not have it yet. Used by the SDK
|
|
177
|
+
* to warm this cache together with other loaders in a single multicall.
|
|
178
|
+
*
|
|
179
|
+
* @param tokens - tokens to load data for, defaults to all tokens
|
|
180
|
+
**/
|
|
181
|
+
getLoadTokenDataMulticall(...tokens) {
|
|
182
|
+
const tokenz = new require_sdk_utils_AddressSet.AddressSet(tokens.length > 0 ? tokens : this.keys());
|
|
183
|
+
const tokensToLoad = Array.from(tokenz.difference(this.#tokenDataLoaded));
|
|
184
|
+
return {
|
|
185
|
+
contracts: tokensToLoad.flatMap((t) => [
|
|
186
|
+
{
|
|
187
|
+
address: t,
|
|
188
|
+
abi: require_abi_iVersion.iVersionAbi,
|
|
189
|
+
functionName: "contractType"
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
address: t,
|
|
193
|
+
abi: require_abi_iStateSerializer.iStateSerializerAbi,
|
|
194
|
+
functionName: "serialize"
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
address: t,
|
|
198
|
+
abi: require_abi_iExpirable.iExpirableAbi,
|
|
199
|
+
functionName: "isExpired"
|
|
200
|
+
}
|
|
201
|
+
]),
|
|
202
|
+
onResults: (resps) => {
|
|
203
|
+
this.#logger?.debug(`loaded data of ${tokensToLoad.length} tokens`);
|
|
204
|
+
for (let i = 0; i < tokensToLoad.length; i++) {
|
|
205
|
+
this.#overrideTokenMeta(tokensToLoad[i], resps[3 * i], resps[3 * i + 1], resps[3 * i + 2]);
|
|
206
|
+
this.#tokenDataLoaded.add(tokensToLoad[i]);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
171
212
|
* Loads token information about phantom tokens
|
|
172
213
|
* In future other custom tokens types that do not have compressors might be handled here
|
|
173
214
|
*
|
|
215
|
+
* Tokens loaded during SDK attach or restored by {@link hydrate} are skipped,
|
|
216
|
+
* so calling this after either is a no-op.
|
|
217
|
+
*
|
|
174
218
|
* @param tokens - tokens to load data for, defaults to all tokens
|
|
175
219
|
*/
|
|
176
220
|
async loadTokenData(...tokens) {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
abi: require_abi_iStateSerializer.iStateSerializerAbi,
|
|
188
|
-
functionName: "serialize"
|
|
189
|
-
}]),
|
|
190
|
-
allowFailure: true,
|
|
191
|
-
batchSize: 0
|
|
192
|
-
});
|
|
193
|
-
this.#logger?.debug(`loaded ${resp.length} contract types`);
|
|
194
|
-
for (let i = 0; i < tokensToLoad.length; i++) {
|
|
195
|
-
this.#overrideTokenMeta(tokensToLoad[i], resp[2 * i], resp[2 * i + 1]);
|
|
196
|
-
this.#tokenDataLoaded.add(tokensToLoad[i]);
|
|
197
|
-
}
|
|
221
|
+
await require_sdk_utils_viem_executeMulticallBatches.executeMulticallBatches(this.#client, [this.getLoadTokenDataMulticall(...tokens)]);
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Serializable snapshot of all token metadata, suitable for hydration.
|
|
225
|
+
**/
|
|
226
|
+
get state() {
|
|
227
|
+
return {
|
|
228
|
+
tokens: this.values(),
|
|
229
|
+
extendedLoaded: this.#tokenDataLoaded.asArray()
|
|
230
|
+
};
|
|
198
231
|
}
|
|
199
|
-
|
|
232
|
+
/**
|
|
233
|
+
* Restores token metadata from a previously serialized snapshot,
|
|
234
|
+
* bypassing on-chain reads.
|
|
235
|
+
*
|
|
236
|
+
* Entries are merged into the ones already registered by markets, zappers and
|
|
237
|
+
* the RWA registry (see {@link upsert}), so the snapshot must be applied last
|
|
238
|
+
* for its augmented fields to win.
|
|
239
|
+
*
|
|
240
|
+
* @param state - Token metadata snapshot.
|
|
241
|
+
**/
|
|
242
|
+
hydrate(state) {
|
|
243
|
+
for (const token of state.tokens) this.upsert(token.addr, token);
|
|
244
|
+
for (const token of state.extendedLoaded) this.#tokenDataLoaded.add(token);
|
|
245
|
+
}
|
|
246
|
+
#overrideTokenMeta(token, contractTypeResp, serializeResp, isExpiredResp) {
|
|
200
247
|
const meta = this.mustGet(token);
|
|
248
|
+
const update = { ...meta };
|
|
201
249
|
if (contractTypeResp.status === "success") {
|
|
202
250
|
const contractType = require_sdk_utils_bytes32ToString.bytes32ToString(contractTypeResp.result);
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
contractType
|
|
206
|
-
});
|
|
251
|
+
update.contractType = contractType;
|
|
252
|
+
update.serializedParams = serializeResp.status === "success" ? serializeResp.result : void 0;
|
|
207
253
|
this.#logger?.debug(`token ${meta.symbol} is ${contractType}`);
|
|
208
254
|
}
|
|
255
|
+
if (isExpiredResp.status === "success") {
|
|
256
|
+
update.isExpired = isExpiredResp.result;
|
|
257
|
+
this.#logger?.debug(`token ${meta.symbol} is expirable, expired: ${isExpiredResp.result}`);
|
|
258
|
+
}
|
|
259
|
+
if (contractTypeResp.status === "success" || isExpiredResp.status === "success") this.upsert(token, update);
|
|
209
260
|
return this.mustGet(token);
|
|
210
261
|
}
|
|
211
262
|
};
|
package/dist/cjs/sdk/index.js
CHANGED
|
@@ -31,6 +31,7 @@ const require_sdk_utils_zod = require("./utils/zod.js");
|
|
|
31
31
|
require("./utils/index.js");
|
|
32
32
|
const require_sdk_utils_viem_cast = require("./utils/viem/cast.js");
|
|
33
33
|
const require_sdk_utils_viem_simulateCall = require("./utils/viem/simulateCall.js");
|
|
34
|
+
const require_sdk_utils_viem_executeMulticallBatches = require("./utils/viem/executeMulticallBatches.js");
|
|
34
35
|
const require_sdk_base_TokensMeta = require("./base/TokensMeta.js");
|
|
35
36
|
const require_sdk_base_ChainContractsRegister = require("./base/ChainContractsRegister.js");
|
|
36
37
|
const require_sdk_base_Construct = require("./base/Construct.js");
|
|
@@ -348,6 +349,7 @@ exports.estimateRawTxGas = require_sdk_utils_viem_sendRawTx.estimateRawTxGas;
|
|
|
348
349
|
exports.etherscanApiUrl = require_sdk_utils_etherscan.etherscanApiUrl;
|
|
349
350
|
exports.etherscanUrl = require_sdk_utils_etherscan.etherscanUrl;
|
|
350
351
|
exports.executeDelegatedMulticalls = require_sdk_utils_viem_executeDelegatedMulticalls.executeDelegatedMulticalls;
|
|
352
|
+
exports.executeMulticallBatches = require_sdk_utils_viem_executeMulticallBatches.executeMulticallBatches;
|
|
351
353
|
exports.expectedBalanceDeltas = require_sdk_market_credit_expectedBalanceDeltas.expectedBalanceDeltas;
|
|
352
354
|
exports.fetchRedstonePayloads = require_sdk_market_pricefeeds_updates_fetchRedstonePayloads.fetchRedstonePayloads;
|
|
353
355
|
exports.filterDust = require_sdk_utils_filterDust.filterDust;
|
|
@@ -95,29 +95,38 @@ var MarketRegister = class extends require_sdk_market_ZapperRegister.ZapperRegis
|
|
|
95
95
|
* Otherwise only prices are refreshed.
|
|
96
96
|
*
|
|
97
97
|
* @param ignoreUpdateablePrices - When `true`, skips off-chain price updates.
|
|
98
|
+
* @param extra - Additional multicalls to execute in the same batch, so that
|
|
99
|
+
* other registries can be synced without an extra request.
|
|
100
|
+
* @returns `true` when markets were fully reloaded, so that callers can
|
|
101
|
+
* refresh the caches derived from the market set.
|
|
98
102
|
**/
|
|
99
|
-
async syncState(ignoreUpdateablePrices) {
|
|
103
|
+
async syncState(ignoreUpdateablePrices, extra = []) {
|
|
100
104
|
const dirty = this.markets.some((m) => m.dirty) || this.marketConfigurators.some((c) => c.dirty);
|
|
101
105
|
let multicalls;
|
|
102
106
|
let txs = [];
|
|
103
107
|
if (dirty) {
|
|
104
108
|
this.logger?.debug("some markets or market configurators are dirty, reloading everything");
|
|
105
|
-
multicalls = this.getLoadMulticalls([...this.marketFilter.configurators]);
|
|
109
|
+
multicalls = [...this.getLoadMulticalls([...this.marketFilter.configurators]), ...extra];
|
|
106
110
|
if (!ignoreUpdateablePrices) {
|
|
107
111
|
const updatables = await this.sdk.priceFeeds.getPartialUpdatablePriceFeeds([...this.marketFilter.configurators]);
|
|
108
112
|
txs = (await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(updatables)).txs;
|
|
109
113
|
}
|
|
110
114
|
} else if (!ignoreUpdateablePrices) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
115
|
+
const oracles = this.#getOracleSyncMulticalls();
|
|
116
|
+
multicalls = [...oracles, ...extra];
|
|
117
|
+
if (!multicalls.length) return false;
|
|
118
|
+
if (oracles.length) {
|
|
119
|
+
this.logger?.debug(`syncing prices on ${oracles.length} oracles`);
|
|
120
|
+
txs = (await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs()).txs;
|
|
121
|
+
}
|
|
122
|
+
} else if (extra.length) multicalls = extra;
|
|
123
|
+
else return false;
|
|
116
124
|
await require_sdk_utils_viem_executeDelegatedMulticalls.executeDelegatedMulticalls(this.client, multicalls, {
|
|
117
125
|
priceUpdates: txs,
|
|
118
126
|
blockNumber: this.sdk.currentBlock,
|
|
119
127
|
gas: this.sdk.gasLimit
|
|
120
128
|
});
|
|
129
|
+
return dirty;
|
|
121
130
|
}
|
|
122
131
|
#getOracleSyncMulticalls(oracles) {
|
|
123
132
|
const uniqOracles = new require_sdk_utils_AddressMap.AddressMap();
|
|
@@ -5,53 +5,84 @@ const require_sdk_constants_versions = require("../constants/versions.js");
|
|
|
5
5
|
require("../constants/index.js");
|
|
6
6
|
const require_sdk_utils_hex = require("../utils/hex.js");
|
|
7
7
|
require("../utils/index.js");
|
|
8
|
+
const require_sdk_utils_viem_executeMulticallBatches = require("../utils/viem/executeMulticallBatches.js");
|
|
8
9
|
const require_sdk_base_SDKConstruct = require("../base/SDKConstruct.js");
|
|
9
10
|
require("../base/index.js");
|
|
10
11
|
const require_abi_compressors_peripheryCompressor = require("../../abi/compressors/peripheryCompressor.js");
|
|
12
|
+
require("../utils/viem/index.js");
|
|
11
13
|
const require_sdk_market_zapper_createZapper = require("./zapper/createZapper.js");
|
|
12
14
|
require("./zapper/index.js");
|
|
13
15
|
//#region src/sdk/market/ZapperRegister.ts
|
|
14
16
|
var ZapperRegister = class extends require_sdk_base_SDKConstruct.SDKConstruct {
|
|
15
17
|
/**
|
|
16
18
|
* Mapping pool.address -> Zapper[]
|
|
17
|
-
*
|
|
19
|
+
* Loaded during SDK attach, or restored by hydration
|
|
18
20
|
*/
|
|
19
21
|
#zappers;
|
|
20
22
|
/**
|
|
21
|
-
*
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
* @internal
|
|
24
|
+
*
|
|
25
|
+
* Returns the multicall batch that loads zappers of all pools from the
|
|
26
|
+
* periphery compressor. Used by the SDK to warm this cache together with
|
|
27
|
+
* other loaders in a single multicall.
|
|
28
|
+
*
|
|
29
|
+
* Returns an empty batch when zappers are already loaded and `force` is not set.
|
|
30
|
+
*
|
|
31
|
+
* @param force - reload zappers even when they are already loaded
|
|
32
|
+
**/
|
|
33
|
+
getLoadZappersMulticall(force) {
|
|
34
|
+
if (!force && this.#zappers) return {
|
|
35
|
+
contracts: [],
|
|
36
|
+
onResults: () => {}
|
|
37
|
+
};
|
|
38
|
+
this.#zappers = new require_sdk_utils_AddressMap.AddressMap(void 0, "zappers");
|
|
39
|
+
const compressor = this.sdk.addressProvider.getLatest(require_sdk_constants_address_provider.AP_PERIPHERY_COMPRESSOR, require_sdk_constants_versions.VERSION_RANGE_310);
|
|
40
|
+
if (!compressor) {
|
|
41
|
+
this.logger?.warn("no periphery compressor on this chain, skipping zappers");
|
|
42
|
+
return {
|
|
43
|
+
contracts: [],
|
|
44
|
+
onResults: () => {}
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
const [pcAddr] = compressor;
|
|
26
48
|
this.logger?.debug(`loading zappers with periphery compressor ${pcAddr}`);
|
|
27
49
|
const markets = this.sdk.marketRegister.markets;
|
|
28
|
-
|
|
50
|
+
return {
|
|
29
51
|
contracts: markets.map((m) => ({
|
|
30
52
|
abi: require_abi_compressors_peripheryCompressor.peripheryCompressorAbi,
|
|
31
53
|
address: pcAddr,
|
|
32
54
|
functionName: "getZappers",
|
|
33
55
|
args: [m.configurator.address, m.pool.pool.address]
|
|
34
56
|
})),
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
|
|
57
|
+
onResults: (resps) => {
|
|
58
|
+
for (let i = 0; i < resps.length; i++) {
|
|
59
|
+
const { status, result, error } = resps[i];
|
|
60
|
+
const marketConfigurator = markets[i].configurator.address;
|
|
61
|
+
const pool = markets[i].pool.pool.address;
|
|
62
|
+
if (status === "success") for (const z of result) this.#addZapper({
|
|
63
|
+
...z,
|
|
64
|
+
pool,
|
|
65
|
+
type: "base"
|
|
66
|
+
});
|
|
67
|
+
else this.logger?.error(`failed to load zapper for market configurator ${this.labelAddress(marketConfigurator)} and pool ${this.labelAddress(pool)}: ${error}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Load zappers for all pools using periphery compressor, adds hardcoded zappers
|
|
74
|
+
*
|
|
75
|
+
* Zappers loaded during SDK attach or restored by hydration are kept unless
|
|
76
|
+
* `force` is set, so calling this after either is a no-op.
|
|
77
|
+
*/
|
|
78
|
+
async loadZappers(force) {
|
|
79
|
+
await require_sdk_utils_viem_executeMulticallBatches.executeMulticallBatches(this.client, [this.getLoadZappersMulticall(force)]);
|
|
50
80
|
}
|
|
51
81
|
/**
|
|
52
82
|
* Serializable snapshot of all loaded zappers, suitable for hydration.
|
|
53
|
-
* Returns `undefined` when zappers were never loaded (i.e.
|
|
54
|
-
*
|
|
83
|
+
* Returns `undefined` when zappers were never loaded (i.e. the SDK was
|
|
84
|
+
* attached without market configurators), so the not-loaded state round-trips
|
|
85
|
+
* cleanly.
|
|
55
86
|
**/
|
|
56
87
|
get zappersState() {
|
|
57
88
|
if (!this.#zappers) return;
|
|
@@ -103,7 +134,7 @@ var ZapperRegister = class extends require_sdk_base_SDKConstruct.SDKConstruct {
|
|
|
103
134
|
}
|
|
104
135
|
}
|
|
105
136
|
get zappers() {
|
|
106
|
-
if (!this.#zappers) throw new Error("zappers not loaded,
|
|
137
|
+
if (!this.#zappers) throw new Error("zappers are not loaded, check if the sdk was properly attached or hydrated");
|
|
107
138
|
return this.#zappers;
|
|
108
139
|
}
|
|
109
140
|
poolZappers(pool) {
|
|
@@ -25,6 +25,11 @@ var RWARegistry = class extends require_sdk_base_SDKConstruct.SDKConstruct {
|
|
|
25
25
|
#state;
|
|
26
26
|
#factories = new require_sdk_utils_AddressMap.AddressMap();
|
|
27
27
|
/**
|
|
28
|
+
* Factories requested during attach; `undefined` when the registry was
|
|
29
|
+
* hydrated instead, in which case the request was never made on this instance.
|
|
30
|
+
**/
|
|
31
|
+
#requestedFactories;
|
|
32
|
+
/**
|
|
28
33
|
* @internal
|
|
29
34
|
*
|
|
30
35
|
* Returns delegated multicalls for loading all RWA underlying tokens from the on-chain RWA compressor.
|
|
@@ -34,6 +39,7 @@ var RWARegistry = class extends require_sdk_base_SDKConstruct.SDKConstruct {
|
|
|
34
39
|
* @param rwaFactories - RWA factory contracts to query.
|
|
35
40
|
*/
|
|
36
41
|
getLoadMulticalls(configurators, rwaFactories = []) {
|
|
42
|
+
this.#requestedFactories = rwaFactories;
|
|
37
43
|
if (!rwaFactories.length) return [];
|
|
38
44
|
const [rwaCompressorAddress] = this.sdk.addressProvider.mustGetLatest(require_sdk_constants_address_provider.AP_RWA_COMPRESSOR, require_sdk_constants_versions.VERSION_RANGE_310);
|
|
39
45
|
return [{
|
|
@@ -47,6 +53,22 @@ var RWARegistry = class extends require_sdk_base_SDKConstruct.SDKConstruct {
|
|
|
47
53
|
}];
|
|
48
54
|
}
|
|
49
55
|
/**
|
|
56
|
+
* @internal
|
|
57
|
+
*
|
|
58
|
+
* Returns delegated multicalls that refresh the RWA state. Unlike the other
|
|
59
|
+
* warmed caches, RWA data carries values that change between blocks (e.g. the
|
|
60
|
+
* deposit allowance and claimable amount of an on-demand liquidity provider),
|
|
61
|
+
* so it is refreshed on every SDK sync.
|
|
62
|
+
*
|
|
63
|
+
* Factories are the ones requested during attach; after hydration the chain
|
|
64
|
+
* defaults are used, since the snapshot does not carry the requested list.
|
|
65
|
+
* An attach that explicitly requested no factories stays disabled.
|
|
66
|
+
**/
|
|
67
|
+
getSyncMulticalls() {
|
|
68
|
+
const factories = this.#requestedFactories ?? this.sdk.chain.rwaFactories;
|
|
69
|
+
return this.getLoadMulticalls([...this.sdk.marketRegister.marketFilter.configurators], factories);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
50
72
|
* Fetches decoded investor data from the on-chain RWA compressor.
|
|
51
73
|
*
|
|
52
74
|
* Each factory produces its own investor data (e.g. registered tokens,
|
package/dist/cjs/sdk/options.js
CHANGED
|
@@ -61,11 +61,7 @@ const attachOptionsSchema = zod_v4.z.object({
|
|
|
61
61
|
/**
|
|
62
62
|
* Options for Redstone price-feed updates.
|
|
63
63
|
**/
|
|
64
|
-
redstone: require_sdk_market_pricefeeds_updates_RedstoneUpdater.RedstoneOptions.optional()
|
|
65
|
-
/**
|
|
66
|
-
* When `true`, automatically load zappers during attach.
|
|
67
|
-
**/
|
|
68
|
-
loadZappers: zod_v4.z.boolean().optional()
|
|
64
|
+
redstone: require_sdk_market_pricefeeds_updates_RedstoneUpdater.RedstoneOptions.optional()
|
|
69
65
|
});
|
|
70
66
|
//#endregion
|
|
71
67
|
exports.attachOptionsSchema = attachOptionsSchema;
|