@d8x/perpetuals-sdk 0.7.5 → 0.7.6
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/accountTrade.js +134 -239
- package/dist/cjs/accountTrade.js.map +1 -1
- package/dist/cjs/brokerTool.js +144 -290
- package/dist/cjs/brokerTool.js.map +1 -1
- package/dist/cjs/contracts/factories/ERC20__factory.js +9 -12
- package/dist/cjs/contracts/factories/ERC20__factory.js.map +1 -1
- package/dist/cjs/contracts/factories/IPerpetualManager__factory.js +9 -12
- package/dist/cjs/contracts/factories/IPerpetualManager__factory.js.map +1 -1
- package/dist/cjs/contracts/factories/LimitOrderBookFactory__factory.js +9 -12
- package/dist/cjs/contracts/factories/LimitOrderBookFactory__factory.js.map +1 -1
- package/dist/cjs/contracts/factories/LimitOrderBook__factory.js +9 -12
- package/dist/cjs/contracts/factories/LimitOrderBook__factory.js.map +1 -1
- package/dist/cjs/contracts/factories/MockTokenSwap__factory.js +9 -12
- package/dist/cjs/contracts/factories/MockTokenSwap__factory.js.map +1 -1
- package/dist/cjs/contracts/factories/ShareToken__factory.js +9 -12
- package/dist/cjs/contracts/factories/ShareToken__factory.js.map +1 -1
- package/dist/cjs/contracts/factories/zkevmTestnet/IPerpetualManager__factory.js +9 -12
- package/dist/cjs/contracts/factories/zkevmTestnet/IPerpetualManager__factory.js.map +1 -1
- package/dist/cjs/contracts/factories/zkevmTestnet/LimitOrderBookFactory__factory.js +9 -12
- package/dist/cjs/contracts/factories/zkevmTestnet/LimitOrderBookFactory__factory.js.map +1 -1
- package/dist/cjs/contracts/factories/zkevmTestnet/LimitOrderBook__factory.js +9 -12
- package/dist/cjs/contracts/factories/zkevmTestnet/LimitOrderBook__factory.js.map +1 -1
- package/dist/cjs/contracts/factories/zkevmTestnet/ShareToken__factory.js +9 -12
- package/dist/cjs/contracts/factories/zkevmTestnet/ShareToken__factory.js.map +1 -1
- package/dist/cjs/contracts/index.js +1 -1
- package/dist/cjs/d8XMath.d.ts +7 -0
- package/dist/cjs/d8XMath.js +81 -61
- package/dist/cjs/d8XMath.js.map +1 -1
- package/dist/cjs/index.js +11 -11
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/liquidatorTool.js +80 -137
- package/dist/cjs/liquidatorTool.js.map +1 -1
- package/dist/cjs/liquidityProviderTool.js +33 -64
- package/dist/cjs/liquidityProviderTool.js.map +1 -1
- package/dist/cjs/marketData.js +635 -978
- package/dist/cjs/marketData.js.map +1 -1
- package/dist/cjs/nodeSDKTypes.d.ts +1 -0
- package/dist/cjs/nodeSDKTypes.js +10 -22
- package/dist/cjs/nodeSDKTypes.js.map +1 -1
- package/dist/cjs/orderReferrerTool.js +200 -321
- package/dist/cjs/orderReferrerTool.js.map +1 -1
- package/dist/cjs/perpetualDataHandler.d.ts +11 -0
- package/dist/cjs/perpetualDataHandler.js +422 -535
- package/dist/cjs/perpetualDataHandler.js.map +1 -1
- package/dist/cjs/perpetualEventHandler.js +129 -190
- package/dist/cjs/perpetualEventHandler.js.map +1 -1
- package/dist/cjs/priceFeeds.js +223 -335
- package/dist/cjs/priceFeeds.js.map +1 -1
- package/dist/cjs/traderDigests.js +20 -23
- package/dist/cjs/traderDigests.js.map +1 -1
- package/dist/cjs/traderInterface.js +54 -87
- package/dist/cjs/traderInterface.js.map +1 -1
- package/dist/cjs/triangulator.js +34 -38
- package/dist/cjs/triangulator.js.map +1 -1
- package/dist/cjs/utils.js +18 -32
- package/dist/cjs/utils.js.map +1 -1
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/writeAccessHandler.js +78 -112
- package/dist/cjs/writeAccessHandler.js.map +1 -1
- package/dist/esm/accountTrade.js +126 -233
- package/dist/esm/accountTrade.js.map +1 -1
- package/dist/esm/brokerTool.js +136 -284
- package/dist/esm/brokerTool.js.map +1 -1
- package/dist/esm/contracts/factories/ERC20__factory.js +8 -12
- package/dist/esm/contracts/factories/ERC20__factory.js.map +1 -1
- package/dist/esm/contracts/factories/IPerpetualManager__factory.js +8 -12
- package/dist/esm/contracts/factories/IPerpetualManager__factory.js.map +1 -1
- package/dist/esm/contracts/factories/LimitOrderBookFactory__factory.js +8 -12
- package/dist/esm/contracts/factories/LimitOrderBookFactory__factory.js.map +1 -1
- package/dist/esm/contracts/factories/LimitOrderBook__factory.js +8 -12
- package/dist/esm/contracts/factories/LimitOrderBook__factory.js.map +1 -1
- package/dist/esm/contracts/factories/MockTokenSwap__factory.js +8 -12
- package/dist/esm/contracts/factories/MockTokenSwap__factory.js.map +1 -1
- package/dist/esm/contracts/factories/ShareToken__factory.js +8 -12
- package/dist/esm/contracts/factories/ShareToken__factory.js.map +1 -1
- package/dist/esm/contracts/factories/zkevmTestnet/IPerpetualManager__factory.js +8 -12
- package/dist/esm/contracts/factories/zkevmTestnet/IPerpetualManager__factory.js.map +1 -1
- package/dist/esm/contracts/factories/zkevmTestnet/LimitOrderBookFactory__factory.js +8 -12
- package/dist/esm/contracts/factories/zkevmTestnet/LimitOrderBookFactory__factory.js.map +1 -1
- package/dist/esm/contracts/factories/zkevmTestnet/LimitOrderBook__factory.js +8 -12
- package/dist/esm/contracts/factories/zkevmTestnet/LimitOrderBook__factory.js.map +1 -1
- package/dist/esm/contracts/factories/zkevmTestnet/ShareToken__factory.js +8 -12
- package/dist/esm/contracts/factories/zkevmTestnet/ShareToken__factory.js.map +1 -1
- package/dist/esm/d8XMath.d.ts +7 -0
- package/dist/esm/d8XMath.js +77 -58
- package/dist/esm/d8XMath.js.map +1 -1
- package/dist/esm/liquidatorTool.js +77 -136
- package/dist/esm/liquidatorTool.js.map +1 -1
- package/dist/esm/liquidityProviderTool.js +30 -63
- package/dist/esm/liquidityProviderTool.js.map +1 -1
- package/dist/esm/marketData.js +626 -971
- package/dist/esm/marketData.js.map +1 -1
- package/dist/esm/nodeSDKTypes.d.ts +1 -0
- package/dist/esm/nodeSDKTypes.js +36 -48
- package/dist/esm/nodeSDKTypes.js.map +1 -1
- package/dist/esm/orderReferrerTool.js +194 -317
- package/dist/esm/orderReferrerTool.js.map +1 -1
- package/dist/esm/perpetualDataHandler.d.ts +11 -0
- package/dist/esm/perpetualDataHandler.js +413 -528
- package/dist/esm/perpetualDataHandler.js.map +1 -1
- package/dist/esm/perpetualEventHandler.js +126 -188
- package/dist/esm/perpetualEventHandler.js.map +1 -1
- package/dist/esm/priceFeeds.js +218 -332
- package/dist/esm/priceFeeds.js.map +1 -1
- package/dist/esm/traderDigests.js +15 -19
- package/dist/esm/traderDigests.js.map +1 -1
- package/dist/esm/traderInterface.js +48 -83
- package/dist/esm/traderInterface.js.map +1 -1
- package/dist/esm/triangulator.js +34 -39
- package/dist/esm/triangulator.js.map +1 -1
- package/dist/esm/utils.js +16 -30
- package/dist/esm/utils.js.map +1 -1
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/version.js.map +1 -1
- package/dist/esm/writeAccessHandler.js +70 -106
- package/dist/esm/writeAccessHandler.js.map +1 -1
- package/package.json +1 -1
- package/src/d8XMath.ts +21 -0
- package/src/liquidityProviderTool.ts +5 -4
- package/src/nodeSDKTypes.ts +1 -0
- package/src/perpetualDataHandler.ts +27 -0
- package/src/version.ts +1 -1
- package/src/writeAccessHandler.ts +3 -3
package/dist/esm/priceFeeds.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { __awaiter, __generator, __read, __values } from "tslib";
|
|
2
1
|
import { BigNumber } from "@ethersproject/bignumber";
|
|
3
2
|
import Triangulator from "./triangulator";
|
|
4
3
|
import { decNToFloat } from "./d8XMath";
|
|
@@ -8,13 +7,12 @@ import { Buffer } from "buffer";
|
|
|
8
7
|
* to be submitted to the smart contracts for certain functions such as
|
|
9
8
|
* trader liquidations, trade executions, change of trader margin amount.
|
|
10
9
|
*/
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
var _a;
|
|
10
|
+
export default class PriceFeeds {
|
|
11
|
+
constructor(dataHandler, priceFeedConfigNetwork) {
|
|
14
12
|
this.THRESHOLD_MARKET_CLOSED_SEC = 15; // smallest lag for which we consider the market as being closed
|
|
15
|
-
|
|
13
|
+
let configs = require("./config/priceFeedConfig.json");
|
|
16
14
|
this.config = PriceFeeds._selectConfig(configs, priceFeedConfigNetwork);
|
|
17
|
-
|
|
15
|
+
[this.feedInfo, this.feedEndpoints] = PriceFeeds._constructFeedInfo(this.config);
|
|
18
16
|
this.dataHandler = dataHandler;
|
|
19
17
|
this.triangulations = new Map();
|
|
20
18
|
}
|
|
@@ -22,140 +20,84 @@ var PriceFeeds = /** @class */ (function () {
|
|
|
22
20
|
* Pre-processing of triangulations for symbols, given the price feeds
|
|
23
21
|
* @param symbols set of symbols we want to triangulate from price feeds
|
|
24
22
|
*/
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
for (var _c = __values(this.feedInfo), _d = _c.next(); !_d.done; _d = _c.next()) {
|
|
30
|
-
var _e = __read(_d.value, 2), value = _e[1];
|
|
31
|
-
feedSymbols.push(value.symbol);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
35
|
-
finally {
|
|
36
|
-
try {
|
|
37
|
-
if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
|
|
38
|
-
}
|
|
39
|
-
finally { if (e_1) throw e_1.error; }
|
|
23
|
+
initializeTriangulations(symbols) {
|
|
24
|
+
let feedSymbols = new Array();
|
|
25
|
+
for (let [, value] of this.feedInfo) {
|
|
26
|
+
feedSymbols.push(value.symbol);
|
|
40
27
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
var triangulation = Triangulator.triangulate(feedSymbols, symbol);
|
|
45
|
-
this.triangulations.set(symbol, triangulation);
|
|
46
|
-
}
|
|
28
|
+
for (let symbol of symbols.values()) {
|
|
29
|
+
let triangulation = Triangulator.triangulate(feedSymbols, symbol);
|
|
30
|
+
this.triangulations.set(symbol, triangulation);
|
|
47
31
|
}
|
|
48
|
-
|
|
49
|
-
finally {
|
|
50
|
-
try {
|
|
51
|
-
if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
|
|
52
|
-
}
|
|
53
|
-
finally { if (e_2) throw e_2.error; }
|
|
54
|
-
}
|
|
55
|
-
};
|
|
32
|
+
}
|
|
56
33
|
/**
|
|
57
34
|
* Get required information to be able to submit a blockchain transaction with price-update
|
|
58
35
|
* such as trade execution, liquidation
|
|
59
36
|
* @param symbol symbol of perpetual, e.g., BTC-USD-MATIC
|
|
60
37
|
* @returns PriceFeedSubmission, index prices, market closed information
|
|
61
38
|
*/
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
idxPrices[1] = _idxPrices[1];
|
|
77
|
-
mktClosed[1] = _mktClosed[1];
|
|
78
|
-
}
|
|
79
|
-
return [2 /*return*/, { submission: submission, pxS2S3: idxPrices, mktClosed: mktClosed }];
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
};
|
|
39
|
+
async fetchFeedPriceInfoAndIndicesForPerpetual(symbol) {
|
|
40
|
+
let indexSymbols = this.dataHandler.getIndexSymbols(symbol);
|
|
41
|
+
// fetch prices from required price-feeds (REST)
|
|
42
|
+
let submission = await this.fetchLatestFeedPriceInfoForPerpetual(symbol);
|
|
43
|
+
// calculate index-prices from price-feeds
|
|
44
|
+
let [_idxPrices, _mktClosed] = this.calculateTriangulatedPricesFromFeedInfo(indexSymbols.filter((x) => x != ""), submission);
|
|
45
|
+
let idxPrices = [_idxPrices[0], 0];
|
|
46
|
+
let mktClosed = [_mktClosed[0], false];
|
|
47
|
+
if (idxPrices.length > 1) {
|
|
48
|
+
idxPrices[1] = _idxPrices[1];
|
|
49
|
+
mktClosed[1] = _mktClosed[1];
|
|
50
|
+
}
|
|
51
|
+
return { submission: submission, pxS2S3: idxPrices, mktClosed: mktClosed };
|
|
52
|
+
}
|
|
84
53
|
/**
|
|
85
54
|
* Get all prices/isMarketClosed for the provided symbols via
|
|
86
55
|
* "latest_price_feeds" and triangulation. Triangulation must be defined in config, unless
|
|
87
56
|
* it is a direct price feed.
|
|
88
57
|
* @returns map of feed-price symbol to price/isMarketClosed
|
|
89
58
|
*/
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
symMap = new Map();
|
|
100
|
-
for (k = 0; k < symbols.length; k++) {
|
|
101
|
-
symMap.set(symbols[k], [prices[k], mktClosed[k]]);
|
|
102
|
-
}
|
|
103
|
-
return [2 /*return*/, symMap];
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
};
|
|
59
|
+
async fetchPrices(symbols) {
|
|
60
|
+
let feedPrices = await this.fetchAllFeedPrices();
|
|
61
|
+
let [prices, mktClosed] = this.triangulatePricesFromFeedPrices(symbols, feedPrices);
|
|
62
|
+
let symMap = new Map();
|
|
63
|
+
for (let k = 0; k < symbols.length; k++) {
|
|
64
|
+
symMap.set(symbols[k], [prices[k], mktClosed[k]]);
|
|
65
|
+
}
|
|
66
|
+
return symMap;
|
|
67
|
+
}
|
|
108
68
|
/**
|
|
109
69
|
* Get index prices and market closed information for the given perpetual
|
|
110
70
|
* @param symbol perpetual symbol such as ETH-USD-MATIC
|
|
111
71
|
* @returns Index prices and market closed information
|
|
112
72
|
*/
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
for (indexSymbols_1 = __values(indexSymbols), indexSymbols_1_1 = indexSymbols_1.next(); !indexSymbols_1_1.done; indexSymbols_1_1 = indexSymbols_1.next()) {
|
|
124
|
-
sym = indexSymbols_1_1.value;
|
|
125
|
-
if (sym != "") {
|
|
126
|
-
triang = this.triangulations.get(sym);
|
|
127
|
-
if (triang == undefined) {
|
|
128
|
-
// no triangulation defined, so symbol must be a feed (unless misconfigured)
|
|
129
|
-
feedSymbols.push(sym);
|
|
130
|
-
}
|
|
131
|
-
else {
|
|
132
|
-
// push all required feeds to array
|
|
133
|
-
triang[0].map(function (feedSym) { return feedSymbols.push(feedSym); });
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
139
|
-
finally {
|
|
140
|
-
try {
|
|
141
|
-
if (indexSymbols_1_1 && !indexSymbols_1_1.done && (_b = indexSymbols_1.return)) _b.call(indexSymbols_1);
|
|
142
|
-
}
|
|
143
|
-
finally { if (e_3) throw e_3.error; }
|
|
144
|
-
}
|
|
145
|
-
return [4 /*yield*/, this.fetchFeedPrices(feedSymbols)];
|
|
146
|
-
case 1:
|
|
147
|
-
feedPrices = _c.sent();
|
|
148
|
-
_a = __read(this.triangulatePricesFromFeedPrices(indexSymbols, feedPrices), 2), prices = _a[0], mktClosed = _a[1];
|
|
149
|
-
// ensure we return an array of 2 in all cases
|
|
150
|
-
if (prices.length == 1) {
|
|
151
|
-
prices.push(0);
|
|
152
|
-
mktClosed.push(false);
|
|
153
|
-
}
|
|
154
|
-
return [2 /*return*/, { idxPrices: prices, mktClosed: mktClosed }];
|
|
73
|
+
async fetchPricesForPerpetual(symbol) {
|
|
74
|
+
let indexSymbols = this.dataHandler.getIndexSymbols(symbol).filter((x) => x != "");
|
|
75
|
+
// determine relevant price feeds
|
|
76
|
+
let feedSymbols = new Array();
|
|
77
|
+
for (let sym of indexSymbols) {
|
|
78
|
+
if (sym != "") {
|
|
79
|
+
let triang = this.triangulations.get(sym);
|
|
80
|
+
if (triang == undefined) {
|
|
81
|
+
// no triangulation defined, so symbol must be a feed (unless misconfigured)
|
|
82
|
+
feedSymbols.push(sym);
|
|
155
83
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
84
|
+
else {
|
|
85
|
+
// push all required feeds to array
|
|
86
|
+
triang[0].map((feedSym) => feedSymbols.push(feedSym));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// get all feed prices
|
|
91
|
+
let feedPrices = await this.fetchFeedPrices(feedSymbols);
|
|
92
|
+
// triangulate
|
|
93
|
+
let [prices, mktClosed] = this.triangulatePricesFromFeedPrices(indexSymbols, feedPrices);
|
|
94
|
+
// ensure we return an array of 2 in all cases
|
|
95
|
+
if (prices.length == 1) {
|
|
96
|
+
prices.push(0);
|
|
97
|
+
mktClosed.push(false);
|
|
98
|
+
}
|
|
99
|
+
return { idxPrices: prices, mktClosed: mktClosed };
|
|
100
|
+
}
|
|
159
101
|
/**
|
|
160
102
|
* Fetch the provided feed prices and bool whether market is closed or open
|
|
161
103
|
* - requires the feeds to be defined in priceFeedConfig.json
|
|
@@ -163,68 +105,49 @@ var PriceFeeds = /** @class */ (function () {
|
|
|
163
105
|
* @param symbols array of feed-price symbols (e.g., [btc-usd, eth-usd]) or undefined
|
|
164
106
|
* @returns mapping symbol-> [price, isMarketClosed]
|
|
165
107
|
*/
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
tsSecNow = Math.round(Date.now() / 1000);
|
|
203
|
-
for (j = 0; j < pxInfo.length; j++) {
|
|
204
|
-
price = decNToFloat(BigNumber.from(pxInfo[j].price), -pxInfo[j].expo);
|
|
205
|
-
isMarketClosed = tsSecNow - pxInfo[j].publish_time > this.THRESHOLD_MARKET_CLOSED_SEC;
|
|
206
|
-
resultPrices.set(symbolsOfEndpoint[k][j], [price, isMarketClosed]);
|
|
207
|
-
}
|
|
208
|
-
_b.label = 3;
|
|
209
|
-
case 3:
|
|
210
|
-
k++;
|
|
211
|
-
return [3 /*break*/, 1];
|
|
212
|
-
case 4: return [2 /*return*/, resultPrices];
|
|
213
|
-
}
|
|
214
|
-
});
|
|
215
|
-
});
|
|
216
|
-
};
|
|
108
|
+
async fetchFeedPrices(symbols) {
|
|
109
|
+
let queries = new Array(this.feedEndpoints.length);
|
|
110
|
+
let symbolsOfEndpoint = [];
|
|
111
|
+
for (let j = 0; j < queries.length; j++) {
|
|
112
|
+
symbolsOfEndpoint.push([]);
|
|
113
|
+
}
|
|
114
|
+
for (let k = 0; k < this.config.ids.length; k++) {
|
|
115
|
+
let currFeed = this.config.ids[k];
|
|
116
|
+
if (symbols != undefined && !symbols.includes(currFeed.symbol)) {
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
// feedInfo: Map<string, {symbol:string, endpointId: number}>; // priceFeedId -> symbol, endpointId
|
|
120
|
+
let endpointId = this.feedInfo.get(currFeed.id).endpointId;
|
|
121
|
+
symbolsOfEndpoint[endpointId].push(currFeed.symbol);
|
|
122
|
+
if (queries[endpointId] == undefined) {
|
|
123
|
+
// each id can have a different endpoint, but we cluster
|
|
124
|
+
// the queries into one per endpoint
|
|
125
|
+
queries[endpointId] = this.feedEndpoints[endpointId] + "/latest_price_feeds?";
|
|
126
|
+
}
|
|
127
|
+
queries[endpointId] = queries[endpointId] + "ids[]=" + currFeed.id + "&";
|
|
128
|
+
}
|
|
129
|
+
let resultPrices = new Map();
|
|
130
|
+
for (let k = 0; k < queries.length; k++) {
|
|
131
|
+
if (queries[k] == undefined) {
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
let [, pxInfo] = await this.fetchPriceQuery(queries[k]);
|
|
135
|
+
let tsSecNow = Math.round(Date.now() / 1000);
|
|
136
|
+
for (let j = 0; j < pxInfo.length; j++) {
|
|
137
|
+
let price = decNToFloat(BigNumber.from(pxInfo[j].price), -pxInfo[j].expo);
|
|
138
|
+
let isMarketClosed = tsSecNow - pxInfo[j].publish_time > this.THRESHOLD_MARKET_CLOSED_SEC;
|
|
139
|
+
resultPrices.set(symbolsOfEndpoint[k][j], [price, isMarketClosed]);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return resultPrices;
|
|
143
|
+
}
|
|
217
144
|
/**
|
|
218
145
|
* Get all configured feed prices via "latest_price_feeds"
|
|
219
146
|
* @returns map of feed-price symbol to price/isMarketClosed
|
|
220
147
|
*/
|
|
221
|
-
|
|
222
|
-
return
|
|
223
|
-
|
|
224
|
-
return [2 /*return*/, this.fetchFeedPrices()];
|
|
225
|
-
});
|
|
226
|
-
});
|
|
227
|
-
};
|
|
148
|
+
async fetchAllFeedPrices() {
|
|
149
|
+
return this.fetchFeedPrices();
|
|
150
|
+
}
|
|
228
151
|
/**
|
|
229
152
|
* Get the latest prices for a given perpetual from the offchain oracle
|
|
230
153
|
* networks
|
|
@@ -232,75 +155,64 @@ var PriceFeeds = /** @class */ (function () {
|
|
|
232
155
|
* @returns array of price feed updates that can be submitted to the smart contract
|
|
233
156
|
* and corresponding price information
|
|
234
157
|
*/
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
return [2 /*return*/, {
|
|
294
|
-
symbols: symbols,
|
|
295
|
-
priceFeedVaas: priceFeedUpdates,
|
|
296
|
-
prices: prices,
|
|
297
|
-
isMarketClosed: mktClosed,
|
|
298
|
-
timestamps: timestamps,
|
|
299
|
-
}];
|
|
300
|
-
}
|
|
301
|
-
});
|
|
302
|
-
});
|
|
303
|
-
};
|
|
158
|
+
async fetchLatestFeedPriceInfoForPerpetual(symbol) {
|
|
159
|
+
let feedIds = this.dataHandler.getPriceIds(symbol);
|
|
160
|
+
let queries = new Array(this.feedEndpoints.length);
|
|
161
|
+
// we need to preserve the order of the price feeds
|
|
162
|
+
let orderEndpointNumber = new Array();
|
|
163
|
+
// count how many prices per endpoint
|
|
164
|
+
let idCountPriceFeeds = new Array(this.feedEndpoints.length);
|
|
165
|
+
let symbols = new Array();
|
|
166
|
+
for (let k = 0; k < feedIds.length; k++) {
|
|
167
|
+
let info = this.feedInfo.get(feedIds[k]);
|
|
168
|
+
if (info == undefined) {
|
|
169
|
+
throw new Error(`priceFeeds: config for symbol ${symbol} insufficient`);
|
|
170
|
+
}
|
|
171
|
+
let id = info.endpointId;
|
|
172
|
+
symbols.push(info.symbol);
|
|
173
|
+
if (queries[id] == undefined) {
|
|
174
|
+
// each id can have a different endpoint, but we cluster
|
|
175
|
+
// the queries into one per endpoint
|
|
176
|
+
queries[id] = this.feedEndpoints[id] + "/latest_price_feeds?target_chain=default&";
|
|
177
|
+
idCountPriceFeeds[id] = 0;
|
|
178
|
+
}
|
|
179
|
+
queries[id] = queries[id] + "ids[]=" + feedIds[k] + "&";
|
|
180
|
+
orderEndpointNumber.push(id * 100 + idCountPriceFeeds[id]);
|
|
181
|
+
idCountPriceFeeds[id] = idCountPriceFeeds[id] + 1;
|
|
182
|
+
}
|
|
183
|
+
let data = await Promise.all(queries.map(async (q) => {
|
|
184
|
+
if (q != undefined) {
|
|
185
|
+
return this.fetchVAAQuery(q);
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
return [[], []];
|
|
189
|
+
}
|
|
190
|
+
}));
|
|
191
|
+
// re-order arrays so we preserve the order of the feeds
|
|
192
|
+
const priceFeedUpdates = new Array();
|
|
193
|
+
const prices = new Array();
|
|
194
|
+
const mktClosed = new Array();
|
|
195
|
+
const timestamps = new Array();
|
|
196
|
+
const tsSecNow = Math.round(Date.now() / 1000);
|
|
197
|
+
for (let k = 0; k < orderEndpointNumber.length; k++) {
|
|
198
|
+
let endpointId = Math.floor(orderEndpointNumber[k] / 100);
|
|
199
|
+
let idWithinEndpoint = orderEndpointNumber[k] - 100 * endpointId;
|
|
200
|
+
priceFeedUpdates.push(data[endpointId][0][idWithinEndpoint]);
|
|
201
|
+
let pxInfo = data[endpointId][1][idWithinEndpoint];
|
|
202
|
+
let price = decNToFloat(BigNumber.from(pxInfo.price), -pxInfo.expo);
|
|
203
|
+
let isMarketClosed = tsSecNow - pxInfo.publish_time > this.THRESHOLD_MARKET_CLOSED_SEC;
|
|
204
|
+
mktClosed.push(isMarketClosed);
|
|
205
|
+
prices.push(price);
|
|
206
|
+
timestamps.push(pxInfo.publish_time);
|
|
207
|
+
}
|
|
208
|
+
return {
|
|
209
|
+
symbols: symbols,
|
|
210
|
+
priceFeedVaas: priceFeedUpdates,
|
|
211
|
+
prices: prices,
|
|
212
|
+
isMarketClosed: mktClosed,
|
|
213
|
+
timestamps: timestamps,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
304
216
|
/**
|
|
305
217
|
* Extract pair-prices from underlying price feeds via triangulation
|
|
306
218
|
* The function either needs a direct price feed or a defined triangulation to succesfully
|
|
@@ -309,13 +221,13 @@ var PriceFeeds = /** @class */ (function () {
|
|
|
309
221
|
* @param feeds data obtained via fetchLatestFeedPriceInfo or fetchLatestFeedPrices
|
|
310
222
|
* @returns array of prices with same order as symbols
|
|
311
223
|
*/
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
for (
|
|
224
|
+
calculateTriangulatedPricesFromFeedInfo(symbols, feeds) {
|
|
225
|
+
let priceMap = new Map();
|
|
226
|
+
for (let j = 0; j < feeds.prices.length; j++) {
|
|
315
227
|
priceMap.set(feeds.symbols[j], [feeds.prices[j], feeds.isMarketClosed[j]]);
|
|
316
228
|
}
|
|
317
229
|
return this.triangulatePricesFromFeedPrices(symbols, priceMap);
|
|
318
|
-
}
|
|
230
|
+
}
|
|
319
231
|
/**
|
|
320
232
|
* Extract pair-prices from underlying price feeds via triangulation
|
|
321
233
|
* The function either needs a direct price feed or a defined triangulation to succesfully
|
|
@@ -324,15 +236,15 @@ var PriceFeeds = /** @class */ (function () {
|
|
|
324
236
|
* @param feeds data obtained via fetchLatestFeedPriceInfo or fetchLatestFeedPrices
|
|
325
237
|
* @returns array of prices with same order as symbols
|
|
326
238
|
*/
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
for (
|
|
331
|
-
|
|
239
|
+
triangulatePricesFromFeedPrices(symbols, feedPriceMap) {
|
|
240
|
+
let prices = new Array();
|
|
241
|
+
let mktClosed = new Array();
|
|
242
|
+
for (let k = 0; k < symbols.length; k++) {
|
|
243
|
+
let triangulation = this.triangulations.get(symbols[k]);
|
|
332
244
|
if (triangulation == undefined) {
|
|
333
|
-
|
|
245
|
+
let feedPrice = feedPriceMap.get(symbols[k]);
|
|
334
246
|
if (feedPrice == undefined) {
|
|
335
|
-
throw new Error(
|
|
247
|
+
throw new Error(`PriceFeeds: no triangulation defined for ${symbols[k]}`);
|
|
336
248
|
}
|
|
337
249
|
else {
|
|
338
250
|
prices.push(feedPrice[0]); //price
|
|
@@ -340,110 +252,86 @@ var PriceFeeds = /** @class */ (function () {
|
|
|
340
252
|
continue;
|
|
341
253
|
}
|
|
342
254
|
}
|
|
343
|
-
|
|
255
|
+
let [px, isMktClosed] = Triangulator.calculateTriangulatedPrice(triangulation, feedPriceMap);
|
|
344
256
|
prices.push(px);
|
|
345
257
|
mktClosed.push(isMktClosed);
|
|
346
258
|
}
|
|
347
259
|
return [prices, mktClosed];
|
|
348
|
-
}
|
|
260
|
+
}
|
|
349
261
|
/**
|
|
350
262
|
* Queries the REST endpoint and returns parsed VAA price data
|
|
351
263
|
* @param query query price-info from endpoint
|
|
352
264
|
* @returns vaa and price info
|
|
353
265
|
*/
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
priceFeedUpdates = new Array();
|
|
371
|
-
px = new Array();
|
|
372
|
-
for (k = 0; k < values.length; k++) {
|
|
373
|
-
vaa = values[k].vaa;
|
|
374
|
-
priceFeedUpdates.push("0x" + Buffer.from(vaa, "base64").toString("hex"));
|
|
375
|
-
px.push(values[k].price);
|
|
376
|
-
}
|
|
377
|
-
return [2 /*return*/, [priceFeedUpdates, px]];
|
|
378
|
-
}
|
|
379
|
-
});
|
|
380
|
-
});
|
|
381
|
-
};
|
|
266
|
+
async fetchVAAQuery(query) {
|
|
267
|
+
const headers = { headers: { "Content-Type": "application/json" } };
|
|
268
|
+
let response = await fetch(query, headers);
|
|
269
|
+
if (!response.ok) {
|
|
270
|
+
throw new Error(`Failed to fetch posts (${response.status}): ${response.statusText}`);
|
|
271
|
+
}
|
|
272
|
+
let values = (await response.json());
|
|
273
|
+
const priceFeedUpdates = new Array();
|
|
274
|
+
const px = new Array();
|
|
275
|
+
for (let k = 0; k < values.length; k++) {
|
|
276
|
+
const vaa = values[k].vaa;
|
|
277
|
+
priceFeedUpdates.push("0x" + Buffer.from(vaa, "base64").toString("hex"));
|
|
278
|
+
px.push(values[k].price);
|
|
279
|
+
}
|
|
280
|
+
return [priceFeedUpdates, px];
|
|
281
|
+
}
|
|
382
282
|
/**
|
|
383
283
|
* Queries the REST endpoint and returns parsed price data
|
|
384
284
|
* @param query query price-info from endpoint
|
|
385
285
|
* @returns vaa and price info
|
|
386
286
|
*/
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
values = _a.sent();
|
|
403
|
-
priceFeedUpdates = new Array();
|
|
404
|
-
px = new Array();
|
|
405
|
-
for (k = 0; k < values.length; k++) {
|
|
406
|
-
priceFeedUpdates.push("0x" + Buffer.from(values[k].id, "base64").toString("hex"));
|
|
407
|
-
px.push(values[k].price);
|
|
408
|
-
}
|
|
409
|
-
return [2 /*return*/, [priceFeedUpdates, px]];
|
|
410
|
-
}
|
|
411
|
-
});
|
|
412
|
-
});
|
|
413
|
-
};
|
|
287
|
+
async fetchPriceQuery(query) {
|
|
288
|
+
const headers = { headers: { "Content-Type": "application/json" } };
|
|
289
|
+
let response = await fetch(query, headers);
|
|
290
|
+
if (!response.ok) {
|
|
291
|
+
throw new Error(`Failed to fetch posts (${response.status}): ${response.statusText}`);
|
|
292
|
+
}
|
|
293
|
+
let values = await response.json();
|
|
294
|
+
const priceFeedUpdates = new Array();
|
|
295
|
+
const px = new Array();
|
|
296
|
+
for (let k = 0; k < values.length; k++) {
|
|
297
|
+
priceFeedUpdates.push("0x" + Buffer.from(values[k].id, "base64").toString("hex"));
|
|
298
|
+
px.push(values[k].price);
|
|
299
|
+
}
|
|
300
|
+
return [priceFeedUpdates, px];
|
|
301
|
+
}
|
|
414
302
|
/**
|
|
415
303
|
* Searches for configuration for given network
|
|
416
304
|
* @param configs pricefeed configuration from json
|
|
417
305
|
* @param network e.g. testnet
|
|
418
306
|
* @returns selected configuration
|
|
419
307
|
*/
|
|
420
|
-
|
|
421
|
-
|
|
308
|
+
static _selectConfig(configs, network) {
|
|
309
|
+
let k = 0;
|
|
422
310
|
while (k < configs.length) {
|
|
423
311
|
if (configs[k].network == network) {
|
|
424
312
|
return configs[k];
|
|
425
313
|
}
|
|
426
314
|
k = k + 1;
|
|
427
315
|
}
|
|
428
|
-
throw new Error(
|
|
429
|
-
}
|
|
316
|
+
throw new Error(`PriceFeeds: config not found for network ${network}`);
|
|
317
|
+
}
|
|
430
318
|
/**
|
|
431
319
|
* Wraps configuration into convenient data-structure
|
|
432
320
|
* @param config configuration for the selected network
|
|
433
321
|
* @returns feedInfo-map and endPoints-array
|
|
434
322
|
*/
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
for (
|
|
323
|
+
static _constructFeedInfo(config) {
|
|
324
|
+
let feed = new Map();
|
|
325
|
+
let endpointId = -1;
|
|
326
|
+
let type = "";
|
|
327
|
+
let feedEndpoints = new Array();
|
|
328
|
+
for (let k = 0; k < config.endpoints.length; k++) {
|
|
441
329
|
feedEndpoints.push(config.endpoints[k].endpoint);
|
|
442
330
|
}
|
|
443
|
-
for (
|
|
331
|
+
for (let k = 0; k < config.ids.length; k++) {
|
|
444
332
|
if (type != config.ids[k].type) {
|
|
445
333
|
type = config.ids[k].type;
|
|
446
|
-
|
|
334
|
+
let j = 0;
|
|
447
335
|
while (j < config.endpoints.length) {
|
|
448
336
|
if (config.endpoints[j].type == type) {
|
|
449
337
|
endpointId = j;
|
|
@@ -452,14 +340,12 @@ var PriceFeeds = /** @class */ (function () {
|
|
|
452
340
|
j++;
|
|
453
341
|
}
|
|
454
342
|
if (config.endpoints[endpointId].type != type) {
|
|
455
|
-
throw new Error(
|
|
343
|
+
throw new Error(`priceFeeds: no enpoint found for ${type} check priceFeedConfig`);
|
|
456
344
|
}
|
|
457
345
|
}
|
|
458
346
|
feed.set(config.ids[k].id, { symbol: config.ids[k].symbol.toUpperCase(), endpointId: endpointId });
|
|
459
347
|
}
|
|
460
348
|
return [feed, feedEndpoints];
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
}());
|
|
464
|
-
export default PriceFeeds;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
465
351
|
//# sourceMappingURL=priceFeeds.js.map
|