@subwallet/extension-base 1.1.59-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.
- package/background/KoniTypes.d.ts +18 -1
- package/cjs/constants/staking.js +2 -1
- package/cjs/constants/storage.js +4 -2
- package/cjs/koni/api/coingecko.js +58 -15
- package/cjs/koni/api/nft/config.js +26 -22
- package/cjs/koni/background/handlers/Extension.js +130 -122
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/balance-service/helpers/subscribe/substrate/index.js +7 -1
- package/cjs/services/chain-service/index.js +6 -1
- package/cjs/services/chain-service/utils/index.js +34 -14
- package/cjs/services/price-service/coingecko.js +54 -35
- package/cjs/services/price-service/index.js +83 -12
- package/cjs/services/setting-service/constants.js +4 -1
- package/cjs/services/storage-service/DatabaseService.js +2 -3
- package/cjs/utils/number.js +84 -1
- package/cjs/utils/staticData/index.js +6 -1
- package/constants/staking.js +2 -1
- package/constants/storage.d.ts +1 -0
- package/constants/storage.js +2 -1
- package/koni/api/coingecko.d.ts +2 -2
- package/koni/api/coingecko.js +58 -15
- package/koni/api/nft/config.js +27 -21
- package/koni/background/handlers/Extension.d.ts +1 -0
- package/koni/background/handlers/Extension.js +7 -0
- package/package.json +7 -6
- package/packageInfo.js +1 -1
- package/services/balance-service/helpers/subscribe/substrate/index.js +8 -2
- package/services/chain-service/index.js +6 -1
- package/services/chain-service/utils/index.d.ts +13 -0
- package/services/chain-service/utils/index.js +32 -14
- package/services/price-service/coingecko.d.ts +3 -2
- package/services/price-service/coingecko.js +50 -32
- package/services/price-service/index.d.ts +7 -2
- package/services/price-service/index.js +85 -15
- package/services/setting-service/constants.d.ts +1 -0
- package/services/setting-service/constants.js +2 -0
- package/services/storage-service/DatabaseService.d.ts +1 -1
- package/services/storage-service/DatabaseService.js +2 -3
- package/utils/number.d.ts +1 -0
- package/utils/number.js +82 -0
- package/utils/staticData/currencySymbol.json +11 -0
- package/utils/staticData/index.d.ts +3 -0
- package/utils/staticData/index.js +4 -0
package/koni/api/nft/config.js
CHANGED
|
@@ -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,27 +112,31 @@ if (isFirefox) {
|
|
|
110
112
|
weight: 5000
|
|
111
113
|
});
|
|
112
114
|
}
|
|
113
|
-
if (
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
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
|
|
134
140
|
RANDOM_IPFS_GATEWAY_SETTING.push({
|
|
135
141
|
provider: NFT_STORAGE_GATEWAY,
|
|
136
142
|
weight: 50
|
|
@@ -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.
|
|
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.
|
|
1877
|
-
"@subwallet/extension-base": "^1.1.
|
|
1878
|
-
"@subwallet/extension-chains": "^1.1.
|
|
1879
|
-
"@subwallet/extension-dapp": "^1.1.
|
|
1880
|
-
"@subwallet/extension-inject": "^1.1.
|
|
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.
|
|
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
|
-
|
|
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
|
|
@@ -645,7 +645,12 @@ export class ChainService {
|
|
|
645
645
|
this.substrateChainHandler.setSubstrateApi(chainInfo.slug, chainApi);
|
|
646
646
|
}
|
|
647
647
|
}
|
|
648
|
-
|
|
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
|
-
|
|
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
|
|
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$
|
|
85
|
-
return ((_tokenInfo$
|
|
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$
|
|
89
|
-
return (_tokenInfo$
|
|
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$
|
|
93
|
-
return (_tokenInfo$
|
|
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$
|
|
248
|
-
return ((_tokenInfo$
|
|
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$
|
|
252
|
-
return ((_tokenInfo$
|
|
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$
|
|
256
|
-
return (_tokenInfo$
|
|
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;
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import { PriceJson } from '@subwallet/extension-base/background/KoniTypes';
|
|
2
|
-
export declare const
|
|
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
|
|
8
|
+
export const getExchangeRateMap = async () => {
|
|
7
9
|
try {
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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>;
|
|
@@ -1,27 +1,87 @@
|
|
|
1
1
|
// Copyright 2019-2022 @subwallet/extension-koni authors & contributors
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
-
import { CRON_REFRESH_PRICE_INTERVAL } from '@subwallet/extension-base/constants';
|
|
4
|
+
import { CRON_REFRESH_PRICE_INTERVAL, CURRENCY } from '@subwallet/extension-base/constants';
|
|
5
5
|
import { ServiceStatus } from '@subwallet/extension-base/services/base/types';
|
|
6
|
-
import {
|
|
6
|
+
import { getExchangeRateMap, getPriceMap } from '@subwallet/extension-base/services/price-service/coingecko';
|
|
7
|
+
import { SWStorage } from '@subwallet/extension-base/storage';
|
|
8
|
+
import { addLazy } from '@subwallet/extension-base/utils';
|
|
7
9
|
import { createPromiseHandler } from '@subwallet/extension-base/utils/promise';
|
|
8
|
-
import {
|
|
10
|
+
import { staticData, StaticKey } from '@subwallet/extension-base/utils/staticData';
|
|
11
|
+
import { BehaviorSubject, merge } from 'rxjs';
|
|
12
|
+
const DEFAULT_CURRENCY = 'USD';
|
|
9
13
|
const DEFAULT_PRICE_SUBJECT = {
|
|
14
|
+
currency: DEFAULT_CURRENCY,
|
|
10
15
|
ready: false,
|
|
11
|
-
|
|
16
|
+
currencyData: {
|
|
17
|
+
label: 'United States Dollar',
|
|
18
|
+
symbol: DEFAULT_CURRENCY,
|
|
19
|
+
isPrefix: true
|
|
20
|
+
},
|
|
12
21
|
priceMap: {},
|
|
13
|
-
price24hMap: {}
|
|
22
|
+
price24hMap: {},
|
|
23
|
+
exchangeRateMap: {}
|
|
14
24
|
};
|
|
15
25
|
export class PriceService {
|
|
16
|
-
priceSubject = new BehaviorSubject(DEFAULT_PRICE_SUBJECT);
|
|
17
26
|
priceIds = new Set();
|
|
18
27
|
constructor(dbService, eventService, chainService) {
|
|
28
|
+
const currency = SWStorage.instance.getItem(CURRENCY);
|
|
29
|
+
this.currency = new BehaviorSubject(currency || DEFAULT_CURRENCY);
|
|
30
|
+
this.priceSubject = new BehaviorSubject({
|
|
31
|
+
...DEFAULT_PRICE_SUBJECT,
|
|
32
|
+
currency: this.currency.value
|
|
33
|
+
});
|
|
34
|
+
this.rawPriceSubject = new BehaviorSubject({});
|
|
35
|
+
this.rawExchangeRateMap = new BehaviorSubject({});
|
|
19
36
|
this.status = ServiceStatus.NOT_INITIALIZED;
|
|
20
37
|
this.dbService = dbService;
|
|
21
38
|
this.eventService = eventService;
|
|
22
39
|
this.chainService = chainService;
|
|
40
|
+
const mergeDataSubject = merge(this.rawPriceSubject, this.rawExchangeRateMap, this.currency);
|
|
41
|
+
const onUpdate = () => {
|
|
42
|
+
addLazy('updatePriceData', () => {
|
|
43
|
+
const priceSubjectValue = JSON.parse(JSON.stringify(this.rawPriceSubject.value));
|
|
44
|
+
const exchangeRateMapValue = JSON.parse(JSON.stringify(this.rawExchangeRateMap.value));
|
|
45
|
+
const currencyKey = this.currency.value;
|
|
46
|
+
if (Object.keys(priceSubjectValue).length === 0) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (Object.keys(exchangeRateMapValue).length === 0) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (currencyKey === DEFAULT_CURRENCY) {
|
|
53
|
+
this.priceSubject.next({
|
|
54
|
+
...priceSubjectValue,
|
|
55
|
+
currency: currencyKey,
|
|
56
|
+
exchangeRateMap: exchangeRateMapValue,
|
|
57
|
+
currencyData: staticData[StaticKey.CURRENCY_SYMBOL][currencyKey]
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
Object.keys(priceSubjectValue.price24hMap).forEach(key => {
|
|
61
|
+
priceSubjectValue.price24hMap[key] *= exchangeRateMapValue[currencyKey].exchange;
|
|
62
|
+
priceSubjectValue.priceMap[key] *= exchangeRateMapValue[currencyKey].exchange;
|
|
63
|
+
});
|
|
64
|
+
this.priceSubject.next({
|
|
65
|
+
...priceSubjectValue,
|
|
66
|
+
currency: currencyKey,
|
|
67
|
+
exchangeRateMap: exchangeRateMapValue,
|
|
68
|
+
currencyData: staticData[StaticKey.CURRENCY_SYMBOL][currencyKey || DEFAULT_CURRENCY]
|
|
69
|
+
});
|
|
70
|
+
this.dbService.updatePriceStore({
|
|
71
|
+
...priceSubjectValue,
|
|
72
|
+
exchangeRateMap: exchangeRateMapValue
|
|
73
|
+
}).catch(console.error);
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
mergeDataSubject.subscribe(onUpdate);
|
|
23
77
|
this.init().catch(console.error);
|
|
24
78
|
}
|
|
79
|
+
async getTokenPrice(priceIds, currency, resolve, reject) {
|
|
80
|
+
await Promise.all([getExchangeRateMap(), getPriceMap(priceIds, currency)]).then(([exchangeRateMap, priceMap]) => {
|
|
81
|
+
this.rawExchangeRateMap.next(exchangeRateMap);
|
|
82
|
+
this.rawPriceSubject.next(priceMap);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
25
85
|
async getPrice() {
|
|
26
86
|
return Promise.resolve(this.priceSubject.value);
|
|
27
87
|
}
|
|
@@ -32,18 +92,28 @@ export class PriceService {
|
|
|
32
92
|
const priceIdList = Object.values(this.chainService.getAssetRegistry()).map(a => a.priceId).filter(a => a);
|
|
33
93
|
return new Set(priceIdList);
|
|
34
94
|
}
|
|
35
|
-
|
|
95
|
+
async setPriceCurrency(newCurrencyCode) {
|
|
96
|
+
if (newCurrencyCode === this.currency.value) {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
this.currency.next(newCurrencyCode);
|
|
100
|
+
|
|
101
|
+
// Await 1s to get the latest exchange rate
|
|
102
|
+
await new Promise(resolve => setTimeout(resolve, 300));
|
|
103
|
+
SWStorage.instance.setItem(CURRENCY, newCurrencyCode);
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
refreshPriceData(priceIds, resolve, reject) {
|
|
36
107
|
clearTimeout(this.refreshTimeout);
|
|
37
108
|
this.priceIds = priceIds || this.getPriceIds();
|
|
38
109
|
|
|
39
110
|
// Update for tokens price
|
|
40
|
-
getTokenPrice(this.priceIds).then(
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}).catch(console.error);
|
|
111
|
+
this.getTokenPrice(this.priceIds, this.priceSubject.value.currency).then(() => {
|
|
112
|
+
resolve && resolve(true);
|
|
113
|
+
}).catch(e => {
|
|
114
|
+
console.error(e);
|
|
115
|
+
reject && reject(false);
|
|
116
|
+
});
|
|
47
117
|
this.refreshTimeout = setTimeout(this.refreshPriceData.bind(this), CRON_REFRESH_PRICE_INTERVAL);
|
|
48
118
|
}
|
|
49
119
|
async init() {
|
|
@@ -63,7 +133,7 @@ export class PriceService {
|
|
|
63
133
|
this.eventService.on('asset.updateState', eventHandler);
|
|
64
134
|
}
|
|
65
135
|
async loadData() {
|
|
66
|
-
const data = await this.dbService.getPriceStore();
|
|
136
|
+
const data = await this.dbService.getPriceStore(this.priceSubject.value.currency);
|
|
67
137
|
this.priceSubject.next(data || DEFAULT_PRICE_SUBJECT);
|
|
68
138
|
}
|
|
69
139
|
async persistData() {
|
|
@@ -5,6 +5,7 @@ export declare const DEFAULT_AUTO_LOCK_TIME = 15;
|
|
|
5
5
|
export declare const DEFAULT_UNLOCK_TYPE: WalletUnlockType;
|
|
6
6
|
export declare const DEFAULT_CHAIN_PATROL_ENABLE = false;
|
|
7
7
|
export declare const DEFAULT_LANGUAGE: LanguageType;
|
|
8
|
+
export declare const DEFAULT_CURRENCY = "usd";
|
|
8
9
|
export declare const DEFAULT_SHOW_ZERO_BALANCE = true;
|
|
9
10
|
export declare const DEFAULT_SHOW_BALANCE = false;
|
|
10
11
|
export declare const DEFAULT_ALL_LOGO = "";
|
|
@@ -9,12 +9,14 @@ export const DEFAULT_AUTO_LOCK_TIME = 15;
|
|
|
9
9
|
export const DEFAULT_UNLOCK_TYPE = TARGET_ENV === 'extension' ? WalletUnlockType.ALWAYS_REQUIRED : WalletUnlockType.WHEN_NEEDED;
|
|
10
10
|
export const DEFAULT_CHAIN_PATROL_ENABLE = false;
|
|
11
11
|
export const DEFAULT_LANGUAGE = 'en';
|
|
12
|
+
export const DEFAULT_CURRENCY = 'usd';
|
|
12
13
|
export const DEFAULT_SHOW_ZERO_BALANCE = true;
|
|
13
14
|
export const DEFAULT_SHOW_BALANCE = false;
|
|
14
15
|
export const DEFAULT_ALL_LOGO = '';
|
|
15
16
|
export const DEFAULT_CAMERA_ENABLE = false;
|
|
16
17
|
export const DEFAULT_SETTING = {
|
|
17
18
|
language: DEFAULT_LANGUAGE,
|
|
19
|
+
currency: DEFAULT_CURRENCY,
|
|
18
20
|
browserConfirmationType: DEFAULT_NOTIFICATION_TYPE,
|
|
19
21
|
isShowZeroBalance: DEFAULT_SHOW_ZERO_BALANCE,
|
|
20
22
|
isShowBalance: DEFAULT_SHOW_BALANCE,
|
|
@@ -42,7 +42,7 @@ export default class DatabaseService {
|
|
|
42
42
|
private yieldInfoSubscription;
|
|
43
43
|
constructor(eventService: EventService);
|
|
44
44
|
updatePriceStore(priceData: PriceJson): Promise<void>;
|
|
45
|
-
getPriceStore(): Promise<PriceJson | undefined>;
|
|
45
|
+
getPriceStore(keyData?: string): Promise<PriceJson | undefined>;
|
|
46
46
|
getStoredBalance(): Promise<IBalance[]>;
|
|
47
47
|
updateBalanceStore(item: BalanceItem): Promise<unknown>;
|
|
48
48
|
updateBulkBalanceStore(items: BalanceItem[]): Promise<unknown>;
|
|
@@ -52,10 +52,9 @@ export default class DatabaseService {
|
|
|
52
52
|
async updatePriceStore(priceData) {
|
|
53
53
|
await this.stores.price.table.put(priceData);
|
|
54
54
|
}
|
|
55
|
-
async getPriceStore() {
|
|
55
|
+
async getPriceStore(keyData) {
|
|
56
56
|
try {
|
|
57
|
-
|
|
58
|
-
return rs;
|
|
57
|
+
return await this.stores.price.table.get(keyData || 'USD');
|
|
59
58
|
} catch (e) {
|
|
60
59
|
this.logger.error(e);
|
|
61
60
|
return undefined;
|
package/utils/number.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export interface NumberFormatter {
|
|
|
7
7
|
(input: string, metadata?: Record<string, number>): string;
|
|
8
8
|
}
|
|
9
9
|
export declare const balanceFormatter: NumberFormatter;
|
|
10
|
+
export declare const balanceNoPrefixFormater: NumberFormatter;
|
|
10
11
|
export declare const PREDEFINED_FORMATTER: Record<string, NumberFormatter>;
|
|
11
12
|
export declare const toBNString: (input: string | number | BigNumber, decimal: number) => string;
|
|
12
13
|
export declare const formatNumber: (input: string | number | BigNumber, decimal: number, formatter?: NumberFormatter, metadata?: Record<string, number>) => string;
|