@subwallet/extension-base 1.1.58-0 → 1.1.60-0

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.
Files changed (54) hide show
  1. package/background/KoniTypes.d.ts +18 -1
  2. package/cjs/constants/staking.js +2 -1
  3. package/cjs/constants/storage.js +4 -2
  4. package/cjs/koni/api/coingecko.js +58 -15
  5. package/cjs/koni/api/nft/config.js +27 -21
  6. package/cjs/koni/api/staking/bonding/utils.js +7 -3
  7. package/cjs/koni/background/handlers/Extension.js +130 -122
  8. package/cjs/packageInfo.js +1 -1
  9. package/cjs/services/balance-service/helpers/subscribe/substrate/index.js +7 -1
  10. package/cjs/services/chain-service/constants.js +4 -2
  11. package/cjs/services/chain-service/index.js +6 -1
  12. package/cjs/services/chain-service/utils/index.js +34 -14
  13. package/cjs/services/earning-service/constants/chains.js +2 -2
  14. package/cjs/services/earning-service/handlers/native-staking/relay-chain.js +4 -4
  15. package/cjs/services/earning-service/handlers/nomination-pool/index.js +2 -2
  16. package/cjs/services/price-service/coingecko.js +54 -35
  17. package/cjs/services/price-service/index.js +83 -12
  18. package/cjs/services/setting-service/constants.js +4 -1
  19. package/cjs/services/storage-service/DatabaseService.js +2 -3
  20. package/cjs/utils/number.js +84 -1
  21. package/cjs/utils/staticData/index.js +6 -1
  22. package/constants/staking.js +2 -1
  23. package/constants/storage.d.ts +1 -0
  24. package/constants/storage.js +2 -1
  25. package/koni/api/coingecko.d.ts +2 -2
  26. package/koni/api/coingecko.js +58 -15
  27. package/koni/api/nft/config.js +28 -20
  28. package/koni/api/staking/bonding/utils.d.ts +1 -1
  29. package/koni/api/staking/bonding/utils.js +7 -3
  30. package/koni/background/handlers/Extension.d.ts +1 -0
  31. package/koni/background/handlers/Extension.js +7 -0
  32. package/package.json +7 -6
  33. package/packageInfo.js +1 -1
  34. package/services/balance-service/helpers/subscribe/substrate/index.js +8 -2
  35. package/services/chain-service/constants.js +4 -2
  36. package/services/chain-service/index.js +6 -1
  37. package/services/chain-service/utils/index.d.ts +13 -0
  38. package/services/chain-service/utils/index.js +32 -14
  39. package/services/earning-service/constants/chains.js +2 -2
  40. package/services/earning-service/handlers/native-staking/relay-chain.js +4 -4
  41. package/services/earning-service/handlers/nomination-pool/index.js +2 -2
  42. package/services/price-service/coingecko.d.ts +3 -2
  43. package/services/price-service/coingecko.js +50 -32
  44. package/services/price-service/index.d.ts +7 -2
  45. package/services/price-service/index.js +85 -15
  46. package/services/setting-service/constants.d.ts +1 -0
  47. package/services/setting-service/constants.js +2 -0
  48. package/services/storage-service/DatabaseService.d.ts +1 -1
  49. package/services/storage-service/DatabaseService.js +2 -3
  50. package/utils/number.d.ts +1 -0
  51. package/utils/number.js +82 -0
  52. package/utils/staticData/currencySymbol.json +11 -0
  53. package/utils/staticData/index.d.ts +3 -0
  54. package/utils/staticData/index.js +4 -0
@@ -1,4 +1,5 @@
1
1
  // Copyright 2019-2022 @subwallet/extension-base authors & contributors
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- export const LANGUAGE = 'current-language';
4
+ export const LANGUAGE = 'current-language';
5
+ export const CURRENCY = 'current-currency';
@@ -1,2 +1,2 @@
1
- import { PriceJson } from '@subwallet/extension-base/background/KoniTypes';
2
- export declare const getTokenPrice: (priceIds: Array<string>, currency?: string) => Promise<PriceJson>;
1
+ import { CurrencyType, PriceJson } from '@subwallet/extension-base/background/KoniTypes';
2
+ export declare const getTokenPrice: (priceIds: Set<string>, currencyCode?: CurrencyType) => Promise<PriceJson>;
@@ -1,29 +1,72 @@
1
1
  // Copyright 2019-2022 @subwallet/extension-koni authors & contributors
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
+ import { staticData, StaticKey } from '@subwallet/extension-base/utils/staticData';
4
5
  import axios from 'axios';
