@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
@@ -13,6 +13,6 @@ const packageInfo = {
13
13
  name: '@subwallet/extension-base',
14
14
  path: typeof __dirname === 'string' ? __dirname : 'auto',
15
15
  type: 'cjs',
16
- version: '1.1.58-0'
16
+ version: '1.1.60-0'
17
17
  };
18
18
  exports.packageInfo = packageInfo;
@@ -60,7 +60,13 @@ const subscribeSubstrateBalance = async (addresses, chainInfo, assetMap, substra
60
60
  if (_constants2._BALANCE_CHAIN_GROUP.supportBridged.includes(chain)) {
61
61
  unsubBridgedToken = await subscribeBridgedBalance(substrateParams);
62
62
  }
63
- if ((0, _utils2._isChainEvmCompatible)(chainInfo)) {
63
+
64
+ /**
65
+ * Some substrate chain use evm account format but not have evm connection and support ERC20 contract,
66
+ * so we need to check if the chain is compatible with EVM and support ERC20
67
+ * */
68
+ if ((0, _utils2._isChainEvmCompatible)(chainInfo) && (0, _utils2._getTokenTypesSupportedByChain)(chainInfo).includes(_types._AssetType.ERC20)) {
69
+ // Get sub-token for EVM-compatible chains
64
70
  unsubEvmContractToken = (0, _evm.subscribeERC20Interval)({
65
71
  ...baseParams,
66
72
  evmApi: evmApi
@@ -103,7 +103,8 @@ const _STAKING_ERA_LENGTH_MAP = {
103
103
  manta_network: 6,
104
104
  krest_network: 4,
105
105
  polimec: 6,
106
- enjin_relaychain: 24
106
+ enjin_relaychain: 24,
107
+ availTuringTest: 24
107
108
  };
108
109
  exports._STAKING_ERA_LENGTH_MAP = _STAKING_ERA_LENGTH_MAP;
109
110
  const _EXPECTED_BLOCK_TIME = {
@@ -133,7 +134,8 @@ const _EXPECTED_BLOCK_TIME = {
133
134
  calamari: 12,
134
135
  calamari_test: 12,
135
136
  manta_network: 12,
136
- enjin_relaychain: 6
137
+ enjin_relaychain: 6,
138
+ availTuringTest: 20
137
139
  };
138
140
  exports._EXPECTED_BLOCK_TIME = _EXPECTED_BLOCK_TIME;
139
141
  const _PARACHAIN_INFLATION_DISTRIBUTION = {
@@ -667,7 +667,12 @@ class ChainService {
667
667
  this.substrateChainHandler.setSubstrateApi(chainInfo.slug, chainApi);
668
668
  }
669
669
  }
670
- if (chainInfo.evmInfo !== null && chainInfo.evmInfo !== undefined) {
670
+
671
+ /**
672
+ * To check if the chain is EVM chain, we need to check if the chain has evmInfo and evmChainId is not -1
673
+ * (fake evm chain to connect to substrate chain)
674
+ * */
675
+ if (chainInfo.evmInfo !== null && chainInfo.evmInfo !== undefined && chainInfo.evmInfo.evmChainId !== -1) {
671
676
  const chainApi = await this.evmChainHandler.initApi(chainInfo.slug, endpoint, {
672
677
  providerName,
673
678
  onUpdateStatus
@@ -13,6 +13,7 @@ var _exportNames = {
13
13
  _isPureSubstrateChain: true,
14
14
  _getOriginChainOfAsset: true,
15
15
  _getContractAddressOfToken: true,
16
+ _isNativeTokenTransferredByEvm: true,
16
17
  _isTokenTransferredByEvm: true,
17
18
  _checkSmartContractSupportByChain: true,
18
19
  _getTokenOnChainAssetId: true,
@@ -132,6 +133,7 @@ exports._isLocalToken = _isLocalToken;
132
133
  exports._isMantaZkAsset = _isMantaZkAsset;
133
134
  exports._isNativeToken = _isNativeToken;
134
135
  exports._isNativeTokenBySlug = _isNativeTokenBySlug;
136
+ exports._isNativeTokenTransferredByEvm = _isNativeTokenTransferredByEvm;
135
137
  exports._isPureEvmChain = _isPureEvmChain;
136
138
  exports._isPureSubstrateChain = _isPureSubstrateChain;
137
139
  exports._isSmartContractToken = _isSmartContractToken;
@@ -229,9 +231,27 @@ function _getContractAddressOfToken(tokenInfo) {
229
231
  var _tokenInfo$metadata;
230
232
  return ((_tokenInfo$metadata = tokenInfo.metadata) === null || _tokenInfo$metadata === void 0 ? void 0 : _tokenInfo$metadata.contractAddress) || '';
231
233
  }
232
- function _isTokenTransferredByEvm(tokenInfo) {
234
+
235
+ /**
236
+ * @function _isNativeTokenTransferredByEvm
237
+ * @description Check if the native token is transferred by EVM, some token is only transferred by Substrate, need to check disableEvmTransfer flag
238
+ * @param {_ChainAsset} tokenInfo - The token info object
239
+ * @returns {boolean} - Return true if the native token can transfer by EVM
240
+ * */
241
+ function _isNativeTokenTransferredByEvm(tokenInfo) {
233
242
  var _tokenInfo$metadata2;
234
- return !!((_tokenInfo$metadata2 = tokenInfo.metadata) !== null && _tokenInfo$metadata2 !== void 0 && _tokenInfo$metadata2.contractAddress) || _isNativeToken(tokenInfo);
243
+ return !((_tokenInfo$metadata2 = tokenInfo.metadata) !== null && _tokenInfo$metadata2 !== void 0 && _tokenInfo$metadata2.disableEvmTransfer);
244
+ }
245
+
246
+ /**
247
+ * @function _isTokenTransferredByEvm
248
+ * @description Check if the token is transferred by EVM
249
+ * @param {_ChainAsset} tokenInfo - The token info object
250
+ * @returns {boolean} - Return true if the token can transfer by EVM
251
+ * */
252
+ function _isTokenTransferredByEvm(tokenInfo) {
253
+ var _tokenInfo$metadata3;
254
+ return !!((_tokenInfo$metadata3 = tokenInfo.metadata) !== null && _tokenInfo$metadata3 !== void 0 && _tokenInfo$metadata3.contractAddress) || _isNativeToken(tokenInfo) && _isNativeTokenTransferredByEvm(tokenInfo);
235
255
  }
236
256
  function _checkSmartContractSupportByChain(chainInfo, contractType) {
237
257
  // EVM chains support smart contract by default so just checking Substrate chains
@@ -243,16 +263,16 @@ function _checkSmartContractSupportByChain(chainInfo, contractType) {
243
263
 
244
264
  // Utils for balance functions
245
265
  function _getTokenOnChainAssetId(tokenInfo) {
246
- var _tokenInfo$metadata3;
247
- return ((_tokenInfo$metadata3 = tokenInfo.metadata) === null || _tokenInfo$metadata3 === void 0 ? void 0 : _tokenInfo$metadata3.assetId) || '-1';
266
+ var _tokenInfo$metadata4;
267
+ return ((_tokenInfo$metadata4 = tokenInfo.metadata) === null || _tokenInfo$metadata4 === void 0 ? void 0 : _tokenInfo$metadata4.assetId) || '-1';
248
268
  }
249
269
  function _getTokenOnChainInfo(tokenInfo) {
250
- var _tokenInfo$metadata4;
251
- return (_tokenInfo$metadata4 = tokenInfo.metadata) === null || _tokenInfo$metadata4 === void 0 ? void 0 : _tokenInfo$metadata4.onChainInfo;
270
+ var _tokenInfo$metadata5;
271
+ return (_tokenInfo$metadata5 = tokenInfo.metadata) === null || _tokenInfo$metadata5 === void 0 ? void 0 : _tokenInfo$metadata5.onChainInfo;
252
272
  }
253
273
  function _isBridgedToken(tokenInfo) {
254
- var _tokenInfo$metadata5;
255
- return (_tokenInfo$metadata5 = tokenInfo.metadata) === null || _tokenInfo$metadata5 === void 0 ? void 0 : _tokenInfo$metadata5.isBridged;
274
+ var _tokenInfo$metadata6;
275
+ return (_tokenInfo$metadata6 = tokenInfo.metadata) === null || _tokenInfo$metadata6 === void 0 ? void 0 : _tokenInfo$metadata6.isBridged;
256
276
  }
257
277
  function _getTokenMinAmount(tokenInfo) {
258
278
  return tokenInfo.minAmount || '0';
@@ -407,16 +427,16 @@ function _isXcmPathSupported(originTokenSlug, destinationTokenSlug, assetRefMap)
407
427
  return assetRef.path === _types._AssetRefPath.XCM;
408
428
  }
409
429
  function _getXcmAssetType(tokenInfo) {
410
- var _tokenInfo$metadata6;
411
- return ((_tokenInfo$metadata6 = tokenInfo.metadata) === null || _tokenInfo$metadata6 === void 0 ? void 0 : _tokenInfo$metadata6.assetType) || '';
430
+ var _tokenInfo$metadata7;
431
+ return ((_tokenInfo$metadata7 = tokenInfo.metadata) === null || _tokenInfo$metadata7 === void 0 ? void 0 : _tokenInfo$metadata7.assetType) || '';
412
432
  }
413
433
  function _getXcmAssetId(tokenInfo) {
414
- var _tokenInfo$metadata7;
415
- return ((_tokenInfo$metadata7 = tokenInfo.metadata) === null || _tokenInfo$metadata7 === void 0 ? void 0 : _tokenInfo$metadata7.assetId) || '-1';
434
+ var _tokenInfo$metadata8;
435
+ return ((_tokenInfo$metadata8 = tokenInfo.metadata) === null || _tokenInfo$metadata8 === void 0 ? void 0 : _tokenInfo$metadata8.assetId) || '-1';
416
436
  }
417
437
  function _getXcmAssetMultilocation(tokenInfo) {
418
- var _tokenInfo$metadata8;
419
- return (_tokenInfo$metadata8 = tokenInfo.metadata) === null || _tokenInfo$metadata8 === void 0 ? void 0 : _tokenInfo$metadata8.multilocation;
438
+ var _tokenInfo$metadata9;
439
+ return (_tokenInfo$metadata9 = tokenInfo.metadata) === null || _tokenInfo$metadata9 === void 0 ? void 0 : _tokenInfo$metadata9.multilocation;
420
440
  }
421
441
  function _getXcmTransferType(originChainInfo, destinationChainInfo) {
422
442
  var _originChainInfo$subs, _destinationChainInfo;
@@ -8,13 +8,13 @@ exports._STAKING_CHAIN_GROUP = exports.ST_LIQUID_TOKEN_ABI = exports.MaxEraRewar
8
8
  // SPDX-License-Identifier: Apache-2.0
9
9
 
10
10
  const _STAKING_CHAIN_GROUP = {
11
- relay: ['polkadot', 'kusama', 'aleph', 'polkadex', 'ternoa', 'alephTest', 'polkadexTest', 'westend', 'kate', 'edgeware', 'creditcoin', 'vara_network', 'goldberg_testnet'],
11
+ relay: ['polkadot', 'kusama', 'aleph', 'polkadex', 'ternoa', 'alephTest', 'polkadexTest', 'westend', 'kate', 'edgeware', 'creditcoin', 'vara_network', 'goldberg_testnet', 'availTuringTest'],
12
12
  para: ['moonbeam', 'moonriver', 'moonbase', 'turing', 'turingStaging', 'bifrost', 'bifrost_testnet', 'calamari_test', 'calamari', 'manta_network', 'polimec'],
13
13
  astar: ['astar', 'shiden', 'shibuya'],
14
14
  amplitude: ['amplitude', 'amplitude_test', 'kilt', 'kilt_peregrine', 'pendulum', 'krest_network'],
15
15
  // amplitude and kilt only share some common logic
16
16
  kilt: ['kilt', 'kilt_peregrine'],
17
- nominationPool: ['polkadot', 'kusama', 'westend', 'alephTest', 'aleph', 'kate', 'vara_network', 'goldberg_testnet'],
17
+ nominationPool: ['polkadot', 'kusama', 'westend', 'alephTest', 'aleph', 'kate', 'vara_network', 'goldberg_testnet', 'availTuringTest'],
18
18
  bifrost: ['bifrost', 'bifrost_testnet'],
19
19
  aleph: ['aleph', 'alephTest'],
20
20
  // A0 has distinct tokenomics
@@ -64,9 +64,9 @@ class RelayNativeStakingPoolHandler extends _base.default {
64
64
  const maxUnlockingChunks = substrateApi.api.consts.staking.maxUnlockingChunks.toString();
65
65
  const unlockingEras = substrateApi.api.consts.staking.bondingDuration.toString();
66
66
  const maxSupportedEras = substrateApi.api.consts.staking.historyDepth.toString();
67
- const erasPerDay = 24 / _constants._STAKING_ERA_LENGTH_MAP[chainInfo.slug]; // Can be exactly calculate from epochDuration, blockTime, sessionsPerEra
67
+ const erasPerDay = 24 / _constants._STAKING_ERA_LENGTH_MAP[chainInfo.slug]; // Can be exactly calculate from babe.epochDuration * blockTime * staking.sessionsPerEra
68
68
 
69
- const supportedDays = (0, _utils.getSupportedDaysByHistoryDepth)(erasPerDay, parseInt(maxSupportedEras));
69
+ const supportedDays = (0, _utils.getSupportedDaysByHistoryDepth)(erasPerDay, parseInt(maxSupportedEras), parseInt(currentEra) / erasPerDay);
70
70
  const startEra = parseInt(currentEra) - supportedDays * erasPerDay;
71
71
  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))]);
72
72
  const [_totalEraStake, _lastTotalStaked] = _EraStakeInfo;
@@ -151,7 +151,7 @@ class RelayNativeStakingPoolHandler extends _base.default {
151
151
  let nominationStatus = _types.EarningStatus.NOT_EARNING;
152
152
  let eraStakerOtherList = [];
153
153
  let identity;
154
- if (['kusama', 'polkadot', 'westend'].includes(this.chain)) {
154
+ if (['kusama', 'polkadot', 'westend', 'availTuringTest'].includes(this.chain)) {
155
155
  // todo: review all relaychains later
156
156
  const [[_identity], _eraStaker] = await Promise.all([(0, _utils3.parseIdentity)(substrateApi, validatorAddress), substrateApi.api.query.staking.erasStakersPaged.entries(currentEra, validatorAddress)]);
157
157
  identity = _identity;
@@ -305,7 +305,7 @@ class RelayNativeStakingPoolHandler extends _base.default {
305
305
  const endEraForPoints = parseInt(activeEra) - 1;
306
306
  let startEraForPoints = endEraForPoints - maxEraRewardPointsEras + 1;
307
307
  let _eraStakersPromise;
308
- if (['kusama', 'polkadot', 'westend'].includes(this.chain)) {
308
+ if (['kusama', 'polkadot', 'westend', 'availTuringTest'].includes(this.chain)) {
309
309
  // todo: review all relaychains later
310
310
  _eraStakersPromise = chainApi.api.query.staking.erasStakersOverview.entries(parseInt(currentEra));
311
311
  } else {
@@ -89,7 +89,7 @@ class NominationPoolHandler extends _base.default {
89
89
  const maxSupportedEras = substrateApi.api.consts.staking.historyDepth.toString();
90
90
  const erasPerDay = 24 / _constants._STAKING_ERA_LENGTH_MAP[chainInfo.slug]; // Can be exactly calculate from epochDuration, blockTime, sessionsPerEra
91
91
 
92
- const supportedDays = (0, _utils.getSupportedDaysByHistoryDepth)(erasPerDay, parseInt(maxSupportedEras));
92
+ const supportedDays = (0, _utils.getSupportedDaysByHistoryDepth)(erasPerDay, parseInt(maxSupportedEras), parseInt(currentEra) / erasPerDay);
93
93
  const startEra = parseInt(currentEra) - supportedDays * erasPerDay;
94
94
  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))]);
95
95
  const [_totalEraStake, _lastTotalStaked] = _EraStakeInfo;
@@ -167,7 +167,7 @@ class NominationPoolHandler extends _base.default {
167
167
  const validatorList = nominations.targets;
168
168
  await Promise.all(validatorList.map(async validatorAddress => {
169
169
  let eraStakerOtherList = [];
170
- if (['kusama', 'polkadot', 'westend'].includes(this.chain)) {
170
+ if (['kusama', 'polkadot', 'westend', 'availTuringTest'].includes(this.chain)) {
171
171
  // todo: review all relaychains later
172
172
  const _eraStaker = await substrateApi.api.query.staking.erasStakersPaged.entries(currentEra, validatorAddress);
173
173
  eraStakerOtherList = _eraStaker.flatMap(paged => paged[1].toPrimitive().others);
@@ -4,49 +4,68 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.getTokenPrice = void 0;
7
+ exports.getPriceMap = exports.getExchangeRateMap = void 0;
8
+ var _staticData = require("@subwallet/extension-base/utils/staticData");
8
9
  var _axios = _interopRequireDefault(require("axios"));
9
10
  // Copyright 2019-2022 @subwallet/extension-koni authors & contributors
10
11
  // SPDX-License-Identifier: Apache-2.0
11
12
 
13
+ const DEFAULT_CURRENCY = 'USD';
12
14
  let useBackupApi = false;
13
- const getTokenPrice = async function (priceIds) {
14
- let currency = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'usd';
15
+ const getExchangeRateMap = async () => {
15
16
  try {
16
- var _res;
17
- const idStr = Array.from(priceIds).join(',');
18
- let res;
19
- if (!useBackupApi) {
20
- try {
21
- res = await _axios.default.get(`https://api.coingecko.com/api/v3/coins/markets?vs_currency=${currency}&per_page=250&ids=${idStr}`);
22
- } catch (err) {
23
- useBackupApi = true;
17
+ const responseDataExchangeRate = (await _axios.default.get('https://api-cache.subwallet.app/exchange-rate')).data || {};
18
+ const exchangeRateMap = Object.keys(responseDataExchangeRate.conversion_rates).reduce((map, exchangeKey) => {
19
+ if (!_staticData.staticData[_staticData.StaticKey.CURRENCY_SYMBOL][exchangeKey]) {
20
+ return map;
24
21
  }
25
- }
26
- if (useBackupApi || ((_res = res) === null || _res === void 0 ? void 0 : _res.status) !== 200) {
22
+ map[exchangeKey] = {
23
+ exchange: responseDataExchangeRate.conversion_rates[exchangeKey],
24
+ label: _staticData.staticData[_staticData.StaticKey.CURRENCY_SYMBOL][exchangeKey].label
25
+ };
26
+ return map;
27
+ }, {});
28
+ return exchangeRateMap;
29
+ } catch (e) {
30
+ console.warn('Failed to get exchange rate');
31
+ return {};
32
+ }
33
+ };
34
+ exports.getExchangeRateMap = getExchangeRateMap;
35
+ const getPriceMap = async function (priceIds) {
36
+ var _rs, _rs2, _rs3;
37
+ let currency = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'USD';
38
+ const idStr = Array.from(priceIds).join(',');
39
+ let rs;
40
+ if (!useBackupApi) {
41
+ try {
42
+ rs = await _axios.default.get(`https://api.coingecko.com/api/v3/coins/markets?vs_currency=${currency.toLowerCase()}&per_page=250&ids=${idStr}`);
43
+ } catch (err) {
27
44
  useBackupApi = true;
28
- res = await _axios.default.get(`https://chain-data.subwallet.app/api/price/get?ids=${idStr}`);
29
45
  }
30
- if (res.status !== 200) {
31
- console.warn('Failed to get token price');
32
- }
33
- const responseData = res.data || [];
34
- const priceMap = {};
35
- const price24hMap = {};
36
- responseData.forEach(val => {
37
- const currentPrice = val.current_price || 0;
38
- const price24h = currentPrice - (val.price_change_24h || 0);
39
- priceMap[val.id] = currentPrice;
40
- price24hMap[val.id] = price24h;
41
- });
42
- return {
43
- currency,
44
- priceMap,
45
- price24hMap
46
- };
47
- } catch (err) {
48
- console.error(err);
49
- throw err;
50
46
  }
47
+ if (useBackupApi || ((_rs = rs) === null || _rs === void 0 ? void 0 : _rs.status) !== 200) {
48
+ useBackupApi = true;
49
+ rs = await _axios.default.get(`https://chain-data.subwallet.app/api/price/get?ids=${idStr}`);
50
+ }
51
+ if (((_rs2 = rs) === null || _rs2 === void 0 ? void 0 : _rs2.status) !== 200) {
52
+ console.warn('Failed to get token price');
53
+ }
54
+ const responseDataPrice = ((_rs3 = rs) === null || _rs3 === void 0 ? void 0 : _rs3.data) || [];
55
+ const currencyData = _staticData.staticData[_staticData.StaticKey.CURRENCY_SYMBOL][currency || DEFAULT_CURRENCY];
56
+ const priceMap = {};
57
+ const price24hMap = {};
58
+ responseDataPrice.forEach(val => {
59
+ const currentPrice = val.current_price || 0;
60
+ const price24h = currentPrice - (val.price_change_24h || 0);
61
+ priceMap[val.id] = currentPrice;
62
+ price24hMap[val.id] = price24h;
63
+ });
64
+ return {
65
+ currency,
66
+ currencyData,
67
+ priceMap,
68
+ price24hMap
69
+ };
51
70
  };
52
- exports.getTokenPrice = getTokenPrice;
71
+ exports.getPriceMap = getPriceMap;
@@ -7,27 +7,88 @@ exports.PriceService = void 0;
7
7
  var _constants = require("@subwallet/extension-base/constants");
8
8
  var _types = require("@subwallet/extension-base/services/base/types");
9
9
  var _coingecko = require("@subwallet/extension-base/services/price-service/coingecko");
10
+ var _storage = require("@subwallet/extension-base/storage");
11
+ var _utils = require("@subwallet/extension-base/utils");
10
12
  var _promise = require("@subwallet/extension-base/utils/promise");
13
+ var _staticData = require("@subwallet/extension-base/utils/staticData");
11
14
  var _rxjs = require("rxjs");
12
15
  // Copyright 2019-2022 @subwallet/extension-koni authors & contributors
13
16
  // SPDX-License-Identifier: Apache-2.0
14
17
 
18
+ const DEFAULT_CURRENCY = 'USD';
15
19
  const DEFAULT_PRICE_SUBJECT = {
20
+ currency: DEFAULT_CURRENCY,
16
21
  ready: false,
17
- currency: 'usd',
22
+ currencyData: {
23
+ label: 'United States Dollar',
24
+ symbol: DEFAULT_CURRENCY,
25
+ isPrefix: true
26
+ },
18
27
  priceMap: {},
19
- price24hMap: {}
28
+ price24hMap: {},
29
+ exchangeRateMap: {}
20
30
  };
21
31
  class PriceService {
22
- priceSubject = new _rxjs.BehaviorSubject(DEFAULT_PRICE_SUBJECT);
23
32
  priceIds = new Set();
24
33
  constructor(dbService, eventService, chainService) {
34
+ const currency = _storage.SWStorage.instance.getItem(_constants.CURRENCY);
35
+ this.currency = new _rxjs.BehaviorSubject(currency || DEFAULT_CURRENCY);
36
+ this.priceSubject = new _rxjs.BehaviorSubject({
37
+ ...DEFAULT_PRICE_SUBJECT,
38
+ currency: this.currency.value
39
+ });
40
+ this.rawPriceSubject = new _rxjs.BehaviorSubject({});
41
+ this.rawExchangeRateMap = new _rxjs.BehaviorSubject({});
25
42
  this.status = _types.ServiceStatus.NOT_INITIALIZED;
26
43
  this.dbService = dbService;
27
44
  this.eventService = eventService;
28
45
  this.chainService = chainService;
46
+ const mergeDataSubject = (0, _rxjs.merge)(this.rawPriceSubject, this.rawExchangeRateMap, this.currency);
47
+ const onUpdate = () => {
48
+ (0, _utils.addLazy)('updatePriceData', () => {
49
+ const priceSubjectValue = JSON.parse(JSON.stringify(this.rawPriceSubject.value));
50
+ const exchangeRateMapValue = JSON.parse(JSON.stringify(this.rawExchangeRateMap.value));
51
+ const currencyKey = this.currency.value;
52
+ if (Object.keys(priceSubjectValue).length === 0) {
53
+ return;
54
+ }
55
+ if (Object.keys(exchangeRateMapValue).length === 0) {
56
+ return;
57
+ }
58
+ if (currencyKey === DEFAULT_CURRENCY) {
59
+ this.priceSubject.next({
60
+ ...priceSubjectValue,
61
+ currency: currencyKey,
62
+ exchangeRateMap: exchangeRateMapValue,
63
+ currencyData: _staticData.staticData[_staticData.StaticKey.CURRENCY_SYMBOL][currencyKey]
64
+ });
65
+ }
66
+ Object.keys(priceSubjectValue.price24hMap).forEach(key => {
67
+ priceSubjectValue.price24hMap[key] *= exchangeRateMapValue[currencyKey].exchange;
68
+ priceSubjectValue.priceMap[key] *= exchangeRateMapValue[currencyKey].exchange;
69
+ });
70
+ this.priceSubject.next({
71
+ ...priceSubjectValue,
72
+ currency: currencyKey,
73
+ exchangeRateMap: exchangeRateMapValue,
74
+ currencyData: _staticData.staticData[_staticData.StaticKey.CURRENCY_SYMBOL][currencyKey || DEFAULT_CURRENCY]
75
+ });
76
+ this.dbService.updatePriceStore({
77
+ ...priceSubjectValue,
78
+ exchangeRateMap: exchangeRateMapValue
79
+ }).catch(console.error);
80
+ });
81
+ };
82
+ mergeDataSubject.subscribe(onUpdate);
29
83
  this.init().catch(console.error);
30
84
  }
85
+ async getTokenPrice(priceIds, currency, resolve, reject) {
86
+ await Promise.all([(0, _coingecko.getExchangeRateMap)(), (0, _coingecko.getPriceMap)(priceIds, currency)]).then(_ref => {
87
+ let [exchangeRateMap, priceMap] = _ref;
88
+ this.rawExchangeRateMap.next(exchangeRateMap);
89
+ this.rawPriceSubject.next(priceMap);
90
+ });
91
+ }
31
92
  async getPrice() {
32
93
  return Promise.resolve(this.priceSubject.value);
33
94
  }
@@ -38,18 +99,28 @@ class PriceService {
38
99
  const priceIdList = Object.values(this.chainService.getAssetRegistry()).map(a => a.priceId).filter(a => a);
39
100
  return new Set(priceIdList);
40
101
  }
41
- refreshPriceData(priceIds) {
102
+ async setPriceCurrency(newCurrencyCode) {
103
+ if (newCurrencyCode === this.currency.value) {
104
+ return false;
105
+ }
106
+ this.currency.next(newCurrencyCode);
107
+
108
+ // Await 1s to get the latest exchange rate
109
+ await new Promise(resolve => setTimeout(resolve, 300));
110
+ _storage.SWStorage.instance.setItem(_constants.CURRENCY, newCurrencyCode);
111
+ return true;
112
+ }
113
+ refreshPriceData(priceIds, resolve, reject) {
42
114
  clearTimeout(this.refreshTimeout);
43
115
  this.priceIds = priceIds || this.getPriceIds();
44
116
 
45
117
  // Update for tokens price
46
- (0, _coingecko.getTokenPrice)(this.priceIds).then(rs => {
47
- this.priceSubject.next({
48
- ...rs,
49
- ready: true
50
- });
51
- this.dbService.updatePriceStore(rs).catch(console.error);
52
- }).catch(console.error);
118
+ this.getTokenPrice(this.priceIds, this.priceSubject.value.currency).then(() => {
119
+ resolve && resolve(true);
120
+ }).catch(e => {
121
+ console.error(e);
122
+ reject && reject(false);
123
+ });
53
124
  this.refreshTimeout = setTimeout(this.refreshPriceData.bind(this), _constants.CRON_REFRESH_PRICE_INTERVAL);
54
125
  }
55
126
  async init() {
@@ -69,7 +140,7 @@ class PriceService {
69
140
  this.eventService.on('asset.updateState', eventHandler);
70
141
  }
71
142
  async loadData() {
72
- const data = await this.dbService.getPriceStore();
143
+ const data = await this.dbService.getPriceStore(this.priceSubject.value.currency);
73
144
  this.priceSubject.next(data || DEFAULT_PRICE_SUBJECT);
74
145
  }
75
146
  async persistData() {
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.DEFAULT_UNLOCK_TYPE = exports.DEFAULT_THEME = exports.DEFAULT_SHOW_ZERO_BALANCE = exports.DEFAULT_SHOW_BALANCE = exports.DEFAULT_SETTING = exports.DEFAULT_NOTIFICATION_TYPE = exports.DEFAULT_LANGUAGE = exports.DEFAULT_CHAIN_PATROL_ENABLE = exports.DEFAULT_CAMERA_ENABLE = exports.DEFAULT_AUTO_LOCK_TIME = exports.DEFAULT_ALL_LOGO = void 0;
6
+ exports.DEFAULT_UNLOCK_TYPE = exports.DEFAULT_THEME = exports.DEFAULT_SHOW_ZERO_BALANCE = exports.DEFAULT_SHOW_BALANCE = exports.DEFAULT_SETTING = exports.DEFAULT_NOTIFICATION_TYPE = exports.DEFAULT_LANGUAGE = exports.DEFAULT_CURRENCY = exports.DEFAULT_CHAIN_PATROL_ENABLE = exports.DEFAULT_CAMERA_ENABLE = exports.DEFAULT_AUTO_LOCK_TIME = exports.DEFAULT_ALL_LOGO = void 0;
7
7
  var _KoniTypes = require("@subwallet/extension-base/background/KoniTypes");
8
8
  var _utils = require("@subwallet/extension-base/utils");
9
9
  // Copyright 2019-2022 @subwallet/extension-koni authors & contributors
@@ -21,6 +21,8 @@ const DEFAULT_CHAIN_PATROL_ENABLE = false;
21
21
  exports.DEFAULT_CHAIN_PATROL_ENABLE = DEFAULT_CHAIN_PATROL_ENABLE;
22
22
  const DEFAULT_LANGUAGE = 'en';
23
23
  exports.DEFAULT_LANGUAGE = DEFAULT_LANGUAGE;
24
+ const DEFAULT_CURRENCY = 'usd';
25
+ exports.DEFAULT_CURRENCY = DEFAULT_CURRENCY;
24
26
  const DEFAULT_SHOW_ZERO_BALANCE = true;
25
27
  exports.DEFAULT_SHOW_ZERO_BALANCE = DEFAULT_SHOW_ZERO_BALANCE;
26
28
  const DEFAULT_SHOW_BALANCE = false;
@@ -31,6 +33,7 @@ const DEFAULT_CAMERA_ENABLE = false;
31
33
  exports.DEFAULT_CAMERA_ENABLE = DEFAULT_CAMERA_ENABLE;
32
34
  const DEFAULT_SETTING = {
33
35
  language: DEFAULT_LANGUAGE,
36
+ currency: DEFAULT_CURRENCY,
34
37
  browserConfirmationType: DEFAULT_NOTIFICATION_TYPE,
35
38
  isShowZeroBalance: DEFAULT_SHOW_ZERO_BALANCE,
36
39
  isShowBalance: DEFAULT_SHOW_BALANCE,
@@ -60,10 +60,9 @@ class DatabaseService {
60
60
  async updatePriceStore(priceData) {
61
61
  await this.stores.price.table.put(priceData);
62
62
  }
63
- async getPriceStore() {
63
+ async getPriceStore(keyData) {
64
64
  try {
65
- const rs = await this.stores.price.table.get('usd');
66
- return rs;
65
+ return await this.stores.price.table.get(keyData || 'USD');
67
66
  } catch (e) {
68
67
  this.logger.error(e);
69
68
  return undefined;
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.toBNString = exports.formatNumber = exports.balanceFormatter = exports.PREDEFINED_FORMATTER = exports.BN_ZERO = exports.BN_WEI = exports.BN_TEN = exports.BN_ONE = void 0;
7
+ exports.toBNString = exports.formatNumber = exports.balanceNoPrefixFormater = exports.balanceFormatter = exports.PREDEFINED_FORMATTER = exports.BN_ZERO = exports.BN_WEI = exports.BN_TEN = exports.BN_ONE = void 0;
8
8
  var _bignumber = _interopRequireDefault(require("bignumber.js"));
9
9
  // Copyright 2019-2022 @subwallet/extension-koni authors & contributors
10
10
  // SPDX-License-Identifier: Apache-2.0
@@ -102,6 +102,89 @@ const balanceFormatter = (input, metadata) => {
102
102
  return int;
103
103
  };
104
104
  exports.balanceFormatter = balanceFormatter;
105
+ const intToLocaleString = (str, separator) => str.replace(/\B(?=(\d{3})+(?!\d))/g, separator);
106
+ const getNumberSeparators = () => {
107
+ // default
108
+ const res = {
109
+ decimal: '.',
110
+ thousand: ''
111
+ };
112
+
113
+ // convert a number formatted according to locale
114
+ const str = parseFloat('1234.56').toLocaleString();
115
+
116
+ // if the resulting number does not contain previous number
117
+ // (i.e. in some Arabic formats), return defaults
118
+ if (!str.match('1')) {
119
+ return res;
120
+ }
121
+
122
+ // get decimal and thousand separators
123
+ res.decimal = str.replace(/.*4(.*)5.*/, '$1');
124
+ res.thousand = str.replace(/.*1(.*)2.*/, '$1');
125
+
126
+ // return results
127
+ return res;
128
+ };
129
+ const balanceNoPrefixFormater = (input, metadata) => {
130
+ const [int, decimal] = input.split('.');
131
+ const {
132
+ thousand: thousandSeparator
133
+ } = getNumberSeparators();
134
+ const absGteOne = new _bignumber.default(input).abs().gte(1);
135
+ const minNumberFormat = (metadata === null || metadata === void 0 ? void 0 : metadata.minNumberFormat) || 2;
136
+ const maxNumberFormat = (metadata === null || metadata === void 0 ? void 0 : metadata.maxNumberFormat) || 6;
137
+ let _decimal = '';
138
+ if (absGteOne) {
139
+ // Get only minNumberFormat number at decimal
140
+ if (decimal.length <= minNumberFormat) {
141
+ _decimal = decimal;
142
+ } else {
143
+ _decimal = decimal.slice(0, minNumberFormat);
144
+ }
145
+
146
+ // Clear zero number for decimal
147
+ _decimal = clearZero(_decimal);
148
+ } else {
149
+ // Index of cursor
150
+ let index = 0;
151
+
152
+ // Count of not zero number in decimal
153
+ let current = 0;
154
+
155
+ // Find a not zero number in decimal
156
+ let metNotZero = false;
157
+
158
+ // Get at least minNumberFormat number not 0 from index 0
159
+ // If count of 0 number at prefix greater or equal maxNumberFormat should stop and return 0
160
+
161
+ // current === minNumberFormat: get enough number
162
+ // index === decimal.length: end of decimal
163
+ // index === maxNumberFormat: reach limit of 0 number at prefix
164
+ if (decimal) {
165
+ while (current < minNumberFormat && index < decimal.length && (index < maxNumberFormat || metNotZero)) {
166
+ const _char = decimal[index];
167
+ _decimal += _char;
168
+ index++;
169
+ if (_char !== '0') {
170
+ metNotZero = true;
171
+ }
172
+ if (metNotZero) {
173
+ current++;
174
+ }
175
+ }
176
+
177
+ // Clear zero number for decimal
178
+ _decimal = clearZero(_decimal);
179
+ }
180
+ }
181
+ const int_ = intToLocaleString(int, thousandSeparator);
182
+ if (_decimal) {
183
+ return `${int_}.${_decimal}`;
184
+ }
185
+ return int_;
186
+ };
187
+ exports.balanceNoPrefixFormater = balanceNoPrefixFormater;
105
188
  const PREDEFINED_FORMATTER = {
106
189
  balance: balanceFormatter
107
190
  };
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.termAndCondition = exports.staticData = exports.marketingCampaigns = exports.crowdloanFunds = exports.buyTokenConfigs = exports.buyServiceInfos = exports.StaticKey = void 0;
6
+ exports.termAndCondition = exports.staticData = exports.marketingCampaigns = exports.currencySymbol = exports.crowdloanFunds = exports.buyTokenConfigs = exports.buyServiceInfos = exports.StaticKey = void 0;
7
7
  var _chainList = require("@subwallet/chain-list");
8
8
  // Copyright 2019-2022 @subwallet/extension-base authors & contributors
9
9
  // SPDX-License-Identifier: Apache-2.0
@@ -24,12 +24,16 @@ const marketingCampaigns = require('./marketingCampaigns.json');
24
24
  // eslint-disable-next-line @typescript-eslint/no-var-requires,@typescript-eslint/no-unsafe-assignment
25
25
  exports.marketingCampaigns = marketingCampaigns;
26
26
  const termAndCondition = require('./termAndCondition.json');
27
+ // eslint-disable-next-line @typescript-eslint/no-var-requires,@typescript-eslint/no-unsafe-assignment
27
28
  exports.termAndCondition = termAndCondition;
29
+ const currencySymbol = require('./currencySymbol.json');
30
+ exports.currencySymbol = currencySymbol;
28
31
  let StaticKey;
29
32
  exports.StaticKey = StaticKey;
30
33
  (function (StaticKey) {
31
34
  StaticKey["BUY_SERVICE_INFOS"] = "buy-service-infos";
32
35
  StaticKey["CHAINS"] = "chains";
36
+ StaticKey["CURRENCY_SYMBOL"] = "currency_symbols";
33
37
  StaticKey["MARKETING_CAMPAINGS"] = "marketing-campaigns";
34
38
  StaticKey["CROWDLOAN_FUNDS"] = "crowdloan-funds";
35
39
  StaticKey["TERM_AND_CONDITION"] = "term-and-condition";
@@ -37,6 +41,7 @@ exports.StaticKey = StaticKey;
37
41
  })(StaticKey || (exports.StaticKey = StaticKey = {}));
38
42
  const staticData = {
39
43
  [StaticKey.CHAINS]: Object.values(_chainList.ChainInfoMap),
44
+ [StaticKey.CURRENCY_SYMBOL]: currencySymbol,
40
45
  [StaticKey.BUY_SERVICE_INFOS]: buyServiceInfos,
41
46
  [StaticKey.CROWDLOAN_FUNDS]: crowdloanFunds,
42
47
  [StaticKey.MARKETING_CAMPAINGS]: marketingCampaigns,
@@ -5,6 +5,7 @@ export const PREDEFINED_STAKING_POOL = {
5
5
  kusama: 80,
6
6
  polkadot: 39,
7
7
  vara_network: 62,
8
- aleph: 82
8
+ aleph: 82,
9
+ availTuringTest: 11
9
10
  };
10
11
  export const MAX_NOMINATIONS = '16';
@@ -1 +1,2 @@
1
1
  export declare const LANGUAGE = "current-language";
2
+ export declare const CURRENCY = "current-currency";