@gearbox-protocol/sdk 3.0.0-vfour.334 → 3.0.0-vfour.336

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 (31) hide show
  1. package/dist/cjs/dev/PriceFeedStore.js +15 -13
  2. package/dist/cjs/sdk/accounts/CreditAccountsService.js +20 -28
  3. package/dist/cjs/sdk/market/MarketRegister.js +22 -28
  4. package/dist/cjs/sdk/market/oracle/PriceOracleBaseContract.js +1 -1
  5. package/dist/cjs/sdk/market/pricefeeds/PriceFeedsRegister.js +37 -38
  6. package/dist/cjs/sdk/market/pricefeeds/RedstoneUpdater.js +30 -12
  7. package/dist/cjs/sdk/market/pricefeeds/index.js +0 -2
  8. package/dist/cjs/sdk/utils/viem/index.js +3 -1
  9. package/dist/cjs/sdk/utils/viem/simulateWithPriceUpdates.js +134 -0
  10. package/dist/esm/dev/PriceFeedStore.js +17 -15
  11. package/dist/esm/sdk/accounts/CreditAccountsService.js +21 -29
  12. package/dist/esm/sdk/market/MarketRegister.js +23 -29
  13. package/dist/esm/sdk/market/oracle/PriceOracleBaseContract.js +1 -1
  14. package/dist/esm/sdk/market/pricefeeds/PriceFeedsRegister.js +37 -38
  15. package/dist/esm/sdk/market/pricefeeds/RedstoneUpdater.js +29 -12
  16. package/dist/esm/sdk/market/pricefeeds/index.js +0 -1
  17. package/dist/esm/sdk/utils/viem/index.js +1 -0
  18. package/dist/esm/sdk/utils/viem/simulateWithPriceUpdates.js +114 -0
  19. package/dist/types/abi/errors.d.ts +1 -0
  20. package/dist/types/sdk/chain/chains.d.ts +1 -2
  21. package/dist/types/sdk/market/pricefeeds/PriceFeedsRegister.d.ts +1 -1
  22. package/dist/types/sdk/market/pricefeeds/RedstoneUpdater.d.ts +8 -3
  23. package/dist/types/sdk/market/pricefeeds/index.d.ts +0 -1
  24. package/dist/types/sdk/market/pricefeeds/types.d.ts +2 -2
  25. package/dist/types/sdk/types/transactions.d.ts +14 -0
  26. package/dist/types/sdk/utils/viem/index.d.ts +1 -0
  27. package/dist/types/sdk/utils/viem/simulateWithPriceUpdates.d.ts +28 -0
  28. package/package.json +1 -1
  29. package/dist/cjs/sdk/market/pricefeeds/utils.js +0 -42
  30. package/dist/esm/sdk/market/pricefeeds/utils.js +0 -18
  31. package/dist/types/sdk/market/pricefeeds/utils.d.ts +0 -33
