@pioneer-platform/markets 8.3.13 → 8.3.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.js +129 -29
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
/*
|
|
3
3
|
|
|
4
4
|
https://www.coingecko.com/api/documentations/v3
|
|
5
|
+
https://rest.coincap.io/api-docs.json
|
|
5
6
|
|
|
6
7
|
*/
|
|
7
8
|
var __assign = (this && this.__assign) || function () {
|
|
@@ -59,10 +60,7 @@ var Axios = require('axios');
|
|
|
59
60
|
var https = require('https');
|
|
60
61
|
var axios = Axios.create({
|
|
61
62
|
httpsAgent: new https.Agent({
|
|
62
|
-
rejectUnauthorized: false
|
|
63
|
-
headers: {
|
|
64
|
-
"Authorization": "Bearer " + process.env['COINCAP_API_KEY'],
|
|
65
|
-
}
|
|
63
|
+
rejectUnauthorized: false
|
|
66
64
|
})
|
|
67
65
|
});
|
|
68
66
|
var axiosRetry = require('axios-retry');
|
|
@@ -82,9 +80,17 @@ var ProToken = require("@pioneer-platform/pro-token");
|
|
|
82
80
|
var log = require('@pioneer-platform/loggerdog')();
|
|
83
81
|
var _a = require("@pioneer-platform/pioneer-coins"), getExplorerAddressUrl = _a.getExplorerAddressUrl, needsMemoByNetwork = _a.needsMemoByNetwork, COIN_MAP_LONG = _a.COIN_MAP_LONG;
|
|
84
82
|
var _b = require('@pioneer-platform/default-redis'), subscriber = _b.subscriber, publisher = _b.publisher, redis = _b.redis, redisQueue = _b.redisQueue;
|
|
85
|
-
|
|
83
|
+
// API Documentation URLs
|
|
84
|
+
// https://rest.coincap.io/api-docs.json
|
|
85
|
+
// API Base URLs
|
|
86
|
+
var URL_COINCAP = "https://rest.coincap.io/v3/";
|
|
86
87
|
var URL_COINGECKO = "https://api.coingecko.com/api/v3/";
|
|
88
|
+
// API Keys
|
|
89
|
+
var COINCAP_API_KEY = process.env['COINCAP_API_KEY'];
|
|
87
90
|
var COINGECKO_API_KEY = process.env['COINGECKO_API_KEY'];
|
|
91
|
+
if (!COINCAP_API_KEY) {
|
|
92
|
+
console.warn("COINCAP_API_KEY not found in environment variables. CoinCap API 3.0 requires an API key.");
|
|
93
|
+
}
|
|
88
94
|
var GLOBAL_RATES_COINCAP;
|
|
89
95
|
var GLOBAL_RATES_COINGECKO;
|
|
90
96
|
module.exports = {
|
|
@@ -126,6 +132,11 @@ var update_cache = function () {
|
|
|
126
132
|
_a.label = 1;
|
|
127
133
|
case 1:
|
|
128
134
|
_a.trys.push([1, 16, , 17]);
|
|
135
|
+
// Validate API key is available
|
|
136
|
+
if (!COINCAP_API_KEY) {
|
|
137
|
+
log.error(tag, "COINCAP_API_KEY is required for CoinCap API 3.0");
|
|
138
|
+
return [2 /*return*/, ["COINCAP_API_KEY_MISSING"]];
|
|
139
|
+
}
|
|
129
140
|
entries = Object.entries(pioneer_discovery_1.assetData).map(function (_a) {
|
|
130
141
|
var caip = _a[0], asset = _a[1];
|
|
131
142
|
if (typeof asset === 'object' && asset !== null) {
|
|
@@ -138,11 +149,15 @@ var update_cache = function () {
|
|
|
138
149
|
log.debug(tag, "entries: ", entries);
|
|
139
150
|
log.info(tag, "entries: ", entries[0]);
|
|
140
151
|
log.info(tag, "entries: ", entries.length);
|
|
141
|
-
url = URL_COINCAP
|
|
152
|
+
url = "".concat(URL_COINCAP, "assets?limit=2000");
|
|
142
153
|
log.debug(tag, "url: ", url);
|
|
143
154
|
return [4 /*yield*/, axios({
|
|
144
155
|
url: url,
|
|
145
|
-
method: 'GET'
|
|
156
|
+
method: 'GET',
|
|
157
|
+
headers: {
|
|
158
|
+
'Accept': 'application/json',
|
|
159
|
+
'Authorization': "Bearer ".concat(COINCAP_API_KEY)
|
|
160
|
+
}
|
|
146
161
|
})];
|
|
147
162
|
case 2:
|
|
148
163
|
result = _a.sent();
|
|
@@ -165,7 +180,7 @@ var update_cache = function () {
|
|
|
165
180
|
return [4 /*yield*/, redis.setex(key, 3600, JSON.stringify(entry))];
|
|
166
181
|
case 2:
|
|
167
182
|
_b.sent();
|
|
168
|
-
log.info(tag, "saved: " + key
|
|
183
|
+
log.info(tag, "saved: " + key);
|
|
169
184
|
populatedCaips_1.add(asset.caip);
|
|
170
185
|
_b.label = 3;
|
|
171
186
|
case 3:
|
|
@@ -476,18 +491,27 @@ var get_assets_coincap = function () {
|
|
|
476
491
|
return __generator(this, function (_a) {
|
|
477
492
|
switch (_a.label) {
|
|
478
493
|
case 0:
|
|
479
|
-
tag = TAG + ' |
|
|
494
|
+
tag = TAG + ' | get_assets_coincap | ';
|
|
480
495
|
_a.label = 1;
|
|
481
496
|
case 1:
|
|
482
497
|
_a.trys.push([1, 3, , 4]);
|
|
483
498
|
output = {};
|
|
484
|
-
|
|
499
|
+
// API 3.0 requires an API key
|
|
500
|
+
if (!COINCAP_API_KEY) {
|
|
501
|
+
log.error(tag, "COINCAP_API_KEY is required for CoinCap API 3.0");
|
|
502
|
+
return [2 /*return*/, {}];
|
|
503
|
+
}
|
|
504
|
+
url = "".concat(URL_COINCAP, "assets?limit=2000");
|
|
485
505
|
log.debug(tag, "url: ", url);
|
|
486
506
|
return [4 /*yield*/, axios({
|
|
487
507
|
url: url,
|
|
488
|
-
method: 'GET'
|
|
508
|
+
method: 'GET',
|
|
509
|
+
headers: {
|
|
510
|
+
'Accept': 'application/json',
|
|
511
|
+
'Authorization': "Bearer ".concat(COINCAP_API_KEY)
|
|
512
|
+
}
|
|
489
513
|
})
|
|
490
|
-
//
|
|
514
|
+
// Parse into keys array off ticker
|
|
491
515
|
];
|
|
492
516
|
case 2:
|
|
493
517
|
result = _a.sent();
|
|
@@ -502,7 +526,8 @@ var get_assets_coincap = function () {
|
|
|
502
526
|
return [2 /*return*/, output];
|
|
503
527
|
case 3:
|
|
504
528
|
e_3 = _a.sent();
|
|
505
|
-
|
|
529
|
+
log.error(TAG, "Error fetching CoinCap assets: ", e_3);
|
|
530
|
+
// Handle error gracefully
|
|
506
531
|
return [2 /*return*/, {}];
|
|
507
532
|
case 4: return [2 /*return*/];
|
|
508
533
|
}
|
|
@@ -554,30 +579,77 @@ var get_assets_coingecko = function (limit, skip) {
|
|
|
554
579
|
};
|
|
555
580
|
var get_prices_in_quote = function (assets, quote) {
|
|
556
581
|
return __awaiter(this, void 0, void 0, function () {
|
|
557
|
-
var tag, data, e_5;
|
|
582
|
+
var tag, result, _i, assets_1, asset, url, response, assetError_1, coincapError_1, data, e_5;
|
|
558
583
|
return __generator(this, function (_a) {
|
|
559
584
|
switch (_a.label) {
|
|
560
585
|
case 0:
|
|
561
586
|
tag = " | get_prices_in_quote | ";
|
|
562
587
|
_a.label = 1;
|
|
563
588
|
case 1:
|
|
564
|
-
_a.trys.push([1,
|
|
565
|
-
|
|
589
|
+
_a.trys.push([1, 12, , 13]);
|
|
590
|
+
if (!(COINCAP_API_KEY && quote.toLowerCase() === 'usd')) return [3 /*break*/, 10];
|
|
591
|
+
_a.label = 2;
|
|
566
592
|
case 2:
|
|
593
|
+
_a.trys.push([2, 9, , 10]);
|
|
594
|
+
result = {};
|
|
595
|
+
_i = 0, assets_1 = assets;
|
|
596
|
+
_a.label = 3;
|
|
597
|
+
case 3:
|
|
598
|
+
if (!(_i < assets_1.length)) return [3 /*break*/, 8];
|
|
599
|
+
asset = assets_1[_i];
|
|
600
|
+
_a.label = 4;
|
|
601
|
+
case 4:
|
|
602
|
+
_a.trys.push([4, 6, , 7]);
|
|
603
|
+
url = "".concat(URL_COINCAP, "assets/").concat(asset);
|
|
604
|
+
return [4 /*yield*/, axios({
|
|
605
|
+
url: url,
|
|
606
|
+
method: 'GET',
|
|
607
|
+
headers: {
|
|
608
|
+
'Accept': 'application/json',
|
|
609
|
+
'Authorization': "Bearer ".concat(COINCAP_API_KEY)
|
|
610
|
+
}
|
|
611
|
+
})];
|
|
612
|
+
case 5:
|
|
613
|
+
response = _a.sent();
|
|
614
|
+
if (response.data && response.data.data) {
|
|
615
|
+
result[asset] = {
|
|
616
|
+
usd: parseFloat(response.data.data.priceUsd)
|
|
617
|
+
};
|
|
618
|
+
}
|
|
619
|
+
return [3 /*break*/, 7];
|
|
620
|
+
case 6:
|
|
621
|
+
assetError_1 = _a.sent();
|
|
622
|
+
log.error(tag, "Error fetching price for ".concat(asset, " from CoinCap: "), assetError_1);
|
|
623
|
+
return [3 /*break*/, 7];
|
|
624
|
+
case 7:
|
|
625
|
+
_i++;
|
|
626
|
+
return [3 /*break*/, 3];
|
|
627
|
+
case 8:
|
|
628
|
+
// If we got at least one result, return it
|
|
629
|
+
if (Object.keys(result).length > 0) {
|
|
630
|
+
return [2 /*return*/, result];
|
|
631
|
+
}
|
|
632
|
+
return [3 /*break*/, 10];
|
|
633
|
+
case 9:
|
|
634
|
+
coincapError_1 = _a.sent();
|
|
635
|
+
log.error(tag, "CoinCap API error, falling back to CoinGecko: ", coincapError_1);
|
|
636
|
+
return [3 /*break*/, 10];
|
|
637
|
+
case 10: return [4 /*yield*/, axios.get("".concat(URL_COINGECKO, "/simple/price?ids=").concat(assets.toString(), "&vs_currencies=").concat(quote))];
|
|
638
|
+
case 11:
|
|
567
639
|
data = (_a.sent()).data;
|
|
568
640
|
return [2 /*return*/, data];
|
|
569
|
-
case
|
|
641
|
+
case 12:
|
|
570
642
|
e_5 = _a.sent();
|
|
571
|
-
log.error(tag, "
|
|
572
|
-
return [
|
|
573
|
-
case
|
|
643
|
+
log.error(tag, "Error fetching prices: ", e_5);
|
|
644
|
+
return [2 /*return*/, {}];
|
|
645
|
+
case 13: return [2 /*return*/];
|
|
574
646
|
}
|
|
575
647
|
});
|
|
576
648
|
});
|
|
577
649
|
};
|
|
578
650
|
var get_price = function (asset) {
|
|
579
651
|
return __awaiter(this, void 0, void 0, function () {
|
|
580
|
-
var tag, data, currency, marketData, e_6;
|
|
652
|
+
var tag, url, result, coinInfo, coincapError_2, data, currency, marketData, e_6;
|
|
581
653
|
var _a, _b, _c, _d;
|
|
582
654
|
return __generator(this, function (_e) {
|
|
583
655
|
switch (_e.label) {
|
|
@@ -585,11 +657,39 @@ var get_price = function (asset) {
|
|
|
585
657
|
tag = " | get_price | ";
|
|
586
658
|
_e.label = 1;
|
|
587
659
|
case 1:
|
|
588
|
-
_e.trys.push([1,
|
|
589
|
-
return [
|
|
590
|
-
|
|
591
|
-
];
|
|
660
|
+
_e.trys.push([1, 7, , 8]);
|
|
661
|
+
if (!COINCAP_API_KEY) return [3 /*break*/, 5];
|
|
662
|
+
_e.label = 2;
|
|
592
663
|
case 2:
|
|
664
|
+
_e.trys.push([2, 4, , 5]);
|
|
665
|
+
url = "".concat(URL_COINCAP, "assets/").concat(asset);
|
|
666
|
+
log.debug(tag, "CoinCap URL: ", url);
|
|
667
|
+
return [4 /*yield*/, axios({
|
|
668
|
+
url: url,
|
|
669
|
+
method: 'GET',
|
|
670
|
+
headers: {
|
|
671
|
+
'Accept': 'application/json',
|
|
672
|
+
'Authorization': "Bearer ".concat(COINCAP_API_KEY)
|
|
673
|
+
}
|
|
674
|
+
})];
|
|
675
|
+
case 3:
|
|
676
|
+
result = _e.sent();
|
|
677
|
+
coinInfo = result.data.data;
|
|
678
|
+
return [2 /*return*/, {
|
|
679
|
+
price: parseFloat(coinInfo.priceUsd),
|
|
680
|
+
marketCap: parseFloat(coinInfo.marketCapUsd),
|
|
681
|
+
changePercent24Hr: parseFloat(coinInfo.changePercent24Hr),
|
|
682
|
+
volume: parseFloat(coinInfo.volumeUsd24Hr),
|
|
683
|
+
icon: "https://assets.coincap.io/assets/icons/".concat(coinInfo.symbol.toLowerCase(), "@2x.png")
|
|
684
|
+
}];
|
|
685
|
+
case 4:
|
|
686
|
+
coincapError_2 = _e.sent();
|
|
687
|
+
log.error(tag, "CoinCap API error, falling back to CoinGecko: ", coincapError_2);
|
|
688
|
+
return [3 /*break*/, 5];
|
|
689
|
+
case 5: return [4 /*yield*/, axios.get("".concat(URL_COINGECKO, "/coins/").concat(asset))
|
|
690
|
+
// TODO: get correct localizations
|
|
691
|
+
];
|
|
692
|
+
case 6:
|
|
593
693
|
data = (_e.sent()).data;
|
|
594
694
|
currency = 'usd';
|
|
595
695
|
marketData = data === null || data === void 0 ? void 0 : data.market_data;
|
|
@@ -600,11 +700,11 @@ var get_price = function (asset) {
|
|
|
600
700
|
volume: (_c = marketData === null || marketData === void 0 ? void 0 : marketData.total_volume) === null || _c === void 0 ? void 0 : _c[currency],
|
|
601
701
|
icon: (_d = data === null || data === void 0 ? void 0 : data.image) === null || _d === void 0 ? void 0 : _d.large
|
|
602
702
|
}];
|
|
603
|
-
case
|
|
703
|
+
case 7:
|
|
604
704
|
e_6 = _e.sent();
|
|
605
|
-
log.error(tag, "
|
|
606
|
-
return [
|
|
607
|
-
case
|
|
705
|
+
log.error(tag, "Error fetching price data: ", e_6);
|
|
706
|
+
return [2 /*return*/, null];
|
|
707
|
+
case 8: return [2 /*return*/];
|
|
608
708
|
}
|
|
609
709
|
});
|
|
610
710
|
});
|