@gearbox-protocol/sdk 12.9.9 → 12.10.1
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/history/errors.js +2 -0
- package/dist/cjs/permissionless/utils/price-update/get-prices.js +0 -3
- package/dist/cjs/permissionless/utils/price-update/get-updatable-feeds.js +2 -23
- package/dist/cjs/sdk/GearboxSDK.js +5 -25
- package/dist/cjs/sdk/market/pricefeeds/PriceFeedsRegister.js +8 -6
- package/dist/cjs/sdk/market/pricefeeds/PythPriceFeed.js +3 -27
- package/dist/cjs/sdk/market/pricefeeds/RedstonePriceFeed.js +2 -0
- package/dist/cjs/sdk/market/pricefeeds/index.js +0 -2
- package/dist/cjs/sdk/market/pricefeeds/updates/RedstoneUpdater.js +3 -202
- package/dist/cjs/sdk/market/pricefeeds/updates/fetchRedstonePayloads.js +4 -126
- package/dist/cjs/sdk/market/pricefeeds/updates/index.js +0 -7
- package/dist/cjs/sdk/options.js +1 -5
- package/dist/esm/history/errors.js +2 -0
- package/dist/esm/permissionless/utils/price-update/get-prices.js +0 -3
- package/dist/esm/permissionless/utils/price-update/get-updatable-feeds.js +2 -27
- package/dist/esm/sdk/GearboxSDK.js +5 -25
- package/dist/esm/sdk/market/pricefeeds/PriceFeedsRegister.js +8 -6
- package/dist/esm/sdk/market/pricefeeds/PythPriceFeed.js +4 -28
- package/dist/esm/sdk/market/pricefeeds/RedstonePriceFeed.js +2 -0
- package/dist/esm/sdk/market/pricefeeds/index.js +0 -2
- package/dist/esm/sdk/market/pricefeeds/updates/RedstoneUpdater.js +3 -202
- package/dist/esm/sdk/market/pricefeeds/updates/fetchRedstonePayloads.js +4 -130
- package/dist/esm/sdk/market/pricefeeds/updates/index.js +0 -4
- package/dist/esm/sdk/options.js +2 -9
- package/dist/types/permissionless/utils/price-update/get-updatable-feeds.d.ts +4 -3
- package/dist/types/sdk/market/pricefeeds/PriceFeedsRegister.d.ts +2 -3
- package/dist/types/sdk/market/pricefeeds/PythPriceFeed.d.ts +2 -25
- package/dist/types/sdk/market/pricefeeds/index.d.ts +1 -1
- package/dist/types/sdk/market/pricefeeds/updates/RedstoneUpdater.d.ts +5 -10
- package/dist/types/sdk/market/pricefeeds/updates/fetchRedstonePayloads.d.ts +2 -6
- package/dist/types/sdk/market/pricefeeds/updates/index.d.ts +0 -2
- package/dist/types/sdk/options.d.ts +0 -6
- package/package.json +6 -7
- package/dist/cjs/sdk/market/pricefeeds/updates/PriceUpdateTx.js +0 -55
- package/dist/cjs/sdk/market/pricefeeds/updates/PriceUpdatesCache.js +0 -78
- package/dist/cjs/sdk/market/pricefeeds/updates/PythAccumulatorUpdateData.js +0 -195
- package/dist/cjs/sdk/market/pricefeeds/updates/PythUpdater.js +0 -183
- package/dist/cjs/sdk/market/pricefeeds/updates/fetchPythPayloads.js +0 -135
- package/dist/esm/sdk/market/pricefeeds/updates/PriceUpdateTx.js +0 -31
- package/dist/esm/sdk/market/pricefeeds/updates/PriceUpdatesCache.js +0 -54
- package/dist/esm/sdk/market/pricefeeds/updates/PythAccumulatorUpdateData.js +0 -157
- package/dist/esm/sdk/market/pricefeeds/updates/PythUpdater.js +0 -158
- package/dist/esm/sdk/market/pricefeeds/updates/fetchPythPayloads.js +0 -115
- package/dist/types/sdk/market/pricefeeds/updates/PriceUpdateTx.d.ts +0 -13
- package/dist/types/sdk/market/pricefeeds/updates/PriceUpdatesCache.d.ts +0 -24
- package/dist/types/sdk/market/pricefeeds/updates/PythAccumulatorUpdateData.d.ts +0 -41
- package/dist/types/sdk/market/pricefeeds/updates/PythUpdater.d.ts +0 -26
- package/dist/types/sdk/market/pricefeeds/updates/fetchPythPayloads.d.ts +0 -45
|
@@ -21,29 +21,8 @@ __export(get_updatable_feeds_exports, {
|
|
|
21
21
|
getUpdatablePriceFeeds: () => getUpdatablePriceFeeds
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(get_updatable_feeds_exports);
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
var import_sdk = require("../../../sdk/index.js");
|
|
27
|
-
async function getUpdatablePriceFeeds(args) {
|
|
28
|
-
const { sdk, client, pfCompressor, priceFeeds } = args;
|
|
29
|
-
const priceFeedCompressor = (0, import_viem.getContract)({
|
|
30
|
-
address: pfCompressor,
|
|
31
|
-
abi: import_priceFeedCompressor.priceFeedCompressorAbi,
|
|
32
|
-
client
|
|
33
|
-
});
|
|
34
|
-
const updatablePriceFeeds = (await priceFeedCompressor.read.loadPriceFeedTree([
|
|
35
|
-
priceFeeds
|
|
36
|
-
])).filter(
|
|
37
|
-
(data) => ["PRICE_FEED::PYTH", "PRICE_FEED::REDSTONE"].includes(
|
|
38
|
-
(0, import_sdk.bytes32ToString)(data.baseParams.contractType)
|
|
39
|
-
)
|
|
40
|
-
).map((data) => {
|
|
41
|
-
if ((0, import_sdk.bytes32ToString)(data.baseParams.contractType) === "PRICE_FEED::PYTH") {
|
|
42
|
-
return new import_sdk.PythPriceFeed(sdk, data);
|
|
43
|
-
}
|
|
44
|
-
return new import_sdk.RedstonePriceFeedContract(sdk, data);
|
|
45
|
-
});
|
|
46
|
-
return updatablePriceFeeds;
|
|
24
|
+
async function getUpdatablePriceFeeds(_args) {
|
|
25
|
+
return [];
|
|
47
26
|
}
|
|
48
27
|
// Annotate the CommonJS export names for ESM import in node:
|
|
49
28
|
0 && (module.exports = {
|
|
@@ -100,7 +100,6 @@ class GearboxSDK extends import_base.ChainContractsRegister {
|
|
|
100
100
|
plugins,
|
|
101
101
|
blockNumber,
|
|
102
102
|
redstone,
|
|
103
|
-
pyth,
|
|
104
103
|
ignoreUpdateablePrices,
|
|
105
104
|
ignoreMarkets,
|
|
106
105
|
marketConfigurators: mcs,
|
|
@@ -125,8 +124,7 @@ class GearboxSDK extends import_base.ChainContractsRegister {
|
|
|
125
124
|
ignoreUpdateablePrices,
|
|
126
125
|
ignoreMarkets,
|
|
127
126
|
marketConfigurators,
|
|
128
|
-
redstone
|
|
129
|
-
pyth
|
|
127
|
+
redstone
|
|
130
128
|
});
|
|
131
129
|
}
|
|
132
130
|
static hydrate(options, state) {
|
|
@@ -163,8 +161,7 @@ class GearboxSDK extends import_base.ChainContractsRegister {
|
|
|
163
161
|
ignoreUpdateablePrices,
|
|
164
162
|
ignoreMarkets,
|
|
165
163
|
marketConfigurators,
|
|
166
|
-
redstone
|
|
167
|
-
pyth
|
|
164
|
+
redstone
|
|
168
165
|
} = opts;
|
|
169
166
|
const re = this.#attachConfig ? "re" : "";
|
|
170
167
|
this.logger?.info(
|
|
@@ -178,16 +175,6 @@ class GearboxSDK extends import_base.ChainContractsRegister {
|
|
|
178
175
|
},
|
|
179
176
|
`${re}attaching gearbox sdk`
|
|
180
177
|
);
|
|
181
|
-
if (!!blockNumber && !opts.redstone?.historicTimestamp) {
|
|
182
|
-
this.logger?.warn(
|
|
183
|
-
`${re}attaching to fixed block number, but redstone historicTimestamp is not set. price updates might fail`
|
|
184
|
-
);
|
|
185
|
-
}
|
|
186
|
-
if (!!blockNumber && !opts.pyth?.historicTimestamp) {
|
|
187
|
-
this.logger?.warn(
|
|
188
|
-
`${re}attaching to fixed block number, but pyth historicTimestamp is not set. price updates might fail`
|
|
189
|
-
);
|
|
190
|
-
}
|
|
191
178
|
this.#attachConfig = opts;
|
|
192
179
|
const time = Date.now();
|
|
193
180
|
const block = await this.client.getBlock(
|
|
@@ -197,7 +184,7 @@ class GearboxSDK extends import_base.ChainContractsRegister {
|
|
|
197
184
|
);
|
|
198
185
|
this.#currentBlock = block.number;
|
|
199
186
|
this.#timestamp = block.timestamp;
|
|
200
|
-
this.#priceFeeds = new import_pricefeeds.PriceFeedRegister(this, { redstone
|
|
187
|
+
this.#priceFeeds = new import_pricefeeds.PriceFeedRegister(this, { redstone });
|
|
201
188
|
this.logger?.debug(
|
|
202
189
|
`${re}attach block number ${this.currentBlock} timestamp ${this.timestamp}`
|
|
203
190
|
);
|
|
@@ -247,8 +234,7 @@ class GearboxSDK extends import_base.ChainContractsRegister {
|
|
|
247
234
|
this.#currentBlock = state.currentBlock;
|
|
248
235
|
this.#timestamp = state.timestamp;
|
|
249
236
|
this.#priceFeeds = new import_pricefeeds.PriceFeedRegister(this, {
|
|
250
|
-
redstone: opts.redstone
|
|
251
|
-
pyth: opts.pyth
|
|
237
|
+
redstone: opts.redstone
|
|
252
238
|
});
|
|
253
239
|
this.#addressProvider = (0, import_core.hydrateAddressProvider)(this, state.addressProvider);
|
|
254
240
|
this.logger?.debug(
|
|
@@ -301,8 +287,7 @@ class GearboxSDK extends import_base.ChainContractsRegister {
|
|
|
301
287
|
}
|
|
302
288
|
const opts = {
|
|
303
289
|
ignoreUpdateablePrices: this.#attachConfig.ignoreUpdateablePrices,
|
|
304
|
-
redstone: this.#attachConfig.redstone
|
|
305
|
-
pyth: this.#attachConfig.pyth
|
|
290
|
+
redstone: this.#attachConfig.redstone
|
|
306
291
|
};
|
|
307
292
|
this.#hydrate(opts, state);
|
|
308
293
|
await this.#hooks.triggerHooks("rehydrate", {
|
|
@@ -360,11 +345,6 @@ class GearboxSDK extends import_base.ChainContractsRegister {
|
|
|
360
345
|
timestamp,
|
|
361
346
|
ignoreUpdateablePrices = this.#attachConfig?.ignoreUpdateablePrices
|
|
362
347
|
} = opts ?? {};
|
|
363
|
-
if (this.#attachConfig?.redstone?.historicTimestamp || this.#attachConfig?.pyth?.historicTimestamp) {
|
|
364
|
-
throw new Error(
|
|
365
|
-
"syncState is not supported with redstone or pyth historicTimestamp"
|
|
366
|
-
);
|
|
367
|
-
}
|
|
368
348
|
if (!blockNumber || !timestamp) {
|
|
369
349
|
const block = await this.client.getBlock({
|
|
370
350
|
blockTag: "latest"
|
|
@@ -43,7 +43,6 @@ var import_MellowLRTPriceFeed = require("./MellowLRTPriceFeed.js");
|
|
|
43
43
|
var import_PendleTWAPPTPriceFeed = require("./PendleTWAPPTPriceFeed.js");
|
|
44
44
|
var import_PythPriceFeed = require("./PythPriceFeed.js");
|
|
45
45
|
var import_RedstonePriceFeed = require("./RedstonePriceFeed.js");
|
|
46
|
-
var import_updates = require("./updates/index.js");
|
|
47
46
|
var import_WstETHPriceFeed = require("./WstETHPriceFeed.js");
|
|
48
47
|
var import_YearnPriceFeed = require("./YearnPriceFeed.js");
|
|
49
48
|
var import_ZeroPriceFeed = require("./ZeroPriceFeed.js");
|
|
@@ -52,12 +51,9 @@ class PriceFeedRegister extends import_base.SDKConstruct {
|
|
|
52
51
|
#feeds = new import_utils.AddressMap(void 0, "priceFeeds");
|
|
53
52
|
#latestUpdate;
|
|
54
53
|
updaters;
|
|
55
|
-
constructor(sdk,
|
|
54
|
+
constructor(sdk, _opts = {}) {
|
|
56
55
|
super(sdk);
|
|
57
|
-
this.updaters = [
|
|
58
|
-
new import_updates.RedstoneUpdater(sdk, opts?.redstone),
|
|
59
|
-
new import_updates.PythUpdater(sdk, opts?.pyth)
|
|
60
|
-
];
|
|
56
|
+
this.updaters = [];
|
|
61
57
|
}
|
|
62
58
|
addHook = this.#hooks.addHook.bind(this.#hooks);
|
|
63
59
|
removeHook = this.#hooks.removeHook.bind(this.#hooks);
|
|
@@ -149,6 +145,9 @@ class PriceFeedRegister extends import_base.SDKConstruct {
|
|
|
149
145
|
* @returns
|
|
150
146
|
*/
|
|
151
147
|
async generateExternalPriceFeedsUpdateTxs(feeds, block) {
|
|
148
|
+
if (this.updaters.length === 0) {
|
|
149
|
+
return this.generatePriceFeedsUpdateTxs([]);
|
|
150
|
+
}
|
|
152
151
|
const [priceFeedCompressorAddress] = this.sdk.addressProvider.mustGetLatest(
|
|
153
152
|
import_constants.AP_PRICE_FEED_COMPRESSOR,
|
|
154
153
|
import_constants.VERSION_RANGE_310
|
|
@@ -203,6 +202,9 @@ class PriceFeedRegister extends import_base.SDKConstruct {
|
|
|
203
202
|
* Discovered price feeds are not saved anywhere in PriceFeedRegister, and can later be used to load price feed updates
|
|
204
203
|
*/
|
|
205
204
|
async getPartialUpdatablePriceFeeds(configurators, pools) {
|
|
205
|
+
if (this.updaters.length === 0) {
|
|
206
|
+
return [];
|
|
207
|
+
}
|
|
206
208
|
const [priceFeedCompressorAddress] = this.sdk.addressProvider.mustGetLatest(
|
|
207
209
|
import_constants.AP_PRICE_FEED_COMPRESSOR,
|
|
208
210
|
import_constants.VERSION_RANGE_310
|
|
@@ -25,9 +25,6 @@ var import_viem = require("viem");
|
|
|
25
25
|
var import_oracles = require("../../abi/oracles.js");
|
|
26
26
|
var import_AbstractPriceFeed = require("./AbstractPriceFeed.js");
|
|
27
27
|
const abi = import_oracles.pythPriceFeedAbi;
|
|
28
|
-
const iPythAbi = (0, import_viem.parseAbi)([
|
|
29
|
-
"function getUpdateFee(bytes[] calldata updateData) external view returns (uint256 feeAmount)"
|
|
30
|
-
]);
|
|
31
28
|
class PythPriceFeed extends import_AbstractPriceFeed.AbstractPriceFeedContract {
|
|
32
29
|
token;
|
|
33
30
|
priceFeedId;
|
|
@@ -36,6 +33,9 @@ class PythPriceFeed extends import_AbstractPriceFeed.AbstractPriceFeedContract {
|
|
|
36
33
|
constructor(options, args) {
|
|
37
34
|
super(options, {
|
|
38
35
|
...args,
|
|
36
|
+
// the sdk does not push pyth price updates, so these feeds are never
|
|
37
|
+
// treated as updatable even though the contract implements the interface
|
|
38
|
+
updatable: false,
|
|
39
39
|
name: "PythPriceFeed",
|
|
40
40
|
abi
|
|
41
41
|
});
|
|
@@ -67,30 +67,6 @@ class PythPriceFeed extends import_AbstractPriceFeed.AbstractPriceFeedContract {
|
|
|
67
67
|
this.pyth = decoded[2];
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
|
-
createPriceUpdateTx(data) {
|
|
71
|
-
return this.createRawTx({
|
|
72
|
-
functionName: "updatePrice",
|
|
73
|
-
args: [data],
|
|
74
|
-
description: `updating pyth price for ${this.priceFeedId} [${this.labelAddress(this.address)}]`
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Returns contract function parameters for the getUpdateFee function on original Pyth contract
|
|
79
|
-
* @param calldata
|
|
80
|
-
* @returns
|
|
81
|
-
*/
|
|
82
|
-
getUpdateFeeParams(calldata) {
|
|
83
|
-
const [, updateData] = (0, import_viem.decodeAbiParameters)(
|
|
84
|
-
[{ type: "uint256" }, { type: "bytes[]" }],
|
|
85
|
-
calldata
|
|
86
|
-
);
|
|
87
|
-
return {
|
|
88
|
-
address: this.pyth,
|
|
89
|
-
abi: iPythAbi,
|
|
90
|
-
functionName: "getUpdateFee",
|
|
91
|
-
args: [updateData]
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
70
|
}
|
|
95
71
|
// Annotate the CommonJS export names for ESM import in node:
|
|
96
72
|
0 && (module.exports = {
|
|
@@ -36,6 +36,8 @@ class RedstonePriceFeedContract extends import_AbstractPriceFeed.AbstractPriceFe
|
|
|
36
36
|
constructor(options, args) {
|
|
37
37
|
super(options, {
|
|
38
38
|
...args,
|
|
39
|
+
// RedStone updates are no longer pushed by the SDK.
|
|
40
|
+
updatable: false,
|
|
39
41
|
name: "RedstonePriceFeed",
|
|
40
42
|
abi: import_abi.redstonePriceFeedAbi
|
|
41
43
|
});
|
|
@@ -19,7 +19,6 @@ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "defau
|
|
|
19
19
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
20
|
var pricefeeds_exports = {};
|
|
21
21
|
__export(pricefeeds_exports, {
|
|
22
|
-
fetchPythPayloads: () => import_updates.fetchPythPayloads,
|
|
23
22
|
fetchRedstonePayloads: () => import_updates.fetchRedstonePayloads
|
|
24
23
|
});
|
|
25
24
|
module.exports = __toCommonJS(pricefeeds_exports);
|
|
@@ -49,7 +48,6 @@ __reExport(pricefeeds_exports, require("./YearnPriceFeed.js"), module.exports);
|
|
|
49
48
|
__reExport(pricefeeds_exports, require("./ZeroPriceFeed.js"), module.exports);
|
|
50
49
|
// Annotate the CommonJS export names for ESM import in node:
|
|
51
50
|
0 && (module.exports = {
|
|
52
|
-
fetchPythPayloads,
|
|
53
51
|
fetchRedstonePayloads,
|
|
54
52
|
...require("./AbstractLPPriceFeed.js"),
|
|
55
53
|
...require("./AbstractPriceFeed.js"),
|
|
@@ -24,13 +24,6 @@ __export(RedstoneUpdater_exports, {
|
|
|
24
24
|
module.exports = __toCommonJS(RedstoneUpdater_exports);
|
|
25
25
|
var import_v4 = require("zod/v4");
|
|
26
26
|
var import_base = require("../../../base/index.js");
|
|
27
|
-
var import_utils = require("../../../utils/index.js");
|
|
28
|
-
var import_fetchRedstonePayloads = require("./fetchRedstonePayloads.js");
|
|
29
|
-
var import_PriceUpdatesCache = require("./PriceUpdatesCache.js");
|
|
30
|
-
var import_PriceUpdateTx = require("./PriceUpdateTx.js");
|
|
31
|
-
class RedstoneUpdateTx extends import_PriceUpdateTx.PriceUpdateTx {
|
|
32
|
-
name = "redstone";
|
|
33
|
-
}
|
|
34
27
|
const RedstoneOptions = import_v4.z.object({
|
|
35
28
|
/**
|
|
36
29
|
* Fixed redstone historic timestamp in ms
|
|
@@ -58,204 +51,12 @@ const RedstoneOptions = import_v4.z.object({
|
|
|
58
51
|
enableLogging: import_v4.z.boolean().optional()
|
|
59
52
|
});
|
|
60
53
|
class RedstoneUpdater extends import_base.SDKConstruct {
|
|
61
|
-
|
|
62
|
-
#historicalTimestampMs;
|
|
63
|
-
#gateways;
|
|
64
|
-
#ignoreMissingFeeds;
|
|
65
|
-
#enableLogging;
|
|
66
|
-
constructor(sdk, opts = {}) {
|
|
54
|
+
constructor(sdk, _opts = {}) {
|
|
67
55
|
super(sdk);
|
|
68
|
-
this.#ignoreMissingFeeds = opts.ignoreMissingFeeds;
|
|
69
|
-
this.#enableLogging = opts.enableLogging;
|
|
70
|
-
this.#gateways = opts.gateways?.length ? opts.gateways : void 0;
|
|
71
|
-
let ts = opts.historicTimestamp;
|
|
72
|
-
if (ts) {
|
|
73
|
-
ts = ts === true ? Number(this.sdk.timestamp) * 1e3 : ts;
|
|
74
|
-
this.#historicalTimestampMs = 6e4 * Math.floor(ts / 6e4);
|
|
75
|
-
this.logger?.debug(
|
|
76
|
-
`using historical timestamp ${this.#historicalTimestampMs}`
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
this.#cache = import_PriceUpdatesCache.PriceUpdatesCache.get("redstone", {
|
|
80
|
-
// currently staleness period is 240 seconds on all networks, add some buffer
|
|
81
|
-
// this period of 4 minutes is selected based on time that is required for user to sign transaction with wallet
|
|
82
|
-
// so it's unlikely to decrease
|
|
83
|
-
ttl: opts.cacheTTL ?? 225 * 1e3,
|
|
84
|
-
historical: !!ts
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
async getUpdateTxs(feeds) {
|
|
88
|
-
if (feeds.length === 0) {
|
|
89
|
-
return [];
|
|
90
|
-
}
|
|
91
|
-
this.logger?.debug(
|
|
92
|
-
`generating update transactions for ${feeds.length} redstone price feeds`
|
|
93
|
-
);
|
|
94
|
-
const groupedFeeds = {};
|
|
95
|
-
const priceFeeds = /* @__PURE__ */ new Map();
|
|
96
|
-
for (const feed of feeds) {
|
|
97
|
-
if (!isRedstone(feed)) {
|
|
98
|
-
continue;
|
|
99
|
-
}
|
|
100
|
-
const key = `${feed.dataServiceId}:${feed.signersThreshold}`;
|
|
101
|
-
if (!groupedFeeds[key]) {
|
|
102
|
-
groupedFeeds[key] = /* @__PURE__ */ new Set();
|
|
103
|
-
}
|
|
104
|
-
groupedFeeds[key].add(feed.dataId);
|
|
105
|
-
const pfsForDataId = priceFeeds.get(feed.dataId) ?? new import_utils.AddressMap();
|
|
106
|
-
pfsForDataId.upsert(feed.address, feed);
|
|
107
|
-
priceFeeds.set(feed.dataId, pfsForDataId);
|
|
108
|
-
}
|
|
109
|
-
const results = [];
|
|
110
|
-
let [minTimestamp, maxTimestamp] = [Number.POSITIVE_INFINITY, 0];
|
|
111
|
-
for (const [key, group] of Object.entries(groupedFeeds)) {
|
|
112
|
-
const [dataServiceId, signersStr] = key.split(":");
|
|
113
|
-
const uniqueSignersCount = parseInt(signersStr, 10);
|
|
114
|
-
const payloads = await this.#safeGetPayloads(
|
|
115
|
-
dataServiceId,
|
|
116
|
-
group,
|
|
117
|
-
uniqueSignersCount
|
|
118
|
-
);
|
|
119
|
-
for (const { dataFeedId, data, timestamp, cached } of payloads) {
|
|
120
|
-
const pfsForDataId = priceFeeds.get(dataFeedId);
|
|
121
|
-
if (!pfsForDataId) {
|
|
122
|
-
throw new Error(`cannot get price feed addresses for ${dataFeedId}`);
|
|
123
|
-
}
|
|
124
|
-
for (const priceFeed of pfsForDataId.values()) {
|
|
125
|
-
minTimestamp = Math.min(minTimestamp, timestamp);
|
|
126
|
-
maxTimestamp = Math.max(maxTimestamp, timestamp);
|
|
127
|
-
results.push(
|
|
128
|
-
new RedstoneUpdateTx(priceFeed.createPriceUpdateTx(data), {
|
|
129
|
-
dataFeedId,
|
|
130
|
-
dataServiceId,
|
|
131
|
-
priceFeed: priceFeed.address,
|
|
132
|
-
timestamp,
|
|
133
|
-
cached
|
|
134
|
-
})
|
|
135
|
-
);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
let tsRange = "";
|
|
140
|
-
if (results.length) {
|
|
141
|
-
const minDelta = BigInt(minTimestamp) - this.sdk.timestamp;
|
|
142
|
-
tsRange = `, timestamps ${minTimestamp} (${minDelta})`;
|
|
143
|
-
if (minTimestamp !== maxTimestamp) {
|
|
144
|
-
const maxDelta = BigInt(maxTimestamp) - this.sdk.timestamp;
|
|
145
|
-
tsRange = `${tsRange} - ${maxTimestamp} (${maxDelta})`;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
this.logger?.debug(
|
|
149
|
-
`generated ${results.length} update transactions for redstone price feeds: ${Array.from(priceFeeds.keys()).join(", ")}${tsRange}`
|
|
150
|
-
);
|
|
151
|
-
return results;
|
|
152
56
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
* @param dataServiceId
|
|
156
|
-
* @param dataFeedsIds
|
|
157
|
-
* @param uniqueSignersCount
|
|
158
|
-
* @returns
|
|
159
|
-
*/
|
|
160
|
-
async #safeGetPayloads(dataServiceId, dataFeedsIds, uniqueSignersCount) {
|
|
161
|
-
let result = await this.#getPayloads(
|
|
162
|
-
dataServiceId,
|
|
163
|
-
dataFeedsIds,
|
|
164
|
-
uniqueSignersCount
|
|
165
|
-
);
|
|
166
|
-
if (this.#historicalTimestampMs) {
|
|
167
|
-
return result;
|
|
168
|
-
}
|
|
169
|
-
let expired = false;
|
|
170
|
-
for (const { timestamp, dataFeedId } of result) {
|
|
171
|
-
const delta = Number(this.sdk.timestamp) - timestamp;
|
|
172
|
-
if (delta >= 240 && delta < 255) {
|
|
173
|
-
this.logger?.warn(
|
|
174
|
-
`payload for ${dataFeedId} has expired by ${delta} seconds`
|
|
175
|
-
);
|
|
176
|
-
expired = true;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
if (expired) {
|
|
180
|
-
result = await this.#getPayloads(
|
|
181
|
-
dataServiceId,
|
|
182
|
-
dataFeedsIds,
|
|
183
|
-
uniqueSignersCount
|
|
184
|
-
);
|
|
185
|
-
}
|
|
186
|
-
return result;
|
|
57
|
+
async getUpdateTxs(_feeds) {
|
|
58
|
+
return [];
|
|
187
59
|
}
|
|
188
|
-
/**
|
|
189
|
-
* Gets redstone payloads in one request for multiple feeds with the same dataServiceId and uniqueSignersCount
|
|
190
|
-
* If historicalTimestamp is set, responses will be cached
|
|
191
|
-
* @param dataServiceId
|
|
192
|
-
* @param dataFeedsIds
|
|
193
|
-
* @param uniqueSignersCount
|
|
194
|
-
* @returns
|
|
195
|
-
*/
|
|
196
|
-
async #getPayloads(dataServiceId, dataFeedsIds, uniqueSignersCount) {
|
|
197
|
-
this.logger?.debug(
|
|
198
|
-
`getting redstone payloads for ${dataFeedsIds.size} data feeds in ${dataServiceId} with ${uniqueSignersCount} signers: ${Array.from(dataFeedsIds).join(", ")}`
|
|
199
|
-
);
|
|
200
|
-
const fromCache = [];
|
|
201
|
-
const uncached = [];
|
|
202
|
-
for (const dataFeedId of dataFeedsIds) {
|
|
203
|
-
const cached = this.#cache.get(
|
|
204
|
-
dataServiceId,
|
|
205
|
-
dataFeedId,
|
|
206
|
-
uniqueSignersCount
|
|
207
|
-
);
|
|
208
|
-
if (cached) {
|
|
209
|
-
fromCache.push({ ...cached, cached: true });
|
|
210
|
-
} else {
|
|
211
|
-
uncached.push(dataFeedId);
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
const fromRedstone = await this.#fetchPayloads(
|
|
215
|
-
dataServiceId,
|
|
216
|
-
new Set(uncached),
|
|
217
|
-
uniqueSignersCount
|
|
218
|
-
);
|
|
219
|
-
for (const resp of fromRedstone) {
|
|
220
|
-
this.#cache.set(resp, dataServiceId, resp.dataFeedId, uniqueSignersCount);
|
|
221
|
-
}
|
|
222
|
-
this.logger?.debug(
|
|
223
|
-
`got ${fromRedstone.length} new redstone updates and ${fromCache.length} from cache`
|
|
224
|
-
);
|
|
225
|
-
return [...fromCache, ...fromRedstone];
|
|
226
|
-
}
|
|
227
|
-
/**
|
|
228
|
-
* Fetches redstone payloads in one request for multiple feeds with the same dataServiceId and uniqueSignersCount
|
|
229
|
-
* Payloads are loaded in one request to avoid redstone rate limit
|
|
230
|
-
* @param dataServiceId
|
|
231
|
-
* @param dataFeedsIds
|
|
232
|
-
* @param uniqueSignersCount
|
|
233
|
-
* @returns
|
|
234
|
-
*/
|
|
235
|
-
async #fetchPayloads(dataServiceId, dataFeedsIds, uniqueSignersCount) {
|
|
236
|
-
if (dataFeedsIds.size === 0) {
|
|
237
|
-
return [];
|
|
238
|
-
}
|
|
239
|
-
const dataPackagesIds = Array.from(dataFeedsIds);
|
|
240
|
-
const tsStr = this.#historicalTimestampMs ? ` with historical timestamp ${this.#historicalTimestampMs}` : "";
|
|
241
|
-
this.logger?.debug(
|
|
242
|
-
`fetching redstone payloads for ${dataFeedsIds.size} data feeds in ${dataServiceId} with ${uniqueSignersCount} signers: ${dataPackagesIds.join(", ")}${tsStr}`
|
|
243
|
-
);
|
|
244
|
-
return (0, import_fetchRedstonePayloads.fetchRedstonePayloads)({
|
|
245
|
-
dataServiceId,
|
|
246
|
-
dataFeedsIds,
|
|
247
|
-
uniqueSignersCount,
|
|
248
|
-
historicalTimestampMs: this.#historicalTimestampMs,
|
|
249
|
-
gateways: this.#gateways,
|
|
250
|
-
ignoreMissingFeeds: this.#ignoreMissingFeeds,
|
|
251
|
-
enableLogging: this.#enableLogging,
|
|
252
|
-
logger: this.logger,
|
|
253
|
-
metadataTimestampMs: Number(this.sdk.timestamp) * 1e3
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
function isRedstone(pf) {
|
|
258
|
-
return pf.contractType === "PRICE_FEED::REDSTONE";
|
|
259
60
|
}
|
|
260
61
|
// Annotate the CommonJS export names for ESM import in node:
|
|
261
62
|
0 && (module.exports = {
|
|
@@ -21,135 +21,13 @@ __export(fetchRedstonePayloads_exports, {
|
|
|
21
21
|
fetchRedstonePayloads: () => fetchRedstonePayloads
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(fetchRedstonePayloads_exports);
|
|
24
|
-
var import_evm_connector = require("@redstone-finance/evm-connector");
|
|
25
|
-
var import_protocol = require("@redstone-finance/protocol");
|
|
26
|
-
var import_sdk = require("@redstone-finance/sdk");
|
|
27
|
-
var import_utils = require("@redstone-finance/utils");
|
|
28
|
-
var import_viem = require("viem");
|
|
29
|
-
var import_utils2 = require("../../../utils/index.js");
|
|
30
24
|
async function fetchRedstonePayloads(options) {
|
|
31
|
-
const {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
uniqueSignersCount,
|
|
35
|
-
historicalTimestampMs,
|
|
36
|
-
gateways,
|
|
37
|
-
ignoreMissingFeeds,
|
|
38
|
-
enableLogging,
|
|
39
|
-
logger,
|
|
40
|
-
returnPrices
|
|
41
|
-
} = options;
|
|
42
|
-
const metadataTimestampMs = historicalTimestampMs ?? options.metadataTimestampMs;
|
|
43
|
-
const dataPackagesIds = Array.from(new Set(dataFeedsIds));
|
|
44
|
-
if (dataPackagesIds.length === 0) {
|
|
45
|
-
return [];
|
|
46
|
-
}
|
|
47
|
-
const wrapper = new import_evm_connector.DataServiceWrapper({
|
|
48
|
-
dataServiceId,
|
|
49
|
-
dataPackagesIds,
|
|
50
|
-
uniqueSignersCount,
|
|
51
|
-
authorizedSigners: (0, import_sdk.getSignersForDataServiceId)(
|
|
52
|
-
dataServiceId
|
|
53
|
-
),
|
|
54
|
-
historicalTimestamp: historicalTimestampMs,
|
|
55
|
-
urls: gateways,
|
|
56
|
-
ignoreMissingFeed: ignoreMissingFeeds,
|
|
57
|
-
enableEnhancedLogs: enableLogging
|
|
58
|
-
});
|
|
59
|
-
if (metadataTimestampMs) {
|
|
60
|
-
wrapper.setMetadataTimestamp(metadataTimestampMs);
|
|
61
|
-
}
|
|
62
|
-
const dataPayload = await (0, import_utils2.retry)(() => wrapper.prepareRedstonePayload(true), {
|
|
63
|
-
attempts: 5,
|
|
64
|
-
interval: historicalTimestampMs ? 30500 : 250
|
|
65
|
-
});
|
|
66
|
-
const parsed = import_protocol.RedstonePayload.parse((0, import_viem.toBytes)(`0x${dataPayload}`));
|
|
67
|
-
const packagesByDataFeedId = groupDataPackages(parsed.signedDataPackages);
|
|
68
|
-
const result = [];
|
|
69
|
-
for (const dataFeedId of dataFeedsIds) {
|
|
70
|
-
const signedDataPackages = packagesByDataFeedId[dataFeedId];
|
|
71
|
-
if (!signedDataPackages) {
|
|
72
|
-
if (ignoreMissingFeeds) {
|
|
73
|
-
logger?.warn(`cannot find data packages for ${dataFeedId}`);
|
|
74
|
-
continue;
|
|
75
|
-
}
|
|
76
|
-
throw new Error(`cannot find data packages for ${dataFeedId}`);
|
|
77
|
-
}
|
|
78
|
-
if (signedDataPackages.length !== uniqueSignersCount) {
|
|
79
|
-
if (ignoreMissingFeeds) {
|
|
80
|
-
logger?.warn(
|
|
81
|
-
`got ${signedDataPackages.length} data packages for ${dataFeedId}, but expected ${uniqueSignersCount}`
|
|
82
|
-
);
|
|
83
|
-
continue;
|
|
84
|
-
}
|
|
85
|
-
throw new Error(
|
|
86
|
-
`got ${signedDataPackages.length} data packages for ${dataFeedId}, but expected ${uniqueSignersCount}`
|
|
87
|
-
);
|
|
88
|
-
}
|
|
89
|
-
result.push(
|
|
90
|
-
getCalldataWithTimestamp(
|
|
91
|
-
dataFeedId,
|
|
92
|
-
signedDataPackages,
|
|
93
|
-
wrapper.getUnsignedMetadata(),
|
|
94
|
-
returnPrices
|
|
95
|
-
)
|
|
25
|
+
for (const _feed of options.dataFeedsIds) {
|
|
26
|
+
throw new Error(
|
|
27
|
+
"RedStone price updates are no longer supported by this SDK"
|
|
96
28
|
);
|
|
97
29
|
}
|
|
98
|
-
return
|
|
99
|
-
}
|
|
100
|
-
function groupDataPackages(signedDataPackages) {
|
|
101
|
-
const packagesByDataFeedId = {};
|
|
102
|
-
for (const p of signedDataPackages) {
|
|
103
|
-
const { dataPoints } = p.dataPackage;
|
|
104
|
-
const dataFeedId0 = dataPoints[0].dataFeedId;
|
|
105
|
-
for (const dp of dataPoints) {
|
|
106
|
-
if (dp.dataFeedId !== dataFeedId0) {
|
|
107
|
-
throw new Error(
|
|
108
|
-
`data package contains data points with different dataFeedIds: ${dp.dataFeedId} and ${dataFeedId0}`
|
|
109
|
-
);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
if (!packagesByDataFeedId[dataFeedId0]) {
|
|
113
|
-
packagesByDataFeedId[dataFeedId0] = [];
|
|
114
|
-
}
|
|
115
|
-
packagesByDataFeedId[dataFeedId0].push(p);
|
|
116
|
-
}
|
|
117
|
-
return packagesByDataFeedId;
|
|
118
|
-
}
|
|
119
|
-
function getCalldataWithTimestamp(dataFeedId, packages, unsignedMetadata, returnPrices) {
|
|
120
|
-
const originalPayload = import_protocol.RedstonePayload.prepare(packages, unsignedMetadata);
|
|
121
|
-
const originalPayloadLength = originalPayload.length / 2;
|
|
122
|
-
const bytesToAdd = 32 - originalPayloadLength % 32;
|
|
123
|
-
const newUnsignedMetadata = unsignedMetadata + "_".repeat(bytesToAdd);
|
|
124
|
-
const payload = import_protocol.RedstonePayload.prepare(packages, newUnsignedMetadata);
|
|
125
|
-
let timestamp = 0;
|
|
126
|
-
for (const p of packages) {
|
|
127
|
-
const newTimestamp = p.dataPackage.timestampMilliseconds / 1e3;
|
|
128
|
-
if (timestamp === 0) {
|
|
129
|
-
timestamp = newTimestamp;
|
|
130
|
-
} else if (timestamp !== newTimestamp) {
|
|
131
|
-
throw new Error("Timestamps are not equal");
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
const base = {
|
|
135
|
-
dataFeedId,
|
|
136
|
-
data: (0, import_viem.encodeAbiParameters)(
|
|
137
|
-
[{ type: "uint256" }, { type: "bytes" }],
|
|
138
|
-
[BigInt(timestamp), `0x${payload}`]
|
|
139
|
-
),
|
|
140
|
-
timestamp,
|
|
141
|
-
cached: false
|
|
142
|
-
};
|
|
143
|
-
if (returnPrices) {
|
|
144
|
-
const prices = packages.flatMap((p) => p.dataPackage.dataPoints).map((dp) => BigInt(`0x${Buffer.from(dp.value).toString("hex")}`));
|
|
145
|
-
const medianPrice = BigInt(import_utils.MathUtils.getMedianOfBigNumbers(prices));
|
|
146
|
-
return {
|
|
147
|
-
...base,
|
|
148
|
-
price: medianPrice,
|
|
149
|
-
decimals: 8
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
return base;
|
|
30
|
+
return [];
|
|
153
31
|
}
|
|
154
32
|
// Annotate the CommonJS export names for ESM import in node:
|
|
155
33
|
0 && (module.exports = {
|
|
@@ -19,22 +19,15 @@ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "defau
|
|
|
19
19
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
20
|
var updates_exports = {};
|
|
21
21
|
__export(updates_exports, {
|
|
22
|
-
PythOptions: () => import_PythUpdater.PythOptions,
|
|
23
|
-
PythUpdater: () => import_PythUpdater.PythUpdater,
|
|
24
22
|
RedstoneOptions: () => import_RedstoneUpdater.RedstoneOptions,
|
|
25
23
|
RedstoneUpdater: () => import_RedstoneUpdater.RedstoneUpdater
|
|
26
24
|
});
|
|
27
25
|
module.exports = __toCommonJS(updates_exports);
|
|
28
|
-
__reExport(updates_exports, require("./fetchPythPayloads.js"), module.exports);
|
|
29
26
|
__reExport(updates_exports, require("./fetchRedstonePayloads.js"), module.exports);
|
|
30
|
-
var import_PythUpdater = require("./PythUpdater.js");
|
|
31
27
|
var import_RedstoneUpdater = require("./RedstoneUpdater.js");
|
|
32
28
|
// Annotate the CommonJS export names for ESM import in node:
|
|
33
29
|
0 && (module.exports = {
|
|
34
|
-
PythOptions,
|
|
35
|
-
PythUpdater,
|
|
36
30
|
RedstoneOptions,
|
|
37
31
|
RedstoneUpdater,
|
|
38
|
-
...require("./fetchPythPayloads.js"),
|
|
39
32
|
...require("./fetchRedstonePayloads.js")
|
|
40
33
|
});
|
package/dist/cjs/sdk/options.js
CHANGED
|
@@ -59,13 +59,9 @@ const SDKOptions = import_v4.z.object({
|
|
|
59
59
|
*/
|
|
60
60
|
logger: import_v4.z.any(),
|
|
61
61
|
/**
|
|
62
|
-
*
|
|
62
|
+
* @deprecated RedStone options are accepted for compatibility and ignored.
|
|
63
63
|
*/
|
|
64
64
|
redstone: import_updates.RedstoneOptions.optional(),
|
|
65
|
-
/**
|
|
66
|
-
* Options related to pyth price feeds
|
|
67
|
-
*/
|
|
68
|
-
pyth: import_updates.PythOptions.optional(),
|
|
69
65
|
/**
|
|
70
66
|
* Explicit gas limit for read eth_calls
|
|
71
67
|
* Null to disable explicitly setting gas limit, undefined to use default sdk value
|