@@ -65,19 +65,21 @@ class PriceFeedStore extends import_sdk.SDKConstruct {
65
65
  if (update) {
66
66
  const feeds = result.map((f) => this.sdk.priceFeeds.create(f));
67
67
  const { txs } = await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(feeds);
68
- const resp = await this.provider.publicClient.multicall({
69
- contracts: [
70
- ...txs.map(import_sdk.rawTxToMulticallPriceUpdate),
71
- {
72
- address: this.#compressor,
73
- abi: import_compressors.iPriceFeedCompressorAbi,
74
- functionName: "loadPriceFeedTree",
75
- args: [priceFeeds]
76
- }
77
- ],
78
- allowFailure: false
79
- });
80
- result = resp.pop();
68
+ const [resp] = await (0, import_sdk.simulateWithPriceUpdates)(
69
+ this.provider.publicClient,
70
+ {
71
+ priceUpdates: txs,
72
+ contracts: [
73
+ {
74
+ address: this.#compressor,
75
+ abi: import_compressors.iPriceFeedCompressorAbi,
76
+ functionName: "loadPriceFeedTree",
77
+ args: [priceFeeds]
78
+ }
79
+ ]
80
+ }
81
+ );
82
+ return resp;
81
83
  }
82
84
  this.#logger?.debug(
83
85
  `loaded ${result.length} price feed nodes from compressor`
@@ -28,7 +28,6 @@ var import_v300 = require("../../abi/v300.js");
28
28
  var import_adapters = require("../../adapters/abi/adapters.js");
29
29
  var import_base = require("../base/index.js");
30
30
  var import_constants = require("../constants/index.js");
31
- var import_market = require("../market/index.js");
32
31
  var import_router = require("../router/index.js");
33
32
  var import_sdk_gov_legacy = require("../sdk-gov-legacy/index.js");
34
33
  var import_utils = require("../utils/index.js");
@@ -69,12 +68,12 @@ class CreditAccountsService extends import_base.SDKConstruct {
69
68
  if (raw.success) {
70
69
  return raw;
71
70
  }
72
- const { txs: priceUpdateTxs, timestamp: _ } = await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(void 0, {
71
+ const { txs: priceUpdateTxs } = await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(void 0, {
73
72
  account
74
73
  });
75
- const resp = await (0, import_viem2.simulateMulticall)(this.provider.publicClient, {
74
+ const [cad] = await (0, import_viem2.simulateWithPriceUpdates)(this.provider.publicClient, {
75
+ priceUpdates: priceUpdateTxs,
76
76
  contracts: [
77
- ...priceUpdateTxs.map(import_market.rawTxToMulticallPriceUpdate),
78
77
  {
79
78
  abi: import_compressors.iCreditAccountCompressorAbi,
80
79
  address: this.#compressor,
@@ -82,13 +81,8 @@ class CreditAccountsService extends import_base.SDKConstruct {
82
81
  args: [account]
83
82
  }
84
83
  ],
85
- allowFailure: false,
86
- // gas: 550_000_000n,
87
- batchSize: 0,
88
- // we cannot have price updates and compressor request in different batches
89
84
  blockNumber
90
85
  });
91
- const cad = resp.pop();
92
86
  return cad;
93
87
  }
94
88
  /**
@@ -122,7 +116,7 @@ class CreditAccountsService extends import_base.SDKConstruct {
122
116
  minHealthFactor,
123
117
  maxHealthFactor
124
118
  };
125
- const { txs: priceUpdateTxs, timestamp: _ } = await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs();
119
+ const { txs: priceUpdateTxs } = await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs();
126
120
  const allCAs = [];
127
121
  for (const reverting of [false, true]) {
128
122
  let offset = 0n;
@@ -703,24 +697,22 @@ class CreditAccountsService extends import_base.SDKConstruct {
703
697
  async #getCreditAccounts(args, priceUpdateTxs, options) {
704
698
  const blockNumber = options?.blockNumber;
705
699
  if (priceUpdateTxs?.length) {
706
- const resp = await (0, import_viem2.simulateMulticall)(this.provider.publicClient, {
707
- contracts: [
708
- ...priceUpdateTxs.map(import_market.rawTxToMulticallPriceUpdate),
709
- {
710
- abi: import_compressors.iCreditAccountCompressorAbi,
711
- address: this.#compressor,
712
- functionName: "getCreditAccounts",
713
- args
714
- }
715
- ],
716
- allowFailure: false,
717
- // gas: 550_000_000n,
718
- batchSize: 0,
719
- // we cannot have price updates and compressor request in different batches
720
- blockNumber
721
- });
722
- const getCreditAccountsResp = resp.pop();
723
- return getCreditAccountsResp;
700
+ const [resp] = await (0, import_viem2.simulateWithPriceUpdates)(
701
+ this.provider.publicClient,
702
+ {
703
+ priceUpdates: priceUpdateTxs,
704
+ contracts: [
705
+ {
706
+ abi: import_compressors.iCreditAccountCompressorAbi,
707
+ address: this.#compressor,
708
+ functionName: "getCreditAccounts",
709
+ args
710
+ }
711
+ ],
712
+ blockNumber
713
+ }
714
+ );
715
+ return resp;
724
716
  }
725
717
  return this.provider.publicClient.readContract({
726
718
  abi: import_compressors.iCreditAccountCompressorAbi,
@@ -27,7 +27,6 @@ var import_constants = require("../constants/index.js");
27
27
  var import_utils = require("../utils/index.js");
28
28
  var import_viem = require("../utils/viem/index.js");
29
29
  var import_MarketSuite = require("./MarketSuite.js");
30
- var import_pricefeeds = require("./pricefeeds/index.js");
31
30
  class MarketRegister extends import_base.SDKConstruct {
32
31
  #logger;
33
32
  /**
@@ -102,22 +101,21 @@ class MarketRegister extends import_base.SDKConstruct {
102
101
  );
103
102
  let markets = [];
104
103
  if (txs.length) {
105
- const resp = await (0, import_viem.simulateMulticall)(this.provider.publicClient, {
106
- contracts: [
107
- ...txs.map(import_pricefeeds.rawTxToMulticallPriceUpdate),
108
- {
109
- abi: import_compressors.iMarketCompressorAbi,
110
- address: marketCompressorAddress,
111
- functionName: "getMarkets",
112
- args: [this.#marketFilter]
113
- }
114
- ],
115
- allowFailure: false,
116
- // gas: 550_000_000n,
117
- batchSize: 0
118
- // we cannot have price updates and compressor request in different batches
119
- });
120
- markets = resp.pop();
104
+ const [resp] = await (0, import_viem.simulateWithPriceUpdates)(
105
+ this.provider.publicClient,
106
+ {
107
+ priceUpdates: txs,
108
+ contracts: [
109
+ {
110
+ abi: import_compressors.iMarketCompressorAbi,
111
+ address: marketCompressorAddress,
112
+ functionName: "getMarkets",
113
+ args: [this.#marketFilter]
114
+ }
115
+ ]
116
+ }
117
+ );
118
+ markets = resp;
121
119
  } else {
122
120
  markets = await this.provider.publicClient.readContract({
123
121
  abi: import_compressors.iMarketCompressorAbi,
@@ -145,17 +143,13 @@ class MarketRegister extends import_base.SDKConstruct {
145
143
  return;
146
144
  }
147
145
  const { txs } = await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs();
148
- const resp = await (0, import_viem.simulateMulticall)(this.provider.publicClient, {
149
- contracts: [
150
- ...txs.map(import_pricefeeds.rawTxToMulticallPriceUpdate),
151
- ...multicalls.map((mc) => mc.call)
152
- ],
153
- allowFailure: false,
154
- // gas: 550_000_000n,
155
- batchSize: 0
156
- // we cannot have price updates and compressor request in different batches
157
- });
158
- const oraclesStates = resp.slice(txs.length);
146
+ const oraclesStates = await (0, import_viem.simulateWithPriceUpdates)(
147
+ this.provider.publicClient,
148
+ {
149
+ priceUpdates: txs,
150
+ contracts: multicalls.map((mc) => mc.call)
151
+ }
152
+ );
159
153
  for (let i = 0; i < multicalls.length; i++) {
160
154
  const handler = multicalls[i].onResult;
161
155
  const result = oraclesStates[i];
@@ -107,7 +107,7 @@ class PriceOracleBaseContract extends import_base.BaseContract {
107
107
  }
108
108
  const { txs } = updates;
109
109
  for (const tx of txs) {
110
- const { to: priceFeed, callData, description } = tx;
110
+ const { to: priceFeed, callData, description } = tx.raw;
111
111
  const [token, reserve] = this.findTokenForPriceFeed(priceFeed);
112
112
  if (!token) {
113
113
  this.logger?.debug(
@@ -65,7 +65,43 @@ class PriceFeedRegister extends import_base.SDKConstruct {
65
65
  */
66
66
  async generatePriceFeedsUpdateTxs(priceFeeds, logContext = {}) {
67
67
  const updateables = priceFeeds ? priceFeeds.flatMap((pf) => pf.updatableDependencies()) : this.#feeds.values();
68
- return this.#generatePriceFeedsUpdateTxs(updateables, logContext);
68
+ const txs = [];
69
+ const redstonePFs = [];
70
+ const latestUpdate = {
71
+ redstone: [],
72
+ timestamp: Math.floor(Date.now() / 1e3)
73
+ };
74
+ for (const pf of updateables) {
75
+ if ((0, import_RedstonePriceFeed.isRedstone)(pf)) {
76
+ redstonePFs.push(pf);
77
+ }
78
+ }
79
+ let maxTimestamp = 0;
80
+ if (redstonePFs.length > 0) {
81
+ const redstoneUpdates = await this.redstoneUpdater.getUpdateTxs(
82
+ redstonePFs,
83
+ logContext
84
+ );
85
+ for (const tx of redstoneUpdates) {
86
+ const { data } = tx;
87
+ const { timestamp } = data;
88
+ if (timestamp > maxTimestamp) {
89
+ maxTimestamp = timestamp;
90
+ }
91
+ txs.push(tx);
92
+ latestUpdate.redstone.push(data);
93
+ }
94
+ }
95
+ const result = { txs, timestamp: maxTimestamp };
96
+ this.logger?.debug(
97
+ logContext,
98
+ `generated ${txs.length} price feed update transactions, timestamp: ${maxTimestamp}`
99
+ );
100
+ if (txs.length) {
101
+ await this.#hooks.triggerHooks("updatesGenerated", result);
102
+ }
103
+ this.#latestUpdate = latestUpdate;
104
+ return result;
69
105
  }
70
106
  has(address) {
71
107
  return this.#feeds.has(address);
@@ -114,43 +150,6 @@ class PriceFeedRegister extends import_base.SDKConstruct {
114
150
  this.logger?.debug(`loaded ${result.length} partial updatable price feeds`);
115
151
  return result.map((baseParams) => this.#createUpdatableProxy({ baseParams }));
116
152
  }
117
- async #generatePriceFeedsUpdateTxs(updateables, logContext = {}) {
118
- const txs = [];
119
- const redstonePFs = [];
120
- const latestUpdate = {
121
- redstone: [],
122
- timestamp: Math.floor(Date.now() / 1e3)
123
- };
124
- for (const pf of updateables) {
125
- if ((0, import_RedstonePriceFeed.isRedstone)(pf)) {
126
- redstonePFs.push(pf);
127
- }
128
- }
129
- let maxTimestamp = 0;
130
- if (redstonePFs.length > 0) {
131
- const redstoneUpdates = await this.redstoneUpdater.getUpdateTxs(
132
- redstonePFs,
133
- logContext
134
- );
135
- for (const { tx, timestamp, ...rest } of redstoneUpdates) {
136
- if (timestamp > maxTimestamp) {
137
- maxTimestamp = timestamp;
138
- }
139
- txs.push(tx);
140
- latestUpdate.redstone.push({ ...rest, timestamp });
141
- }
142
- }
143
- const result = { txs, timestamp: maxTimestamp };
144
- this.logger?.debug(
145
- logContext,
146
- `generated ${txs.length} price feed update transactions, timestamp: ${maxTimestamp}`
147
- );
148
- if (txs.length) {
149
- await this.#hooks.triggerHooks("updatesGenerated", result);
150
- }
151
- this.#latestUpdate = latestUpdate;
152
- return result;
153
- }
154
153
  create(data) {
155
154
  const contractType = (0, import_utils.bytes32ToString)(
156
155
  data.baseParams.contractType
@@ -18,6 +18,7 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var RedstoneUpdater_exports = {};
20
20
  __export(RedstoneUpdater_exports, {
21
+ RedstoneUpdateTx: () => RedstoneUpdateTx,
21
22
  RedstoneUpdater: () => RedstoneUpdater
22
23
  });
23
24
  module.exports = __toCommonJS(RedstoneUpdater_exports);
@@ -26,6 +27,18 @@ var import_protocol = require("@redstone-finance/protocol");
26
27
  var import_viem = require("viem");
27
28
  var import_base = require("../../base/index.js");
28
29
  var import_utils = require("../../utils/index.js");
30
+ class RedstoneUpdateTx {
31
+ raw;
32
+ data;
33
+ constructor(raw, data) {
34
+ this.raw = raw;
35
+ this.data = data;
36
+ }
37
+ get pretty() {
38
+ const cached = this.data.cached ? " (cached)" : "";
39
+ return `redstone feed ${this.data.dataFeedId} at ${this.data.priceFeed} with timestamp ${this.data.timestamp}${cached}`;
40
+ }
41
+ }
29
42
  class RedstoneUpdater extends import_base.SDKConstruct {
30
43
  #logger;
31
44
  #cache = /* @__PURE__ */ new Map();
@@ -76,18 +89,22 @@ class RedstoneUpdater extends import_base.SDKConstruct {
76
89
  if (!priceFeed) {
77
90
  throw new Error(`cannot get price feed address for ${dataFeedId}`);
78
91
  }
79
- results.push({
80
- dataFeedId,
81
- dataServiceId,
82
- priceFeed: priceFeed.address.toLowerCase(),
83
- tx: priceFeed.createRawTx({
84
- functionName: "updatePrice",
85
- args: [data],
86
- description: `updating price for ${dataFeedId} [${this.sdk.provider.addressLabels.get(priceFeed.address)}]`
87
- }),
88
- timestamp,
89
- cached
90
- });
92
+ results.push(
93
+ new RedstoneUpdateTx(
94
+ priceFeed.createRawTx({
95
+ functionName: "updatePrice",
96
+ args: [data],
97
+ description: `updating price for ${dataFeedId} [${this.sdk.provider.addressLabels.get(priceFeed.address)}]`
98
+ }),
99
+ {
100
+ dataFeedId,
101
+ dataServiceId,
102
+ priceFeed: priceFeed.address.toLowerCase(),
103
+ timestamp,
104
+ cached
105
+ }
106
+ )
107
+ );
91
108
  }
92
109
  }
93
110
  this.#logger?.debug(
@@ -242,5 +259,6 @@ function getCalldataWithTimestamp(dataFeedId, packages, unsignedMetadata) {
242
259
  }
243
260
  // Annotate the CommonJS export names for ESM import in node:
244
261
  0 && (module.exports = {
262
+ RedstoneUpdateTx,
245
263
  RedstoneUpdater
246
264
  });
@@ -32,7 +32,6 @@ __reExport(pricefeeds_exports, require("./PriceFeedsRegister.js"), module.export
32
32
  __reExport(pricefeeds_exports, require("./PythPriceFeed.js"), module.exports);
33
33
  __reExport(pricefeeds_exports, require("./RedstonePriceFeed.js"), module.exports);
34
34
  __reExport(pricefeeds_exports, require("./types.js"), module.exports);
35
- __reExport(pricefeeds_exports, require("./utils.js"), module.exports);
36
35
  __reExport(pricefeeds_exports, require("./WstETHPriceFeed.js"), module.exports);
37
36
  __reExport(pricefeeds_exports, require("./YearnPriceFeed.js"), module.exports);
38
37
  __reExport(pricefeeds_exports, require("./ZeroPriceFeed.js"), module.exports);
@@ -55,7 +54,6 @@ __reExport(pricefeeds_exports, require("./ZeroPriceFeed.js"), module.exports);
55
54
  ...require("./PythPriceFeed.js"),
56
55
  ...require("./RedstonePriceFeed.js"),
57
56
  ...require("./types.js"),
58
- ...require("./utils.js"),
59
57
  ...require("./WstETHPriceFeed.js"),
60
58
  ...require("./YearnPriceFeed.js"),
61
59
  ...require("./ZeroPriceFeed.js")
@@ -18,9 +18,11 @@ module.exports = __toCommonJS(viem_exports);
18
18
  __reExport(viem_exports, require("./detectNetwork.js"), module.exports);
19
19
  __reExport(viem_exports, require("./sendRawTx.js"), module.exports);
20
20
  __reExport(viem_exports, require("./simulateMulticall.js"), module.exports);
21
+ __reExport(viem_exports, require("./simulateWithPriceUpdates.js"), module.exports);
21
22
  // Annotate the CommonJS export names for ESM import in node:
22
23
  0 && (module.exports = {
23
24
  ...require("./detectNetwork.js"),
24
25
  ...require("./sendRawTx.js"),
25
- ...require("./simulateMulticall.js")
26
+ ...require("./simulateMulticall.js"),
27
+ ...require("./simulateWithPriceUpdates.js")
26
28
  });
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var simulateWithPriceUpdates_exports = {};
20
+ __export(simulateWithPriceUpdates_exports, {
21
+ SimulateWithPriceUpdatesError: () => SimulateWithPriceUpdatesError,
22
+ simulateWithPriceUpdates: () => simulateWithPriceUpdates
23
+ });
24
+ module.exports = __toCommonJS(simulateWithPriceUpdates_exports);
25
+ var import_viem = require("viem");
26
+ var import_abi = require("../../../abi/index.js");
27
+ var import_hex = require("../hex.js");
28
+ var import_simulateMulticall = require("./simulateMulticall.js");
29
+ const updatePriceFeedAbi = [...import_abi.iUpdatablePriceFeedAbi, ...import_abi.errorAbis];
30
+ async function simulateWithPriceUpdates(client, parameters) {
31
+ const { contracts: restContracts, priceUpdates, ...rest } = parameters;
32
+ if (restContracts.length === 0) {
33
+ throw new SimulateWithPriceUpdatesError(
34
+ new import_viem.BaseError("no contracts calls provided"),
35
+ priceUpdates,
36
+ restContracts
37
+ );
38
+ }
39
+ try {
40
+ const contracts = [
41
+ ...priceUpdates.map(rawTxToMulticallPriceUpdate),
42
+ ...restContracts
43
+ ];
44
+ const resp = await (0, import_simulateMulticall.simulateMulticall)(client, {
45
+ contracts,
46
+ ...rest,
47
+ allowFailure: false,
48
+ batchSize: 0
49
+ // we cannot have price updates and compressor request in different batches
50
+ });
51
+ const restResults = resp.slice(priceUpdates.length);
52
+ return restResults;
53
+ } catch (e) {
54
+ throw new SimulateWithPriceUpdatesError(
55
+ e,
56
+ priceUpdates,
57
+ restContracts
58
+ );
59
+ }
60
+ }
61
+ function rawTxToMulticallPriceUpdate({
62
+ raw
63
+ }) {
64
+ const { to, callData } = raw;
65
+ const { args, functionName } = (0, import_viem.decodeFunctionData)({
66
+ abi: updatePriceFeedAbi,
67
+ data: callData
68
+ });
69
+ if (functionName !== "updatePrice") {
70
+ throw new Error(
71
+ `call to function ${functionName} cannot be converted to a price update`
72
+ );
73
+ }
74
+ return {
75
+ abi: updatePriceFeedAbi,
76
+ address: to,
77
+ functionName,
78
+ args
79
+ };
80
+ }
81
+ class SimulateWithPriceUpdatesError extends import_viem.BaseError {
82
+ cause;
83
+ priceUpdates;
84
+ calls;
85
+ constructor(cause, priceUpdates, calls) {
86
+ let failedPriceFeed = "0x0";
87
+ const base = cause instanceof import_viem.BaseError ? cause : {};
88
+ let causeMeta = base.metaMessages ? [...base.metaMessages, " "] : [];
89
+ if (base instanceof import_viem.ContractFunctionExecutionError && base.functionName === "updatePrice") {
90
+ failedPriceFeed = base.contractAddress ?? "0x0";
91
+ causeMeta = [
92
+ `simulate multicall with ${priceUpdates.length} price updates failed`,
93
+ " "
94
+ ];
95
+ const updateRevert = cause instanceof import_viem.BaseError ? cause.walk(
96
+ (err) => err instanceof import_viem.ContractFunctionRevertedError
97
+ ) : void 0;
98
+ if (updateRevert) {
99
+ causeMeta = [
100
+ `simulate multicall with ${priceUpdates.length} price updates failed: ${updateRevert.metaMessages?.[0]}`,
101
+ " "
102
+ ];
103
+ }
104
+ }
105
+ const priceUpdatesMeta = [
106
+ "Price Updates:",
107
+ ...priceUpdates.map(
108
+ (u) => `${(0, import_hex.hexEq)(u.data.priceFeed, failedPriceFeed) ? "[FAILED] " : ""}${u.pretty}`
109
+ )
110
+ ];
111
+ const callsMeta = [
112
+ "Calls:",
113
+ ...calls.map((c) => `${c.address}.${c.functionName}`)
114
+ ];
115
+ super(
116
+ `simulate multicall with ${priceUpdates.length} price updates failed`,
117
+ {
118
+ cause: base,
119
+ metaMessages: [...causeMeta, ...priceUpdatesMeta, ...callsMeta].filter(
120
+ Boolean
121
+ ),
122
+ name: "SimulateWithPriceUpdatesError"
123
+ }
124
+ );
125
+ this.cause = cause;
126
+ this.priceUpdates = priceUpdates;
127
+ this.calls = calls;
128
+ }
129
+ }
130
+ // Annotate the CommonJS export names for ESM import in node:
131
+ 0 && (module.exports = {
132
+ SimulateWithPriceUpdatesError,
133
+ simulateWithPriceUpdates
134
+ });
@@ -3,8 +3,8 @@ import { iPriceFeedStoreAbi } from "../abi/iPriceFeedStore.js";
3
3
  import {
4
4
  AddressMap,
5
5
  AP_PRICE_FEED_COMPRESSOR,
6
- rawTxToMulticallPriceUpdate,
7
- SDKConstruct
6
+ SDKConstruct,
7
+ simulateWithPriceUpdates
8
8
  } from "../sdk/index.js";
9
9
  class PriceFeedStore extends SDKConstruct {
10
10
  #store;
@@ -47,19 +47,21 @@ class PriceFeedStore extends SDKConstruct {
47
47
  if (update) {
48
48
  const feeds = result.map((f) => this.sdk.priceFeeds.create(f));
49
49
  const { txs } = await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(feeds);
50
- const resp = await this.provider.publicClient.multicall({
51
- contracts: [
52
- ...txs.map(rawTxToMulticallPriceUpdate),
53
- {
54
- address: this.#compressor,
55
- abi: iPriceFeedCompressorAbi,
56
- functionName: "loadPriceFeedTree",
57
- args: [priceFeeds]
58
- }
59
- ],
60
- allowFailure: false
61
- });
62
- result = resp.pop();
50
+ const [resp] = await simulateWithPriceUpdates(
51
+ this.provider.publicClient,
52
+ {
53
+ priceUpdates: txs,
54
+ contracts: [
55
+ {
56
+ address: this.#compressor,
57
+ abi: iPriceFeedCompressorAbi,
58
+ functionName: "loadPriceFeedTree",
59
+ args: [priceFeeds]
60
+ }
61
+ ]
62
+ }
63
+ );
64
+ return resp;
63
65
  }
64
66
  this.#logger?.debug(
65
67
  `loaded ${result.length} price feed nodes from compressor`
@@ -20,7 +20,6 @@ import {
20
20
  MIN_INT96,
21
21
  NOT_DEPLOYED
22
22
  } from "../constants/index.js";
23
- import { rawTxToMulticallPriceUpdate } from "../market/index.js";
24
23
  import {
25
24
  assetsMap
26
25
  } from "../router/index.js";
@@ -38,7 +37,7 @@ import {
38
37
  tokenSymbolByAddress
39
38
  } from "../sdk-gov-legacy/index.js";
40
39
  import { childLogger } from "../utils/index.js";
41
- import { simulateMulticall } from "../utils/viem/index.js";
40
+ import { simulateWithPriceUpdates } from "../utils/viem/index.js";
42
41
  class CreditAccountsService extends SDKConstruct {
43
42
  #compressor;
44
43
  #batchSize;
@@ -75,12 +74,12 @@ class CreditAccountsService extends SDKConstruct {
75
74
  if (raw.success) {
76
75
  return raw;
77
76
  }
78
- const { txs: priceUpdateTxs, timestamp: _ } = await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(void 0, {
77
+ const { txs: priceUpdateTxs } = await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(void 0, {
79
78
  account
80
79
  });
81
- const resp = await simulateMulticall(this.provider.publicClient, {
80
+ const [cad] = await simulateWithPriceUpdates(this.provider.publicClient, {
81
+ priceUpdates: priceUpdateTxs,
82
82
  contracts: [
83
- ...priceUpdateTxs.map(rawTxToMulticallPriceUpdate),
84
83
  {
85
84
  abi: iCreditAccountCompressorAbi,
86
85
  address: this.#compressor,
@@ -88,13 +87,8 @@ class CreditAccountsService extends SDKConstruct {
88
87
  args: [account]
89
88
  }
90
89
  ],
91
- allowFailure: false,
92
- // gas: 550_000_000n,
93
- batchSize: 0,
94
- // we cannot have price updates and compressor request in different batches
95
90
  blockNumber
96
91
  });
97
- const cad = resp.pop();
98
92
  return cad;
99
93
  }
100
94
  /**
@@ -128,7 +122,7 @@ class CreditAccountsService extends SDKConstruct {
128
122
  minHealthFactor,
129
123
  maxHealthFactor
130
124
  };
131
- const { txs: priceUpdateTxs, timestamp: _ } = await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs();
125
+ const { txs: priceUpdateTxs } = await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs();
132
126
  const allCAs = [];
133
127
  for (const reverting of [false, true]) {
134
128
  let offset = 0n;
@@ -709,24 +703,22 @@ class CreditAccountsService extends SDKConstruct {
709
703
  async #getCreditAccounts(args, priceUpdateTxs, options) {
710
704
  const blockNumber = options?.blockNumber;
711
705
  if (priceUpdateTxs?.length) {
712
- const resp = await simulateMulticall(this.provider.publicClient, {
713
- contracts: [
714
- ...priceUpdateTxs.map(rawTxToMulticallPriceUpdate),
715
- {
716
- abi: iCreditAccountCompressorAbi,
717
- address: this.#compressor,
718
- functionName: "getCreditAccounts",
719
- args
720
- }
721
- ],
722
- allowFailure: false,
723
- // gas: 550_000_000n,
724
- batchSize: 0,
725
- // we cannot have price updates and compressor request in different batches
726
- blockNumber
727
- });
728
- const getCreditAccountsResp = resp.pop();
729
- return getCreditAccountsResp;
706
+ const [resp] = await simulateWithPriceUpdates(
707
+ this.provider.publicClient,
708
+ {
709
+ priceUpdates: priceUpdateTxs,
710
+ contracts: [
711
+ {
712
+ abi: iCreditAccountCompressorAbi,
713
+ address: this.#compressor,
714
+ functionName: "getCreditAccounts",
715
+ args
716
+ }
717
+ ],
718
+ blockNumber
719
+ }
720
+ );
721
+ return resp;
730
722
  }
731
723
  return this.provider.publicClient.readContract({
732
724
  abi: iCreditAccountCompressorAbi,
@@ -2,9 +2,8 @@ import { iMarketCompressorAbi } from "../../abi/compressors.js";
2
2
  import { SDKConstruct } from "../base/index.js";
3
3
  import { ADDRESS_0X0, AP_MARKET_COMPRESSOR } from "../constants/index.js";
4
4
  import { AddressMap, childLogger } from "../utils/index.js";
5
- import { simulateMulticall } from "../utils/viem/index.js";
5
+ import { simulateWithPriceUpdates } from "../utils/viem/index.js";
6
6
  import { MarketSuite } from "./MarketSuite.js";
7
- import { rawTxToMulticallPriceUpdate } from "./pricefeeds/index.js";
8
7
  class MarketRegister extends SDKConstruct {
9
8
  #logger;
10
9
  /**
@@ -79,22 +78,21 @@ class MarketRegister extends SDKConstruct {
79
78
  );
80
79
  let markets = [];
81
80
  if (txs.length) {
82
- const resp = await simulateMulticall(this.provider.publicClient, {
83
- contracts: [
84
- ...txs.map(rawTxToMulticallPriceUpdate),
85
- {
86
- abi: iMarketCompressorAbi,
87
- address: marketCompressorAddress,
88
- functionName: "getMarkets",
89
- args: [this.#marketFilter]
90
- }
91
- ],
92
- allowFailure: false,
93
- // gas: 550_000_000n,
94
- batchSize: 0
95
- // we cannot have price updates and compressor request in different batches
96
- });
97
- markets = resp.pop();
81
+ const [resp] = await simulateWithPriceUpdates(
82
+ this.provider.publicClient,
83
+ {
84
+ priceUpdates: txs,
85
+ contracts: [
86
+ {
87
+ abi: iMarketCompressorAbi,
88
+ address: marketCompressorAddress,
89
+ functionName: "getMarkets",
90
+ args: [this.#marketFilter]
91
+ }
92
+ ]
93
+ }
94
+ );
95
+ markets = resp;
98
96
  } else {
99
97
  markets = await this.provider.publicClient.readContract({
100
98
  abi: iMarketCompressorAbi,
@@ -122,17 +120,13 @@ class MarketRegister extends SDKConstruct {
122
120
  return;
123
121
  }
124
122
  const { txs } = await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs();
125
- const resp = await simulateMulticall(this.provider.publicClient, {
126
- contracts: [
127
- ...txs.map(rawTxToMulticallPriceUpdate),
128
- ...multicalls.map((mc) => mc.call)
129
- ],
130
- allowFailure: false,
131
- // gas: 550_000_000n,
132
- batchSize: 0
133
- // we cannot have price updates and compressor request in different batches
134
- });
135
- const oraclesStates = resp.slice(txs.length);
123
+ const oraclesStates = await simulateWithPriceUpdates(
124
+ this.provider.publicClient,
125
+ {
126
+ priceUpdates: txs,
127
+ contracts: multicalls.map((mc) => mc.call)
128
+ }
129
+ );
136
130
  for (let i = 0; i < multicalls.length; i++) {
137
131
  const handler = multicalls[i].onResult;
138
132
  const result = oraclesStates[i];
@@ -84,7 +84,7 @@ class PriceOracleBaseContract extends BaseContract {
84
84
  }
85
85
  const { txs } = updates;
86
86
  for (const tx of txs) {
87
- const { to: priceFeed, callData, description } = tx;
87
+ const { to: priceFeed, callData, description } = tx.raw;
88
88
  const [token, reserve] = this.findTokenForPriceFeed(priceFeed);
89
89
  if (!token) {
90
90
  this.logger?.debug(
@@ -44,7 +44,43 @@ class PriceFeedRegister extends SDKConstruct {
44
44
  */
45
45
  async generatePriceFeedsUpdateTxs(priceFeeds, logContext = {}) {
46
46
  const updateables = priceFeeds ? priceFeeds.flatMap((pf) => pf.updatableDependencies()) : this.#feeds.values();
47
- return this.#generatePriceFeedsUpdateTxs(updateables, logContext);
47
+ const txs = [];
48
+ const redstonePFs = [];
49
+ const latestUpdate = {
50
+ redstone: [],
51
+ timestamp: Math.floor(Date.now() / 1e3)
52
+ };
53
+ for (const pf of updateables) {
54
+ if (isRedstone(pf)) {
55
+ redstonePFs.push(pf);
56
+ }
57
+ }
58
+ let maxTimestamp = 0;
59
+ if (redstonePFs.length > 0) {
60
+ const redstoneUpdates = await this.redstoneUpdater.getUpdateTxs(
61
+ redstonePFs,
62
+ logContext
63
+ );
64
+ for (const tx of redstoneUpdates) {
65
+ const { data } = tx;
66
+ const { timestamp } = data;
67
+ if (timestamp > maxTimestamp) {
68
+ maxTimestamp = timestamp;
69
+ }
70
+ txs.push(tx);
71
+ latestUpdate.redstone.push(data);
72
+ }
73
+ }
74
+ const result = { txs, timestamp: maxTimestamp };
75
+ this.logger?.debug(
76
+ logContext,
77
+ `generated ${txs.length} price feed update transactions, timestamp: ${maxTimestamp}`
78
+ );
79
+ if (txs.length) {
80
+ await this.#hooks.triggerHooks("updatesGenerated", result);
81
+ }
82
+ this.#latestUpdate = latestUpdate;
83
+ return result;
48
84
  }
49
85
  has(address) {
50
86
  return this.#feeds.has(address);
@@ -93,43 +129,6 @@ class PriceFeedRegister extends SDKConstruct {
93
129
  this.logger?.debug(`loaded ${result.length} partial updatable price feeds`);
94
130
  return result.map((baseParams) => this.#createUpdatableProxy({ baseParams }));
95
131
  }
96
- async #generatePriceFeedsUpdateTxs(updateables, logContext = {}) {
97
- const txs = [];
98
- const redstonePFs = [];
99
- const latestUpdate = {
100
- redstone: [],
101
- timestamp: Math.floor(Date.now() / 1e3)
102
- };
103
- for (const pf of updateables) {
104
- if (isRedstone(pf)) {
105
- redstonePFs.push(pf);
106
- }
107
- }
108
- let maxTimestamp = 0;
109
- if (redstonePFs.length > 0) {
110
- const redstoneUpdates = await this.redstoneUpdater.getUpdateTxs(
111
- redstonePFs,
112
- logContext
113
- );
114
- for (const { tx, timestamp, ...rest } of redstoneUpdates) {
115
- if (timestamp > maxTimestamp) {
116
- maxTimestamp = timestamp;
117
- }
118
- txs.push(tx);
119
- latestUpdate.redstone.push({ ...rest, timestamp });
120
- }
121
- }
122
- const result = { txs, timestamp: maxTimestamp };
123
- this.logger?.debug(
124
- logContext,
125
- `generated ${txs.length} price feed update transactions, timestamp: ${maxTimestamp}`
126
- );
127
- if (txs.length) {
128
- await this.#hooks.triggerHooks("updatesGenerated", result);
129
- }
130
- this.#latestUpdate = latestUpdate;
131
- return result;
132
- }
133
132
  create(data) {
134
133
  const contractType = bytes32ToString(
135
134
  data.baseParams.contractType
@@ -3,6 +3,18 @@ import { RedstonePayload } from "@redstone-finance/protocol";
3
3
  import { encodeAbiParameters, toBytes } from "viem";
4
4
  import { SDKConstruct } from "../../base/index.js";
5
5
  import { childLogger, retry } from "../../utils/index.js";
6
+ class RedstoneUpdateTx {
7
+ raw;
8
+ data;
9
+ constructor(raw, data) {
10
+ this.raw = raw;
11
+ this.data = data;
12
+ }
13
+ get pretty() {
14
+ const cached = this.data.cached ? " (cached)" : "";
15
+ return `redstone feed ${this.data.dataFeedId} at ${this.data.priceFeed} with timestamp ${this.data.timestamp}${cached}`;
16
+ }
17
+ }
6
18
  class RedstoneUpdater extends SDKConstruct {
7
19
  #logger;
8
20
  #cache = /* @__PURE__ */ new Map();
@@ -53,18 +65,22 @@ class RedstoneUpdater extends SDKConstruct {
53
65
  if (!priceFeed) {
54
66
  throw new Error(`cannot get price feed address for ${dataFeedId}`);
55
67
  }
56
- results.push({
57
- dataFeedId,
58
- dataServiceId,
59
- priceFeed: priceFeed.address.toLowerCase(),
60
- tx: priceFeed.createRawTx({
61
- functionName: "updatePrice",
62
- args: [data],
63
- description: `updating price for ${dataFeedId} [${this.sdk.provider.addressLabels.get(priceFeed.address)}]`
64
- }),
65
- timestamp,
66
- cached
67
- });
68
+ results.push(
69
+ new RedstoneUpdateTx(
70
+ priceFeed.createRawTx({
71
+ functionName: "updatePrice",
72
+ args: [data],
73
+ description: `updating price for ${dataFeedId} [${this.sdk.provider.addressLabels.get(priceFeed.address)}]`
74
+ }),
75
+ {
76
+ dataFeedId,
77
+ dataServiceId,
78
+ priceFeed: priceFeed.address.toLowerCase(),
79
+ timestamp,
80
+ cached
81
+ }
82
+ )
83
+ );
68
84
  }
69
85
  }
70
86
  this.#logger?.debug(
@@ -218,5 +234,6 @@ function getCalldataWithTimestamp(dataFeedId, packages, unsignedMetadata) {
218
234
  };
219
235
  }
220
236
  export {
237
+ RedstoneUpdateTx,
221
238
  RedstoneUpdater
222
239
  };
@@ -15,7 +15,6 @@ export * from "./PriceFeedsRegister.js";
15
15
  export * from "./PythPriceFeed.js";
16
16
  export * from "./RedstonePriceFeed.js";
17
17
  export * from "./types.js";
18
- export * from "./utils.js";
19
18
  export * from "./WstETHPriceFeed.js";
20
19
  export * from "./YearnPriceFeed.js";
21
20
  export * from "./ZeroPriceFeed.js";
@@ -1,3 +1,4 @@
1
1
  export * from "./detectNetwork.js";
2
2
  export * from "./sendRawTx.js";
3
3
  export * from "./simulateMulticall.js";
4
+ export * from "./simulateWithPriceUpdates.js";
@@ -0,0 +1,114 @@
1
+ import {
2
+ BaseError,
3
+ ContractFunctionExecutionError,
4
+ ContractFunctionRevertedError,
5
+ decodeFunctionData
6
+ } from "viem";
7
+ import { errorAbis, iUpdatablePriceFeedAbi } from "../../../abi/index.js";
8
+ import { hexEq } from "../hex.js";
9
+ import { simulateMulticall } from "./simulateMulticall.js";
10
+ const updatePriceFeedAbi = [...iUpdatablePriceFeedAbi, ...errorAbis];
11
+ async function simulateWithPriceUpdates(client, parameters) {
12
+ const { contracts: restContracts, priceUpdates, ...rest } = parameters;
13
+ if (restContracts.length === 0) {
14
+ throw new SimulateWithPriceUpdatesError(
15
+ new BaseError("no contracts calls provided"),
16
+ priceUpdates,
17
+ restContracts
18
+ );
19
+ }
20
+ try {
21
+ const contracts = [
22
+ ...priceUpdates.map(rawTxToMulticallPriceUpdate),
23
+ ...restContracts
24
+ ];
25
+ const resp = await simulateMulticall(client, {
26
+ contracts,
27
+ ...rest,
28
+ allowFailure: false,
29
+ batchSize: 0
30
+ // we cannot have price updates and compressor request in different batches
31
+ });
32
+ const restResults = resp.slice(priceUpdates.length);
33
+ return restResults;
34
+ } catch (e) {
35
+ throw new SimulateWithPriceUpdatesError(
36
+ e,
37
+ priceUpdates,
38
+ restContracts
39
+ );
40
+ }
41
+ }
42
+ function rawTxToMulticallPriceUpdate({
43
+ raw
44
+ }) {
45
+ const { to, callData } = raw;
46
+ const { args, functionName } = decodeFunctionData({
47
+ abi: updatePriceFeedAbi,
48
+ data: callData
49
+ });
50
+ if (functionName !== "updatePrice") {
51
+ throw new Error(
52
+ `call to function ${functionName} cannot be converted to a price update`
53
+ );
54
+ }
55
+ return {
56
+ abi: updatePriceFeedAbi,
57
+ address: to,
58
+ functionName,
59
+ args
60
+ };
61
+ }
62
+ class SimulateWithPriceUpdatesError extends BaseError {
63
+ cause;
64
+ priceUpdates;
65
+ calls;
66
+ constructor(cause, priceUpdates, calls) {
67
+ let failedPriceFeed = "0x0";
68
+ const base = cause instanceof BaseError ? cause : {};
69
+ let causeMeta = base.metaMessages ? [...base.metaMessages, " "] : [];
70
+ if (base instanceof ContractFunctionExecutionError && base.functionName === "updatePrice") {
71
+ failedPriceFeed = base.contractAddress ?? "0x0";
72
+ causeMeta = [
73
+ `simulate multicall with ${priceUpdates.length} price updates failed`,
74
+ " "
75
+ ];
76
+ const updateRevert = cause instanceof BaseError ? cause.walk(
77
+ (err) => err instanceof ContractFunctionRevertedError
78
+ ) : void 0;
79
+ if (updateRevert) {
80
+ causeMeta = [
81
+ `simulate multicall with ${priceUpdates.length} price updates failed: ${updateRevert.metaMessages?.[0]}`,
82
+ " "
83
+ ];
84
+ }
85
+ }
86
+ const priceUpdatesMeta = [
87
+ "Price Updates:",
88
+ ...priceUpdates.map(
89
+ (u) => `${hexEq(u.data.priceFeed, failedPriceFeed) ? "[FAILED] " : ""}${u.pretty}`
90
+ )
91
+ ];
92
+ const callsMeta = [
93
+ "Calls:",
94
+ ...calls.map((c) => `${c.address}.${c.functionName}`)
95
+ ];
96
+ super(
97
+ `simulate multicall with ${priceUpdates.length} price updates failed`,
98
+ {
99
+ cause: base,
100
+ metaMessages: [...causeMeta, ...priceUpdatesMeta, ...callsMeta].filter(
101
+ Boolean
102
+ ),
103
+ name: "SimulateWithPriceUpdatesError"
104
+ }
105
+ );
106
+ this.cause = cause;
107
+ this.priceUpdates = priceUpdates;
108
+ this.calls = calls;
109
+ }
110
+ }
111
+ export {
112
+ SimulateWithPriceUpdatesError,
113
+ simulateWithPriceUpdates
114
+ };
@@ -980,3 +980,4 @@ export declare const errorAbis: readonly [{
980
980
  }];
981
981
  readonly name: "UnsupportedRouterComponent";
982
982
  }];
983
+ export type errorAbis = typeof errorAbis;
@@ -1,6 +1,6 @@
1
1
  import type { Address, Chain } from "viem";
2
2
  import { z } from "zod";
3
- type Curator = "Chaos Labs" | "K3";
3
+ export type Curator = "Chaos Labs" | "K3";
4
4
  export interface GearboxChain extends Chain {
5
5
  network: NetworkType;
6
6
  defaultMarketConfigurators: Record<Address, Curator>;
@@ -15,4 +15,3 @@ export declare function getChain(chainIdOrNetworkType: number | bigint | Network
15
15
  export declare function getNetworkType(chainId: number | bigint): NetworkType;
16
16
  export declare function isSupportedNetwork(chainId: number | undefined): chainId is number;
17
17
  export declare function isPublicNetwork(networkOrChainId: NetworkType | number | bigint): boolean;
18
- export {};
@@ -16,7 +16,7 @@ export type PriceFeedRegisterHooks = {
16
16
  };
17
17
  export interface LatestUpdate {
18
18
  timestamp: number;
19
- redstone: Omit<RedstoneUpdateTask, "tx">[];
19
+ redstone: RedstoneUpdateTask[];
20
20
  }
21
21
  /**
22
22
  * PriceFeedRegister acts as a chain-level cache to avoid creating multiple contract instances.
@@ -1,16 +1,21 @@
1
1
  import type { Address } from "viem";
2
2
  import { SDKConstruct } from "../../base/index.js";
3
3
  import type { GearboxSDK } from "../../GearboxSDK.js";
4
- import type { RawTx } from "../../types/index.js";
4
+ import type { IPriceUpdateTx, RawTx } from "../../types/index.js";
5
5
  import type { RedstonePriceFeedContract } from "./RedstonePriceFeed.js";
6
6
  export interface RedstoneUpdateTask {
7
7
  dataFeedId: string;
8
8
  dataServiceId: string;
9
9
  priceFeed: Address;
10
- tx: RawTx;
11
10
  timestamp: number;
12
11
  cached: boolean;
13
12
  }
13
+ export declare class RedstoneUpdateTx implements IPriceUpdateTx<RedstoneUpdateTask> {
14
+ readonly raw: RawTx;
15
+ readonly data: RedstoneUpdateTask;
16
+ constructor(raw: RawTx, data: RedstoneUpdateTask);
17
+ get pretty(): string;
18
+ }
14
19
  /**
15
20
  * Class to update multiple redstone price feeds at once
16
21
  */
@@ -25,5 +30,5 @@ export declare class RedstoneUpdater extends SDKConstruct {
25
30
  * Set redstone gateways
26
31
  */
27
32
  set gateways(gateways: string[]);
28
- getUpdateTxs(feeds: RedstonePriceFeedContract[], logContext?: Record<string, any>): Promise<RedstoneUpdateTask[]>;
33
+ getUpdateTxs(feeds: RedstonePriceFeedContract[], logContext?: Record<string, any>): Promise<RedstoneUpdateTx[]>;
29
34
  }
@@ -15,7 +15,6 @@ export * from "./PriceFeedsRegister.js";
15
15
  export * from "./PythPriceFeed.js";
16
16
  export * from "./RedstonePriceFeed.js";
17
17
  export * from "./types.js";
18
- export * from "./utils.js";
19
18
  export * from "./WstETHPriceFeed.js";
20
19
  export * from "./YearnPriceFeed.js";
21
20
  export * from "./ZeroPriceFeed.js";
@@ -1,6 +1,6 @@
1
1
  import type { UnionOmit } from "viem";
2
2
  import type { IBaseContract } from "../../base/index.js";
3
- import type { PriceFeedStateHuman, RawTx } from "../../types/index.js";
3
+ import type { IPriceUpdateTx, PriceFeedStateHuman } from "../../types/index.js";
4
4
  import type { PriceFeedRef } from "./PriceFeedRef.js";
5
5
  export type PriceFeedUsageType = "Main" | "Reserve";
6
6
  export type PriceFeedContractTypeLegacy = "PF_BALANCER_STABLE_LP_ORACLE" | "PF_BALANCER_WEIGHTED_LP_ORACLE" | "PF_BOUNDED_ORACLE" | "PF_CHAINLINK_ORACLE" | "PF_COMPOSITE_ORACLE" | "PF_CURVE_CRYPTO_LP_ORACLE" | "PF_CURVE_STABLE_LP_ORACLE" | "PF_CURVE_USD_ORACLE" | "PF_ERC4626_ORACLE" | "PF_MELLOW_LRT_ORACLE" | "PF_PENDLE_PT_TWAP_ORACLE" | "PF_PYTH_ORACLE" | "PF_REDSTONE_ORACLE" | "PF_WSTETH_ORACLE" | "PF_YEARN_ORACLE" | "PF_ZERO_ORACLE";
@@ -35,6 +35,6 @@ export interface ILPPriceFeedContract extends IPriceFeedContract {
35
35
  currentLowerBound: () => Promise<bigint>;
36
36
  }
37
37
  export interface UpdatePriceFeedsResult {
38
- txs: RawTx[];
38
+ txs: IPriceUpdateTx[];
39
39
  timestamp: number;
40
40
  }
@@ -13,6 +13,20 @@ export interface RawTx {
13
13
  contractInputsValues: Record<string, any>;
14
14
  description?: string;
15
15
  }
16
+ /**
17
+ * Wrapper interface for RawTx with diagnostic data
18
+ */
19
+ export interface IPriceUpdateTx<Data extends {
20
+ timestamp: number;
21
+ priceFeed: Address;
22
+ } = {
23
+ priceFeed: Address;
24
+ timestamp: number;
25
+ }> {
26
+ raw: RawTx;
27
+ data: Data;
28
+ pretty: string;
29
+ }
16
30
  export interface MultiCall {
17
31
  target: Address;
18
32
  callData: Hex;
@@ -1,3 +1,4 @@
1
1
  export * from "./detectNetwork.js";
2
2
  export * from "./sendRawTx.js";
3
3
  export * from "./simulateMulticall.js";
4
+ export * from "./simulateWithPriceUpdates.js";
@@ -0,0 +1,28 @@
1
+ import type { AbiStateMutability, Narrow } from "abitype";
2
+ import type { Chain, Client, ContractFunctionParameters, MulticallContracts, MulticallParameters, MulticallReturnType, Transport } from "viem";
3
+ import { BaseError } from "viem";
4
+ import type { IPriceUpdateTx } from "../../types/index.js";
5
+ export type SimulateWithPriceUpdatesParameters<contracts extends readonly unknown[] = readonly ContractFunctionParameters[], options extends {
6
+ optional?: boolean;
7
+ properties?: Record<string, any>;
8
+ } = {}> = MulticallParameters<contracts, false, options> & {
9
+ priceUpdates: IPriceUpdateTx[];
10
+ contracts: MulticallContracts<Narrow<contracts>, {
11
+ mutability: AbiStateMutability;
12
+ }>;
13
+ };
14
+ export type SimulateWithPriceUpdatesReturnType<contracts extends readonly unknown[] = readonly ContractFunctionParameters[], options extends {
15
+ error?: Error;
16
+ } = {
17
+ error: Error;
18
+ }> = MulticallReturnType<contracts, false, options>;
19
+ export declare function simulateWithPriceUpdates<const contracts extends readonly unknown[], chain extends Chain | undefined>(client: Client<Transport, chain>, parameters: SimulateWithPriceUpdatesParameters<contracts>): Promise<SimulateWithPriceUpdatesReturnType<contracts>>;
20
+ export type SimulateWithPriceUpdatesErrorType<contracts extends readonly unknown[]> = SimulateWithPriceUpdatesError<contracts> & {
21
+ name: "SimulateWithPriceUpdatesError";
22
+ };
23
+ export declare class SimulateWithPriceUpdatesError<contracts extends readonly unknown[]> extends BaseError {
24
+ cause: Error;
25
+ readonly priceUpdates: IPriceUpdateTx[];
26
+ readonly calls: MulticallContracts<Narrow<contracts>>;
27
+ constructor(cause: Error, priceUpdates: IPriceUpdateTx[], calls: MulticallContracts<Narrow<contracts>>);
28
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gearbox-protocol/sdk",
3
- "version": "3.0.0-vfour.334",
3
+ "version": "3.0.0-vfour.336",
4
4
  "description": "Gearbox SDK",
5
5
  "license": "MIT",
6
6
  "main": "./dist/cjs/sdk/index.js",
@@ -1,42 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- var utils_exports = {};
20
- __export(utils_exports, {
21
- rawTxToMulticallPriceUpdate: () => rawTxToMulticallPriceUpdate
22
- });
23
- module.exports = __toCommonJS(utils_exports);
24
- var import_viem = require("viem");
25
- var import_iUpdatablePriceFeed = require("../../../abi/iUpdatablePriceFeed.js");
26
- function rawTxToMulticallPriceUpdate(tx) {
27
- const { to, callData } = tx;
28
- const { args, functionName } = (0, import_viem.decodeFunctionData)({
29
- abi: import_iUpdatablePriceFeed.iUpdatablePriceFeedAbi,
30
- data: callData
31
- });
32
- return {
33
- abi: import_iUpdatablePriceFeed.iUpdatablePriceFeedAbi,
34
- address: to,
35
- functionName,
36
- args
37
- };
38
- }
39
- // Annotate the CommonJS export names for ESM import in node:
40
- 0 && (module.exports = {
41
- rawTxToMulticallPriceUpdate
42
- });
@@ -1,18 +0,0 @@
1
- import { decodeFunctionData } from "viem";
2
- import { iUpdatablePriceFeedAbi } from "../../../abi/iUpdatablePriceFeed.js";
3
- function rawTxToMulticallPriceUpdate(tx) {
4
- const { to, callData } = tx;
5
- const { args, functionName } = decodeFunctionData({
6
- abi: iUpdatablePriceFeedAbi,
7
- data: callData
8
- });
9
- return {
10
- abi: iUpdatablePriceFeedAbi,
11
- address: to,
12
- functionName,
13
- args
14
- };
15
- }
16
- export {
17
- rawTxToMulticallPriceUpdate
18
- };
@@ -1,33 +0,0 @@
1
- import type { RawTx } from "../../types/index.js";
2
- /**
3
- * Helper method to convert our RawTx into viem's multicall format
4
- * Involves decoding what was previously encoded, but it's better than adding another method to PriceOracle
5
- * @param tx
6
- * @returns
7
- */
8
- export declare function rawTxToMulticallPriceUpdate(tx: RawTx): {
9
- abi: readonly [{
10
- readonly type: "function";
11
- readonly name: "updatable";
12
- readonly inputs: readonly [];
13
- readonly outputs: readonly [{
14
- readonly name: "";
15
- readonly type: "bool";
16
- readonly internalType: "bool";
17
- }];
18
- readonly stateMutability: "view";
19
- }, {
20
- readonly type: "function";
21
- readonly name: "updatePrice";
22
- readonly inputs: readonly [{
23
- readonly name: "data";
24
- readonly type: "bytes";
25
- readonly internalType: "bytes";
26
- }];
27
- readonly outputs: readonly [];
28
- readonly stateMutability: "nonpayable";
29
- }];
30
- address: `0x${string}`;
31
- functionName: "updatable" | "updatePrice";
32
- args: readonly [] | readonly [`0x${string}`];
33
- };