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