@pioneer-platform/markets 8.11.10 → 8.11.13

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.
@@ -1 +1,2 @@
1
- $ tsc -p .
1
+
2
+ $ tsc -p .
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @pioneer-platform/markets
2
2
 
3
+ ## 8.11.13
4
+
5
+ ### Patch Changes
6
+
7
+ - feed4f1: Fix Polygon (MATIC → POL) CoinMarketCap symbol mapping and add validation for invalid price data
8
+
9
+ ## 8.11.12
10
+
11
+ ### Patch Changes
12
+
13
+ - Update @pioneer-platform/pioneer-discovery dependency to ^8.11.11 with fixed icon URLs
14
+
3
15
  ## 8.11.10
4
16
 
5
17
  ### Patch Changes
package/lib/index.js CHANGED
@@ -194,8 +194,10 @@ var update_cache = function () {
194
194
  if (!(j < assetsMatchSymbol.length)) return [3 /*break*/, 4];
195
195
  asset = assetsMatchSymbol[j];
196
196
  key = "coincap:" + asset.caip;
197
- return [4 /*yield*/, redis.setex(key, 3600, JSON.stringify(entry))];
197
+ // NEVER EXPIRE - data persists forever for instant responses
198
+ return [4 /*yield*/, redis.set(key, JSON.stringify(entry))];
198
199
  case 2:
200
+ // NEVER EXPIRE - data persists forever for instant responses
199
201
  _b.sent();
200
202
  log.info(tag, "saved: " + key);
201
203
  populatedCaips_1.add(asset.caip);
@@ -245,8 +247,10 @@ var update_cache = function () {
245
247
  if (!(_c < matchingAssets_1.length)) return [3 /*break*/, 4];
246
248
  matchingAsset = matchingAssets_1[_c];
247
249
  key = "coingecko:".concat(matchingAsset.caip);
248
- return [4 /*yield*/, redis.setex(key, 3600, JSON.stringify(coin))];
250
+ // NEVER EXPIRE - data persists forever for instant responses
251
+ return [4 /*yield*/, redis.set(key, JSON.stringify(coin))];
249
252
  case 2:
253
+ // NEVER EXPIRE - data persists forever for instant responses
250
254
  _d.sent();
251
255
  log.info(tag, "Saved ".concat(coin.symbol, " under ").concat(key));
252
256
  populatedCaips_1.add(matchingAsset.caip);
@@ -632,21 +636,36 @@ var caip_to_identifiers = function (caip) {
632
636
  // @ts-ignore
633
637
  var mappedCoingeckoId = pioneer_discovery_1.coingeckoMapping[caip];
634
638
  if (mappedCoingeckoId) {
639
+ // Special case: Polygon rebranded from MATIC to POL on CoinMarketCap (March 2024)
640
+ // CMC still has MATIC symbol but with null price - must use POL
641
+ var cmcSymbol = (caip === 'eip155:137/slip44:60') ? 'POL' : symbol;
642
+ // Special case: Base network (eip155:8453) uses ETH as native asset
643
+ // On CMC and CoinCap, "BASE" symbol refers to Base Protocol (different token)
644
+ // Must use "ETH" to get correct Ethereum price
645
+ if (caip === 'eip155:8453/slip44:60') {
646
+ cmcSymbol = 'ETH';
647
+ }
635
648
  return {
636
649
  symbol: symbol,
637
650
  coingeckoId: mappedCoingeckoId,
638
- cmcSymbol: symbol,
639
- coincapSymbol: symbol.toLowerCase()
651
+ cmcSymbol: cmcSymbol,
652
+ coincapSymbol: cmcSymbol.toLowerCase() // Use cmcSymbol for CoinCap too
640
653
  };
641
654
  }
642
655
  // PRIORITY 2: Try ShapeShift CAIP adapter (for coins we might have missed)
643
656
  var shapeshiftCoingeckoId = caip_1.adapters.assetIdToCoingecko(caip);
644
657
  if (shapeshiftCoingeckoId) {
658
+ // Special case: Polygon rebranded from MATIC to POL on CoinMarketCap (March 2024)
659
+ var cmcSymbol = (caip === 'eip155:137/slip44:60') ? 'POL' : symbol;
660
+ // Special case: Base network uses ETH as native asset
661
+ if (caip === 'eip155:8453/slip44:60') {
662
+ cmcSymbol = 'ETH';
663
+ }
645
664
  return {
646
665
  symbol: symbol,
647
666
  coingeckoId: shapeshiftCoingeckoId,
648
- cmcSymbol: symbol,
649
- coincapSymbol: symbol.toLowerCase()
667
+ cmcSymbol: cmcSymbol,
668
+ coincapSymbol: cmcSymbol.toLowerCase()
650
669
  };
651
670
  }
652
671
  // PRIORITY 3: Fallback to asset data
@@ -709,19 +728,19 @@ var get_price_from_coingecko = function (coingeckoId) {
709
728
  */
710
729
  var get_price_from_coinmarketcap = function (symbol) {
711
730
  return __awaiter(this, void 0, void 0, function () {
712
- var tag, url, response, price, error_2, status_4;
713
- var _a;
714
- return __generator(this, function (_b) {
715
- switch (_b.label) {
731
+ var tag, url, response, coinData, priceData, price, error_2, status_4;
732
+ var _a, _b, _c;
733
+ return __generator(this, function (_d) {
734
+ switch (_d.label) {
716
735
  case 0:
717
736
  tag = TAG + ' | get_price_from_coinmarketcap | ';
718
737
  if (!CMC_PRO_API_KEY) {
719
738
  log.debug(tag, 'CMC_PRO_API_KEY not set, skipping CoinMarketCap');
720
739
  return [2 /*return*/, 0];
721
740
  }
722
- _b.label = 1;
741
+ _d.label = 1;
723
742
  case 1:
724
- _b.trys.push([1, 3, , 4]);
743
+ _d.trys.push([1, 3, , 4]);
725
744
  url = "".concat(URL_COINMARKETCAP, "cryptocurrency/quotes/latest?symbol=").concat(symbol, "&convert=USD");
726
745
  log.debug(tag, "Fetching from CoinMarketCap: ".concat(url));
727
746
  return [4 /*yield*/, axios.get(url, {
@@ -731,17 +750,24 @@ var get_price_from_coinmarketcap = function (symbol) {
731
750
  }
732
751
  })];
733
752
  case 2:
734
- response = _b.sent();
753
+ response = _d.sent();
735
754
  if (response.data && response.data.data && response.data.data[symbol]) {
736
- price = parseFloat(response.data.data[symbol].quote.USD.price);
755
+ coinData = response.data.data[symbol];
756
+ priceData = (_b = (_a = coinData.quote) === null || _a === void 0 ? void 0 : _a.USD) === null || _b === void 0 ? void 0 : _b.price;
757
+ if (!priceData || isNaN(parseFloat(priceData))) {
758
+ log.warn(tag, "\u26A0\uFE0F CoinMarketCap returned invalid price for ".concat(symbol));
759
+ log.warn(tag, "Symbol: ".concat(coinData.symbol, ", Slug: ").concat(coinData.slug, ", Quote keys:"), Object.keys(coinData.quote || {}));
760
+ return [2 /*return*/, 0];
761
+ }
762
+ price = parseFloat(priceData);
737
763
  log.debug(tag, "\u2705 CoinMarketCap price for ".concat(symbol, ": $").concat(price));
738
764
  return [2 /*return*/, price];
739
765
  }
740
766
  log.debug(tag, "No price data from CoinMarketCap for ".concat(symbol));
741
767
  return [2 /*return*/, 0];
742
768
  case 3:
743
- error_2 = _b.sent();
744
- status_4 = ((_a = error_2.response) === null || _a === void 0 ? void 0 : _a.status) || error_2.status;
769
+ error_2 = _d.sent();
770
+ status_4 = ((_c = error_2.response) === null || _c === void 0 ? void 0 : _c.status) || error_2.status;
745
771
  if (status_4 === 429 || status_4 === 403) {
746
772
  log.warn(tag, "CoinMarketCap rate limit (".concat(status_4, ") for ").concat(symbol));
747
773
  }
@@ -805,12 +831,14 @@ var get_price_from_coincap = function (symbol) {
805
831
  });
806
832
  };
807
833
  /**
808
- * Get price from MayaScan for MAYA token
809
- * MAYA token is different from CACAO (the gas token)
834
+ * Get price from MayaScan for MAYA token or CACAO gas token
835
+ * MAYA token (denom:maya) is different from CACAO (slip44:931 - the gas token)
836
+ * @param asset - 'maya' for MAYA token, 'cacao' for CACAO gas token
810
837
  */
811
838
  var get_price_from_mayascan = function () {
812
- return __awaiter(this, void 0, void 0, function () {
839
+ return __awaiter(this, arguments, void 0, function (asset) {
813
840
  var tag, url, response, price, error_4;
841
+ if (asset === void 0) { asset = 'maya'; }
814
842
  return __generator(this, function (_a) {
815
843
  switch (_a.label) {
816
844
  case 0:
@@ -819,16 +847,24 @@ var get_price_from_mayascan = function () {
819
847
  case 1:
820
848
  _a.trys.push([1, 3, , 4]);
821
849
  url = 'https://www.mayascan.org/api/maya/price?days=1';
822
- log.debug(tag, "Fetching MAYA token price from MayaScan: ".concat(url));
850
+ log.debug(tag, "Fetching ".concat(asset.toUpperCase(), " price from MayaScan: ").concat(url));
823
851
  return [4 /*yield*/, axios.get(url)];
824
852
  case 2:
825
853
  response = _a.sent();
826
- if (response.data && response.data.mayaPriceInUsd) {
827
- price = parseFloat(response.data.mayaPriceInUsd);
828
- log.debug(tag, "\u2705 MayaScan price for MAYA token: $".concat(price));
829
- return [2 /*return*/, price];
854
+ if (response.data) {
855
+ price = 0;
856
+ if (asset === 'maya' && response.data.mayaPriceInUsd) {
857
+ price = parseFloat(response.data.mayaPriceInUsd);
858
+ }
859
+ else if (asset === 'cacao' && response.data.cacaoPriceInUsd) {
860
+ price = parseFloat(response.data.cacaoPriceInUsd);
861
+ }
862
+ if (price > 0) {
863
+ log.debug(tag, "\u2705 MayaScan price for ".concat(asset.toUpperCase(), ": $").concat(price));
864
+ return [2 /*return*/, price];
865
+ }
830
866
  }
831
- log.debug(tag, 'No MAYA price data from MayaScan');
867
+ log.debug(tag, "No ".concat(asset.toUpperCase(), " price data from MayaScan"));
832
868
  return [2 /*return*/, 0];
833
869
  case 3:
834
870
  error_4 = _a.sent();
@@ -846,7 +882,7 @@ var get_price_from_mayascan = function () {
846
882
  */
847
883
  var get_asset_price_by_caip = function (caip_2) {
848
884
  return __awaiter(this, arguments, void 0, function (caip, returnSource) {
849
- var tag, mayaPrice, identifiers, price;
885
+ var tag, mayaPrice, isCacao, identifiers, price, cacaoPrice;
850
886
  if (returnSource === void 0) { returnSource = false; }
851
887
  return __generator(this, function (_a) {
852
888
  switch (_a.label) {
@@ -855,7 +891,7 @@ var get_asset_price_by_caip = function (caip_2) {
855
891
  log.debug(tag, "Looking up price for: ".concat(caip));
856
892
  if (!(caip === 'cosmos:mayachain-mainnet-v1/denom:maya' || caip.toLowerCase().includes('denom:maya'))) return [3 /*break*/, 2];
857
893
  log.debug(tag, 'MAYA token detected, using MayaScan API');
858
- return [4 /*yield*/, get_price_from_mayascan()];
894
+ return [4 /*yield*/, get_price_from_mayascan('maya')];
859
895
  case 1:
860
896
  mayaPrice = _a.sent();
861
897
  if (mayaPrice > 0) {
@@ -864,6 +900,7 @@ var get_asset_price_by_caip = function (caip_2) {
864
900
  log.warn(tag, '❌ Failed to get MAYA price from MayaScan, trying standard APIs');
865
901
  _a.label = 2;
866
902
  case 2:
903
+ isCacao = caip === 'cosmos:mayachain-mainnet-v1/slip44:931';
867
904
  identifiers = caip_to_identifiers(caip);
868
905
  if (!identifiers) {
869
906
  log.warn(tag, "No identifier mapping found for CAIP: ".concat(caip));
@@ -897,6 +934,16 @@ var get_asset_price_by_caip = function (caip_2) {
897
934
  if (price > 0) {
898
935
  return [2 /*return*/, returnSource ? { price: price, source: 'coincap' } : price];
899
936
  }
937
+ if (!isCacao) return [3 /*break*/, 7];
938
+ log.debug(tag, '🏔️ All pricing APIs failed for CACAO, trying MayaScan as final fallback');
939
+ return [4 /*yield*/, get_price_from_mayascan('cacao')];
940
+ case 6:
941
+ cacaoPrice = _a.sent();
942
+ if (cacaoPrice > 0) {
943
+ return [2 /*return*/, returnSource ? { price: cacaoPrice, source: 'mayascan' } : cacaoPrice];
944
+ }
945
+ _a.label = 7;
946
+ case 7:
900
947
  log.warn(tag, "\u274C No price found from any API for: ".concat(caip));
901
948
  return [2 /*return*/, returnSource ? { price: 0, source: 'none' } : 0];
902
949
  }
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@pioneer-platform/markets",
3
- "version": "8.11.10",
3
+ "version": "8.11.13",
4
4
  "main": "./lib/index.js",
5
5
  "types": "./lib/index.d.ts",
6
6
  "dependencies": {
7
7
  "@pioneer-platform/default-redis": "^8.11.0",
8
8
  "@pioneer-platform/loggerdog": "^8.11.0",
9
9
  "@pioneer-platform/pioneer-coins": "^9.11.0",
10
- "@pioneer-platform/pioneer-discovery": "^8.11.4",
10
+ "@pioneer-platform/pioneer-discovery": "^8.11.11",
11
11
  "@pioneer-platform/pioneer-types": "^8.11.0",
12
12
  "@pioneer-platform/pro-token": "^0.8.0",
13
13
  "@shapeshiftoss/caip": "^9.0.0-alpha.0",