@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.
Files changed (65) hide show
  1. package/dist/cjs/abi/iExpirable.js +15 -0
  2. package/dist/cjs/dev/AccountOpener.js +0 -1
  3. package/dist/cjs/sdk/MultichainSDK.js +3 -4
  4. package/dist/cjs/sdk/OnchainSDK.js +42 -13
  5. package/dist/cjs/sdk/accounts/withdrawal-compressor/AbstractWithdrawalCompressorContract.js +29 -18
  6. package/dist/cjs/sdk/base/TokensMeta.js +78 -27
  7. package/dist/cjs/sdk/index.js +2 -0
  8. package/dist/cjs/sdk/market/MarketRegister.js +16 -7
  9. package/dist/cjs/sdk/market/ZapperRegister.js +56 -25
  10. package/dist/cjs/sdk/market/rwa/RWARegistry.js +22 -0
  11. package/dist/cjs/sdk/options.js +1 -5
  12. package/dist/cjs/sdk/utils/viem/executeMulticallBatches.js +32 -0
  13. package/dist/cjs/sdk/utils/viem/index.js +2 -0
  14. package/dist/esm/abi/iExpirable.js +14 -0
  15. package/dist/esm/dev/AccountOpener.js +1 -2
  16. package/dist/esm/dev/withdrawalUtils.js +1 -1
  17. package/dist/esm/plugins/adapters/contracts/ERC4626AdapterContract.js +1 -1
  18. package/dist/esm/preview/simulate/simulatePoolOperation.js +1 -1
  19. package/dist/esm/preview/trace/extractTransfers.js +1 -1
  20. package/dist/esm/sdk/MultichainSDK.js +3 -4
  21. package/dist/esm/sdk/OnchainSDK.js +42 -13
  22. package/dist/esm/sdk/accounts/CreditAccountsServiceV310.js +2 -2
  23. package/dist/esm/sdk/accounts/liquidations/LiquidationsService.js +1 -1
  24. package/dist/esm/sdk/accounts/withdrawal-compressor/AbstractWithdrawalCompressorContract.js +29 -18
  25. package/dist/esm/sdk/accounts/withdrawal-compressor/RedemptionLoggerV310Contract.js +1 -1
  26. package/dist/esm/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV310Contract.js +1 -1
  27. package/dist/esm/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV311Contract.js +1 -1
  28. package/dist/esm/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV313Contract.js +1 -1
  29. package/dist/esm/sdk/base/TokensMeta.js +80 -29
  30. package/dist/esm/sdk/chain/detectNetwork.js +1 -1
  31. package/dist/esm/sdk/core/createAddressProvider.js +1 -1
  32. package/dist/esm/sdk/index.js +2 -1
  33. package/dist/esm/sdk/market/MarketRegister.js +16 -7
  34. package/dist/esm/sdk/market/ZapperRegister.js +56 -25
  35. package/dist/esm/sdk/market/credit/CreditFacadeV310BaseContract.js +1 -1
  36. package/dist/esm/sdk/market/pool/PoolV310Contract.js +1 -1
  37. package/dist/esm/sdk/market/rwa/RWARegistry.js +22 -0
  38. package/dist/esm/sdk/market/zapper/IETHZapperContract.js +1 -1
  39. package/dist/esm/sdk/market/zapper/ZapperContract.js +1 -1
  40. package/dist/esm/sdk/options.js +1 -5
  41. package/dist/esm/sdk/pools/PoolService.js +1 -1
  42. package/dist/esm/sdk/utils/viem/executeMulticallBatches.js +31 -0
  43. package/dist/esm/sdk/utils/viem/index.js +2 -1
  44. package/dist/esm/sdk/utils/viem/simulateWithPriceUpdates.js +1 -1
  45. package/dist/types/abi/iExpirable.d.ts +14 -0
  46. package/dist/types/sdk/MultichainSDK.d.ts +0 -5
  47. package/dist/types/sdk/OnchainSDK.d.ts +1 -5
  48. package/dist/types/sdk/accounts/withdrawal-compressor/AbstractWithdrawalCompressorContract.d.ts +6 -0
  49. package/dist/types/sdk/accounts/withdrawal-compressor/types.d.ts +18 -0
  50. package/dist/types/sdk/base/TokensMeta.d.ts +44 -1
  51. package/dist/types/sdk/base/index.d.ts +2 -2
  52. package/dist/types/sdk/base/token-types.d.ts +12 -1
  53. package/dist/types/sdk/index.d.ts +12 -11
  54. package/dist/types/sdk/market/MarketRegister.d.ts +7 -3
  55. package/dist/types/sdk/market/ZapperRegister.d.ts +20 -2
  56. package/dist/types/sdk/market/index.d.ts +2 -2
  57. package/dist/types/sdk/market/oracle/PriceOracleBaseContract.d.ts +2 -2
  58. package/dist/types/sdk/market/oracle/types.d.ts +2 -2
  59. package/dist/types/sdk/market/rwa/RWARegistry.d.ts +13 -0
  60. package/dist/types/sdk/market/types.d.ts +5 -1
  61. package/dist/types/sdk/options.d.ts +0 -1
  62. package/dist/types/sdk/types/state.d.ts +6 -0
  63. package/dist/types/sdk/utils/viem/executeMulticallBatches.d.ts +39 -0
  64. package/dist/types/sdk/utils/viem/index.d.ts +3 -2
  65. package/package.json +1 -1
