@gearbox-protocol/sdk 8.1.0-next.2 → 8.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/sdk/GearboxSDK.js +8 -20
- package/dist/cjs/sdk/abi/oracles.js +0 -141
- package/dist/cjs/sdk/chain/chains.js +3 -0
- package/dist/cjs/sdk/market/pricefeeds/AbstractPriceFeed.js +1 -2
- package/dist/cjs/sdk/market/pricefeeds/PriceFeedsRegister.js +23 -17
- package/dist/cjs/sdk/market/pricefeeds/PythPriceFeed.js +1 -9
- package/dist/cjs/sdk/market/pricefeeds/{updates/PriceUpdatesCache.js → RedstoneCache.js} +12 -12
- package/dist/cjs/sdk/market/pricefeeds/RedstonePriceFeed.js +7 -9
- package/dist/cjs/sdk/market/pricefeeds/{updates/RedstoneUpdater.js → RedstoneUpdater.js} +45 -21
- package/dist/cjs/sdk/market/pricefeeds/index.js +0 -2
- package/dist/cjs/sdk/sdk-gov-legacy/tokens/normal.js +5 -0
- package/dist/cjs/sdk/sdk-gov-legacy/tokens/token.js +5 -0
- package/dist/cjs/sdk/sdk-legacy/apy/index.js +1 -0
- package/dist/cjs/sdk/utils/retry.js +2 -4
- package/dist/esm/sdk/GearboxSDK.js +8 -20
- package/dist/esm/sdk/abi/oracles.js +0 -140
- package/dist/esm/sdk/chain/chains.js +3 -0
- package/dist/esm/sdk/market/pricefeeds/AbstractPriceFeed.js +1 -2
- package/dist/esm/sdk/market/pricefeeds/PriceFeedsRegister.js +24 -18
- package/dist/esm/sdk/market/pricefeeds/PythPriceFeed.js +1 -9
- package/dist/esm/sdk/market/pricefeeds/{updates/PriceUpdatesCache.js → RedstoneCache.js} +8 -8
- package/dist/esm/sdk/market/pricefeeds/RedstonePriceFeed.js +5 -8
- package/dist/esm/sdk/market/pricefeeds/{updates/RedstoneUpdater.js → RedstoneUpdater.js} +44 -21
- package/dist/esm/sdk/market/pricefeeds/index.js +0 -1
- package/dist/esm/sdk/sdk-gov-legacy/tokens/normal.js +5 -0
- package/dist/esm/sdk/sdk-gov-legacy/tokens/token.js +5 -0
- package/dist/esm/sdk/sdk-legacy/apy/index.js +1 -0
- package/dist/esm/sdk/utils/retry.js +2 -4
- package/dist/types/sdk/GearboxSDK.d.ts +1 -5
- package/dist/types/sdk/abi/oracles.d.ts +0 -212
- package/dist/types/sdk/chain/chains.d.ts +1 -1
- package/dist/types/sdk/market/pricefeeds/AbstractPriceFeed.d.ts +2 -2
- package/dist/types/sdk/market/pricefeeds/PriceFeedsRegister.d.ts +4 -4
- package/dist/types/sdk/market/pricefeeds/PythPriceFeed.d.ts +4 -218
- package/dist/types/sdk/market/pricefeeds/RedstoneCache.d.ts +25 -0
- package/dist/types/sdk/market/pricefeeds/RedstonePriceFeed.d.ts +4 -4
- package/dist/types/sdk/market/pricefeeds/{updates/RedstoneUpdater.d.ts → RedstoneUpdater.d.ts} +18 -11
- package/dist/types/sdk/market/pricefeeds/index.d.ts +0 -1
- package/dist/types/sdk/market/pricefeeds/types.d.ts +2 -5
- package/dist/types/sdk/sdk-gov-legacy/tokens/normal.d.ts +1 -1
- package/dist/types/sdk/sdk-legacy/apy/index.d.ts +1 -1
- package/dist/types/sdk/utils/retry.d.ts +0 -1
- package/package.json +1 -4
- package/dist/cjs/sdk/market/pricefeeds/isUpdatablePriceFeed.js +0 -30
- package/dist/cjs/sdk/market/pricefeeds/updates/PriceUpdateTx.js +0 -52
- package/dist/cjs/sdk/market/pricefeeds/updates/PythUpdater.js +0 -189
- package/dist/cjs/sdk/market/pricefeeds/updates/index.js +0 -31
- package/dist/cjs/sdk/market/pricefeeds/updates/types.js +0 -16
- package/dist/esm/sdk/market/pricefeeds/isUpdatablePriceFeed.js +0 -6
- package/dist/esm/sdk/market/pricefeeds/updates/PriceUpdateTx.js +0 -28
- package/dist/esm/sdk/market/pricefeeds/updates/PythUpdater.js +0 -169
- package/dist/esm/sdk/market/pricefeeds/updates/index.js +0 -6
- package/dist/esm/sdk/market/pricefeeds/updates/types.js +0 -0
- package/dist/types/sdk/market/pricefeeds/isUpdatablePriceFeed.d.ts +0 -2
- package/dist/types/sdk/market/pricefeeds/updates/PriceUpdateTx.d.ts +0 -10
- package/dist/types/sdk/market/pricefeeds/updates/PriceUpdatesCache.d.ts +0 -17
- package/dist/types/sdk/market/pricefeeds/updates/PythUpdater.d.ts +0 -40
- package/dist/types/sdk/market/pricefeeds/updates/RedstoneUpdater.test.d.ts +0 -1
- package/dist/types/sdk/market/pricefeeds/updates/index.d.ts +0 -3
- package/dist/types/sdk/market/pricefeeds/updates/types.d.ts +0 -21
|
@@ -79,7 +79,6 @@ class GearboxSDK {
|
|
|
79
79
|
plugins,
|
|
80
80
|
blockNumber,
|
|
81
81
|
redstone,
|
|
82
|
-
pyth,
|
|
83
82
|
ignoreUpdateablePrices,
|
|
84
83
|
marketConfigurators: mcs,
|
|
85
84
|
strictContractTypes
|
|
@@ -113,8 +112,7 @@ class GearboxSDK {
|
|
|
113
112
|
blockNumber,
|
|
114
113
|
ignoreUpdateablePrices,
|
|
115
114
|
marketConfigurators,
|
|
116
|
-
redstone
|
|
117
|
-
pyth
|
|
115
|
+
redstone
|
|
118
116
|
});
|
|
119
117
|
}
|
|
120
118
|
static hydrate(options, state) {
|
|
@@ -146,8 +144,7 @@ class GearboxSDK {
|
|
|
146
144
|
blockNumber,
|
|
147
145
|
ignoreUpdateablePrices,
|
|
148
146
|
marketConfigurators,
|
|
149
|
-
redstone
|
|
150
|
-
pyth
|
|
147
|
+
redstone
|
|
151
148
|
} = opts;
|
|
152
149
|
const re = this.#attachConfig ? "re" : "";
|
|
153
150
|
this.logger?.info(
|
|
@@ -162,12 +159,7 @@ class GearboxSDK {
|
|
|
162
159
|
);
|
|
163
160
|
if (!!blockNumber && !opts.redstone?.historicTimestamp) {
|
|
164
161
|
this.logger?.warn(
|
|
165
|
-
`${re}attaching to fixed block number, but
|
|
166
|
-
);
|
|
167
|
-
}
|
|
168
|
-
if (!!blockNumber && !opts.pyth?.historicTimestamp) {
|
|
169
|
-
this.logger?.warn(
|
|
170
|
-
`${re}attaching to fixed block number, but pyth historicTimestamp is not set. price updates might fail`
|
|
162
|
+
`${re}attaching to fixed block number, but redstoneHistoricTimestamp is not set. price updates might fail`
|
|
171
163
|
);
|
|
172
164
|
}
|
|
173
165
|
this.#attachConfig = opts;
|
|
@@ -179,7 +171,7 @@ class GearboxSDK {
|
|
|
179
171
|
);
|
|
180
172
|
this.#currentBlock = block.number;
|
|
181
173
|
this.#timestamp = block.timestamp;
|
|
182
|
-
this.#priceFeeds = new PriceFeedRegister(this, { redstone
|
|
174
|
+
this.#priceFeeds = new PriceFeedRegister(this, { redstone });
|
|
183
175
|
this.logger?.debug(
|
|
184
176
|
`${re}attach block number ${this.currentBlock} timestamp ${this.timestamp}`
|
|
185
177
|
);
|
|
@@ -230,10 +222,7 @@ class GearboxSDK {
|
|
|
230
222
|
);
|
|
231
223
|
this.#currentBlock = state.currentBlock;
|
|
232
224
|
this.#timestamp = state.timestamp;
|
|
233
|
-
this.#priceFeeds = new PriceFeedRegister(this, {
|
|
234
|
-
redstone: opts.redstone,
|
|
235
|
-
pyth: opts.pyth
|
|
236
|
-
});
|
|
225
|
+
this.#priceFeeds = new PriceFeedRegister(this, { redstone: opts.redstone });
|
|
237
226
|
this.#addressProvider = hydrateAddressProvider(this, state.addressProvider);
|
|
238
227
|
this.logger?.debug(
|
|
239
228
|
`address provider version: ${this.#addressProvider.version}`
|
|
@@ -285,8 +274,7 @@ class GearboxSDK {
|
|
|
285
274
|
}
|
|
286
275
|
const opts = {
|
|
287
276
|
ignoreUpdateablePrices: this.#attachConfig.ignoreUpdateablePrices,
|
|
288
|
-
redstone: this.#attachConfig.redstone
|
|
289
|
-
pyth: this.#attachConfig.pyth
|
|
277
|
+
redstone: this.#attachConfig.redstone
|
|
290
278
|
};
|
|
291
279
|
this.#hydrate(opts, state);
|
|
292
280
|
await this.#hooks.triggerHooks("rehydrate", {
|
|
@@ -385,9 +373,9 @@ class GearboxSDK {
|
|
|
385
373
|
*/
|
|
386
374
|
async syncState(opts) {
|
|
387
375
|
let { blockNumber, timestamp, skipPriceUpdate } = opts ?? {};
|
|
388
|
-
if (this.#attachConfig?.redstone?.historicTimestamp
|
|
376
|
+
if (this.#attachConfig?.redstone?.historicTimestamp) {
|
|
389
377
|
throw new Error(
|
|
390
|
-
"syncState is not supported with
|
|
378
|
+
"syncState is not supported with redstoneHistoricTimestamp"
|
|
391
379
|
);
|
|
392
380
|
}
|
|
393
381
|
if (!blockNumber || !timestamp) {
|
|
@@ -4497,145 +4497,6 @@ const pendleTWAPPTPriceFeedAbi = [
|
|
|
4497
4497
|
inputs: []
|
|
4498
4498
|
}
|
|
4499
4499
|
];
|
|
4500
|
-
const pythPriceFeedAbi = [
|
|
4501
|
-
{
|
|
4502
|
-
type: "constructor",
|
|
4503
|
-
inputs: [
|
|
4504
|
-
{ name: "_token", type: "address", internalType: "address" },
|
|
4505
|
-
{ name: "_priceFeedId", type: "bytes32", internalType: "bytes32" },
|
|
4506
|
-
{ name: "_pyth", type: "address", internalType: "address" },
|
|
4507
|
-
{
|
|
4508
|
-
name: "_maxConfToPriceRatio",
|
|
4509
|
-
type: "uint256",
|
|
4510
|
-
internalType: "uint256"
|
|
4511
|
-
},
|
|
4512
|
-
{ name: "descriptionTicker", type: "string", internalType: "string" }
|
|
4513
|
-
],
|
|
4514
|
-
stateMutability: "nonpayable"
|
|
4515
|
-
},
|
|
4516
|
-
{ type: "receive", stateMutability: "payable" },
|
|
4517
|
-
{
|
|
4518
|
-
type: "function",
|
|
4519
|
-
name: "contractType",
|
|
4520
|
-
inputs: [],
|
|
4521
|
-
outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }],
|
|
4522
|
-
stateMutability: "view"
|
|
4523
|
-
},
|
|
4524
|
-
{
|
|
4525
|
-
type: "function",
|
|
4526
|
-
name: "decimals",
|
|
4527
|
-
inputs: [],
|
|
4528
|
-
outputs: [{ name: "", type: "uint8", internalType: "uint8" }],
|
|
4529
|
-
stateMutability: "view"
|
|
4530
|
-
},
|
|
4531
|
-
{
|
|
4532
|
-
type: "function",
|
|
4533
|
-
name: "description",
|
|
4534
|
-
inputs: [],
|
|
4535
|
-
outputs: [{ name: "", type: "string", internalType: "string" }],
|
|
4536
|
-
stateMutability: "view"
|
|
4537
|
-
},
|
|
4538
|
-
{
|
|
4539
|
-
type: "function",
|
|
4540
|
-
name: "latestRoundData",
|
|
4541
|
-
inputs: [],
|
|
4542
|
-
outputs: [
|
|
4543
|
-
{ name: "", type: "uint80", internalType: "uint80" },
|
|
4544
|
-
{ name: "", type: "int256", internalType: "int256" },
|
|
4545
|
-
{ name: "", type: "uint256", internalType: "uint256" },
|
|
4546
|
-
{ name: "", type: "uint256", internalType: "uint256" },
|
|
4547
|
-
{ name: "", type: "uint80", internalType: "uint80" }
|
|
4548
|
-
],
|
|
4549
|
-
stateMutability: "view"
|
|
4550
|
-
},
|
|
4551
|
-
{
|
|
4552
|
-
type: "function",
|
|
4553
|
-
name: "maxConfToPriceRatio",
|
|
4554
|
-
inputs: [],
|
|
4555
|
-
outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
|
|
4556
|
-
stateMutability: "view"
|
|
4557
|
-
},
|
|
4558
|
-
{
|
|
4559
|
-
type: "function",
|
|
4560
|
-
name: "priceFeedId",
|
|
4561
|
-
inputs: [],
|
|
4562
|
-
outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }],
|
|
4563
|
-
stateMutability: "view"
|
|
4564
|
-
},
|
|
4565
|
-
{
|
|
4566
|
-
type: "function",
|
|
4567
|
-
name: "pyth",
|
|
4568
|
-
inputs: [],
|
|
4569
|
-
outputs: [{ name: "", type: "address", internalType: "address" }],
|
|
4570
|
-
stateMutability: "view"
|
|
4571
|
-
},
|
|
4572
|
-
{
|
|
4573
|
-
type: "function",
|
|
4574
|
-
name: "serialize",
|
|
4575
|
-
inputs: [],
|
|
4576
|
-
outputs: [{ name: "", type: "bytes", internalType: "bytes" }],
|
|
4577
|
-
stateMutability: "view"
|
|
4578
|
-
},
|
|
4579
|
-
{
|
|
4580
|
-
type: "function",
|
|
4581
|
-
name: "skipPriceCheck",
|
|
4582
|
-
inputs: [],
|
|
4583
|
-
outputs: [{ name: "", type: "bool", internalType: "bool" }],
|
|
4584
|
-
stateMutability: "view"
|
|
4585
|
-
},
|
|
4586
|
-
{
|
|
4587
|
-
type: "function",
|
|
4588
|
-
name: "token",
|
|
4589
|
-
inputs: [],
|
|
4590
|
-
outputs: [{ name: "", type: "address", internalType: "address" }],
|
|
4591
|
-
stateMutability: "view"
|
|
4592
|
-
},
|
|
4593
|
-
{
|
|
4594
|
-
type: "function",
|
|
4595
|
-
name: "updatable",
|
|
4596
|
-
inputs: [],
|
|
4597
|
-
outputs: [{ name: "", type: "bool", internalType: "bool" }],
|
|
4598
|
-
stateMutability: "view"
|
|
4599
|
-
},
|
|
4600
|
-
{
|
|
4601
|
-
type: "function",
|
|
4602
|
-
name: "updatePrice",
|
|
4603
|
-
inputs: [{ name: "data", type: "bytes", internalType: "bytes" }],
|
|
4604
|
-
outputs: [],
|
|
4605
|
-
stateMutability: "nonpayable"
|
|
4606
|
-
},
|
|
4607
|
-
{
|
|
4608
|
-
type: "function",
|
|
4609
|
-
name: "version",
|
|
4610
|
-
inputs: [],
|
|
4611
|
-
outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
|
|
4612
|
-
stateMutability: "view"
|
|
4613
|
-
},
|
|
4614
|
-
{
|
|
4615
|
-
type: "event",
|
|
4616
|
-
name: "UpdatePrice",
|
|
4617
|
-
inputs: [
|
|
4618
|
-
{
|
|
4619
|
-
name: "price",
|
|
4620
|
-
type: "uint256",
|
|
4621
|
-
indexed: false,
|
|
4622
|
-
internalType: "uint256"
|
|
4623
|
-
}
|
|
4624
|
-
],
|
|
4625
|
-
anonymous: false
|
|
4626
|
-
},
|
|
4627
|
-
{ type: "error", name: "ConfToPriceRatioTooHighException", inputs: [] },
|
|
4628
|
-
{
|
|
4629
|
-
type: "error",
|
|
4630
|
-
name: "IncorrectExpectedPublishTimestampException",
|
|
4631
|
-
inputs: []
|
|
4632
|
-
},
|
|
4633
|
-
{ type: "error", name: "IncorrectParameterException", inputs: [] },
|
|
4634
|
-
{ type: "error", name: "IncorrectPriceDecimalsException", inputs: [] },
|
|
4635
|
-
{ type: "error", name: "IncorrectPriceException", inputs: [] },
|
|
4636
|
-
{ type: "error", name: "PriceTimestampTooFarAheadException", inputs: [] },
|
|
4637
|
-
{ type: "error", name: "PriceTimestampTooFarBehindException", inputs: [] }
|
|
4638
|
-
];
|
|
4639
4500
|
export {
|
|
4640
4501
|
boundedPriceFeedAbi,
|
|
4641
4502
|
bptStablePriceFeedAbi,
|
|
@@ -4657,7 +4518,6 @@ export {
|
|
|
4657
4518
|
iyVaultAbi,
|
|
4658
4519
|
mellowLrtPriceFeedAbi,
|
|
4659
4520
|
pendleTWAPPTPriceFeedAbi,
|
|
4660
|
-
pythPriceFeedAbi,
|
|
4661
4521
|
redstonePriceFeedAbi,
|
|
4662
4522
|
wstEthPriceFeedAbi,
|
|
4663
4523
|
yearnPriceFeedAbi,
|
|
@@ -50,6 +50,9 @@ const chains = {
|
|
|
50
50
|
"0x354fe9f450F60b8547f88BE042E4A45b46128a06": "Chaos Labs",
|
|
51
51
|
"0x4d427D418342d8CE89a7634c3a402851978B680A": "K3"
|
|
52
52
|
},
|
|
53
|
+
testMarketConfigurators: {
|
|
54
|
+
"0xc168343c791d56dd1da4b4b8b0cc1c1ec1a16e6b": "cp0x"
|
|
55
|
+
},
|
|
53
56
|
isPublic: true,
|
|
54
57
|
wellKnownToken: {
|
|
55
58
|
address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { ilpPriceFeedAbi } from "../../abi/index.js";
|
|
2
2
|
import { BaseContract } from "../../base/index.js";
|
|
3
|
-
import { isUpdatablePriceFeed } from "./isUpdatablePriceFeed.js";
|
|
4
3
|
import { PriceFeedRef } from "./PriceFeedRef.js";
|
|
5
4
|
class PartialPriceFeedInitError extends Error {
|
|
6
5
|
priceFeed;
|
|
@@ -105,7 +104,7 @@ class AbstractPriceFeedContract extends BaseContract {
|
|
|
105
104
|
const underlying = this.underlyingPriceFeeds.flatMap(
|
|
106
105
|
(f) => f.priceFeed.updatableDependencies()
|
|
107
106
|
);
|
|
108
|
-
return
|
|
107
|
+
return this.updatable ? [this, ...underlying] : underlying;
|
|
109
108
|
}
|
|
110
109
|
}
|
|
111
110
|
export {
|
|
@@ -22,8 +22,8 @@ import { ExternalPriceFeedContract } from "./ExternalPriceFeed.js";
|
|
|
22
22
|
import { MellowLRTPriceFeedContract } from "./MellowLRTPriceFeed.js";
|
|
23
23
|
import { PendleTWAPPTPriceFeed } from "./PendleTWAPPTPriceFeed.js";
|
|
24
24
|
import { PythPriceFeed } from "./PythPriceFeed.js";
|
|
25
|
-
import { RedstonePriceFeedContract } from "./RedstonePriceFeed.js";
|
|
26
|
-
import {
|
|
25
|
+
import { isRedstone, RedstonePriceFeedContract } from "./RedstonePriceFeed.js";
|
|
26
|
+
import { RedstoneUpdater } from "./RedstoneUpdater.js";
|
|
27
27
|
import { WstETHPriceFeedContract } from "./WstETHPriceFeed.js";
|
|
28
28
|
import { YearnPriceFeedContract } from "./YearnPriceFeed.js";
|
|
29
29
|
import { ZeroPriceFeedContract } from "./ZeroPriceFeed.js";
|
|
@@ -32,14 +32,11 @@ class PriceFeedRegister extends SDKConstruct {
|
|
|
32
32
|
#hooks = new Hooks();
|
|
33
33
|
#feeds = new AddressMap(void 0, "priceFeeds");
|
|
34
34
|
#latestUpdate;
|
|
35
|
-
|
|
35
|
+
redstoneUpdater;
|
|
36
36
|
constructor(sdk, opts = {}) {
|
|
37
37
|
super(sdk);
|
|
38
38
|
this.logger = childLogger("PriceFeedRegister", sdk.logger);
|
|
39
|
-
this.
|
|
40
|
-
new RedstoneUpdater(sdk, opts?.redstone),
|
|
41
|
-
new PythUpdater(sdk, opts?.pyth)
|
|
42
|
-
];
|
|
39
|
+
this.redstoneUpdater = new RedstoneUpdater(sdk, opts?.redstone);
|
|
43
40
|
}
|
|
44
41
|
addHook = this.#hooks.addHook.bind(this.#hooks);
|
|
45
42
|
removeHook = this.#hooks.removeHook.bind(this.#hooks);
|
|
@@ -52,22 +49,31 @@ class PriceFeedRegister extends SDKConstruct {
|
|
|
52
49
|
async generatePriceFeedsUpdateTxs(priceFeeds, logContext = {}) {
|
|
53
50
|
const updateables = priceFeeds ? priceFeeds.flatMap((pf) => pf.updatableDependencies()) : this.#feeds.values();
|
|
54
51
|
const txs = [];
|
|
52
|
+
const redstonePFs = [];
|
|
55
53
|
const latestUpdate = {
|
|
56
|
-
|
|
54
|
+
redstone: [],
|
|
57
55
|
timestamp: Math.floor(Date.now() / 1e3)
|
|
58
56
|
};
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
57
|
+
for (const pf of updateables) {
|
|
58
|
+
if (isRedstone(pf)) {
|
|
59
|
+
redstonePFs.push(pf);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
62
|
let maxTimestamp = 0;
|
|
63
|
-
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
63
|
+
if (redstonePFs.length > 0) {
|
|
64
|
+
const redstoneUpdates = await this.redstoneUpdater.getUpdateTxs(
|
|
65
|
+
redstonePFs,
|
|
66
|
+
logContext
|
|
67
|
+
);
|
|
68
|
+
for (const tx of redstoneUpdates) {
|
|
69
|
+
const { data } = tx;
|
|
70
|
+
const { timestamp } = data;
|
|
71
|
+
if (timestamp > maxTimestamp) {
|
|
72
|
+
maxTimestamp = timestamp;
|
|
73
|
+
}
|
|
74
|
+
txs.push(tx);
|
|
75
|
+
latestUpdate.redstone.push(data);
|
|
68
76
|
}
|
|
69
|
-
txs.push(tx);
|
|
70
|
-
latestUpdate.updates.push(data);
|
|
71
77
|
}
|
|
72
78
|
const result = { txs, timestamp: maxTimestamp };
|
|
73
79
|
const tsDelta = BigInt(maxTimestamp) - this.sdk.timestamp;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { decodeAbiParameters } from "viem";
|
|
2
|
-
import { pythPriceFeedAbi } from "../../abi/oracles.js";
|
|
3
2
|
import { AbstractPriceFeedContract } from "./AbstractPriceFeed.js";
|
|
4
|
-
const abi =
|
|
3
|
+
const abi = [];
|
|
5
4
|
class PythPriceFeed extends AbstractPriceFeedContract {
|
|
6
5
|
token;
|
|
7
6
|
priceFeedId;
|
|
@@ -41,13 +40,6 @@ class PythPriceFeed extends AbstractPriceFeedContract {
|
|
|
41
40
|
this.pyth = decoded[2];
|
|
42
41
|
}
|
|
43
42
|
}
|
|
44
|
-
createPriceUpdateTx(data) {
|
|
45
|
-
return this.createRawTx({
|
|
46
|
-
functionName: "updatePrice",
|
|
47
|
-
args: [data],
|
|
48
|
-
description: `updating pyth price for ${this.priceFeedId} [${this.labelAddress(this.address)}]`
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
43
|
}
|
|
52
44
|
export {
|
|
53
45
|
PythPriceFeed
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class
|
|
1
|
+
class RedstoneCache {
|
|
2
2
|
#cache = /* @__PURE__ */ new Map();
|
|
3
3
|
#ttlMs;
|
|
4
4
|
#historical;
|
|
@@ -6,8 +6,8 @@ class PriceUpdatesCache {
|
|
|
6
6
|
this.#ttlMs = opts.ttl;
|
|
7
7
|
this.#historical = opts.historical;
|
|
8
8
|
}
|
|
9
|
-
get(
|
|
10
|
-
const key = this.#cacheKey(
|
|
9
|
+
get(dataServiceId, dataFeedId, uniqueSignersCount) {
|
|
10
|
+
const key = this.#cacheKey(dataServiceId, dataFeedId, uniqueSignersCount);
|
|
11
11
|
const data = this.#cache.get(key);
|
|
12
12
|
if (!data) {
|
|
13
13
|
return void 0;
|
|
@@ -18,8 +18,8 @@ class PriceUpdatesCache {
|
|
|
18
18
|
}
|
|
19
19
|
return data;
|
|
20
20
|
}
|
|
21
|
-
set(
|
|
22
|
-
const key = this.#cacheKey(
|
|
21
|
+
set(dataServiceId, dataFeedId, uniqueSignersCount, value) {
|
|
22
|
+
const key = this.#cacheKey(dataServiceId, dataFeedId, uniqueSignersCount);
|
|
23
23
|
this.#cache.set(key, value);
|
|
24
24
|
}
|
|
25
25
|
#expired(value) {
|
|
@@ -28,10 +28,10 @@ class PriceUpdatesCache {
|
|
|
28
28
|
}
|
|
29
29
|
return value.timestamp * 1e3 + this.#ttlMs < Date.now();
|
|
30
30
|
}
|
|
31
|
-
#cacheKey(
|
|
32
|
-
return
|
|
31
|
+
#cacheKey(dataServiceId, dataFeedId, uniqueSignersCount) {
|
|
32
|
+
return `${dataServiceId}:${dataFeedId}:${uniqueSignersCount}`;
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
export {
|
|
36
|
-
|
|
36
|
+
RedstoneCache
|
|
37
37
|
};
|
|
@@ -75,14 +75,11 @@ class RedstonePriceFeedContract extends AbstractPriceFeedContract {
|
|
|
75
75
|
lastPayloadTimestamp: this.lastPayloadTimestamp.toString()
|
|
76
76
|
};
|
|
77
77
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
args: [data],
|
|
82
|
-
description: `updating redstone price for ${this.dataId} [${this.labelAddress(this.address)}]`
|
|
83
|
-
});
|
|
84
|
-
}
|
|
78
|
+
}
|
|
79
|
+
function isRedstone(pf) {
|
|
80
|
+
return pf.contractType === "PRICE_FEED::REDSTONE";
|
|
85
81
|
}
|
|
86
82
|
export {
|
|
87
|
-
RedstonePriceFeedContract
|
|
83
|
+
RedstonePriceFeedContract,
|
|
84
|
+
isRedstone
|
|
88
85
|
};
|
|
@@ -1,12 +1,33 @@
|
|
|
1
1
|
import { DataServiceWrapper } from "@redstone-finance/evm-connector";
|
|
2
2
|
import { RedstonePayload } from "@redstone-finance/protocol";
|
|
3
3
|
import { encodeAbiParameters, toBytes } from "viem";
|
|
4
|
-
import { SDKConstruct } from "
|
|
5
|
-
import { AddressMap, childLogger, retry } from "
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
import { SDKConstruct } from "../../base/index.js";
|
|
5
|
+
import { AddressMap, childLogger, retry } from "../../utils/index.js";
|
|
6
|
+
import { RedstoneCache } from "./RedstoneCache.js";
|
|
7
|
+
const MAX_DATA_TIMESTAMP_DELAY_SECONDS = 10n * 60n;
|
|
8
|
+
const MAX_DATA_TIMESTAMP_AHEAD_SECONDS = 60n;
|
|
9
|
+
class RedstoneUpdateTx {
|
|
10
|
+
raw;
|
|
11
|
+
data;
|
|
12
|
+
constructor(raw, data) {
|
|
13
|
+
this.raw = raw;
|
|
14
|
+
this.data = data;
|
|
15
|
+
}
|
|
16
|
+
get pretty() {
|
|
17
|
+
const cached = this.data.cached ? " (cached)" : "";
|
|
18
|
+
return `redstone feed ${this.data.dataFeedId} at ${this.data.priceFeed} with timestamp ${this.data.timestamp}${cached}`;
|
|
19
|
+
}
|
|
20
|
+
validateTimestamp(blockTimestamp) {
|
|
21
|
+
const { timestamp: expectedPayloadTimestamp } = this.data;
|
|
22
|
+
if (blockTimestamp < expectedPayloadTimestamp) {
|
|
23
|
+
if (BigInt(expectedPayloadTimestamp) - blockTimestamp > MAX_DATA_TIMESTAMP_AHEAD_SECONDS) {
|
|
24
|
+
return "in future";
|
|
25
|
+
}
|
|
26
|
+
} else if (blockTimestamp - BigInt(expectedPayloadTimestamp) > MAX_DATA_TIMESTAMP_DELAY_SECONDS) {
|
|
27
|
+
return "too old";
|
|
28
|
+
}
|
|
29
|
+
return "valid";
|
|
30
|
+
}
|
|
10
31
|
}
|
|
11
32
|
class RedstoneUpdater extends SDKConstruct {
|
|
12
33
|
#logger;
|
|
@@ -26,7 +47,7 @@ class RedstoneUpdater extends SDKConstruct {
|
|
|
26
47
|
ts = ts === true ? Number(this.sdk.timestamp) * 1e3 : ts;
|
|
27
48
|
this.#historicalTimestampMs = 6e4 * Math.floor(ts / 6e4);
|
|
28
49
|
}
|
|
29
|
-
this.#cache = new
|
|
50
|
+
this.#cache = new RedstoneCache({
|
|
30
51
|
// currently staleness period is 240 seconds on all networks, add some buffer
|
|
31
52
|
// this period of 4 minutes is selected based on time that is required for user to sign transaction with wallet
|
|
32
53
|
// so it's unlikely to decrease
|
|
@@ -42,9 +63,6 @@ class RedstoneUpdater extends SDKConstruct {
|
|
|
42
63
|
const groupedFeeds = {};
|
|
43
64
|
const priceFeeds = /* @__PURE__ */ new Map();
|
|
44
65
|
for (const feed of feeds) {
|
|
45
|
-
if (!isRedstone(feed)) {
|
|
46
|
-
continue;
|
|
47
|
-
}
|
|
48
66
|
const key = `${feed.dataServiceId}:${feed.signersThreshold}`;
|
|
49
67
|
if (!groupedFeeds[key]) {
|
|
50
68
|
groupedFeeds[key] = /* @__PURE__ */ new Set();
|
|
@@ -70,13 +88,20 @@ class RedstoneUpdater extends SDKConstruct {
|
|
|
70
88
|
}
|
|
71
89
|
for (const priceFeed of pfsForDataId.values()) {
|
|
72
90
|
results.push(
|
|
73
|
-
new RedstoneUpdateTx(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
91
|
+
new RedstoneUpdateTx(
|
|
92
|
+
priceFeed.createRawTx({
|
|
93
|
+
functionName: "updatePrice",
|
|
94
|
+
args: [data],
|
|
95
|
+
description: `updating price for ${dataFeedId} [${this.labelAddress(priceFeed.address)}]`
|
|
96
|
+
}),
|
|
97
|
+
{
|
|
98
|
+
dataFeedId,
|
|
99
|
+
dataServiceId,
|
|
100
|
+
priceFeed: priceFeed.address,
|
|
101
|
+
timestamp,
|
|
102
|
+
cached
|
|
103
|
+
}
|
|
104
|
+
)
|
|
80
105
|
);
|
|
81
106
|
}
|
|
82
107
|
}
|
|
@@ -119,7 +144,7 @@ class RedstoneUpdater extends SDKConstruct {
|
|
|
119
144
|
uniqueSignersCount
|
|
120
145
|
);
|
|
121
146
|
for (const resp of fromRedstone) {
|
|
122
|
-
this.#cache.set(
|
|
147
|
+
this.#cache.set(dataServiceId, resp.dataFeedId, uniqueSignersCount, resp);
|
|
123
148
|
}
|
|
124
149
|
this.#logger?.debug(
|
|
125
150
|
`got ${fromRedstone.length} new redstone updates and ${fromCache.length} from cache`
|
|
@@ -220,9 +245,7 @@ function getCalldataWithTimestamp(dataFeedId, packages, unsignedMetadata) {
|
|
|
220
245
|
cached: false
|
|
221
246
|
};
|
|
222
247
|
}
|
|
223
|
-
function isRedstone(pf) {
|
|
224
|
-
return pf.contractType === "PRICE_FEED::REDSTONE";
|
|
225
|
-
}
|
|
226
248
|
export {
|
|
249
|
+
RedstoneUpdateTx,
|
|
227
250
|
RedstoneUpdater
|
|
228
251
|
};
|
|
@@ -8,7 +8,6 @@ export * from "./CurveStablePriceFeed.js";
|
|
|
8
8
|
export * from "./CurveUSDPriceFeed.js";
|
|
9
9
|
export * from "./Erc4626PriceFeed.js";
|
|
10
10
|
export * from "./ExternalPriceFeed.js";
|
|
11
|
-
export * from "./isUpdatablePriceFeed.js";
|
|
12
11
|
export * from "./MellowLRTPriceFeed.js";
|
|
13
12
|
export * from "./PendleTWAPPTPriceFeed.js";
|
|
14
13
|
export * from "./PriceFeedRef.js";
|
|
@@ -461,6 +461,11 @@ const normalTokens = {
|
|
|
461
461
|
name: "USDX",
|
|
462
462
|
symbol: "USDX",
|
|
463
463
|
type: { AllNetworks: TokenType.NORMAL_TOKEN }
|
|
464
|
+
},
|
|
465
|
+
cp0xLRT: {
|
|
466
|
+
name: "cp0xLRT",
|
|
467
|
+
symbol: "cp0xLRT",
|
|
468
|
+
type: { AllNetworks: TokenType.NORMAL_TOKEN }
|
|
464
469
|
}
|
|
465
470
|
};
|
|
466
471
|
const isNormalToken = (t) => typeof t === "string" && !!normalTokens[t];
|
|
@@ -330,6 +330,7 @@ const tokenDataByNetwork = {
|
|
|
330
330
|
pzETH: "0x8c9532a60E0E7C6BbD2B2c1303F63aCE1c3E9811",
|
|
331
331
|
DVstETH: "0x5E362eb2c0706Bd1d134689eC75176018385430B",
|
|
332
332
|
waEthLidowstETH: "0x775F661b0bD1739349b9A2A3EF60be277c5d2D29",
|
|
333
|
+
cp0xLRT: "0xB908c9FE885369643adB5FBA4407d52bD726c72d",
|
|
333
334
|
BTCB: NOT_DEPLOYED,
|
|
334
335
|
WBNB: NOT_DEPLOYED,
|
|
335
336
|
dUSDTv310: NOT_DEPLOYED,
|
|
@@ -647,6 +648,7 @@ const tokenDataByNetwork = {
|
|
|
647
648
|
pzETH: NOT_DEPLOYED,
|
|
648
649
|
DVstETH: NOT_DEPLOYED,
|
|
649
650
|
waEthLidowstETH: NOT_DEPLOYED,
|
|
651
|
+
cp0xLRT: NOT_DEPLOYED,
|
|
650
652
|
BTCB: NOT_DEPLOYED,
|
|
651
653
|
WBNB: NOT_DEPLOYED,
|
|
652
654
|
dUSDTv310: NOT_DEPLOYED,
|
|
@@ -964,6 +966,7 @@ const tokenDataByNetwork = {
|
|
|
964
966
|
pzETH: NOT_DEPLOYED,
|
|
965
967
|
DVstETH: NOT_DEPLOYED,
|
|
966
968
|
waEthLidowstETH: NOT_DEPLOYED,
|
|
969
|
+
cp0xLRT: NOT_DEPLOYED,
|
|
967
970
|
BTCB: NOT_DEPLOYED,
|
|
968
971
|
WBNB: NOT_DEPLOYED,
|
|
969
972
|
dUSDTv310: NOT_DEPLOYED,
|
|
@@ -1280,6 +1283,7 @@ const tokenDataByNetwork = {
|
|
|
1280
1283
|
pzETH: NOT_DEPLOYED,
|
|
1281
1284
|
DVstETH: NOT_DEPLOYED,
|
|
1282
1285
|
waEthLidowstETH: NOT_DEPLOYED,
|
|
1286
|
+
cp0xLRT: NOT_DEPLOYED,
|
|
1283
1287
|
BTCB: NOT_DEPLOYED,
|
|
1284
1288
|
WBNB: NOT_DEPLOYED,
|
|
1285
1289
|
dUSDTv310: NOT_DEPLOYED,
|
|
@@ -1596,6 +1600,7 @@ const tokenDataByNetwork = {
|
|
|
1596
1600
|
pzETH: NOT_DEPLOYED,
|
|
1597
1601
|
DVstETH: NOT_DEPLOYED,
|
|
1598
1602
|
waEthLidowstETH: NOT_DEPLOYED,
|
|
1603
|
+
cp0xLRT: NOT_DEPLOYED,
|
|
1599
1604
|
BTCB: NOT_DEPLOYED,
|
|
1600
1605
|
WBNB: NOT_DEPLOYED,
|
|
1601
1606
|
dUSDTv310: NOT_DEPLOYED,
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
async function retry(fn, options = {}) {
|
|
2
|
-
const { attempts = 3, interval = 200
|
|
3
|
-
let wait = interval;
|
|
2
|
+
const { attempts = 3, interval = 200 } = options;
|
|
4
3
|
let cause;
|
|
5
4
|
for (let i = 0; i < attempts; i++) {
|
|
6
5
|
try {
|
|
@@ -9,9 +8,8 @@ async function retry(fn, options = {}) {
|
|
|
9
8
|
} catch (e) {
|
|
10
9
|
cause = e;
|
|
11
10
|
await new Promise((resolve) => {
|
|
12
|
-
setTimeout(resolve,
|
|
11
|
+
setTimeout(resolve, interval);
|
|
13
12
|
});
|
|
14
|
-
wait = wait * exponent;
|
|
15
13
|
}
|
|
16
14
|
}
|
|
17
15
|
throw new Error(`all attempts failed: ${cause}`);
|
|
@@ -8,7 +8,7 @@ import type { IAddressProviderContract } from "./core/index.js";
|
|
|
8
8
|
import { BotListContract, GearStakingContract } from "./core/index.js";
|
|
9
9
|
import { MarketRegister } from "./market/MarketRegister.js";
|
|
10
10
|
import { PriceFeedRegister } from "./market/pricefeeds/index.js";
|
|
11
|
-
import type {
|
|
11
|
+
import type { RedstoneOptions } from "./market/pricefeeds/RedstoneUpdater.js";
|
|
12
12
|
import { type PluginsMap } from "./plugins/index.js";
|
|
13
13
|
import { type IRouterContract } from "./router/index.js";
|
|
14
14
|
import type { GearboxState, GearboxStateHuman, ILogger, MultiCall } from "./types/index.js";
|
|
@@ -51,10 +51,6 @@ export interface SDKOptions<Plugins extends PluginsMap> {
|
|
|
51
51
|
* Options related to redstone price feeds
|
|
52
52
|
*/
|
|
53
53
|
redstone?: RedstoneOptions;
|
|
54
|
-
/**
|
|
55
|
-
* Options related to pyth price feeds
|
|
56
|
-
*/
|
|
57
|
-
pyth?: PythOptions;
|
|
58
54
|
}
|
|
59
55
|
export type HydrateOptions<Plugins extends PluginsMap> = Omit<SDKOptions<Plugins>, "blockNumber" | "addressProvider" | "marketConfigurators">;
|
|
60
56
|
export interface SyncStateOptions {
|