@gearbox-protocol/sdk 8.1.6 → 8.2.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 (70) hide show
  1. package/dist/cjs/plugins/degen-distributors/DegenDistributorsPlugin.js +3 -1
  2. package/dist/cjs/plugins/pools-history/Pools7DAgoPlugin.js +6 -1
  3. package/dist/cjs/sdk/GearboxSDK.js +20 -8
  4. package/dist/cjs/sdk/abi/oracles.js +141 -0
  5. package/dist/cjs/sdk/accounts/CreditAccountsService.js +37 -0
  6. package/dist/cjs/sdk/chain/chains.js +4 -4
  7. package/dist/cjs/sdk/market/pricefeeds/AbstractPriceFeed.js +2 -1
  8. package/dist/cjs/sdk/market/pricefeeds/PriceFeedsRegister.js +17 -23
  9. package/dist/cjs/sdk/market/pricefeeds/PythPriceFeed.js +9 -1
  10. package/dist/cjs/sdk/market/pricefeeds/RedstonePriceFeed.js +9 -7
  11. package/dist/cjs/sdk/market/pricefeeds/index.js +2 -0
  12. package/dist/cjs/sdk/market/pricefeeds/isUpdatablePriceFeed.js +30 -0
  13. package/dist/cjs/sdk/market/pricefeeds/updates/PriceUpdateTx.js +52 -0
  14. package/dist/cjs/sdk/market/pricefeeds/{RedstoneCache.js → updates/PriceUpdatesCache.js} +12 -12
  15. package/dist/cjs/sdk/market/pricefeeds/updates/PythUpdater.js +189 -0
  16. package/dist/cjs/sdk/market/pricefeeds/{RedstoneUpdater.js → updates/RedstoneUpdater.js} +21 -45
  17. package/dist/cjs/sdk/market/pricefeeds/updates/index.js +31 -0
  18. package/dist/cjs/sdk/market/pricefeeds/updates/types.js +16 -0
  19. package/dist/cjs/sdk/sdk-legacy/tokens/tokenData.js +1 -2
  20. package/dist/cjs/sdk/utils/retry.js +4 -2
  21. package/dist/cjs/sdk/utils/viem/cast.js +5 -2
  22. package/dist/cjs/sdk/utils/viem/simulateMulticall.js +3 -1
  23. package/dist/cjs/sdk/utils/viem/simulateWithPriceUpdates.js +2 -2
  24. package/dist/esm/plugins/degen-distributors/DegenDistributorsPlugin.js +3 -1
  25. package/dist/esm/plugins/pools-history/Pools7DAgoPlugin.js +6 -1
  26. package/dist/esm/sdk/GearboxSDK.js +20 -8
  27. package/dist/esm/sdk/abi/oracles.js +140 -0
  28. package/dist/esm/sdk/accounts/CreditAccountsService.js +40 -1
  29. package/dist/esm/sdk/chain/chains.js +4 -4
  30. package/dist/esm/sdk/market/pricefeeds/AbstractPriceFeed.js +2 -1
  31. package/dist/esm/sdk/market/pricefeeds/PriceFeedsRegister.js +18 -24
  32. package/dist/esm/sdk/market/pricefeeds/PythPriceFeed.js +9 -1
  33. package/dist/esm/sdk/market/pricefeeds/RedstonePriceFeed.js +8 -5
  34. package/dist/esm/sdk/market/pricefeeds/index.js +1 -0
  35. package/dist/esm/sdk/market/pricefeeds/isUpdatablePriceFeed.js +6 -0
  36. package/dist/esm/sdk/market/pricefeeds/updates/PriceUpdateTx.js +28 -0
  37. package/dist/esm/sdk/market/pricefeeds/{RedstoneCache.js → updates/PriceUpdatesCache.js} +8 -8
  38. package/dist/esm/sdk/market/pricefeeds/updates/PythUpdater.js +169 -0
  39. package/dist/esm/sdk/market/pricefeeds/{RedstoneUpdater.js → updates/RedstoneUpdater.js} +21 -44
  40. package/dist/esm/sdk/market/pricefeeds/updates/index.js +6 -0
  41. package/dist/esm/sdk/market/pricefeeds/updates/types.js +0 -0
  42. package/dist/esm/sdk/sdk-legacy/tokens/tokenData.js +1 -2
  43. package/dist/esm/sdk/utils/retry.js +4 -2
  44. package/dist/esm/sdk/utils/viem/cast.js +5 -2
  45. package/dist/esm/sdk/utils/viem/simulateMulticall.js +3 -1
  46. package/dist/esm/sdk/utils/viem/simulateWithPriceUpdates.js +2 -2
  47. package/dist/types/sdk/GearboxSDK.d.ts +5 -1
  48. package/dist/types/sdk/abi/oracles.d.ts +212 -0
  49. package/dist/types/sdk/accounts/CreditAccountsService.d.ts +11 -0
  50. package/dist/types/sdk/chain/chains.d.ts +1 -1
  51. package/dist/types/sdk/market/pricefeeds/AbstractPriceFeed.d.ts +2 -2
  52. package/dist/types/sdk/market/pricefeeds/PriceFeedsRegister.d.ts +4 -4
  53. package/dist/types/sdk/market/pricefeeds/PythPriceFeed.d.ts +218 -4
  54. package/dist/types/sdk/market/pricefeeds/RedstonePriceFeed.d.ts +4 -4
  55. package/dist/types/sdk/market/pricefeeds/index.d.ts +1 -0
  56. package/dist/types/sdk/market/pricefeeds/isUpdatablePriceFeed.d.ts +2 -0
  57. package/dist/types/sdk/market/pricefeeds/types.d.ts +5 -2
  58. package/dist/types/sdk/market/pricefeeds/updates/PriceUpdateTx.d.ts +10 -0
  59. package/dist/types/sdk/market/pricefeeds/updates/PriceUpdatesCache.d.ts +17 -0
  60. package/dist/types/sdk/market/pricefeeds/updates/PythUpdater.d.ts +40 -0
  61. package/dist/types/sdk/market/pricefeeds/{RedstoneUpdater.d.ts → updates/RedstoneUpdater.d.ts} +11 -18
  62. package/dist/types/sdk/market/pricefeeds/updates/RedstoneUpdater.test.d.ts +1 -0
  63. package/dist/types/sdk/market/pricefeeds/updates/index.d.ts +3 -0
  64. package/dist/types/sdk/market/pricefeeds/updates/types.d.ts +21 -0
  65. package/dist/types/sdk/utils/retry.d.ts +1 -0
  66. package/dist/types/sdk/utils/viem/cast.d.ts +1 -1
  67. package/dist/types/sdk/utils/viem/simulateMulticall.d.ts +1 -1
  68. package/dist/types/sdk/utils/viem/simulateWithPriceUpdates.d.ts +1 -1
  69. package/package.json +4 -1
  70. package/dist/types/sdk/market/pricefeeds/RedstoneCache.d.ts +0 -25
