@gearbox-protocol/sdk 12.6.0-next.3 → 12.6.0-next.4
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/market/pricefeeds/updates/fetchPythPayloads.js +29 -5
- package/dist/cjs/sdk/market/pricefeeds/updates/fetchRedstonePayloads.js +19 -6
- package/dist/esm/sdk/market/pricefeeds/updates/fetchPythPayloads.js +29 -5
- package/dist/esm/sdk/market/pricefeeds/updates/fetchRedstonePayloads.js +17 -4
- package/dist/types/sdk/market/pricefeeds/updates/fetchPythPayloads.d.ts +19 -4
- package/dist/types/sdk/market/pricefeeds/updates/fetchRedstonePayloads.d.ts +17 -2
- package/dist/types/sdk/market/pricefeeds/updates/types.d.ts +4 -0
- package/package.json +2 -1
|
@@ -31,7 +31,9 @@ async function fetchPythPayloads(options) {
|
|
|
31
31
|
ignoreMissingFeeds,
|
|
32
32
|
historicalTimestampSeconds,
|
|
33
33
|
logger,
|
|
34
|
-
apiProxy
|
|
34
|
+
apiProxy,
|
|
35
|
+
customFetch = fetch,
|
|
36
|
+
returnPrices
|
|
35
37
|
} = options;
|
|
36
38
|
const ids = Array.from(new Set(dataFeedsIds));
|
|
37
39
|
if (ids.length === 0) {
|
|
@@ -49,7 +51,7 @@ async function fetchPythPayloads(options) {
|
|
|
49
51
|
}
|
|
50
52
|
const resp = await (0, import_utils.retry)(
|
|
51
53
|
async () => {
|
|
52
|
-
const resp2 = await
|
|
54
|
+
const resp2 = await customFetch(url.toString());
|
|
53
55
|
if (!resp2.ok) {
|
|
54
56
|
const body = await resp2.text();
|
|
55
57
|
throw new Error(
|
|
@@ -61,7 +63,7 @@ async function fetchPythPayloads(options) {
|
|
|
61
63
|
},
|
|
62
64
|
{ attempts: 3, exponent: 2, interval: 200 }
|
|
63
65
|
);
|
|
64
|
-
const result = respToCalldata(resp);
|
|
66
|
+
const result = respToCalldata(resp, returnPrices);
|
|
65
67
|
if (result.length !== ids.length) {
|
|
66
68
|
if (ignoreMissingFeeds) {
|
|
67
69
|
logger?.warn(`expected ${ids.length} price feeds, got ${result.length}`);
|
|
@@ -73,13 +75,23 @@ async function fetchPythPayloads(options) {
|
|
|
73
75
|
}
|
|
74
76
|
return result;
|
|
75
77
|
}
|
|
76
|
-
function respToCalldata(resp) {
|
|
78
|
+
function respToCalldata(resp, returnPrices) {
|
|
77
79
|
if (resp.binary.data.length === 0) {
|
|
78
80
|
return [];
|
|
79
81
|
}
|
|
80
82
|
const updates = splitAccumulatorUpdates(resp.binary.data[0]);
|
|
83
|
+
const priceMap = /* @__PURE__ */ new Map();
|
|
84
|
+
if (returnPrices && resp.parsed) {
|
|
85
|
+
for (const feed of resp.parsed) {
|
|
86
|
+
const feedId = feed.id.startsWith("0x") ? feed.id : `0x${feed.id}`;
|
|
87
|
+
priceMap.set(feedId.toLowerCase(), {
|
|
88
|
+
price: BigInt(feed.price.price),
|
|
89
|
+
decimals: Math.abs(feed.price.expo)
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
81
93
|
return updates.map(({ data, dataFeedId, timestamp }) => {
|
|
82
|
-
|
|
94
|
+
const base = {
|
|
83
95
|
dataFeedId,
|
|
84
96
|
data: (0, import_viem.encodeAbiParameters)(
|
|
85
97
|
[{ type: "uint256" }, { type: "bytes[]" }],
|
|
@@ -88,6 +100,18 @@ function respToCalldata(resp) {
|
|
|
88
100
|
timestamp,
|
|
89
101
|
cached: false
|
|
90
102
|
};
|
|
103
|
+
if (returnPrices) {
|
|
104
|
+
const priceInfo = priceMap.get(dataFeedId.toLowerCase());
|
|
105
|
+
if (!priceInfo) {
|
|
106
|
+
throw new Error(`Price info not found for feed ${dataFeedId}`);
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
...base,
|
|
110
|
+
price: priceInfo.price,
|
|
111
|
+
decimals: priceInfo.decimals
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
return base;
|
|
91
115
|
});
|
|
92
116
|
}
|
|
93
117
|
function splitAccumulatorUpdates(binary) {
|
|
@@ -24,8 +24,9 @@ module.exports = __toCommonJS(fetchRedstonePayloads_exports);
|
|
|
24
24
|
var import_evm_connector = require("@redstone-finance/evm-connector");
|
|
25
25
|
var import_protocol = require("@redstone-finance/protocol");
|
|
26
26
|
var import_sdk = require("@redstone-finance/sdk");
|
|
27
|
+
var import_utils = require("@redstone-finance/utils");
|
|
27
28
|
var import_viem = require("viem");
|
|
28
|
-
var
|
|
29
|
+
var import_utils2 = require("../../../utils/index.js");
|
|
29
30
|
async function fetchRedstonePayloads(options) {
|
|
30
31
|
const {
|
|
31
32
|
dataServiceId,
|
|
@@ -35,7 +36,8 @@ async function fetchRedstonePayloads(options) {
|
|
|
35
36
|
gateways,
|
|
36
37
|
ignoreMissingFeeds,
|
|
37
38
|
enableLogging,
|
|
38
|
-
logger
|
|
39
|
+
logger,
|
|
40
|
+
returnPrices
|
|
39
41
|
} = options;
|
|
40
42
|
const metadataTimestampMs = historicalTimestampMs ?? options.metadataTimestampMs;
|
|
41
43
|
const dataPackagesIds = Array.from(new Set(dataFeedsIds));
|
|
@@ -57,7 +59,7 @@ async function fetchRedstonePayloads(options) {
|
|
|
57
59
|
if (metadataTimestampMs) {
|
|
58
60
|
wrapper.setMetadataTimestamp(metadataTimestampMs);
|
|
59
61
|
}
|
|
60
|
-
const dataPayload = await (0,
|
|
62
|
+
const dataPayload = await (0, import_utils2.retry)(() => wrapper.prepareRedstonePayload(true), {
|
|
61
63
|
attempts: 5,
|
|
62
64
|
interval: historicalTimestampMs ? 30500 : 250
|
|
63
65
|
});
|
|
@@ -88,7 +90,8 @@ async function fetchRedstonePayloads(options) {
|
|
|
88
90
|
getCalldataWithTimestamp(
|
|
89
91
|
dataFeedId,
|
|
90
92
|
signedDataPackages,
|
|
91
|
-
wrapper.getUnsignedMetadata()
|
|
93
|
+
wrapper.getUnsignedMetadata(),
|
|
94
|
+
returnPrices
|
|
92
95
|
)
|
|
93
96
|
);
|
|
94
97
|
}
|
|
@@ -113,7 +116,7 @@ function groupDataPackages(signedDataPackages) {
|
|
|
113
116
|
}
|
|
114
117
|
return packagesByDataFeedId;
|
|
115
118
|
}
|
|
116
|
-
function getCalldataWithTimestamp(dataFeedId, packages, unsignedMetadata) {
|
|
119
|
+
function getCalldataWithTimestamp(dataFeedId, packages, unsignedMetadata, returnPrices) {
|
|
117
120
|
const originalPayload = import_protocol.RedstonePayload.prepare(packages, unsignedMetadata);
|
|
118
121
|
const originalPayloadLength = originalPayload.length / 2;
|
|
119
122
|
const bytesToAdd = 32 - originalPayloadLength % 32;
|
|
@@ -128,7 +131,7 @@ function getCalldataWithTimestamp(dataFeedId, packages, unsignedMetadata) {
|
|
|
128
131
|
throw new Error("Timestamps are not equal");
|
|
129
132
|
}
|
|
130
133
|
}
|
|
131
|
-
|
|
134
|
+
const base = {
|
|
132
135
|
dataFeedId,
|
|
133
136
|
data: (0, import_viem.encodeAbiParameters)(
|
|
134
137
|
[{ type: "uint256" }, { type: "bytes" }],
|
|
@@ -137,6 +140,16 @@ function getCalldataWithTimestamp(dataFeedId, packages, unsignedMetadata) {
|
|
|
137
140
|
timestamp,
|
|
138
141
|
cached: false
|
|
139
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;
|
|
140
153
|
}
|
|
141
154
|
// Annotate the CommonJS export names for ESM import in node:
|
|
142
155
|
0 && (module.exports = {
|
|
@@ -12,7 +12,9 @@ async function fetchPythPayloads(options) {
|
|
|
12
12
|
ignoreMissingFeeds,
|
|
13
13
|
historicalTimestampSeconds,
|
|
14
14
|
logger,
|
|
15
|
-
apiProxy
|
|
15
|
+
apiProxy,
|
|
16
|
+
customFetch = fetch,
|
|
17
|
+
returnPrices
|
|
16
18
|
} = options;
|
|
17
19
|
const ids = Array.from(new Set(dataFeedsIds));
|
|
18
20
|
if (ids.length === 0) {
|
|
@@ -30,7 +32,7 @@ async function fetchPythPayloads(options) {
|
|
|
30
32
|
}
|
|
31
33
|
const resp = await retry(
|
|
32
34
|
async () => {
|
|
33
|
-
const resp2 = await
|
|
35
|
+
const resp2 = await customFetch(url.toString());
|
|
34
36
|
if (!resp2.ok) {
|
|
35
37
|
const body = await resp2.text();
|
|
36
38
|
throw new Error(
|
|
@@ -42,7 +44,7 @@ async function fetchPythPayloads(options) {
|
|
|
42
44
|
},
|
|
43
45
|
{ attempts: 3, exponent: 2, interval: 200 }
|
|
44
46
|
);
|
|
45
|
-
const result = respToCalldata(resp);
|
|
47
|
+
const result = respToCalldata(resp, returnPrices);
|
|
46
48
|
if (result.length !== ids.length) {
|
|
47
49
|
if (ignoreMissingFeeds) {
|
|
48
50
|
logger?.warn(`expected ${ids.length} price feeds, got ${result.length}`);
|
|
@@ -54,13 +56,23 @@ async function fetchPythPayloads(options) {
|
|
|
54
56
|
}
|
|
55
57
|
return result;
|
|
56
58
|
}
|
|
57
|
-
function respToCalldata(resp) {
|
|
59
|
+
function respToCalldata(resp, returnPrices) {
|
|
58
60
|
if (resp.binary.data.length === 0) {
|
|
59
61
|
return [];
|
|
60
62
|
}
|
|
61
63
|
const updates = splitAccumulatorUpdates(resp.binary.data[0]);
|
|
64
|
+
const priceMap = /* @__PURE__ */ new Map();
|
|
65
|
+
if (returnPrices && resp.parsed) {
|
|
66
|
+
for (const feed of resp.parsed) {
|
|
67
|
+
const feedId = feed.id.startsWith("0x") ? feed.id : `0x${feed.id}`;
|
|
68
|
+
priceMap.set(feedId.toLowerCase(), {
|
|
69
|
+
price: BigInt(feed.price.price),
|
|
70
|
+
decimals: Math.abs(feed.price.expo)
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
62
74
|
return updates.map(({ data, dataFeedId, timestamp }) => {
|
|
63
|
-
|
|
75
|
+
const base = {
|
|
64
76
|
dataFeedId,
|
|
65
77
|
data: encodeAbiParameters(
|
|
66
78
|
[{ type: "uint256" }, { type: "bytes[]" }],
|
|
@@ -69,6 +81,18 @@ function respToCalldata(resp) {
|
|
|
69
81
|
timestamp,
|
|
70
82
|
cached: false
|
|
71
83
|
};
|
|
84
|
+
if (returnPrices) {
|
|
85
|
+
const priceInfo = priceMap.get(dataFeedId.toLowerCase());
|
|
86
|
+
if (!priceInfo) {
|
|
87
|
+
throw new Error(`Price info not found for feed ${dataFeedId}`);
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
...base,
|
|
91
|
+
price: priceInfo.price,
|
|
92
|
+
decimals: priceInfo.decimals
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
return base;
|
|
72
96
|
});
|
|
73
97
|
}
|
|
74
98
|
function splitAccumulatorUpdates(binary) {
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
getSignersForDataServiceId
|
|
7
7
|
} from "@redstone-finance/sdk";
|
|
8
|
+
import { MathUtils } from "@redstone-finance/utils";
|
|
8
9
|
import { encodeAbiParameters, toBytes } from "viem";
|
|
9
10
|
import { retry } from "../../../utils/index.js";
|
|
10
11
|
async function fetchRedstonePayloads(options) {
|
|
@@ -16,7 +17,8 @@ async function fetchRedstonePayloads(options) {
|
|
|
16
17
|
gateways,
|
|
17
18
|
ignoreMissingFeeds,
|
|
18
19
|
enableLogging,
|
|
19
|
-
logger
|
|
20
|
+
logger,
|
|
21
|
+
returnPrices
|
|
20
22
|
} = options;
|
|
21
23
|
const metadataTimestampMs = historicalTimestampMs ?? options.metadataTimestampMs;
|
|
22
24
|
const dataPackagesIds = Array.from(new Set(dataFeedsIds));
|
|
@@ -69,7 +71,8 @@ async function fetchRedstonePayloads(options) {
|
|
|
69
71
|
getCalldataWithTimestamp(
|
|
70
72
|
dataFeedId,
|
|
71
73
|
signedDataPackages,
|
|
72
|
-
wrapper.getUnsignedMetadata()
|
|
74
|
+
wrapper.getUnsignedMetadata(),
|
|
75
|
+
returnPrices
|
|
73
76
|
)
|
|
74
77
|
);
|
|
75
78
|
}
|
|
@@ -94,7 +97,7 @@ function groupDataPackages(signedDataPackages) {
|
|
|
94
97
|
}
|
|
95
98
|
return packagesByDataFeedId;
|
|
96
99
|
}
|
|
97
|
-
function getCalldataWithTimestamp(dataFeedId, packages, unsignedMetadata) {
|
|
100
|
+
function getCalldataWithTimestamp(dataFeedId, packages, unsignedMetadata, returnPrices) {
|
|
98
101
|
const originalPayload = RedstonePayload.prepare(packages, unsignedMetadata);
|
|
99
102
|
const originalPayloadLength = originalPayload.length / 2;
|
|
100
103
|
const bytesToAdd = 32 - originalPayloadLength % 32;
|
|
@@ -109,7 +112,7 @@ function getCalldataWithTimestamp(dataFeedId, packages, unsignedMetadata) {
|
|
|
109
112
|
throw new Error("Timestamps are not equal");
|
|
110
113
|
}
|
|
111
114
|
}
|
|
112
|
-
|
|
115
|
+
const base = {
|
|
113
116
|
dataFeedId,
|
|
114
117
|
data: encodeAbiParameters(
|
|
115
118
|
[{ type: "uint256" }, { type: "bytes" }],
|
|
@@ -118,6 +121,16 @@ function getCalldataWithTimestamp(dataFeedId, packages, unsignedMetadata) {
|
|
|
118
121
|
timestamp,
|
|
119
122
|
cached: false
|
|
120
123
|
};
|
|
124
|
+
if (returnPrices) {
|
|
125
|
+
const prices = packages.flatMap((p) => p.dataPackage.dataPoints).map((dp) => BigInt(`0x${Buffer.from(dp.value).toString("hex")}`));
|
|
126
|
+
const medianPrice = BigInt(MathUtils.getMedianOfBigNumbers(prices));
|
|
127
|
+
return {
|
|
128
|
+
...base,
|
|
129
|
+
price: medianPrice,
|
|
130
|
+
decimals: 8
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
return base;
|
|
121
134
|
}
|
|
122
135
|
export {
|
|
123
136
|
fetchRedstonePayloads
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ILogger } from "../../../types/logger.js";
|
|
2
|
-
import type { TimestampedCalldata } from "./types.js";
|
|
2
|
+
import type { TimestampedCalldata, TimestampedCalldataWithPrice } from "./types.js";
|
|
3
3
|
export interface FetchPythPayloadsOptions {
|
|
4
4
|
/**
|
|
5
5
|
* Feeds to fetch
|
|
@@ -21,10 +21,25 @@ export interface FetchPythPayloadsOptions {
|
|
|
21
21
|
* Logger to use
|
|
22
22
|
*/
|
|
23
23
|
logger?: ILogger;
|
|
24
|
+
/**
|
|
25
|
+
* Custom fetch function to use instead of global fetch.
|
|
26
|
+
* Can be used to add custom headers, authentication, or use a different HTTP client.
|
|
27
|
+
*/
|
|
28
|
+
customFetch?: typeof fetch;
|
|
29
|
+
/**
|
|
30
|
+
* When true, returns the price data for each feed.
|
|
31
|
+
*/
|
|
32
|
+
returnPrices?: boolean;
|
|
24
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Fetches pyth payloads from Hermes API with price data
|
|
36
|
+
*/
|
|
37
|
+
export declare function fetchPythPayloads(options: FetchPythPayloadsOptions & {
|
|
38
|
+
returnPrices: true;
|
|
39
|
+
}): Promise<TimestampedCalldataWithPrice[]>;
|
|
25
40
|
/**
|
|
26
41
|
* Fetches pyth payloads from Hermes API
|
|
27
|
-
* @param dataFeedsIds
|
|
28
|
-
* @returns
|
|
29
42
|
*/
|
|
30
|
-
export declare function fetchPythPayloads(options: FetchPythPayloadsOptions
|
|
43
|
+
export declare function fetchPythPayloads(options: FetchPythPayloadsOptions & {
|
|
44
|
+
returnPrices?: false;
|
|
45
|
+
}): Promise<TimestampedCalldata[]>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ILogger } from "../../../types/logger.js";
|
|
2
|
-
import type { TimestampedCalldata } from "./types.js";
|
|
2
|
+
import type { TimestampedCalldata, TimestampedCalldataWithPrice } from "./types.js";
|
|
3
3
|
export interface FetchRedstonePayloadsOptions {
|
|
4
4
|
/**
|
|
5
5
|
* Redstone data service id
|
|
@@ -40,5 +40,20 @@ export interface FetchRedstonePayloadsOptions {
|
|
|
40
40
|
* Logger to use
|
|
41
41
|
*/
|
|
42
42
|
logger?: ILogger;
|
|
43
|
+
/**
|
|
44
|
+
* When true, returns the price data for each feed.
|
|
45
|
+
*/
|
|
46
|
+
returnPrices?: boolean;
|
|
43
47
|
}
|
|
44
|
-
|
|
48
|
+
/**
|
|
49
|
+
* Fetches redstone payloads with price data
|
|
50
|
+
*/
|
|
51
|
+
export declare function fetchRedstonePayloads(options: FetchRedstonePayloadsOptions & {
|
|
52
|
+
returnPrices: true;
|
|
53
|
+
}): Promise<TimestampedCalldataWithPrice[]>;
|
|
54
|
+
/**
|
|
55
|
+
* Fetches redstone payloads
|
|
56
|
+
*/
|
|
57
|
+
export declare function fetchRedstonePayloads(options: FetchRedstonePayloadsOptions & {
|
|
58
|
+
returnPrices?: false;
|
|
59
|
+
}): Promise<TimestampedCalldata[]>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gearbox-protocol/sdk",
|
|
3
|
-
"version": "12.6.0-next.
|
|
3
|
+
"version": "12.6.0-next.4",
|
|
4
4
|
"description": "Gearbox SDK",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "./dist/cjs/sdk/index.js",
|
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
"@redstone-finance/evm-connector": "^0.9.0",
|
|
56
56
|
"@redstone-finance/protocol": "^0.9.0",
|
|
57
57
|
"@redstone-finance/sdk": "^0.9.0",
|
|
58
|
+
"@redstone-finance/utils": "^0.9.0",
|
|
58
59
|
"@types/bn.js": "^5.2.0",
|
|
59
60
|
"abitype": "^1.2.3",
|
|
60
61
|
"bn.js": "^5.2.2",
|