@@ -94,29 +94,38 @@ var MarketRegister = class extends ZapperRegister {
94
94
  * Otherwise only prices are refreshed.
95
95
  *
96
96
  * @param ignoreUpdateablePrices - When `true`, skips off-chain price updates.
97
+ * @param extra - Additional multicalls to execute in the same batch, so that
98
+ * other registries can be synced without an extra request.
99
+ * @returns `true` when markets were fully reloaded, so that callers can
100
+ * refresh the caches derived from the market set.
97
101
  **/
98
- async syncState(ignoreUpdateablePrices) {
102
+ async syncState(ignoreUpdateablePrices, extra = []) {
99
103
  const dirty = this.markets.some((m) => m.dirty) || this.marketConfigurators.some((c) => c.dirty);
100
104
  let multicalls;
101
105
  let txs = [];
102
106
  if (dirty) {
103
107
  this.logger?.debug("some markets or market configurators are dirty, reloading everything");
104
- multicalls = this.getLoadMulticalls([...this.marketFilter.configurators]);
108
+ multicalls = [...this.getLoadMulticalls([...this.marketFilter.configurators]), ...extra];
105
109
  if (!ignoreUpdateablePrices) {
106
110
  const updatables = await this.sdk.priceFeeds.getPartialUpdatablePriceFeeds([...this.marketFilter.configurators]);
107
111
  txs = (await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(updatables)).txs;
108
112
  }
109
113
  } else if (!ignoreUpdateablePrices) {
110
- multicalls = this.#getOracleSyncMulticalls();
111
- if (!multicalls.length) return;
112
- this.logger?.debug(`syncing prices on ${multicalls.length} oracles`);
113
- txs = (await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs()).txs;
114
- } else return;
114
+ const oracles = this.#getOracleSyncMulticalls();
115
+ multicalls = [...oracles, ...extra];
116
+ if (!multicalls.length) return false;
117
+ if (oracles.length) {
118
+ this.logger?.debug(`syncing prices on ${oracles.length} oracles`);
119
+ txs = (await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs()).txs;
120
+ }
121
+ } else if (extra.length) multicalls = extra;
122
+ else return false;
115
123
  await executeDelegatedMulticalls(this.client, multicalls, {
116
124
  priceUpdates: txs,
117
125
  blockNumber: this.sdk.currentBlock,
118
126
  gas: this.sdk.gasLimit
119
127
  });
128
+ return dirty;
120
129
  }
121
130
  #getOracleSyncMulticalls(oracles) {
122
131
  const uniqOracles = new AddressMap();
@@ -4,53 +4,84 @@ import { VERSION_RANGE_310 } from "../constants/versions.js";
4
4
  import "../constants/index.js";
5
5
  import { hexEq } from "../utils/hex.js";
6
6
  import "../utils/index.js";
7
+ import { executeMulticallBatches } from "../utils/viem/executeMulticallBatches.js";
7
8
  import { SDKConstruct } from "../base/SDKConstruct.js";
8
9
  import "../base/index.js";
9
10
  import { peripheryCompressorAbi } from "../../abi/compressors/peripheryCompressor.js";
11
+ import "../utils/viem/index.js";
10
12
  import { createZapper } from "./zapper/createZapper.js";
11
13
  import "./zapper/index.js";
12
14
  //#region src/sdk/market/ZapperRegister.ts
13
15
  var ZapperRegister = class extends SDKConstruct {
14
16
  /**
15
17
  * Mapping pool.address -> Zapper[]
16
- * Needs to be loaded explicitly using loadZappers method
18
+ * Loaded during SDK attach, or restored by hydration
17
19
  */
18
20
  #zappers;
19
21
  /**
20
- * Load zappers for all pools using periphery compressor, adds hardcoded zappers
21
- */
22
- async loadZappers(force) {
23
- if (!force && this.#zappers) return;
24
- const [pcAddr] = this.sdk.addressProvider.mustGetLatest(AP_PERIPHERY_COMPRESSOR, VERSION_RANGE_310);
22
+ * @internal
23
+ *
24
+ * Returns the multicall batch that loads zappers of all pools from the
25
+ * periphery compressor. Used by the SDK to warm this cache together with
26
+ * other loaders in a single multicall.
27
+ *
28
+ * Returns an empty batch when zappers are already loaded and `force` is not set.
29
+ *
30
+ * @param force - reload zappers even when they are already loaded
31
+ **/
32
+ getLoadZappersMulticall(force) {
33
+ if (!force && this.#zappers) return {
34
+ contracts: [],
35
+ onResults: () => {}
36
+ };
37
+ this.#zappers = new AddressMap(void 0, "zappers");
38
+ const compressor = this.sdk.addressProvider.getLatest(AP_PERIPHERY_COMPRESSOR, VERSION_RANGE_310);
39
+ if (!compressor) {
40
+ this.logger?.warn("no periphery compressor on this chain, skipping zappers");
41
+ return {
42
+ contracts: [],
43
+ onResults: () => {}
44
+ };
45
+ }
46
+ const [pcAddr] = compressor;
25
47
  this.logger?.debug(`loading zappers with periphery compressor ${pcAddr}`);
26
48
  const markets = this.sdk.marketRegister.markets;
27
- const resp = await this.client.multicall({
49
+ return {
28
50
  contracts: markets.map((m) => ({
29
51
  abi: peripheryCompressorAbi,
30
52
  address: pcAddr,
31
53
  functionName: "getZappers",
32
54
  args: [m.configurator.address, m.pool.pool.address]
33
55
  })),
34
- allowFailure: true,
35
- batchSize: 0
36
- });
37
- this.#zappers = new AddressMap(void 0, "zappers");
38
- for (let i = 0; i < resp.length; i++) {
39
- const { status, result, error } = resp[i];
40
- const marketConfigurator = markets[i].configurator.address;
41
- const pool = markets[i].pool.pool.address;
42
- if (status === "success") for (const z of result) this.#addZapper({
43
- ...z,
44
- pool,
45
- type: "base"
46
- });
47
- else this.logger?.error(`failed to load zapper for market configurator ${this.labelAddress(marketConfigurator)} and pool ${this.labelAddress(pool)}: ${error}`);
48
- }
56
+ onResults: (resps) => {
57
+ for (let i = 0; i < resps.length; i++) {
58
+ const { status, result, error } = resps[i];
59
+ const marketConfigurator = markets[i].configurator.address;
60
+ const pool = markets[i].pool.pool.address;
61
+ if (status === "success") for (const z of result) this.#addZapper({
62
+ ...z,
63
+ pool,
64
+ type: "base"
65
+ });
66
+ else this.logger?.error(`failed to load zapper for market configurator ${this.labelAddress(marketConfigurator)} and pool ${this.labelAddress(pool)}: ${error}`);
67
+ }
68
+ }
69
+ };
70
+ }
71
+ /**
72
+ * Load zappers for all pools using periphery compressor, adds hardcoded zappers
73
+ *
74
+ * Zappers loaded during SDK attach or restored by hydration are kept unless
75
+ * `force` is set, so calling this after either is a no-op.
76
+ */
77
+ async loadZappers(force) {
78
+ await executeMulticallBatches(this.client, [this.getLoadZappersMulticall(force)]);
49
79
  }