@@ -47,13 +47,15 @@ class DegenDistributorsPlugin extends import_sdk.BasePlugin {
47
47
  acc[cfgLC] = distributors[index];
48
48
  return acc;
49
49
  }, {});
50
- this.#distributors = new import_sdk.AddressMap(void 0, MAP_LABEL);
51
50
  this.sdk.marketRegister.markets.forEach((m) => {
52
51
  const pool = m.pool.pool.address;
53
52
  const cfg = m.configurator.address;
54
53
  const cfgLC = cfg.toLowerCase();
55
54
  const r = distributorByConfigurator?.[cfgLC];
56
55
  if (r.status === "fulfilled") {
56
+ if (!this.#distributors) {
57
+ this.#distributors = new import_sdk.AddressMap(void 0, MAP_LABEL);
58
+ }
57
59
  this.#distributors.upsert(pool, r.value);
58
60
  } else {
59
61
  this.sdk.logger?.error(
@@ -51,12 +51,17 @@ class Pools7DAgoPlugin extends import_sdk.BasePlugin {
51
51
  ),
52
52
  blockNumber: import_sdk.BigIntMath.max(0n, targetBlock)
53
53
  });
54
- this.#pools7DAgo = new import_sdk.AddressMap(void 0, MAP_LABEL);
55
54
  resp.forEach((r, index) => {
56
55
  const m = markets[index];
57
56
  const cfg = m.configurator.address;
58
57
  const pool = m.pool.pool.address;
59
58
  if (r.status === "success") {
59
+ if (!this.#pools7DAgo) {
60
+ this.#pools7DAgo = new import_sdk.AddressMap(
61
+ void 0,
62
+ MAP_LABEL
63
+ );
64
+ }
60
65
  this.#pools7DAgo.upsert(m.pool.pool.address, {
61
66
  dieselRate: r.result.dieselRate,
62
67
  pool
@@ -81,6 +81,7 @@ class GearboxSDK {
81
81
  plugins,
82
82
  blockNumber,
83
83
  redstone,
84
+ pyth,
84
85
  ignoreUpdateablePrices,
85
86
  marketConfigurators: mcs,
86
87
  strictContractTypes
@@ -114,7 +115,8 @@ class GearboxSDK {
114
115
  blockNumber,
115
116
  ignoreUpdateablePrices,
116
117
  marketConfigurators,
117
- redstone
118
+ redstone,
119
+ pyth
118
120
  });
119
121
  }
120
122
  static hydrate(options, state) {
@@ -146,7 +148,8 @@ class GearboxSDK {
146
148
  blockNumber,
147
149
  ignoreUpdateablePrices,
148
150
  marketConfigurators,
149
- redstone
151
+ redstone,
152
+ pyth
150
153
  } = opts;
151
154
  const re = this.#attachConfig ? "re" : "";
152
155
  this.logger?.info(
@@ -161,7 +164,12 @@ class GearboxSDK {
161
164
  );
162
165
  if (!!blockNumber && !opts.redstone?.historicTimestamp) {
163
166
  this.logger?.warn(
164
- `${re}attaching to fixed block number, but redstoneHistoricTimestamp is not set. price updates might fail`
167
+ `${re}attaching to fixed block number, but redstone historicTimestamp is not set. price updates might fail`
168
+ );
169
+ }
170
+ if (!!blockNumber && !opts.pyth?.historicTimestamp) {
171
+ this.logger?.warn(
172
+ `${re}attaching to fixed block number, but pyth historicTimestamp is not set. price updates might fail`
165
173
  );
166
174
  }
167
175
  this.#attachConfig = opts;
@@ -173,7 +181,7 @@ class GearboxSDK {
173
181
  );
174
182
  this.#currentBlock = block.number;
175
183
  this.#timestamp = block.timestamp;
176
- this.#priceFeeds = new import_pricefeeds.PriceFeedRegister(this, { redstone });
184
+ this.#priceFeeds = new import_pricefeeds.PriceFeedRegister(this, { redstone, pyth });
177
185
  this.logger?.debug(
178
186
  `${re}attach block number ${this.currentBlock} timestamp ${this.timestamp}`
179
187
  );
@@ -224,7 +232,10 @@ class GearboxSDK {
224
232
  );
225
233
  this.#currentBlock = state.currentBlock;
226
234
  this.#timestamp = state.timestamp;
227
- this.#priceFeeds = new import_pricefeeds.PriceFeedRegister(this, { redstone: opts.redstone });
235
+ this.#priceFeeds = new import_pricefeeds.PriceFeedRegister(this, {
236
+ redstone: opts.redstone,
237
+ pyth: opts.pyth
238
+ });
228
239
  this.#addressProvider = (0, import_core.hydrateAddressProvider)(this, state.addressProvider);
229
240
  this.logger?.debug(
230
241
  `address provider version: ${this.#addressProvider.version}`
@@ -276,7 +287,8 @@ class GearboxSDK {
276
287
  }
277
288
  const opts = {
278
289
  ignoreUpdateablePrices: this.#attachConfig.ignoreUpdateablePrices,
279
- redstone: this.#attachConfig.redstone
290
+ redstone: this.#attachConfig.redstone,
291
+ pyth: this.#attachConfig.pyth
280
292
  };
281
293
  this.#hydrate(opts, state);
282
294
  await this.#hooks.triggerHooks("rehydrate", {
@@ -375,9 +387,9 @@ class GearboxSDK {
375
387
  */
376
388
  async syncState(opts) {
377
389
  let { blockNumber, timestamp, skipPriceUpdate } = opts ?? {};
378
- if (this.#attachConfig?.redstone?.historicTimestamp) {
390
+ if (this.#attachConfig?.redstone?.historicTimestamp || this.#attachConfig?.pyth?.historicTimestamp) {
379
391
  throw new Error(
380
- "syncState is not supported with redstoneHistoricTimestamp"
392
+ "syncState is not supported with redstone or pyth historicTimestamp"
381
393
  );
382
394
  }
383
395
  if (!blockNumber || !timestamp) {
@@ -38,6 +38,7 @@ __export(oracles_exports, {
38
38
  iyVaultAbi: () => iyVaultAbi,
39
39
  mellowLrtPriceFeedAbi: () => mellowLrtPriceFeedAbi,
40
40
  pendleTWAPPTPriceFeedAbi: () => pendleTWAPPTPriceFeedAbi,
41
+ pythPriceFeedAbi: () => pythPriceFeedAbi,
41
42
  redstonePriceFeedAbi: () => redstonePriceFeedAbi,
42
43
  wstEthPriceFeedAbi: () => wstEthPriceFeedAbi,
43
44
  yearnPriceFeedAbi: () => yearnPriceFeedAbi,
@@ -4543,6 +4544,145 @@ const pendleTWAPPTPriceFeedAbi = [
4543
4544
  inputs: []
4544
4545
  }
4545
4546
  ];
4547
+ const pythPriceFeedAbi = [
4548
+ {
4549
+ type: "constructor",
4550
+ inputs: [
4551
+ { name: "_token", type: "address", internalType: "address" },
4552
+ { name: "_priceFeedId", type: "bytes32", internalType: "bytes32" },
4553
+ { name: "_pyth", type: "address", internalType: "address" },
4554
+ {
4555
+ name: "_maxConfToPriceRatio",
4556
+ type: "uint256",
4557
+ internalType: "uint256"
4558
+ },
4559
+ { name: "descriptionTicker", type: "string", internalType: "string" }
4560
+ ],
4561
+ stateMutability: "nonpayable"
4562
+ },
4563
+ { type: "receive", stateMutability: "payable" },
4564
+ {
4565
+ type: "function",
4566
+ name: "contractType",
4567
+ inputs: [],
4568
+ outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }],
4569
+ stateMutability: "view"
4570
+ },
4571
+ {
4572
+ type: "function",
4573
+ name: "decimals",
4574
+ inputs: [],
4575
+ outputs: [{ name: "", type: "uint8", internalType: "uint8" }],
4576
+ stateMutability: "view"
4577
+ },
4578
+ {
4579
+ type: "function",
4580
+ name: "description",
4581
+ inputs: [],
4582
+ outputs: [{ name: "", type: "string", internalType: "string" }],
4583
+ stateMutability: "view"
4584
+ },
4585
+ {
4586
+ type: "function",
4587
+ name: "latestRoundData",
4588
+ inputs: [],
4589
+ outputs: [
4590
+ { name: "", type: "uint80", internalType: "uint80" },
4591
+ { name: "", type: "int256", internalType: "int256" },
4592
+ { name: "", type: "uint256", internalType: "uint256" },
4593
+ { name: "", type: "uint256", internalType: "uint256" },
4594
+ { name: "", type: "uint80", internalType: "uint80" }
4595
+ ],
4596
+ stateMutability: "view"
4597
+ },
4598
+ {
4599
+ type: "function",
4600
+ name: "maxConfToPriceRatio",
4601
+ inputs: [],
4602
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
4603
+ stateMutability: "view"
4604
+ },
4605
+ {
4606
+ type: "function",
4607
+ name: "priceFeedId",
4608
+ inputs: [],
4609
+ outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }],
4610
+ stateMutability: "view"
4611
+ },
4612
+ {
4613
+ type: "function",
4614
+ name: "pyth",
4615
+ inputs: [],
4616
+ outputs: [{ name: "", type: "address", internalType: "address" }],
4617
+ stateMutability: "view"
4618
+ },
4619
+ {
4620
+ type: "function",
4621
+ name: "serialize",
4622
+ inputs: [],
4623
+ outputs: [{ name: "", type: "bytes", internalType: "bytes" }],
4624
+ stateMutability: "view"
4625
+ },
4626
+ {
4627
+ type: "function",
4628
+ name: "skipPriceCheck",
4629
+ inputs: [],
4630
+ outputs: [{ name: "", type: "bool", internalType: "bool" }],
4631
+ stateMutability: "view"
4632
+ },
4633
+ {
4634
+ type: "function",
4635
+ name: "token",
4636
+ inputs: [],
4637
+ outputs: [{ name: "", type: "address", internalType: "address" }],
4638
+ stateMutability: "view"
4639
+ },
4640
+ {
4641
+ type: "function",
4642
+ name: "updatable",
4643
+ inputs: [],
4644
+ outputs: [{ name: "", type: "bool", internalType: "bool" }],
4645
+ stateMutability: "view"
4646
+ },
4647
+ {
4648
+ type: "function",
4649
+ name: "updatePrice",
4650
+ inputs: [{ name: "data", type: "bytes", internalType: "bytes" }],
4651
+ outputs: [],
4652
+ stateMutability: "nonpayable"
4653
+ },
4654
+ {
4655
+ type: "function",
4656
+ name: "version",
4657
+ inputs: [],
4658
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
4659
+ stateMutability: "view"
4660
+ },
4661
+ {
4662
+ type: "event",
4663
+ name: "UpdatePrice",
4664
+ inputs: [
4665
+ {
4666
+ name: "price",
4667
+ type: "uint256",
4668
+ indexed: false,
4669
+ internalType: "uint256"
4670
+ }
4671
+ ],
4672
+ anonymous: false
4673
+ },
4674
+ { type: "error", name: "ConfToPriceRatioTooHighException", inputs: [] },
4675
+ {
4676
+ type: "error",
4677
+ name: "IncorrectExpectedPublishTimestampException",
4678
+ inputs: []
4679
+ },
4680
+ { type: "error", name: "IncorrectParameterException", inputs: [] },
4681
+ { type: "error", name: "IncorrectPriceDecimalsException", inputs: [] },
4682
+ { type: "error", name: "IncorrectPriceException", inputs: [] },
4683
+ { type: "error", name: "PriceTimestampTooFarAheadException", inputs: [] },
4684
+ { type: "error", name: "PriceTimestampTooFarBehindException", inputs: [] }
4685
+ ];
4546
4686
  // Annotate the CommonJS export names for ESM import in node:
4547
4687
  0 && (module.exports = {
4548
4688
  boundedPriceFeedAbi,
@@ -4565,6 +4705,7 @@ const pendleTWAPPTPriceFeedAbi = [
4565
4705
  iyVaultAbi,
4566
4706
  mellowLrtPriceFeedAbi,
4567
4707
  pendleTWAPPTPriceFeedAbi,
4708
+ pythPriceFeedAbi,
4568
4709
  redstonePriceFeedAbi,
4569
4710
  wstEthPriceFeedAbi,
4570
4711
  yearnPriceFeedAbi,
@@ -718,6 +718,43 @@ class CreditAccountsService extends import_base.SDKConstruct {
718
718
  tx.value = ethAmount.toString(10);
719
719
  return { calls, tx, creditFacade: cmSuite.creditFacade };
720
720
  }
721
+ /**
722
+ * Returns borrow rate with 4 digits precision (10000 = 100%)
723
+ * @param ca
724
+ * @returns
725
+ */
726
+ getBorrowRate(ca) {
727
+ const { creditManager } = this.sdk.marketRegister.findCreditManager(
728
+ ca.creditManager
729
+ );
730
+ const { pool } = this.sdk.marketRegister.findByCreditManager(
731
+ ca.creditManager
732
+ );
733
+ const { feeInterest } = creditManager;
734
+ const { baseInterestRate } = pool.pool;
735
+ const baseRateWithFee = baseInterestRate * (BigInt(feeInterest) + import_constants.PERCENTAGE_FACTOR);
736
+ const totalDebt = ca.debt + ca.accruedInterest + ca.accruedFees;
737
+ const r = ca.debt * baseRateWithFee / (totalDebt * import_constants.RAY);
738
+ const caTokens = new import_utils.AddressMap(ca.tokens.map((t) => [t.token, t]));
739
+ let qr = 0n;
740
+ for (const t of creditManager.collateralTokens) {
741
+ const b = caTokens.get(t);
742
+ if (b) {
743
+ qr += b.quota * BigInt(pool.pqk.quotas.get(t)?.rate ?? 0);
744
+ }
745
+ }
746
+ qr = qr * (BigInt(feeInterest) + import_constants.PERCENTAGE_FACTOR) / import_constants.PERCENTAGE_FACTOR;
747
+ qr /= totalDebt;
748
+ return r + qr;
749
+ }
750
+ /**
751
+ * Returns optimal HF for partial liquidation with 4 digits precision (10000 = 100%)
752
+ * @param ca
753
+ */
754
+ getOptimalHFForPartialLiquidation(ca) {
755
+ const borrowRate = this.getBorrowRate(ca);
756
+ return borrowRate < 100n ? borrowRate : 100n;
757
+ }
721
758
  /**
722
759
  * Internal wrapper for CreditAccountCompressor.getCreditAccounts + price updates wrapped into multicall
723
760
  * @param args
@@ -64,11 +64,11 @@ const chains = {
64
64
  network: "Mainnet",
65
65
  defaultMarketConfigurators: {
66
66
  "0x354fe9f450F60b8547f88BE042E4A45b46128a06": "Chaos Labs",
67
- "0x4d427D418342d8CE89a7634c3a402851978B680A": "K3",
68
- "0xc168343c791d56dd1da4b4b8b0cc1c1ec1a16e6b": "cp0x",
69
- "0x3b56538833fc02f4f0e75609390f26ded0c32e42": "Re7"
67
+ "0x4d427D418342d8CE89a7634c3a402851978B680A": "K3"
68
+ },
69
+ testMarketConfigurators: {
70
+ "0xc168343c791d56dd1da4b4b8b0cc1c1ec1a16e6b": "cp0x"
70
71
  },
71
- testMarketConfigurators: {},
72
72
  isPublic: true,
73
73
  wellKnownToken: {
74
74
  address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
@@ -24,6 +24,7 @@ __export(AbstractPriceFeed_exports, {
24
24
  module.exports = __toCommonJS(AbstractPriceFeed_exports);
25
25
  var import_abi = require("../../abi/index.js");
26
26
  var import_base = require("../../base/index.js");
27
+ var import_isUpdatablePriceFeed = require("./isUpdatablePriceFeed.js");
27
28
  var import_PriceFeedRef = require("./PriceFeedRef.js");
28
29
  class PartialPriceFeedInitError extends Error {
29
30
  priceFeed;
@@ -128,7 +129,7 @@ class AbstractPriceFeedContract extends import_base.BaseContract {
128
129
  const underlying = this.underlyingPriceFeeds.flatMap(
129
130
  (f) => f.priceFeed.updatableDependencies()
130
131
  );
131
- return this.updatable ? [this, ...underlying] : underlying;
132
+ return (0, import_isUpdatablePriceFeed.isUpdatablePriceFeed)(this) ? [this, ...underlying] : underlying;
132
133
  }
133
134
  }
134
135
  // Annotate the CommonJS export names for ESM import in node:
@@ -40,7 +40,7 @@ var import_MellowLRTPriceFeed = require("./MellowLRTPriceFeed.js");
40
40
  var import_PendleTWAPPTPriceFeed = require("./PendleTWAPPTPriceFeed.js");
41
41
  var import_PythPriceFeed = require("./PythPriceFeed.js");
42
42
  var import_RedstonePriceFeed = require("./RedstonePriceFeed.js");
43
- var import_RedstoneUpdater = require("./RedstoneUpdater.js");
43
+ var import_updates = require("./updates/index.js");
44
44
  var import_WstETHPriceFeed = require("./WstETHPriceFeed.js");
45
45
  var import_YearnPriceFeed = require("./YearnPriceFeed.js");
46
46
  var import_ZeroPriceFeed = require("./ZeroPriceFeed.js");
@@ -49,11 +49,14 @@ class PriceFeedRegister extends import_base.SDKConstruct {
49
49
  #hooks = new import_internal.Hooks();
50
50
  #feeds = new import_utils.AddressMap(void 0, "priceFeeds");
51
51
  #latestUpdate;
52
- redstoneUpdater;
52
+ updaters;
53
53
  constructor(sdk, opts = {}) {
54
54
  super(sdk);
55
55
  this.logger = (0, import_utils.childLogger)("PriceFeedRegister", sdk.logger);
56
- this.redstoneUpdater = new import_RedstoneUpdater.RedstoneUpdater(sdk, opts?.redstone);
56
+ this.updaters = [
57
+ new import_updates.RedstoneUpdater(sdk, opts?.redstone),
58
+ new import_updates.PythUpdater(sdk, opts?.pyth)
59
+ ];
57
60
  }
58
61
  addHook = this.#hooks.addHook.bind(this.#hooks);
59
62
  removeHook = this.#hooks.removeHook.bind(this.#hooks);
@@ -66,31 +69,22 @@ class PriceFeedRegister extends import_base.SDKConstruct {
66
69
  async generatePriceFeedsUpdateTxs(priceFeeds, logContext = {}) {
67
70
  const updateables = priceFeeds ? priceFeeds.flatMap((pf) => pf.updatableDependencies()) : this.#feeds.values();
68
71
  const txs = [];
69
- const redstonePFs = [];
70
72
  const latestUpdate = {
71
- redstone: [],
73
+ updates: [],
72
74
  timestamp: Math.floor(Date.now() / 1e3)
73
75
  };
74
- for (const pf of updateables) {
75
- if ((0, import_RedstonePriceFeed.isRedstone)(pf)) {
76
- redstonePFs.push(pf);
77
- }
78
- }
76
+ const updates = (await Promise.all(
77
+ this.updaters.map((u) => u.getUpdateTxs(updateables, logContext))
78
+ )).flat();
79
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);
80
+ for (const tx of updates) {
81
+ const { data } = tx;
82
+ const { timestamp } = data;
83
+ if (timestamp > maxTimestamp) {
84
+ maxTimestamp = timestamp;
93
85
  }
86
+ txs.push(tx);
87
+ latestUpdate.updates.push(data);
94
88
  }
95
89
  const result = { txs, timestamp: maxTimestamp };
96
90
  const tsDelta = BigInt(maxTimestamp) - this.sdk.timestamp;
@@ -22,8 +22,9 @@ __export(PythPriceFeed_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(PythPriceFeed_exports);
24
24
  var import_viem = require("viem");
25
+ var import_oracles = require("../../abi/oracles.js");
25
26
  var import_AbstractPriceFeed = require("./AbstractPriceFeed.js");
26
- const abi = [];
27
+ const abi = import_oracles.pythPriceFeedAbi;
27
28
  class PythPriceFeed extends import_AbstractPriceFeed.AbstractPriceFeedContract {
28
29
  token;
29
30
  priceFeedId;
@@ -63,6 +64,13 @@ class PythPriceFeed extends import_AbstractPriceFeed.AbstractPriceFeedContract {
63
64
  this.pyth = decoded[2];
64
65
  }
65
66
  }
67
+ createPriceUpdateTx(data) {
68
+ return this.createRawTx({
69
+ functionName: "updatePrice",
70
+ args: [data],
71
+ description: `updating pyth price for ${this.priceFeedId} [${this.labelAddress(this.address)}]`
72
+ });
73
+ }
66
74
  }
67
75
  // Annotate the CommonJS export names for ESM import in node:
68
76
  0 && (module.exports = {
@@ -18,8 +18,7 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var RedstonePriceFeed_exports = {};
20
20
  __export(RedstonePriceFeed_exports, {
21
- RedstonePriceFeedContract: () => RedstonePriceFeedContract,
22
- isRedstone: () => isRedstone
21
+ RedstonePriceFeedContract: () => RedstonePriceFeedContract
23
22
  });
24
23
  module.exports = __toCommonJS(RedstonePriceFeed_exports);
25
24
  var import_viem = require("viem");
@@ -99,12 +98,15 @@ class RedstonePriceFeedContract extends import_AbstractPriceFeed.AbstractPriceFe
99
98
  lastPayloadTimestamp: this.lastPayloadTimestamp.toString()
100
99
  };
101
100
  }
102
- }
103
- function isRedstone(pf) {
104
- return pf.contractType === "PRICE_FEED::REDSTONE";
101
+ createPriceUpdateTx(data) {
102
+ return this.createRawTx({
103
+ functionName: "updatePrice",
104
+ args: [data],
105
+ description: `updating redstone price for ${this.dataId} [${this.labelAddress(this.address)}]`
106
+ });
107
+ }
105
108
  }
106
109
  // Annotate the CommonJS export names for ESM import in node:
107
110
  0 && (module.exports = {
108
- RedstonePriceFeedContract,
109
- isRedstone
111
+ RedstonePriceFeedContract
110
112
  });
@@ -25,6 +25,7 @@ __reExport(pricefeeds_exports, require("./CurveStablePriceFeed.js"), module.expo
25
25
  __reExport(pricefeeds_exports, require("./CurveUSDPriceFeed.js"), module.exports);
26
26
  __reExport(pricefeeds_exports, require("./Erc4626PriceFeed.js"), module.exports);
27
27
  __reExport(pricefeeds_exports, require("./ExternalPriceFeed.js"), module.exports);
28
+ __reExport(pricefeeds_exports, require("./isUpdatablePriceFeed.js"), module.exports);
28
29
  __reExport(pricefeeds_exports, require("./MellowLRTPriceFeed.js"), module.exports);
29
30
  __reExport(pricefeeds_exports, require("./PendleTWAPPTPriceFeed.js"), module.exports);
30
31
  __reExport(pricefeeds_exports, require("./PriceFeedRef.js"), module.exports);
@@ -47,6 +48,7 @@ __reExport(pricefeeds_exports, require("./ZeroPriceFeed.js"), module.exports);
47
48
  ...require("./CurveUSDPriceFeed.js"),
48
49
  ...require("./Erc4626PriceFeed.js"),
49
50
  ...require("./ExternalPriceFeed.js"),
51
+ ...require("./isUpdatablePriceFeed.js"),
50
52
  ...require("./MellowLRTPriceFeed.js"),
51
53
  ...require("./PendleTWAPPTPriceFeed.js"),
52
54
  ...require("./PriceFeedRef.js"),
@@ -0,0 +1,30 @@
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 isUpdatablePriceFeed_exports = {};
20
+ __export(isUpdatablePriceFeed_exports, {
21
+ isUpdatablePriceFeed: () => isUpdatablePriceFeed
22
+ });
23
+ module.exports = __toCommonJS(isUpdatablePriceFeed_exports);
24
+ function isUpdatablePriceFeed(pf) {
25
+ return pf.updatable;
26
+ }
27
+ // Annotate the CommonJS export names for ESM import in node:
28
+ 0 && (module.exports = {
29
+ isUpdatablePriceFeed
30
+ });
@@ -0,0 +1,52 @@
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 PriceUpdateTx_exports = {};
20
+ __export(PriceUpdateTx_exports, {
21
+ PriceUpdateTx: () => PriceUpdateTx
22
+ });
23
+ module.exports = __toCommonJS(PriceUpdateTx_exports);
24
+ const MAX_DATA_TIMESTAMP_DELAY_SECONDS = 10n * 60n;
25
+ const MAX_DATA_TIMESTAMP_AHEAD_SECONDS = 60n;
26
+ class PriceUpdateTx {
27
+ raw;
28
+ data;
29
+ constructor(raw, data) {
30
+ this.raw = raw;
31
+ this.data = data;
32
+ }
33
+ get pretty() {
34
+ const cached = this.data.cached ? " (cached)" : "";
35
+ return `${this.name} feed ${this.data.dataFeedId} at ${this.data.priceFeed} with timestamp ${this.data.timestamp}${cached}`;
36
+ }
37
+ validateTimestamp(blockTimestamp) {
38
+ const { timestamp: expectedPayloadTimestamp } = this.data;
39
+ if (blockTimestamp < expectedPayloadTimestamp) {
40
+ if (BigInt(expectedPayloadTimestamp) - blockTimestamp > MAX_DATA_TIMESTAMP_AHEAD_SECONDS) {
41
+ return "in future";
42
+ }
43
+ } else if (blockTimestamp - BigInt(expectedPayloadTimestamp) > MAX_DATA_TIMESTAMP_DELAY_SECONDS) {
44
+ return "too old";
45
+ }
46
+ return "valid";
47
+ }
48
+ }
49
+ // Annotate the CommonJS export names for ESM import in node:
50
+ 0 && (module.exports = {
51
+ PriceUpdateTx
52
+ });
@@ -16,12 +16,12 @@ var __copyProps = (to, from, except, desc) => {
16
16
  return to;
17
17
  };
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- var RedstoneCache_exports = {};
20
- __export(RedstoneCache_exports, {
21
- RedstoneCache: () => RedstoneCache
19
+ var PriceUpdatesCache_exports = {};
20
+ __export(PriceUpdatesCache_exports, {
21
+ PriceUpdatesCache: () => PriceUpdatesCache
22
22
  });
23
- module.exports = __toCommonJS(RedstoneCache_exports);
24
- class RedstoneCache {
23
+ module.exports = __toCommonJS(PriceUpdatesCache_exports);
24
+ class PriceUpdatesCache {
25
25
  #cache = /* @__PURE__ */ new Map();
26
26
  #ttlMs;
27
27
  #historical;
@@ -29,8 +29,8 @@ class RedstoneCache {
29
29
  this.#ttlMs = opts.ttl;
30
30
  this.#historical = opts.historical;
31
31
  }
32
- get(dataServiceId, dataFeedId, uniqueSignersCount) {
33
- const key = this.#cacheKey(dataServiceId, dataFeedId, uniqueSignersCount);
32
+ get(...path) {
33
+ const key = this.#cacheKey(...path);
34
34
  const data = this.#cache.get(key);
35
35
  if (!data) {
36
36
  return void 0;
@@ -41,8 +41,8 @@ class RedstoneCache {
41
41
  }
42
42
  return data;
43
43
  }
44
- set(dataServiceId, dataFeedId, uniqueSignersCount, value) {
45
- const key = this.#cacheKey(dataServiceId, dataFeedId, uniqueSignersCount);
44
+ set(value, ...path) {
45
+ const key = this.#cacheKey(...path);
46
46
  this.#cache.set(key, value);
47
47
  }
48
48
  #expired(value) {
@@ -51,11 +51,11 @@ class RedstoneCache {
51
51
  }
52
52
  return value.timestamp * 1e3 + this.#ttlMs < Date.now();
53
53
  }
54
- #cacheKey(dataServiceId, dataFeedId, uniqueSignersCount) {
55
- return `${dataServiceId}:${dataFeedId}:${uniqueSignersCount}`;
54
+ #cacheKey(...path) {
55
+ return path.join(":");
56
56
  }
57
57
  }
58
58
  // Annotate the CommonJS export names for ESM import in node:
59
59
  0 && (module.exports = {
60
- RedstoneCache
60
+ PriceUpdatesCache
61
61
  });