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