5
- export const getTokenPrice = async (priceIds, currency = 'usd') => {
6
+ let useBackupApi = false;
7
+ export const getTokenPrice = async (priceIds, currencyCode = 'USD') => {
6
8
  try {
7
- // const inverseMap: Record<string, string> = {};
8
- const idStr = priceIds.join(',');
9
- const res = await axios.get(`https://api.coingecko.com/api/v3/coins/markets?vs_currency=${currency}&per_page=1000&ids=${idStr}`);
10
- const responseData = res.data;
9
+ var _resMultiPromise$, _resMultiPromise$2;
10
+ const idStr = Array.from(priceIds).join(',');
11
+ const getPriceMap = async () => {
12
+ var _rs, _rs2;
13
+ let rs;
14
+ if (!useBackupApi) {
15
+ try {
16
+ rs = await axios.get(`https://api.coingecko.com/api/v3/coins/markets?vs_currency=${currencyCode.toLowerCase()}&per_page=250&ids=${idStr}`);
17
+ } catch (err) {
18
+ useBackupApi = true;
19
+ }
20
+ }
21
+ if (useBackupApi || ((_rs = rs) === null || _rs === void 0 ? void 0 : _rs.status) !== 200) {
22
+ useBackupApi = true;
23
+ rs = await axios.get(`https://chain-data.subwallet.app/api/price/get?ids=${idStr}`);
24
+ }
25
+ if (((_rs2 = rs) === null || _rs2 === void 0 ? void 0 : _rs2.status) !== 200) {
26
+ console.warn('Failed to get token price');
27
+ }
28
+ return rs;
29
+ };
30
+ const getExchangeRate = async () => {
31
+ var _rs3;
32
+ let rs;
33
+ try {
34
+ rs = await axios.get('https://api-cache.subwallet.app/exchange-rate');
35
+ } catch (e) {
36
+ console.warn('Failed to get exchange rate');
37
+ }
38
+ if (((_rs3 = rs) === null || _rs3 === void 0 ? void 0 : _rs3.status) !== 200) {
39
+ console.warn('Failed to get exchange rate');
40
+ }
41
+ return rs;
42
+ };
43
+ const resMultiPromise = await Promise.all([getPriceMap(), getExchangeRate()]);
44
+ const responseDataPrice = ((_resMultiPromise$ = resMultiPromise[0]) === null || _resMultiPromise$ === void 0 ? void 0 : _resMultiPromise$.data) || [];
45
+ const responseDataExchangeRate = ((_resMultiPromise$2 = resMultiPromise[1]) === null || _resMultiPromise$2 === void 0 ? void 0 : _resMultiPromise$2.data) || {};
11
46
  const priceMap = {};
12
47
  const price24hMap = {};
13
- responseData.forEach(val => {
48
+ const exchangeRateMap = Object.keys(responseDataExchangeRate.conversion_rates).reduce((map, exchangeKey) => {
49
+ if (!staticData[StaticKey.CURRENCY_SYMBOL][exchangeKey]) {
50
+ return map;
51
+ }
52
+ map[exchangeKey] = {
53
+ exchange: responseDataExchangeRate.conversion_rates[exchangeKey],
54
+ label: staticData[StaticKey.CURRENCY_SYMBOL][exchangeKey].label
55
+ };
56
+ return map;
57
+ }, {});
58
+ const currencyData = staticData[StaticKey.CURRENCY_SYMBOL][currencyCode];
59
+ responseDataPrice.forEach(val => {
14
60
  const currentPrice = val.current_price || 0;
15
61
  const price24h = currentPrice - (val.price_change_24h || 0);
16
- priceMap[val.id] = currentPrice;
17
- price24hMap[val.id] = price24h;
18
-
19
- // if (inverseMap[val.id]) {
20
- // priceMap[inverseMap[val.id]] = currentPrice;
21
- // price24hMap[inverseMap[val.id]] = price24h;
22
- // }
62
+ const exchangeRate = exchangeRateMap[currencyCode] || 1;
63
+ priceMap[val.id] = currentPrice * exchangeRate.exchange;
64
+ price24hMap[val.id] = price24h * exchangeRate.exchange;
23
65
  });
24
-
25
66
  return {
26
- currency,
67
+ currency: currencyCode,
68
+ currencyData,
69
+ exchangeRateMap,
27
70
  priceMap,
28
71
  price24hMap
29
72
  };
@@ -88,6 +88,8 @@ export const TRANSFER_CHAIN_ID = {
88
88
  [SUPPORTED_TRANSFER_EVM_CHAIN_NAME.shibuya]: 81
89
89
  };
90
90
  export let SUPPORTED_TRANSFER_SUBSTRATE_CHAIN_NAME;
91
+
92
+ // This is for localhost or http only
91
93
  (function (SUPPORTED_TRANSFER_SUBSTRATE_CHAIN_NAME) {
92
94
  SUPPORTED_TRANSFER_SUBSTRATE_CHAIN_NAME["statemine"] = "statemine";
93
95
  SUPPORTED_TRANSFER_SUBSTRATE_CHAIN_NAME["acala"] = "acala";
@@ -110,33 +112,39 @@ if (isFirefox) {
110
112
  weight: 5000
111
113
  });
112
114
  }
113
- if (!RuntimeInfo.protocol || !RuntimeInfo.protocol.startsWith('http') || RuntimeInfo.protocol.startsWith('https')) {
115
+ if (RuntimeInfo.protocol && RuntimeInfo.protocol.startsWith('http')) {
116
+ // This is for https
117
+ if (RuntimeInfo.protocol.startsWith('https')) {
118
+ RANDOM_IPFS_GATEWAY_SETTING.push({
119
+ provider: IPFS_FLEEK,
120
+ weight: 4
121
+ }, {
122
+ provider: IPFS_GATEWAY_4EVERLAND,
123
+ weight: 2
124
+ }, {
125
+ provider: IPFS_W3S_LINK,
126
+ weight: 1
127
+ }, {
128
+ provider: CF_IPFS_GATEWAY,
129
+ weight: 4
130
+ }, {
131
+ provider: PINATA_IPFS_GATEWAY,
132
+ weight: 1 // Rate limit too low
133
+ }, {
134
+ provider: IPFS_IO,
135
+ weight: 5
136
+ });
137
+ }
138
+ } else {
139
+ // This is for extension env or other
114
140
  RANDOM_IPFS_GATEWAY_SETTING.push({
115
- provider: IPFS_FLEEK,
116
- weight: 4
117
- }, {
118
- provider: IPFS_GATEWAY_4EVERLAND,
119
- weight: 2
120
- }, {
121
- provider: IPFS_W3S_LINK,
122
- weight: 1
123
- }, {
124
- provider: CF_IPFS_GATEWAY,
125
- weight: 4
126
- }, {
127
- provider: PINATA_IPFS_GATEWAY,
128
- weight: 1 // Rate limit too low
129
- }, {
130
141
  provider: NFT_STORAGE_GATEWAY,
131
142
  weight: 50
132
- }, {
133
- provider: GATEWAY_IPFS_IO,
134
- weight: 5
135
143
  }, {
136
144
  provider: DWEB_LINK,
137
145
  weight: 5
138
146
  }, {
139
- provider: IPFS_IO,
147
+ provider: GATEWAY_IPFS_IO,
140
148
  weight: 5
141
149
  });
142
150
  }
@@ -157,7 +157,7 @@ export declare function getWithdrawalInfo(nominatorMetadata: NominatorMetadata):
157
157
  export declare function getEarningStatusByNominations(bnTotalActiveStake: BN, nominationList: NominationInfo[]): EarningStatus;
158
158
  export declare function getValidatorLabel(chain: string): "dApp" | "Validator" | "Collator";
159
159
  export declare function getAvgValidatorEraReward(supportedDays: number, eraRewardHistory: Codec[]): BigNumber;
160
- export declare function getSupportedDaysByHistoryDepth(erasPerDay: number, maxSupportedEras: number): 15 | 30;
160
+ export declare function getSupportedDaysByHistoryDepth(erasPerDay: number, maxSupportedEras: number, liveDay?: number): number;
161
161
  export declare function getValidatorPointsMap(eraRewardMap: Record<string, PalletStakingEraRewardPoints>): Record<string, BigNumber>;
162
162
  export declare function getTopValidatorByPoints(validatorPointsList: Record<string, BigNumber>): string[];
163
163
  export declare const getMinStakeErrorMessage: (chainInfo: _ChainInfo, bnMinStake: BN) => string;
@@ -343,11 +343,15 @@ export function getAvgValidatorEraReward(supportedDays, eraRewardHistory) {
343
343
  }
344
344
  return sumEraReward.dividedBy(new BigNumber(supportedDays - failEra));
345
345
  }
346
- export function getSupportedDaysByHistoryDepth(erasPerDay, maxSupportedEras) {
347
- if (maxSupportedEras / erasPerDay > 30) {
346
+ export function getSupportedDaysByHistoryDepth(erasPerDay, maxSupportedEras, liveDay) {
347
+ const maxSupportDay = maxSupportedEras / erasPerDay;
348
+ if (liveDay && liveDay <= 30) {
349
+ return Math.min(liveDay - 1, maxSupportDay);
350
+ }
351
+ if (maxSupportDay > 30) {
348
352
  return 30;
349
353
  } else {
350
- return 15;
354
+ return maxSupportDay;
351
355
  }
352
356
  }
353
357
  export function getValidatorPointsMap(eraRewardMap) {
@@ -88,6 +88,7 @@ export default class KoniExtension {
88
88
  private subscribeAssetSetting;
89
89
  private updateAssetSetting;
90
90
  private getPrice;
91
+ private setPriceCurrency;
91
92
  private subscribePrice;
92
93
  private getBalance;
93
94
  private subscribeBalance;
@@ -1024,6 +1024,11 @@ export default class KoniExtension {
1024
1024
  async getPrice() {
1025
1025
  return this.#koniState.priceService.getPrice();
1026
1026
  }
1027
+ async setPriceCurrency({
1028
+ currency
1029
+ }) {
1030
+ return await this.#koniState.priceService.setPriceCurrency(currency);
1031
+ }
1027
1032
  subscribePrice(id, port) {
1028
1033
  const cb = createSubscription(id, port);
1029
1034
  const priceSubscription = this.#koniState.priceService.getPriceSubject().subscribe(rs => {
@@ -4158,6 +4163,8 @@ export default class KoniExtension {
4158
4163
  return await this.getPrice();
4159
4164
  case 'pri(price.getSubscription)':
4160
4165
  return await this.subscribePrice(id, port);
4166
+ case 'pri(settings.savePriceCurrency)':
4167
+ return await this.setPriceCurrency(request);
4161
4168
  case 'pri(balance.getBalance)':
4162
4169
  return await this.getBalance();
4163
4170
  case 'pri(balance.getSubscription)':
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "./cjs/detectPackage.js"
18
18
  ],
19
19
  "type": "module",
20
- "version": "1.1.58-0",
20
+ "version": "1.1.60-0",
21
21
  "main": "./cjs/index.js",
22
22
  "module": "./index.js",
23
23
  "types": "./index.d.ts",
@@ -1829,6 +1829,7 @@
1829
1829
  "./utils/staticData/buyTokenConfigs.json": "./utils/staticData/buyTokenConfigs.json",
1830
1830
  "./utils/staticData/chains.json": "./utils/staticData/chains.json",
1831
1831
  "./utils/staticData/crowdloanFunds.json": "./utils/staticData/crowdloanFunds.json",
1832
+ "./utils/staticData/currencySymbol.json": "./utils/staticData/currencySymbol.json",
1832
1833
  "./utils/staticData/marketingCampaigns.json": "./utils/staticData/marketingCampaigns.json",
1833
1834
  "./utils/staticData/termAndCondition.json": "./utils/staticData/termAndCondition.json",
1834
1835
  "./utils/swap": {
@@ -1873,11 +1874,11 @@
1873
1874
  "@reduxjs/toolkit": "^1.9.1",
1874
1875
  "@sora-substrate/type-definitions": "^1.17.7",
1875
1876
  "@substrate/connect": "^0.8.9",
1876
- "@subwallet/chain-list": "0.2.57",
1877
- "@subwallet/extension-base": "^1.1.58-0",
1878
- "@subwallet/extension-chains": "^1.1.58-0",
1879
- "@subwallet/extension-dapp": "^1.1.58-0",
1880
- "@subwallet/extension-inject": "^1.1.58-0",
1877
+ "@subwallet/chain-list": "0.2.58",
1878
+ "@subwallet/extension-base": "^1.1.60-0",
1879
+ "@subwallet/extension-chains": "^1.1.60-0",
1880
+ "@subwallet/extension-dapp": "^1.1.60-0",
1881
+ "@subwallet/extension-inject": "^1.1.60-0",
1881
1882
  "@subwallet/keyring": "^0.1.5",
1882
1883
  "@subwallet/ui-keyring": "^0.1.5",
1883
1884
  "@walletconnect/sign-client": "^2.8.4",
package/packageInfo.js CHANGED
@@ -7,5 +7,5 @@ export const packageInfo = {
7
7
  name: '@subwallet/extension-base',
8
8
  path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto',
9
9
  type: 'esm',
10
- version: '1.1.58-0'
10
+ version: '1.1.60-0'
11
11
  };
@@ -7,7 +7,7 @@ import { SUB_TOKEN_REFRESH_BALANCE_INTERVAL } from '@subwallet/extension-base/co
7
7
  import { getPSP22ContractPromise } from '@subwallet/extension-base/koni/api/tokens/wasm';
8
8
  import { getDefaultWeightV2 } from '@subwallet/extension-base/koni/api/tokens/wasm/utils';
9
9
  import { _BALANCE_CHAIN_GROUP, _MANTA_ZK_CHAIN_GROUP, _ZK_ASSET_PREFIX } from '@subwallet/extension-base/services/chain-service/constants';
10
- import { _checkSmartContractSupportByChain, _getChainNativeTokenSlug, _getContractAddressOfToken, _getTokenOnChainAssetId, _getTokenOnChainInfo, _getXcmAssetMultilocation, _isBridgedToken, _isChainEvmCompatible, _isSubstrateRelayChain } from '@subwallet/extension-base/services/chain-service/utils';
10
+ import { _checkSmartContractSupportByChain, _getChainNativeTokenSlug, _getContractAddressOfToken, _getTokenOnChainAssetId, _getTokenOnChainInfo, _getTokenTypesSupportedByChain, _getXcmAssetMultilocation, _isBridgedToken, _isChainEvmCompatible, _isSubstrateRelayChain } from '@subwallet/extension-base/services/chain-service/utils';
11
11
  import { filterAssetsByChainAndType } from '@subwallet/extension-base/utils';
12
12
  import { combineLatest, Observable } from 'rxjs';
13
13
  import { BN, BN_ZERO } from '@polkadot/util';
@@ -54,7 +54,13 @@ export const subscribeSubstrateBalance = async (addresses, chainInfo, assetMap,
54
54
  if (_BALANCE_CHAIN_GROUP.supportBridged.includes(chain)) {
55
55
  unsubBridgedToken = await subscribeBridgedBalance(substrateParams);
56
56
  }
57
- if (_isChainEvmCompatible(chainInfo)) {
57
+
58
+ /**
59
+ * Some substrate chain use evm account format but not have evm connection and support ERC20 contract,
60
+ * so we need to check if the chain is compatible with EVM and support ERC20
61
+ * */
62
+ if (_isChainEvmCompatible(chainInfo) && _getTokenTypesSupportedByChain(chainInfo).includes(_AssetType.ERC20)) {
63
+ // Get sub-token for EVM-compatible chains
58
64
  unsubEvmContractToken = subscribeERC20Interval({
59
65
  ...baseParams,
60
66
  evmApi: evmApi
@@ -90,7 +90,8 @@ export const _STAKING_ERA_LENGTH_MAP = {
90
90
  manta_network: 6,
91
91
  krest_network: 4,
92
92
  polimec: 6,
93
- enjin_relaychain: 24
93
+ enjin_relaychain: 24,
94
+ availTuringTest: 24
94
95
  };
95
96
  export const _EXPECTED_BLOCK_TIME = {
96
97
  // in seconds
@@ -119,7 +120,8 @@ export const _EXPECTED_BLOCK_TIME = {
119
120
  calamari: 12,
120
121
  calamari_test: 12,
121
122
  manta_network: 12,
122
- enjin_relaychain: 6
123
+ enjin_relaychain: 6,
124
+ availTuringTest: 20
123
125
  };
124
126
  export const _PARACHAIN_INFLATION_DISTRIBUTION = {
125
127
  moonbeam: {
@@ -645,7 +645,12 @@ export class ChainService {
645
645
  this.substrateChainHandler.setSubstrateApi(chainInfo.slug, chainApi);
646
646
  }
647
647
  }
648
- if (chainInfo.evmInfo !== null && chainInfo.evmInfo !== undefined) {
648
+
649
+ /**
650
+ * To check if the chain is EVM chain, we need to check if the chain has evmInfo and evmChainId is not -1
651
+ * (fake evm chain to connect to substrate chain)
652
+ * */
653
+ if (chainInfo.evmInfo !== null && chainInfo.evmInfo !== undefined && chainInfo.evmInfo.evmChainId !== -1) {
649
654
  const chainApi = await this.evmChainHandler.initApi(chainInfo.slug, endpoint, {
650
655
  providerName,
651
656
  onUpdateStatus
@@ -11,6 +11,19 @@ export declare function _isPureEvmChain(chainInfo: _ChainInfo): boolean;
11
11
  export declare function _isPureSubstrateChain(chainInfo: _ChainInfo): boolean;
12
12
  export declare function _getOriginChainOfAsset(assetSlug: string): string;
13
13
  export declare function _getContractAddressOfToken(tokenInfo: _ChainAsset): string;
14
+ /**
15
+ * @function _isNativeTokenTransferredByEvm
16
+ * @description Check if the native token is transferred by EVM, some token is only transferred by Substrate, need to check disableEvmTransfer flag
17
+ * @param {_ChainAsset} tokenInfo - The token info object
18
+ * @returns {boolean} - Return true if the native token can transfer by EVM
19
+ * */
20
+ export declare function _isNativeTokenTransferredByEvm(tokenInfo: _ChainAsset): boolean;
21
+ /**
22
+ * @function _isTokenTransferredByEvm
23
+ * @description Check if the token is transferred by EVM
24
+ * @param {_ChainAsset} tokenInfo - The token info object
25
+ * @returns {boolean} - Return true if the token can transfer by EVM
26
+ * */
14
27
  export declare function _isTokenTransferredByEvm(tokenInfo: _ChainAsset): boolean;
15
28
  export declare function _checkSmartContractSupportByChain(chainInfo: _ChainInfo, contractType: _AssetType): boolean;
16
29
  export declare function _getTokenOnChainAssetId(tokenInfo: _ChainAsset): string;
@@ -67,9 +67,27 @@ export function _getContractAddressOfToken(tokenInfo) {
67
67
  var _tokenInfo$metadata;
68
68
  return ((_tokenInfo$metadata = tokenInfo.metadata) === null || _tokenInfo$metadata === void 0 ? void 0 : _tokenInfo$metadata.contractAddress) || '';
69
69
  }
70
- export function _isTokenTransferredByEvm(tokenInfo) {
70
+
71
+ /**
72
+ * @function _isNativeTokenTransferredByEvm
73
+ * @description Check if the native token is transferred by EVM, some token is only transferred by Substrate, need to check disableEvmTransfer flag
74
+ * @param {_ChainAsset} tokenInfo - The token info object
75
+ * @returns {boolean} - Return true if the native token can transfer by EVM
76
+ * */
77
+ export function _isNativeTokenTransferredByEvm(tokenInfo) {
71
78
  var _tokenInfo$metadata2;
72
- return !!((_tokenInfo$metadata2 = tokenInfo.metadata) !== null && _tokenInfo$metadata2 !== void 0 && _tokenInfo$metadata2.contractAddress) || _isNativeToken(tokenInfo);
79
+ return !((_tokenInfo$metadata2 = tokenInfo.metadata) !== null && _tokenInfo$metadata2 !== void 0 && _tokenInfo$metadata2.disableEvmTransfer);
80
+ }
81
+
82
+ /**
83
+ * @function _isTokenTransferredByEvm
84
+ * @description Check if the token is transferred by EVM
85
+ * @param {_ChainAsset} tokenInfo - The token info object
86
+ * @returns {boolean} - Return true if the token can transfer by EVM
87
+ * */
88
+ export function _isTokenTransferredByEvm(tokenInfo) {
89
+ var _tokenInfo$metadata3;
90
+ return !!((_tokenInfo$metadata3 = tokenInfo.metadata) !== null && _tokenInfo$metadata3 !== void 0 && _tokenInfo$metadata3.contractAddress) || _isNativeToken(tokenInfo) && _isNativeTokenTransferredByEvm(tokenInfo);
73
91
  }
74
92
  export function _checkSmartContractSupportByChain(chainInfo, contractType) {
75
93
  // EVM chains support smart contract by default so just checking Substrate chains
@@ -81,16 +99,16 @@ export function _checkSmartContractSupportByChain(chainInfo, contractType) {
81
99
 
82
100
  // Utils for balance functions
83
101
  export function _getTokenOnChainAssetId(tokenInfo) {
84
- var _tokenInfo$metadata3;
85
- return ((_tokenInfo$metadata3 = tokenInfo.metadata) === null || _tokenInfo$metadata3 === void 0 ? void 0 : _tokenInfo$metadata3.assetId) || '-1';
102
+ var _tokenInfo$metadata4;
103
+ return ((_tokenInfo$metadata4 = tokenInfo.metadata) === null || _tokenInfo$metadata4 === void 0 ? void 0 : _tokenInfo$metadata4.assetId) || '-1';
86
104
  }
87
105
  export function _getTokenOnChainInfo(tokenInfo) {
88
- var _tokenInfo$metadata4;
89
- return (_tokenInfo$metadata4 = tokenInfo.metadata) === null || _tokenInfo$metadata4 === void 0 ? void 0 : _tokenInfo$metadata4.onChainInfo;
106
+ var _tokenInfo$metadata5;
107
+ return (_tokenInfo$metadata5 = tokenInfo.metadata) === null || _tokenInfo$metadata5 === void 0 ? void 0 : _tokenInfo$metadata5.onChainInfo;
90
108
  }
91
109
  export function _isBridgedToken(tokenInfo) {
92
- var _tokenInfo$metadata5;
93
- return (_tokenInfo$metadata5 = tokenInfo.metadata) === null || _tokenInfo$metadata5 === void 0 ? void 0 : _tokenInfo$metadata5.isBridged;
110
+ var _tokenInfo$metadata6;
111
+ return (_tokenInfo$metadata6 = tokenInfo.metadata) === null || _tokenInfo$metadata6 === void 0 ? void 0 : _tokenInfo$metadata6.isBridged;
94
112
  }
95
113
  export function _getTokenMinAmount(tokenInfo) {
96
114
  return tokenInfo.minAmount || '0';
@@ -244,16 +262,16 @@ export function _isXcmPathSupported(originTokenSlug, destinationTokenSlug, asset
244
262
  return assetRef.path === _AssetRefPath.XCM;
245
263
  }
246
264
  export function _getXcmAssetType(tokenInfo) {
247
- var _tokenInfo$metadata6;
248
- return ((_tokenInfo$metadata6 = tokenInfo.metadata) === null || _tokenInfo$metadata6 === void 0 ? void 0 : _tokenInfo$metadata6.assetType) || '';
265
+ var _tokenInfo$metadata7;
266
+ return ((_tokenInfo$metadata7 = tokenInfo.metadata) === null || _tokenInfo$metadata7 === void 0 ? void 0 : _tokenInfo$metadata7.assetType) || '';
249
267
  }
250
268
  export function _getXcmAssetId(tokenInfo) {
251
- var _tokenInfo$metadata7;
252
- return ((_tokenInfo$metadata7 = tokenInfo.metadata) === null || _tokenInfo$metadata7 === void 0 ? void 0 : _tokenInfo$metadata7.assetId) || '-1';
269
+ var _tokenInfo$metadata8;
270
+ return ((_tokenInfo$metadata8 = tokenInfo.metadata) === null || _tokenInfo$metadata8 === void 0 ? void 0 : _tokenInfo$metadata8.assetId) || '-1';
253
271
  }
254
272
  export function _getXcmAssetMultilocation(tokenInfo) {
255
- var _tokenInfo$metadata8;
256
- return (_tokenInfo$metadata8 = tokenInfo.metadata) === null || _tokenInfo$metadata8 === void 0 ? void 0 : _tokenInfo$metadata8.multilocation;
273
+ var _tokenInfo$metadata9;
274
+ return (_tokenInfo$metadata9 = tokenInfo.metadata) === null || _tokenInfo$metadata9 === void 0 ? void 0 : _tokenInfo$metadata9.multilocation;
257
275
  }
258
276
  export function _getXcmTransferType(originChainInfo, destinationChainInfo) {
259
277
  var _originChainInfo$subs, _destinationChainInfo;
@@ -2,13 +2,13 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  export const _STAKING_CHAIN_GROUP = {
5
- relay: ['polkadot', 'kusama', 'aleph', 'polkadex', 'ternoa', 'alephTest', 'polkadexTest', 'westend', 'kate', 'edgeware', 'creditcoin', 'vara_network', 'goldberg_testnet'],
5
+ relay: ['polkadot', 'kusama', 'aleph', 'polkadex', 'ternoa', 'alephTest', 'polkadexTest', 'westend', 'kate', 'edgeware', 'creditcoin', 'vara_network', 'goldberg_testnet', 'availTuringTest'],
6
6
  para: ['moonbeam', 'moonriver', 'moonbase', 'turing', 'turingStaging', 'bifrost', 'bifrost_testnet', 'calamari_test', 'calamari', 'manta_network', 'polimec'],
7
7
  astar: ['astar', 'shiden', 'shibuya'],
8
8
  amplitude: ['amplitude', 'amplitude_test', 'kilt', 'kilt_peregrine', 'pendulum', 'krest_network'],
9
9
  // amplitude and kilt only share some common logic
10
10
  kilt: ['kilt', 'kilt_peregrine'],
11
- nominationPool: ['polkadot', 'kusama', 'westend', 'alephTest', 'aleph', 'kate', 'vara_network', 'goldberg_testnet'],
11
+ nominationPool: ['polkadot', 'kusama', 'westend', 'alephTest', 'aleph', 'kate', 'vara_network', 'goldberg_testnet', 'availTuringTest'],
12
12
  bifrost: ['bifrost', 'bifrost_testnet'],
13
13
  aleph: ['aleph', 'alephTest'],
14
14
  // A0 has distinct tokenomics
@@ -57,9 +57,9 @@ export default class RelayNativeStakingPoolHandler extends BaseNativeStakingPool
57
57
  const maxUnlockingChunks = substrateApi.api.consts.staking.maxUnlockingChunks.toString();
58
58
  const unlockingEras = substrateApi.api.consts.staking.bondingDuration.toString();
59
59
  const maxSupportedEras = substrateApi.api.consts.staking.historyDepth.toString();
60
- const erasPerDay = 24 / _STAKING_ERA_LENGTH_MAP[chainInfo.slug]; // Can be exactly calculate from epochDuration, blockTime, sessionsPerEra
60
+ const erasPerDay = 24 / _STAKING_ERA_LENGTH_MAP[chainInfo.slug]; // Can be exactly calculate from babe.epochDuration * blockTime * staking.sessionsPerEra
61
61
 
62
- const supportedDays = getSupportedDaysByHistoryDepth(erasPerDay, parseInt(maxSupportedEras));
62
+ const supportedDays = getSupportedDaysByHistoryDepth(erasPerDay, parseInt(maxSupportedEras), parseInt(currentEra) / erasPerDay);
63
63
  const startEra = parseInt(currentEra) - supportedDays * erasPerDay;
64
64
  const [_EraStakeInfo, _totalIssuance, _auctionCounter, _minNominatorBond, _counterForNominators, _minimumActiveStake, ..._eraReward] = await Promise.all([substrateApi.api.query.staking.erasTotalStake.multi([parseInt(currentEra), parseInt(currentEra) - 1]), substrateApi.api.query.balances.totalIssuance(), (_substrateApi$api$que2 = substrateApi.api.query.auctions) === null || _substrateApi$api$que2 === void 0 ? void 0 : _substrateApi$api$que2.auctionCounter(), substrateApi.api.query.staking.minNominatorBond(), substrateApi.api.query.staking.counterForNominators(), ((_substrateApi$api$que3 = substrateApi.api.query) === null || _substrateApi$api$que3 === void 0 ? void 0 : (_substrateApi$api$que4 = _substrateApi$api$que3.staking) === null || _substrateApi$api$que4 === void 0 ? void 0 : _substrateApi$api$que4.minimumActiveStake) && ((_substrateApi$api$que5 = substrateApi.api.query) === null || _substrateApi$api$que5 === void 0 ? void 0 : (_substrateApi$api$que6 = _substrateApi$api$que5.staking) === null || _substrateApi$api$que6 === void 0 ? void 0 : _substrateApi$api$que6.minimumActiveStake()), substrateApi.api.query.staking.erasValidatorReward.multi([...Array(supportedDays).keys()].map(i => i + startEra))]);
65
65
  const [_totalEraStake, _lastTotalStaked] = _EraStakeInfo;
@@ -144,7 +144,7 @@ export default class RelayNativeStakingPoolHandler extends BaseNativeStakingPool
144
144
  let nominationStatus = EarningStatus.NOT_EARNING;
145
145
  let eraStakerOtherList = [];
146
146
  let identity;
147
- if (['kusama', 'polkadot', 'westend'].includes(this.chain)) {
147
+ if (['kusama', 'polkadot', 'westend', 'availTuringTest'].includes(this.chain)) {
148
148
  // todo: review all relaychains later
149
149
  const [[_identity], _eraStaker] = await Promise.all([parseIdentity(substrateApi, validatorAddress), substrateApi.api.query.staking.erasStakersPaged.entries(currentEra, validatorAddress)]);
150
150
  identity = _identity;
@@ -298,7 +298,7 @@ export default class RelayNativeStakingPoolHandler extends BaseNativeStakingPool
298
298
  const endEraForPoints = parseInt(activeEra) - 1;
299
299
  let startEraForPoints = endEraForPoints - maxEraRewardPointsEras + 1;
300
300
  let _eraStakersPromise;
301
- if (['kusama', 'polkadot', 'westend'].includes(this.chain)) {
301
+ if (['kusama', 'polkadot', 'westend', 'availTuringTest'].includes(this.chain)) {
302
302
  // todo: review all relaychains later
303
303
  _eraStakersPromise = chainApi.api.query.staking.erasStakersOverview.entries(parseInt(currentEra));
304
304
  } else {
@@ -81,7 +81,7 @@ export default class NominationPoolHandler extends BasePoolHandler {
81
81
  const maxSupportedEras = substrateApi.api.consts.staking.historyDepth.toString();
82
82
  const erasPerDay = 24 / _STAKING_ERA_LENGTH_MAP[chainInfo.slug]; // Can be exactly calculate from epochDuration, blockTime, sessionsPerEra
83
83
 
84
- const supportedDays = getSupportedDaysByHistoryDepth(erasPerDay, parseInt(maxSupportedEras));
84
+ const supportedDays = getSupportedDaysByHistoryDepth(erasPerDay, parseInt(maxSupportedEras), parseInt(currentEra) / erasPerDay);
85
85
  const startEra = parseInt(currentEra) - supportedDays * erasPerDay;
86
86
  const [_EraStakeInfo, _totalIssuance, _auctionCounter, _minPoolJoin, ..._eraReward] = await Promise.all([substrateApi.api.query.staking.erasTotalStake.multi([parseInt(currentEra), parseInt(currentEra) - 1]), substrateApi.api.query.balances.totalIssuance(), (_substrateApi$api$que2 = substrateApi.api.query.auctions) === null || _substrateApi$api$que2 === void 0 ? void 0 : _substrateApi$api$que2.auctionCounter(), (_substrateApi$api$que3 = substrateApi.api.query) === null || _substrateApi$api$que3 === void 0 ? void 0 : (_substrateApi$api$que4 = _substrateApi$api$que3.nominationPools) === null || _substrateApi$api$que4 === void 0 ? void 0 : _substrateApi$api$que4.minJoinBond(), substrateApi.api.query.staking.erasValidatorReward.multi([...Array(supportedDays).keys()].map(i => i + startEra))]);
87
87
  const [_totalEraStake, _lastTotalStaked] = _EraStakeInfo;
@@ -159,7 +159,7 @@ export default class NominationPoolHandler extends BasePoolHandler {
159
159
  const validatorList = nominations.targets;
160
160
  await Promise.all(validatorList.map(async validatorAddress => {
161
161
  let eraStakerOtherList = [];
162
- if (['kusama', 'polkadot', 'westend'].includes(this.chain)) {
162
+ if (['kusama', 'polkadot', 'westend', 'availTuringTest'].includes(this.chain)) {
163
163
  // todo: review all relaychains later
164
164
  const _eraStaker = await substrateApi.api.query.staking.erasStakersPaged.entries(currentEra, validatorAddress);
165
165
  eraStakerOtherList = _eraStaker.flatMap(paged => paged[1].toPrimitive().others);
@@ -1,2 +1,3 @@
1
- import { PriceJson } from '@subwallet/extension-base/background/KoniTypes';
2
- export declare const getTokenPrice: (priceIds: Set<string>, currency?: string) => Promise<PriceJson>;
1
+ import { CurrencyType, ExchangeRateJSON, PriceJson } from '@subwallet/extension-base/background/KoniTypes';
2
+ export declare const getExchangeRateMap: () => Promise<Record<CurrencyType, ExchangeRateJSON>>;
3
+ export declare const getPriceMap: (priceIds: Set<string>, currency?: CurrencyType) => Promise<Omit<PriceJson, 'exchangeRateMap'>>;
@@ -1,43 +1,61 @@
1
1
  // Copyright 2019-2022 @subwallet/extension-koni authors & contributors
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
+ import { staticData, StaticKey } from '@subwallet/extension-base/utils/staticData';
4
5
  import axios from 'axios';
6
+ const DEFAULT_CURRENCY = 'USD';
5
7
  let useBackupApi = false;
6
- export const getTokenPrice = async (priceIds, currency = 'usd') => {
8
+ export const getExchangeRateMap = async () => {
7
9
  try {
8
- var _res;
9
- const idStr = Array.from(priceIds).join(',');
10
- let res;
11
- if (!useBackupApi) {
12
- try {
13
- res = await axios.get(`https://api.coingecko.com/api/v3/coins/markets?vs_currency=${currency}&per_page=250&ids=${idStr}`);
14
- } catch (err) {
15
- useBackupApi = true;
10
+ const responseDataExchangeRate = (await axios.get('https://api-cache.subwallet.app/exchange-rate')).data || {};
11
+ const exchangeRateMap = Object.keys(responseDataExchangeRate.conversion_rates).reduce((map, exchangeKey) => {
12
+ if (!staticData[StaticKey.CURRENCY_SYMBOL][exchangeKey]) {
13
+ return map;
16
14
  }
17
- }
18
- if (useBackupApi || ((_res = res) === null || _res === void 0 ? void 0 : _res.status) !== 200) {
15
+ map[exchangeKey] = {
16
+ exchange: responseDataExchangeRate.conversion_rates[exchangeKey],
17
+ label: staticData[StaticKey.CURRENCY_SYMBOL][exchangeKey].label
18
+ };
19
+ return map;
20
+ }, {});
21
+ return exchangeRateMap;
22
+ } catch (e) {
23
+ console.warn('Failed to get exchange rate');
24
+ return {};
25
+ }
26
+ };
27
+ export const getPriceMap = async (priceIds, currency = 'USD') => {
28
+ var _rs, _rs2, _rs3;
29
+ const idStr = Array.from(priceIds).join(',');
30
+ let rs;
31
+ if (!useBackupApi) {
32
+ try {
33
+ rs = await axios.get(`https://api.coingecko.com/api/v3/coins/markets?vs_currency=${currency.toLowerCase()}&per_page=250&ids=${idStr}`);
34
+ } catch (err) {
19
35
  useBackupApi = true;
20
- res = await axios.get(`https://chain-data.subwallet.app/api/price/get?ids=${idStr}`);
21
- }
22
- if (res.status !== 200) {
23
- console.warn('Failed to get token price');
24
36
  }
25
- const responseData = res.data || [];
26
- const priceMap = {};
27
- const price24hMap = {};
28
- responseData.forEach(val => {
29
- const currentPrice = val.current_price || 0;
30
- const price24h = currentPrice - (val.price_change_24h || 0);
31
- priceMap[val.id] = currentPrice;
32
- price24hMap[val.id] = price24h;
33
- });
34
- return {
35
- currency,
36
- priceMap,
37
- price24hMap
38
- };
39
- } catch (err) {
40
- console.error(err);
41
- throw err;
42
37
  }
38
+ if (useBackupApi || ((_rs = rs) === null || _rs === void 0 ? void 0 : _rs.status) !== 200) {
39
+ useBackupApi = true;
40
+ rs = await axios.get(`https://chain-data.subwallet.app/api/price/get?ids=${idStr}`);
41
+ }
42
+ if (((_rs2 = rs) === null || _rs2 === void 0 ? void 0 : _rs2.status) !== 200) {
43
+ console.warn('Failed to get token price');
44
+ }
45
+ const responseDataPrice = ((_rs3 = rs) === null || _rs3 === void 0 ? void 0 : _rs3.data) || [];
46
+ const currencyData = staticData[StaticKey.CURRENCY_SYMBOL][currency || DEFAULT_CURRENCY];
47
+ const priceMap = {};
48
+ const price24hMap = {};
49
+ responseDataPrice.forEach(val => {
50
+ const currentPrice = val.current_price || 0;
51
+ const price24h = currentPrice - (val.price_change_24h || 0);
52
+ priceMap[val.id] = currentPrice;
53
+ price24hMap[val.id] = price24h;
54
+ });
55
+ return {
56
+ currency,
57
+ currencyData,
58
+ priceMap,
59
+ price24hMap
60
+ };
43
61
  };
@@ -1,4 +1,4 @@
1
- import { PriceJson } from '@subwallet/extension-base/background/KoniTypes';
1
+ import { CurrencyType, PriceJson } from '@subwallet/extension-base/background/KoniTypes';
2
2
  import { CronServiceInterface, PersistDataServiceInterface, ServiceStatus, StoppableServiceInterface } from '@subwallet/extension-base/services/base/types';
3
3
  import { ChainService } from '@subwallet/extension-base/services/chain-service';
4
4
  import { EventService } from '@subwallet/extension-base/services/event-service';
@@ -10,13 +10,18 @@ export declare class PriceService implements StoppableServiceInterface, PersistD
10
10
  private eventService;
11
11
  private chainService;
12
12
  private priceSubject;
13
+ private rawPriceSubject;
14
+ private rawExchangeRateMap;
13
15
  private refreshTimeout;
14
16
  private priceIds;
17
+ private currency;
15
18
  constructor(dbService: DatabaseService, eventService: EventService, chainService: ChainService);
19
+ private getTokenPrice;
16
20
  getPrice(): Promise<PriceJson>;
17
21
  getPriceSubject(): BehaviorSubject<PriceJson>;
18
22
  getPriceIds(): Set<string>;
19
- refreshPriceData(priceIds?: Set<string>): void;
23
+ setPriceCurrency(newCurrencyCode: CurrencyType): Promise<boolean>;
24
+ refreshPriceData(priceIds?: Set<string>, resolve?: (rs: boolean) => void, reject?: (e: boolean) => void): void;
20
25
  init(): Promise<void>;
21
26
  loadData(): Promise<void>;
22
27
  persistData(): Promise<void>;