@pioneer-platform/markets 8.1.14

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/lib/index.d.ts ADDED
@@ -0,0 +1 @@
1
+ export {};
package/lib/index.js ADDED
@@ -0,0 +1,362 @@
1
+ "use strict";
2
+ /*
3
+
4
+
5
+
6
+ https://www.coingecko.com/api/documentations/v3
7
+
8
+ */
9
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
10
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
11
+ return new (P || (P = Promise))(function (resolve, reject) {
12
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
13
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
14
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
15
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
16
+ });
17
+ };
18
+ var __generator = (this && this.__generator) || function (thisArg, body) {
19
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
20
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
21
+ function verb(n) { return function (v) { return step([n, v]); }; }
22
+ function step(op) {
23
+ if (f) throw new TypeError("Generator is already executing.");
24
+ while (_) try {
25
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
26
+ if (y = 0, t) op = [op[0] & 2, t.value];
27
+ switch (op[0]) {
28
+ case 0: case 1: t = op; break;
29
+ case 4: _.label++; return { value: op[1], done: false };
30
+ case 5: _.label++; y = op[1]; op = [0]; continue;
31
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
32
+ default:
33
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
34
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
35
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
36
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
37
+ if (t[2]) _.ops.pop();
38
+ _.trys.pop(); continue;
39
+ }
40
+ op = body.call(thisArg, _);
41
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
42
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
43
+ }
44
+ };
45
+ Object.defineProperty(exports, "__esModule", { value: true });
46
+ var TAG = " | market-module | ";
47
+ var Axios = require('axios');
48
+ var https = require('https');
49
+ var axios = Axios.create({
50
+ httpsAgent: new https.Agent({
51
+ rejectUnauthorized: false,
52
+ headers: {
53
+ "authorization": process.env['COINCAP_API_KEY'],
54
+ "Authorization": "Bearer " + process.env['COINCAP_API_KEY'],
55
+ }
56
+ })
57
+ });
58
+ var log = require("@pioneer-platform/loggerdog")();
59
+ var URL_COINCAP = "https://api.coincap.io/v2/";
60
+ var URL_COINGECKO = "https://api.coingecko.com/api/v3/";
61
+ var COINGECKO_API_KEY = process.env['COINGECKO_API_KEY'];
62
+ var GLOBAL_RATES_COINCAP;
63
+ var GLOBAL_RATES_COINGECKO;
64
+ module.exports = {
65
+ init: function (settings) {
66
+ if (settings === null || settings === void 0 ? void 0 : settings.apiKey) {
67
+ COINGECKO_API_KEY = settings.apiKey;
68
+ }
69
+ //if(!COINGECKO_API_KEY) throw Error("api key required! set env COINGECKO_API_KEY")
70
+ },
71
+ getAssetsCoincap: function () {
72
+ return get_assets_coincap();
73
+ },
74
+ getAssetsCoingecko: function () {
75
+ return get_assets_coingecko();
76
+ },
77
+ getPrice: function (asset) {
78
+ return get_price(asset);
79
+ },
80
+ getPricesInQuote: function (assets, quote) {
81
+ return get_prices_in_quote(assets, quote);
82
+ },
83
+ valuePortfolio: function (pubkeys, quote) {
84
+ return get_value_pubkeys(pubkeys, quote);
85
+ }
86
+ };
87
+ var get_value_pubkeys = function (pubkeys, quote) {
88
+ return __awaiter(this, void 0, void 0, function () {
89
+ var tag, valuesUsd, totalValueUsd, allNames, hydratedPubkeys, i, pubkey, j, entry, symbol, coinInfoCoinCap, coinInfoCoinGecko, rateUsdCoinCap, rateUsdCoinGecko, relDiff, percent, chosenRate, valueUsd, e_1;
90
+ return __generator(this, function (_a) {
91
+ switch (_a.label) {
92
+ case 0:
93
+ tag = TAG + ' | get_value_portfolio | ';
94
+ _a.label = 1;
95
+ case 1:
96
+ _a.trys.push([1, 6, , 7]);
97
+ if (!!GLOBAL_RATES_COINCAP) return [3 /*break*/, 3];
98
+ return [4 /*yield*/, get_assets_coincap()];
99
+ case 2:
100
+ GLOBAL_RATES_COINCAP = _a.sent();
101
+ _a.label = 3;
102
+ case 3:
103
+ if (!!GLOBAL_RATES_COINGECKO) return [3 /*break*/, 5];
104
+ return [4 /*yield*/, get_assets_coingecko()];
105
+ case 4:
106
+ GLOBAL_RATES_COINGECKO = _a.sent();
107
+ _a.label = 5;
108
+ case 5:
109
+ valuesUsd = {};
110
+ totalValueUsd = 0;
111
+ allNames = [];
112
+ hydratedPubkeys = [];
113
+ for (i = 0; i < pubkeys.length; i++) {
114
+ pubkey = pubkeys[i];
115
+ for (j = 0; j < pubkey.balances.length; j++) {
116
+ entry = pubkey.balances[i];
117
+ symbol = entry.symbol;
118
+ coinInfoCoinCap = GLOBAL_RATES_COINCAP[symbol];
119
+ log.info(tag, "coinInfoCoinCap: ", coinInfoCoinCap);
120
+ coinInfoCoinGecko = GLOBAL_RATES_COINGECKO[symbol];
121
+ log.info(tag, "coinInfoCoinGecko: ", coinInfoCoinGecko);
122
+ rateUsdCoinCap = 0;
123
+ if (GLOBAL_RATES_COINCAP[symbol] && GLOBAL_RATES_COINCAP[symbol].priceUsd) {
124
+ rateUsdCoinCap = GLOBAL_RATES_COINCAP[symbol].priceUsd;
125
+ }
126
+ else {
127
+ log.error(tag, " COINCAP Missing rate data for " + symbol);
128
+ }
129
+ //look for symbol conflicts
130
+ if (coinInfoCoinCap.symbol === coinInfoCoinGecko.symbol) {
131
+ }
132
+ else {
133
+ //
134
+ if (coinInfoCoinCap.symbol) {
135
+ }
136
+ }
137
+ entry.marketInfo = {
138
+ symbol: coinInfoCoinCap.symbol || coinInfoCoinGecko.symbol,
139
+ id_coincap: coinInfoCoinCap.id,
140
+ id_coingecko: coinInfoCoinGecko.id,
141
+ rank_coincap: coinInfoCoinCap.rank,
142
+ rank_coingecko: coinInfoCoinGecko.market_cap_rank,
143
+ name_coincap: coinInfoCoinCap.name,
144
+ name_coingecko: coinInfoCoinGecko.name,
145
+ supply: coinInfoCoinCap.supply,
146
+ maxSupply: coinInfoCoinCap.maxSupply,
147
+ marketCapUsd: coinInfoCoinCap.marketCapUsd,
148
+ volumeUsd24Hr: coinInfoCoinCap.volumeUsd24Hr,
149
+ priceUsd: coinInfoCoinCap.priceUsd,
150
+ changePercent24Hr: coinInfoCoinCap.changePercent24Hr,
151
+ vwap24Hr: coinInfoCoinCap.vwap24Hr,
152
+ explorer: coinInfoCoinCap.explorer,
153
+ //gecko
154
+ image: coinInfoCoinGecko.image,
155
+ current_price: coinInfoCoinGecko.current_price,
156
+ market_cap: coinInfoCoinGecko.market_cap,
157
+ fully_diluted_valuation: coinInfoCoinGecko.fully_diluted_valuation,
158
+ total_volume: coinInfoCoinGecko.total_volume,
159
+ high_24h: coinInfoCoinGecko.high_24h,
160
+ low_24h: coinInfoCoinGecko.low_24h,
161
+ price_change_24h: coinInfoCoinGecko.price_change_24h,
162
+ price_change_percentage_24h: coinInfoCoinGecko.price_change_percentage_24h,
163
+ market_cap_change_24h: coinInfoCoinGecko.market_cap_change_24h,
164
+ market_cap_change_percentage_24h: coinInfoCoinGecko.market_cap_change_percentage_24h,
165
+ circulating_supply: coinInfoCoinGecko.circulating_supply,
166
+ total_supply: coinInfoCoinGecko.total_supply,
167
+ max_supply: coinInfoCoinGecko.max_supply,
168
+ ath: coinInfoCoinGecko.ath,
169
+ ath_change_percentage: coinInfoCoinGecko.ath_change_percentage,
170
+ ath_date: coinInfoCoinGecko.ath_date,
171
+ atl: coinInfoCoinGecko.atl,
172
+ atl_change_percentage: coinInfoCoinGecko.atl_change_percentage,
173
+ atl_date: coinInfoCoinGecko.atl_date,
174
+ roi: coinInfoCoinGecko.roi,
175
+ last_updated: coinInfoCoinGecko.last_updated
176
+ };
177
+ rateUsdCoinGecko = 0;
178
+ if (GLOBAL_RATES_COINGECKO[symbol] && GLOBAL_RATES_COINGECKO[symbol].current_price) {
179
+ rateUsdCoinGecko = GLOBAL_RATES_COINGECKO[symbol].current_price;
180
+ }
181
+ else {
182
+ log.error(tag, " COINGECKO Missing rate data for " + symbol);
183
+ }
184
+ log.info(symbol, " rateUsdCoinCap: ", rateUsdCoinCap);
185
+ log.info(symbol, " rateUsdCoinGecko: ", rateUsdCoinGecko);
186
+ relDiff = function (a, b) {
187
+ return 100 * Math.abs((a - b) / ((a + b) / 2));
188
+ };
189
+ percent = relDiff(Number(rateUsdCoinCap), Number(rateUsdCoinGecko));
190
+ log.info(symbol, " percent: ", percent);
191
+ chosenRate = 0;
192
+ if (rateUsdCoinCap === 0) {
193
+ chosenRate = rateUsdCoinGecko;
194
+ }
195
+ else if (rateUsdCoinGecko === 0) {
196
+ chosenRate = rateUsdCoinCap;
197
+ }
198
+ else if (rateUsdCoinGecko > rateUsdCoinCap) {
199
+ chosenRate = rateUsdCoinCap;
200
+ }
201
+ else {
202
+ chosenRate = rateUsdCoinGecko;
203
+ }
204
+ chosenRate = Number(chosenRate);
205
+ valuesUsd[symbol] = chosenRate;
206
+ entry.priceUsd = String(chosenRate);
207
+ valueUsd = totalValueUsd += valuesUsd[symbol] + chosenRate;
208
+ //TODO if quote !== USD
209
+ //calc conversion
210
+ hydratedPubkeys.push(entry);
211
+ }
212
+ }
213
+ // log.info(tag,'names: ',allNames)
214
+ //let priceData in USD
215
+ //let allValuesUsd = get_prices_in_quote()
216
+ //supplement with icons
217
+ //fill any missing from coingecko
218
+ //TODO https://www.coingecko.com/api/documentations/v3#/simple/get_simple_price
219
+ return [2 /*return*/, { pubkeys: hydratedPubkeys, total: totalValueUsd }];
220
+ case 6:
221
+ e_1 = _a.sent();
222
+ console.error(tag, 'Error: ', e_1);
223
+ throw e_1;
224
+ case 7: return [2 /*return*/];
225
+ }
226
+ });
227
+ });
228
+ };
229
+ var get_assets_coincap = function () {
230
+ return __awaiter(this, void 0, void 0, function () {
231
+ var tag, output, url, result, allCoinsArray, i, coinInfo, e_2;
232
+ return __generator(this, function (_a) {
233
+ switch (_a.label) {
234
+ case 0:
235
+ tag = TAG + ' | get_order | ';
236
+ _a.label = 1;
237
+ case 1:
238
+ _a.trys.push([1, 3, , 4]);
239
+ output = {};
240
+ url = URL_COINCAP + 'assets?limit=2000';
241
+ log.debug(tag, "url: ", url);
242
+ return [4 /*yield*/, axios({
243
+ url: url,
244
+ method: 'GET'
245
+ })
246
+ //parse into keys array off ticker
247
+ ];
248
+ case 2:
249
+ result = _a.sent();
250
+ allCoinsArray = result.data.data;
251
+ log.info(tag, "allCoinsArray: ", allCoinsArray.length);
252
+ for (i = 0; i < allCoinsArray.length; i++) {
253
+ coinInfo = allCoinsArray[i];
254
+ log.debug(tag, "coinInfo: ", coinInfo);
255
+ output[coinInfo.symbol] = coinInfo;
256
+ }
257
+ log.debug('result: ', output);
258
+ return [2 /*return*/, output];
259
+ case 3:
260
+ e_2 = _a.sent();
261
+ console.error(tag, 'Error: ', e_2);
262
+ throw e_2;
263
+ case 4: return [2 /*return*/];
264
+ }
265
+ });
266
+ });
267
+ };
268
+ var get_assets_coingecko = function () {
269
+ return __awaiter(this, void 0, void 0, function () {
270
+ var tag, output, url, result, allCoinsArray, i, coinInfo, e_3;
271
+ return __generator(this, function (_a) {
272
+ switch (_a.label) {
273
+ case 0:
274
+ tag = TAG + ' | get_assets_coingecko | ';
275
+ _a.label = 1;
276
+ case 1:
277
+ _a.trys.push([1, 3, , 4]);
278
+ output = {};
279
+ url = URL_COINGECKO + 'coins/markets?vs_currency=usd&order=market_cap_desc&per_page=250&page=1&sparkline=false';
280
+ log.debug(tag, "url: ", url);
281
+ return [4 /*yield*/, axios({
282
+ url: url,
283
+ method: 'GET'
284
+ })];
285
+ case 2:
286
+ result = _a.sent();
287
+ log.debug(tag, "result: ", result.data);
288
+ allCoinsArray = result.data;
289
+ log.debug(tag, "allCoinsArray: ", allCoinsArray.length);
290
+ for (i = 0; i < allCoinsArray.length; i++) {
291
+ coinInfo = allCoinsArray[i];
292
+ log.debug(tag, "coinInfo: ", coinInfo);
293
+ output[coinInfo.symbol.toUpperCase()] = coinInfo;
294
+ }
295
+ log.debug('result: ', output);
296
+ return [2 /*return*/, output];
297
+ case 3:
298
+ e_3 = _a.sent();
299
+ console.error(tag, 'Error: ', e_3);
300
+ throw e_3;
301
+ case 4: return [2 /*return*/];
302
+ }
303
+ });
304
+ });
305
+ };
306
+ var get_prices_in_quote = function (assets, quote) {
307
+ return __awaiter(this, void 0, void 0, function () {
308
+ var tag, data, e_4;
309
+ return __generator(this, function (_a) {
310
+ switch (_a.label) {
311
+ case 0:
312
+ tag = " | get_prices_in_quote | ";
313
+ _a.label = 1;
314
+ case 1:
315
+ _a.trys.push([1, 3, , 4]);
316
+ return [4 /*yield*/, axios.get(URL_COINGECKO + "/simple/price?ids=" + assets.toString() + "&vs_currencies=" + quote)];
317
+ case 2:
318
+ data = (_a.sent()).data;
319
+ return [2 /*return*/, data];
320
+ case 3:
321
+ e_4 = _a.sent();
322
+ log.error(tag, "e: ", e_4);
323
+ return [3 /*break*/, 4];
324
+ case 4: return [2 /*return*/];
325
+ }
326
+ });
327
+ });
328
+ };
329
+ var get_price = function (asset) {
330
+ var _a, _b, _c, _d;
331
+ return __awaiter(this, void 0, void 0, function () {
332
+ var tag, data, currency, marketData, e_5;
333
+ return __generator(this, function (_e) {
334
+ switch (_e.label) {
335
+ case 0:
336
+ tag = " | get_price | ";
337
+ _e.label = 1;
338
+ case 1:
339
+ _e.trys.push([1, 3, , 4]);
340
+ return [4 /*yield*/, axios.get(URL_COINGECKO + "/coins/" + asset)
341
+ // TODO: get correct localizations
342
+ ];
343
+ case 2:
344
+ data = (_e.sent()).data;
345
+ currency = 'usd';
346
+ marketData = data === null || data === void 0 ? void 0 : data.market_data;
347
+ return [2 /*return*/, {
348
+ price: (_a = marketData === null || marketData === void 0 ? void 0 : marketData.current_price) === null || _a === void 0 ? void 0 : _a[currency],
349
+ marketCap: (_b = marketData === null || marketData === void 0 ? void 0 : marketData.market_cap) === null || _b === void 0 ? void 0 : _b[currency],
350
+ changePercent24Hr: marketData === null || marketData === void 0 ? void 0 : marketData.price_change_percentage_24h,
351
+ volume: (_c = marketData === null || marketData === void 0 ? void 0 : marketData.total_volume) === null || _c === void 0 ? void 0 : _c[currency],
352
+ icon: (_d = data === null || data === void 0 ? void 0 : data.image) === null || _d === void 0 ? void 0 : _d.large
353
+ }];
354
+ case 3:
355
+ e_5 = _e.sent();
356
+ log.error(tag, "e: ", e_5);
357
+ return [3 /*break*/, 4];
358
+ case 4: return [2 /*return*/];
359
+ }
360
+ });
361
+ });
362
+ };
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@pioneer-platform/markets",
3
+ "version": "8.1.14",
4
+ "main": "./lib/index.js",
5
+ "types": "./lib/index.d.ts",
6
+ "dependencies": {
7
+ "@pioneer-platform/loggerdog": "^8.1.14",
8
+ "axios": "^0.21.1",
9
+ "dotenv": "^8.2.0"
10
+ },
11
+ "scripts": {
12
+ "npm": "npm i",
13
+ "test": "npm run build && node __tests__/test-module.js",
14
+ "build": "tsc -p .",
15
+ "prepublish": "npm run build",
16
+ "refresh": "rm -rf ./node_modules ./package-lock.json && npm install"
17
+ },
18
+ "devDependencies": {
19
+ "@types/jest": "^25.2.3",
20
+ "@types/node": "^13.13.21",
21
+ "@types/source-map-support": "^0.5.3",
22
+ "jest": "^26.4.2",
23
+ "onchange": "^7.0.2",
24
+ "serve": "^11.3.2",
25
+ "source-map-support": "^0.5.19",
26
+ "ts-jest": "^25.4.0",
27
+ "typescript": "^3.9.7"
28
+ },
29
+ "gitHead": "29767e45c4dc1cb9d17c741ac9a06051c30525b5"
30
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,13 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es5",
4
+ "module": "commonjs",
5
+ "lib": ["es6", "es2015", "dom"],
6
+ "declaration": true,
7
+ "outDir": "lib",
8
+ "rootDir": "src",
9
+ "strict": true,
10
+ "types": ["node"],
11
+ "esModuleInterop": true
12
+ }
13
+ }