50
80
  /**
51
81
  * Serializable snapshot of all loaded zappers, suitable for hydration.
52
- * Returns `undefined` when zappers were never loaded (i.e. `loadZappers` was
53
- * not called), so the not-loaded state round-trips cleanly.
82
+ * Returns `undefined` when zappers were never loaded (i.e. the SDK was
83
+ * attached without market configurators), so the not-loaded state round-trips
84
+ * cleanly.
54
85
  **/
55
86
  get zappersState() {
56
87
  if (!this.#zappers) return;
@@ -102,7 +133,7 @@ var ZapperRegister = class extends SDKConstruct {
102
133
  }
103
134
  }
104
135
  get zappers() {
105
- if (!this.#zappers) throw new Error("zappers not loaded, call loadZappers first");
136
+ if (!this.#zappers) throw new Error("zappers are not loaded, check if the sdk was properly attached or hydrated");
106
137
  return this.#zappers;
107
138
  }
108
139
  poolZappers(pool) {
@@ -1,7 +1,7 @@
1
+ import { iPausableAbi } from "../../../abi/iPausable.js";
1
2
  import { iCreditFacadeMulticallV310Abi, iCreditFacadeV310Abi } from "../../../abi/310/generated.js";
2
3
  import { BaseContract } from "../../base/BaseContract.js";
3
4
  import "../../base/index.js";
4
- import { iPausableAbi } from "../../../abi/iPausable.js";
5
5
  //#region src/sdk/market/credit/CreditFacadeV310BaseContract.ts
6
6
  const abi = [
7
7
  ...iCreditFacadeV310Abi,
@@ -1,3 +1,4 @@
1
+ import { iPausableAbi } from "../../../abi/iPausable.js";
1
2
  import { iPoolV310Abi } from "../../../abi/310/generated.js";
2
3
  import { AddressMap } from "../../utils/AddressMap.js";
3
4
  import { RAY } from "../../constants/math.js";
@@ -6,7 +7,6 @@ import { formatBN, formatBNvalue, percentFmt } from "../../utils/formatter.js";
6
7
  import "../../utils/index.js";
7
8
  import { BaseContract } from "../../base/BaseContract.js";
8
9
  import "../../base/index.js";
9
- import { iPausableAbi } from "../../../abi/iPausable.js";
10
10
  import { utilizationBps } from "../math.js";
11
11
  //#region src/sdk/market/pool/PoolV310Contract.ts
12
12
  const abi = [...iPoolV310Abi, ...iPausableAbi];
@@ -24,6 +24,11 @@ var RWARegistry = class extends SDKConstruct {
24
24
  #state;
25
25
  #factories = new AddressMap();
26
26
  /**
27
+ * Factories requested during attach; `undefined` when the registry was
28
+ * hydrated instead, in which case the request was never made on this instance.
29
+ **/
30
+ #requestedFactories;
31
+ /**
27
32
  * @internal
28
33
  *
29
34
  * Returns delegated multicalls for loading all RWA underlying tokens from the on-chain RWA compressor.
@@ -33,6 +38,7 @@ var RWARegistry = class extends SDKConstruct {
33
38
  * @param rwaFactories - RWA factory contracts to query.
34
39
  */
35
40
  getLoadMulticalls(configurators, rwaFactories = []) {
41
+ this.#requestedFactories = rwaFactories;
36
42
  if (!rwaFactories.length) return [];
37
43
  const [rwaCompressorAddress] = this.sdk.addressProvider.mustGetLatest(AP_RWA_COMPRESSOR, VERSION_RANGE_310);
38
44
  return [{
@@ -46,6 +52,22 @@ var RWARegistry = class extends SDKConstruct {
46
52
  }];
47
53
  }
48
54
  /**
55
+ * @internal
56
+ *
57
+ * Returns delegated multicalls that refresh the RWA state. Unlike the other
58
+ * warmed caches, RWA data carries values that change between blocks (e.g. the
59
+ * deposit allowance and claimable amount of an on-demand liquidity provider),
60
+ * so it is refreshed on every SDK sync.
61
+ *
62
+ * Factories are the ones requested during attach; after hydration the chain
63
+ * defaults are used, since the snapshot does not carry the requested list.
64
+ * An attach that explicitly requested no factories stays disabled.
65
+ **/
66
+ getSyncMulticalls() {
67
+ const factories = this.#requestedFactories ?? this.sdk.chain.rwaFactories;
68
+ return this.getLoadMulticalls([...this.sdk.marketRegister.marketFilter.configurators], factories);
69
+ }
70
+ /**
49
71
  * Fetches decoded investor data from the on-chain RWA compressor.
50
72
  *
51
73
  * Each factory produces its own investor data (e.g. registered tokens,
@@ -1,5 +1,5 @@
1
- import { ZapperContract } from "./ZapperContract.js";
2
1
  import { iethZapperAbi } from "../../../abi/iETHZapper.js";
2
+ import { ZapperContract } from "./ZapperContract.js";
3
3
  //#region src/sdk/market/zapper/IETHZapperContract.ts
4
4
  const abi = iethZapperAbi;
5
5
  var IETHZapperContract = class extends ZapperContract {
@@ -1,6 +1,6 @@
1
+ import { iZapperAbi } from "../../../abi/iZapper.js";
1
2
  import { BaseContract } from "../../base/BaseContract.js";
2
3
  import "../../base/index.js";
3
- import { iZapperAbi } from "../../../abi/iZapper.js";
4
4
  import { UnsupportedZapperFunctionError } from "./errors.js";
5
5
  //#region src/sdk/market/zapper/ZapperContract.ts
6
6
  /**
@@ -60,11 +60,7 @@ const attachOptionsSchema = z.object({
60
60
  /**
61
61
  * Options for Redstone price-feed updates.
62
62
  **/
63
- redstone: RedstoneOptions.optional(),
64
- /**
65
- * When `true`, automatically load zappers during attach.
66
- **/
67
- loadZappers: z.boolean().optional()
63
+ redstone: RedstoneOptions.optional()
68
64
  });
69
65
  //#endregion
70
66
  export { attachOptionsSchema, onchainSDKOptionsSchema };
@@ -1,5 +1,5 @@
1
- import { AddressSet } from "../utils/AddressSet.js";
2
1
  import { ierc20Abi } from "../../abi/iERC20.js";
2
+ import { AddressSet } from "../utils/AddressSet.js";
3
3
  import "../constants/addresses.js";
4
4
  import { RAY } from "../constants/math.js";
5
5
  import "../constants/index.js";
@@ -0,0 +1,31 @@
1
+ //#region src/sdk/utils/viem/executeMulticallBatches.ts
2
+ /**
3
+ * Executes the calls of several {@link MulticallBatch}es as a single multicall
4
+ * aggregate and dispatches each batch its own slice of the results.
5
+ *
6
+ * Failures are allowed per call: loaders in a batch decide themselves how to
7
+ * treat a reverted call (e.g. `contractType()` reverting on a plain ERC-20 is
8
+ * expected). Use {@link executeDelegatedMulticalls} instead when the calls need
9
+ * price updates applied first.
10
+ *
11
+ * @param client - Viem public client.
12
+ * @param batches - Batches to execute together, empty ones are allowed.
13
+ * @param opts - Block number forwarded to the multicall.
14
+ **/
15
+ async function executeMulticallBatches(client, batches, opts = {}) {
16
+ const contracts = batches.flatMap((b) => b.contracts);
17
+ if (!contracts.length) return;
18
+ const results = await client.multicall({
19
+ contracts,
20
+ allowFailure: true,
21
+ batchSize: 0,
22
+ blockNumber: opts.blockNumber
23
+ });
24
+ let offset = 0;
25
+ for (const batch of batches) {
26
+ batch.onResults(results.slice(offset, offset + batch.contracts.length));
27
+ offset += batch.contracts.length;
28
+ }
29
+ }
30
+ //#endregion
31
+ export { executeMulticallBatches };
@@ -1,8 +1,9 @@
1
1
  import { generateCastTraceCall, getCastTraceArgs } from "./cast.js";
2
2
  import { SimulationError, simulateCall } from "./simulateCall.js";
3
+ import { executeMulticallBatches } from "./executeMulticallBatches.js";
3
4
  import { simulateMulticall } from "./simulateMulticall.js";
4
5
  import { SimulateWithPriceUpdatesError, getSimulateWithPriceUpdatesError, simulateWithPriceUpdates } from "./simulateWithPriceUpdates.js";
5
6
  import { executeDelegatedMulticalls } from "./executeDelegatedMulticalls.js";
6
7
  import { estimateRawTxGas, sendRawTx } from "./sendRawTx.js";
7
8
  import { watchBlocksAsync } from "./watchBlocksAsync.js";
8
- export { SimulateWithPriceUpdatesError, SimulationError, estimateRawTxGas, executeDelegatedMulticalls, generateCastTraceCall, getCastTraceArgs, getSimulateWithPriceUpdatesError, sendRawTx, simulateCall, simulateMulticall, simulateWithPriceUpdates, watchBlocksAsync };
9
+ export { SimulateWithPriceUpdatesError, SimulationError, estimateRawTxGas, executeDelegatedMulticalls, executeMulticallBatches, generateCastTraceCall, getCastTraceArgs, getSimulateWithPriceUpdatesError, sendRawTx, simulateCall, simulateMulticall, simulateWithPriceUpdates, watchBlocksAsync };
@@ -1,6 +1,6 @@
1
1
  import { errorAbis } from "../../../abi/errors.js";
2
- import { generateCastTraceCall } from "./cast.js";
3
2
  import { iUpdatablePriceFeedAbi } from "../../../abi/iUpdatablePriceFeed.js";
3
+ import { generateCastTraceCall } from "./cast.js";
4
4
  import { simulateMulticall } from "./simulateMulticall.js";
5
5
  import { BaseError, CallExecutionError, ContractFunctionRevertedError, decodeFunctionData, decodeFunctionResult, encodeFunctionData, parseAbi } from "viem";
6
6
  import { getAction, parseAccount } from "viem/utils";
@@ -0,0 +1,14 @@
1
+ //#region src/abi/iExpirable.d.ts
2
+ declare const iExpirableAbi: readonly [{
3
+ readonly type: "function";
4
+ readonly inputs: readonly [];
5
+ readonly name: "isExpired";
6
+ readonly outputs: readonly [{
7
+ readonly name: "";
8
+ readonly internalType: "bool";
9
+ readonly type: "bool";
10
+ }];
11
+ readonly stateMutability: "view";
12
+ }];
13
+ //#endregion
14
+ export { iExpirableAbi };
@@ -63,11 +63,6 @@ interface MultichainAttachOptions {
63
63
  * Options for Redstone price-feed updates (shared cache across chains).
64
64
  **/
65
65
  redstone?: RedstoneOptions;
66
- /**
67
- * When `true`, automatically load zappers after markets are loaded during
68
- * attach on every chain.
69
- **/
70
- loadZappers?: boolean;
71
66
  }
72
67
  /**
73
68
  * Options for {@link MultichainSDK.hydrate}.
@@ -38,7 +38,7 @@ import { HttpRpcClientOptions } from "viem/utils";
38
38
  * Serialised state format version, checked during hydration to detect
39
39
  * incompatible snapshots.
40
40
  **/
41
- declare const STATE_VERSION = 1;
41
+ declare const STATE_VERSION = 2;
42
42
  /**
43
43
  * Connection options for the underlying JSON-RPC provider.
44
44
  *
@@ -132,10 +132,6 @@ interface AttachOptions {
132
132
  * Options for Redstone price-feed updates.
133
133
  **/
134
134
  redstone?: RedstoneOptions;
135
- /**
136
- * When `true`, automatically call {@link MarketRegister.loadZappers} during attach.
137
- **/
138
- loadZappers?: boolean;
139
135
  }
140
136
  /**
141
137
  * Options accepted by {@link OnchainSDK.hydrate}.
@@ -1,4 +1,6 @@
1
1
  import { iWithdrawalCompressorV313Abi } from "../../../abi/IWithdrawalCompressorV313.js";
2
+ import { MulticallBatch } from "../../utils/viem/executeMulticallBatches.js";
3
+ import "../../utils/viem/index.js";
2
4
  import { ClaimableWithdrawal, CurrentWithdrawals, GetExternalAccountCurrentWithdrawalsProps, GetWithdrawalRequestResultProps, IWithdrawalCompressorContract, PendingWithdrawal, RequestableWithdrawal, WithdrawableAsset, WithdrawalStatus, WithdrawalsState } from "./types.js";
3
5
  import { OnchainSDK } from "../../OnchainSDK.js";
4
6
  import { BaseContract, BaseContractArgs } from "../../base/BaseContract.js";
@@ -52,6 +54,10 @@ declare abstract class AbstractWithdrawalCompressorContract<abi extends Abi> ext
52
54
  * {@inheritDoc IWithdrawalCompressorContract.getWithdrawableAssets}
53
55
  **/
54
56
  getWithdrawableAssets(...creditManagers: Address[]): WithdrawableAsset[];
57
+ /**
58
+ * {@inheritDoc IWithdrawalCompressorContract.getLoadWithdrawableAssetsMulticall}
59
+ **/
60
+ getLoadWithdrawableAssetsMulticall(force?: boolean): MulticallBatch;
55
61
  /**
56
62
  * {@inheritDoc IWithdrawalCompressorContract.loadWithdrawableAssets}
57
63
  **/
@@ -1,3 +1,5 @@
1
+ import { MulticallBatch } from "../../utils/viem/executeMulticallBatches.js";
2
+ import "../../utils/viem/index.js";
1
3
  import { IBaseContract } from "../../base/types.js";
2
4
  import { MultiCall } from "../../types/transactions.js";
3
5
  import "../../types/index.js";
@@ -357,11 +359,27 @@ interface IWithdrawalCompressorContract extends IBaseContract {
357
359
  * or state hydration).
358
360
  **/
359
361
  getWithdrawableAssets(...creditManagers: Address[]): WithdrawableAsset[];
362
+ /**
363
+ * @internal
364
+ *
365
+ * Returns the multicall batch that loads withdrawable assets of all credit
366
+ * managers known to the SDK's market register. Used by the SDK to warm this
367
+ * cache together with other loaders in a single multicall.
368
+ *
369
+ * Returns an empty batch when the cache is already loaded and `force` is not set.
370
+ *
371
+ * @param force - Invalidate the cache and refetch even if already loaded.
372
+ **/
373
+ getLoadWithdrawableAssetsMulticall(force?: boolean): MulticallBatch;
360
374
  /**
361
375
  * Loads withdrawable assets of all credit managers known to the SDK's
362
376
  * market register into the cache (a single multicall, only once per SDK
363
377
  * lifetime) and returns them. Failed per-manager calls are logged and
364
378
  * skipped.
379
+ *
380
+ * Assets loaded during SDK attach or restored by state hydration are kept
381
+ * unless `force` is set, so calling this after either is a no-op.
382
+ *
365
383
  * @param force - Invalidate the cache and refetch even if already loaded.
366
384
  * @param blockNumber - Block to read at. Defaults to the latest block.
367
385
  **/
@@ -1,5 +1,6 @@
1
1
  import { ILogger } from "../types/logger.js";
2
2
  import { Token } from "../../model/primitives.js";
3
+ import { MulticallBatch } from "../utils/viem/executeMulticallBatches.js";
3
4
  import { AddressMap } from "../utils/AddressMap.js";
4
5
  import { Asset } from "./types.js";
5
6
  import "../utils/index.js";
@@ -19,6 +20,20 @@ interface FormatBNOptions {
19
20
  **/
20
21
  symbol?: boolean;
21
22
  }
23
+ /**
24
+ * Serializable snapshot of the token metadata registry.
25
+ **/
26
+ interface TokensMetaState {
27
+ /**
28
+ * Metadata of all known tokens.
29
+ **/
30
+ tokens: TokenMetaData[];
31
+ /**
32
+ * Tokens whose extended data (`contractType`, `serialize()`) was loaded,
33
+ * so that the loaded/not-loaded distinction round-trips through hydration.
34
+ **/
35
+ extendedLoaded: Address[];
36
+ }
22
37
  /**
23
38
  * Registry of token metadata (symbol, decimals, phantom type) keyed by address.
24
39
  *
@@ -122,13 +137,41 @@ declare class TokensMeta extends AddressMap<TokenMetaData> {
122
137
  * @throws If no token matches the symbol.
123
138
  */
124
139
  mustFindBySymbol(symbol: string): TokenMetaData;
140
+ /**
141
+ * @internal
142
+ *
143
+ * Returns the multicall batch that loads extended token data (`contractType`
144
+ * and `serialize()`) for the tokens that do not have it yet. Used by the SDK
145
+ * to warm this cache together with other loaders in a single multicall.
146
+ *
147
+ * @param tokens - tokens to load data for, defaults to all tokens
148
+ **/
149
+ getLoadTokenDataMulticall(...tokens: Address[]): MulticallBatch;
125
150
  /**
126
151
  * Loads token information about phantom tokens
127
152
  * In future other custom tokens types that do not have compressors might be handled here
128
153
  *
154
+ * Tokens loaded during SDK attach or restored by {@link hydrate} are skipped,
155
+ * so calling this after either is a no-op.
156
+ *
129
157
  * @param tokens - tokens to load data for, defaults to all tokens
130
158
  */
131
159
  loadTokenData(...tokens: Address[]): Promise<void>;
160
+ /**
161
+ * Serializable snapshot of all token metadata, suitable for hydration.
162
+ **/
163
+ get state(): TokensMetaState;
164
+ /**
165
+ * Restores token metadata from a previously serialized snapshot,
166
+ * bypassing on-chain reads.
167
+ *
168
+ * Entries are merged into the ones already registered by markets, zappers and
169
+ * the RWA registry (see {@link upsert}), so the snapshot must be applied last
170
+ * for its augmented fields to win.
171
+ *
172
+ * @param state - Token metadata snapshot.
173
+ **/
174
+ hydrate(state: TokensMetaState): void;
132
175
  }
133
176
  //#endregion
134
- export { FormatBNOptions, TokensMeta };
177
+ export { FormatBNOptions, TokensMeta, TokensMetaState };
@@ -1,6 +1,6 @@
1
1
  import { AdapterData, AssertAssignable, Asset, BaseParams, BaseState, ConnectedBotData, CreditAccountData, CreditAccountDataPayload, CreditAccountTokensSlice, CreditConfiguratorState, CreditFacadeState, CreditManagerDebtParams, CreditManagerState, CreditSuiteState, GaugeData, IBaseContract, MarketData, MarketFilter, ParsedCall, ParsedCallArgs, ParsedCallV2, PermitResult, PoolState, PriceFeedAnswer, PriceFeedMapEntry, PriceFeedTreeNode, PriceOracleData, QuotaKeeperState, QuotaState, RateKeeperState, RelaxedBaseParams, RewardInfo, TokenInfo, Unarray, VotingContractStatus } from "./types.js";
2
2
  import { LPMonopolizedPoolMeta, PHANTOM_TOKEN_CONTRACT_TYPES, PhantomTokenContractType, PhantomTokenMeta, RWADefaultTokenMeta, RWAOnDemandLPMeta, RWAOnDemandLPMonopolizedMeta, RWAOnDemandLpContractType, RWAOnDemandTokenMeta, RWATokenMeta, RWAUnderlyingContractType, RWA_ON_DEMAND_LP_MONOPOLIZED, RWA_UNDERLYING_DEFAULT, RWA_UNDERLYING_ON_DEMAND, SimpleTokenMeta, TokenMetaData } from "./token-types.js";
3
- import { FormatBNOptions, TokensMeta } from "./TokensMeta.js";
3
+ import { FormatBNOptions, TokensMeta, TokensMetaState } from "./TokensMeta.js";
4
4
  import { ChainContractsRegister, ContractOrInterface } from "./ChainContractsRegister.js";
5
5
  import { Construct, ConstructOptions } from "./Construct.js";
6
6
  import { BaseContract, BaseContractArgs, ContractParseError, ContractParseErrorOptions } from "./BaseContract.js";
@@ -8,4 +8,4 @@ import { MissingSerializedParamsError } from "./errors.js";
8
8
  import { ChainBlock, ChainBlockPin, ChainBlockSource, ChainQueryOneProps, ChainQueryProps, MultichainConstruct } from "./MultichainConstruct.js";
9
9
  import { PlaceholderContract } from "./PlaceholderContract.js";
10
10
  import { SDKConstruct } from "./SDKConstruct.js";
11
- export { AdapterData, AssertAssignable, Asset, BaseContract, BaseContractArgs, BaseParams, BaseState, ChainBlock, ChainBlockPin, ChainBlockSource, ChainContractsRegister, ChainQueryOneProps, ChainQueryProps, ConnectedBotData, Construct, ConstructOptions, ContractOrInterface, ContractParseError, ContractParseErrorOptions, CreditAccountData, CreditAccountDataPayload, CreditAccountTokensSlice, CreditConfiguratorState, CreditFacadeState, CreditManagerDebtParams, CreditManagerState, CreditSuiteState, FormatBNOptions, GaugeData, IBaseContract, LPMonopolizedPoolMeta, MarketData, MarketFilter, MissingSerializedParamsError, MultichainConstruct, PHANTOM_TOKEN_CONTRACT_TYPES, ParsedCall, ParsedCallArgs, ParsedCallV2, PermitResult, PhantomTokenContractType, PhantomTokenMeta, PlaceholderContract, PoolState, PriceFeedAnswer, PriceFeedMapEntry, PriceFeedTreeNode, PriceOracleData, QuotaKeeperState, QuotaState, RWADefaultTokenMeta, RWAOnDemandLPMeta, RWAOnDemandLPMonopolizedMeta, RWAOnDemandLpContractType, RWAOnDemandTokenMeta, RWATokenMeta, RWAUnderlyingContractType, RWA_ON_DEMAND_LP_MONOPOLIZED, RWA_UNDERLYING_DEFAULT, RWA_UNDERLYING_ON_DEMAND, RateKeeperState, RelaxedBaseParams, RewardInfo, SDKConstruct, SimpleTokenMeta, TokenInfo, TokenMetaData, TokensMeta, Unarray, VotingContractStatus };
11
+ export { AdapterData, AssertAssignable, Asset, BaseContract, BaseContractArgs, BaseParams, BaseState, ChainBlock, ChainBlockPin, ChainBlockSource, ChainContractsRegister, ChainQueryOneProps, ChainQueryProps, ConnectedBotData, Construct, ConstructOptions, ContractOrInterface, ContractParseError, ContractParseErrorOptions, CreditAccountData, CreditAccountDataPayload, CreditAccountTokensSlice, CreditConfiguratorState, CreditFacadeState, CreditManagerDebtParams, CreditManagerState, CreditSuiteState, FormatBNOptions, GaugeData, IBaseContract, LPMonopolizedPoolMeta, MarketData, MarketFilter, MissingSerializedParamsError, MultichainConstruct, PHANTOM_TOKEN_CONTRACT_TYPES, ParsedCall, ParsedCallArgs, ParsedCallV2, PermitResult, PhantomTokenContractType, PhantomTokenMeta, PlaceholderContract, PoolState, PriceFeedAnswer, PriceFeedMapEntry, PriceFeedTreeNode, PriceOracleData, QuotaKeeperState, QuotaState, RWADefaultTokenMeta, RWAOnDemandLPMeta, RWAOnDemandLPMonopolizedMeta, RWAOnDemandLpContractType, RWAOnDemandTokenMeta, RWATokenMeta, RWAUnderlyingContractType, RWA_ON_DEMAND_LP_MONOPOLIZED, RWA_UNDERLYING_DEFAULT, RWA_UNDERLYING_ON_DEMAND, RateKeeperState, RelaxedBaseParams, RewardInfo, SDKConstruct, SimpleTokenMeta, TokenInfo, TokenMetaData, TokensMeta, TokensMetaState, Unarray, VotingContractStatus };
@@ -1,5 +1,5 @@
1
1
  import { MarketData, Unarray } from "./types.js";
2
- import { Address } from "viem";
2
+ import { Address, Hex } from "viem";
3
3
  //#region src/sdk/base/token-types.d.ts
4
4
  type TokenData = Unarray<MarketData["tokens"]>;
5
5
  declare const PHANTOM_TOKEN_CONTRACT_TYPES: readonly ["PHANTOM_TOKEN::CONVEX", "PHANTOM_TOKEN::INFINIFI_UNWIND", "PHANTOM_TOKEN::INFRARED", "PHANTOM_TOKEN::MELLOW_WITHDRAWAL", "PHANTOM_TOKEN::MIDAS_REDEMPTION", "PHANTOM_TOKEN::SECURITIZE_RD", "PHANTOM_TOKEN::STAKING_REWARDS", "PHANTOM_TOKEN::UPSHIFT_WITHDRAW"];
@@ -11,6 +11,17 @@ type RWAOnDemandLpContractType = typeof RWA_ON_DEMAND_LP_MONOPOLIZED;
11
11
  type PhantomTokenContractType = (typeof PHANTOM_TOKEN_CONTRACT_TYPES)[number];
12
12
  interface SimpleTokenMeta extends TokenData {
13
13
  contractType?: string;
14
+ /**
15
+ * Raw output of the token's `serialize()` call, when it implements
16
+ * `IStateSerializer`. Decoding is left to the consumer that knows the
17
+ * layout of the given {@link contractType}.
18
+ **/
19
+ serializedParams?: Hex;
20
+ /**
21
+ * Result of the token's `isExpired()` call, when it implements it
22
+ * (e.g. Pendle PT tokens). Undefined for tokens without this method.
23
+ **/
24
+ isExpired?: boolean;
14
25
  }
15
26
  type PhantomTokenMeta = SimpleTokenMeta & {
16
27
  contractType: PhantomTokenContractType;