@subwallet/extension-base 1.2.13-0 → 1.2.15-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/errors/SwapError.js +5 -1
- package/cjs/background/errors/SwapError.js +5 -1
- package/cjs/core/logic-validation/swap.js +56 -3
- package/cjs/core/substrate/nominationpools-pallet.js +2 -1
- package/cjs/koni/api/nft/config.js +37 -23
- package/cjs/koni/api/nft/index.js +9 -1
- package/cjs/koni/api/nft/unique_network_nft/index.js +12 -20
- package/cjs/koni/background/handlers/Extension.js +12 -0
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/balance-service/transfer/xcm/utils.js +2 -2
- package/cjs/services/chain-service/constants.js +2 -1
- package/cjs/services/chain-service/handler/SubstrateApi.js +6 -0
- package/cjs/services/chain-service/health-check/constants/index.js +4 -4
- package/cjs/services/chain-service/health-check/utils/asset-info.js +23 -6
- package/cjs/services/chain-service/health-check/utils/chain-info.js +25 -2
- package/cjs/services/chain-service/health-check/utils/new-utils/asset-asset-validate.js +160 -0
- package/cjs/services/chain-service/health-check/utils/new-utils/asset-validate.js +45 -0
- package/cjs/services/chain-service/health-check/utils/new-utils/chain-asset-validate.js +73 -0
- package/cjs/services/chain-service/health-check/utils/new-utils/chain-validate.js +34 -0
- package/cjs/services/chain-service/index.js +47 -5
- package/cjs/services/earning-service/handlers/liquid-staking/acala.js +49 -19
- package/cjs/services/migration-service/scripts/databases/ReloadMetadata.js +35 -0
- package/cjs/services/migration-service/scripts/index.js +4 -2
- package/cjs/services/price-service/coingecko.js +57 -32
- package/cjs/services/price-service/index.js +30 -11
- package/cjs/services/storage-service/db-stores/BaseStore.js +4 -0
- package/cjs/services/swap-service/handler/asset-hub/handler.js +343 -0
- package/cjs/services/swap-service/handler/asset-hub/index.js +12 -0
- package/cjs/services/swap-service/handler/asset-hub/router.js +93 -0
- package/cjs/services/swap-service/handler/asset-hub/utils.js +158 -0
- package/cjs/services/swap-service/index.js +10 -1
- package/cjs/services/swap-service/utils.js +10 -1
- package/cjs/types/swap/index.js +5 -1
- package/core/logic-validation/swap.d.ts +3 -1
- package/core/logic-validation/swap.js +55 -4
- package/core/substrate/nominationpools-pallet.js +2 -1
- package/koni/api/nft/config.d.ts +1 -0
- package/koni/api/nft/config.js +31 -19
- package/koni/api/nft/index.js +9 -1
- package/koni/api/nft/unique_network_nft/index.js +12 -20
- package/koni/background/handlers/Extension.js +12 -0
- package/package.json +56 -11
- package/packageInfo.js +1 -1
- package/services/balance-service/transfer/xcm/utils.js +2 -2
- package/services/chain-service/constants.d.ts +1 -0
- package/services/chain-service/constants.js +2 -1
- package/services/chain-service/handler/SubstrateApi.js +6 -0
- package/services/chain-service/health-check/constants/index.js +4 -4
- package/services/chain-service/health-check/utils/asset-info.d.ts +1 -0
- package/services/chain-service/health-check/utils/asset-info.js +20 -4
- package/services/chain-service/health-check/utils/chain-info.d.ts +4 -2
- package/services/chain-service/health-check/utils/chain-info.js +20 -0
- package/services/chain-service/health-check/utils/new-utils/asset-asset-validate.d.ts +10 -0
- package/services/chain-service/health-check/utils/new-utils/asset-asset-validate.js +146 -0
- package/services/chain-service/health-check/utils/new-utils/asset-validate.d.ts +3 -0
- package/services/chain-service/health-check/utils/new-utils/asset-validate.js +38 -0
- package/services/chain-service/health-check/utils/new-utils/chain-asset-validate.d.ts +5 -0
- package/services/chain-service/health-check/utils/new-utils/chain-asset-validate.js +64 -0
- package/services/chain-service/health-check/utils/new-utils/chain-validate.d.ts +4 -0
- package/services/chain-service/health-check/utils/new-utils/chain-validate.js +26 -0
- package/services/chain-service/index.js +47 -5
- package/services/chain-service/types.d.ts +5 -0
- package/services/earning-service/handlers/liquid-staking/acala.js +46 -17
- package/services/migration-service/scripts/databases/ReloadMetadata.d.ts +5 -0
- package/services/migration-service/scripts/databases/ReloadMetadata.js +27 -0
- package/services/migration-service/scripts/index.js +4 -2
- package/services/price-service/coingecko.js +54 -32
- package/services/price-service/index.js +29 -11
- package/services/storage-service/db-stores/BaseStore.d.ts +3 -0
- package/services/storage-service/db-stores/BaseStore.js +4 -0
- package/services/swap-service/handler/asset-hub/handler.d.ts +31 -0
- package/services/swap-service/handler/asset-hub/handler.js +335 -0
- package/services/swap-service/handler/asset-hub/index.d.ts +1 -0
- package/services/swap-service/handler/asset-hub/index.js +4 -0
- package/services/swap-service/handler/asset-hub/router.d.ts +16 -0
- package/services/swap-service/handler/asset-hub/router.js +85 -0
- package/services/swap-service/handler/asset-hub/utils.d.ts +18 -0
- package/services/swap-service/handler/asset-hub/utils.js +133 -0
- package/services/swap-service/index.js +10 -1
- package/services/swap-service/utils.d.ts +1 -0
- package/services/swap-service/utils.js +9 -1
- package/types/swap/index.d.ts +15 -2
- package/types/swap/index.js +5 -1
- /package/cjs/services/migration-service/scripts/{ClearMetadataDatabase.js → databases/ClearMetadataDatabase.js} +0 -0
- /package/services/migration-service/scripts/{ClearMetadataDatabase.d.ts → databases/ClearMetadataDatabase.d.ts} +0 -0
- /package/services/migration-service/scripts/{ClearMetadataDatabase.js → databases/ClearMetadataDatabase.js} +0 -0
|
@@ -18,10 +18,27 @@ import { logger as createLogger } from '@polkadot/util/logger';
|
|
|
18
18
|
const filterChainInfoMap = (data, ignoredChains) => {
|
|
19
19
|
return Object.fromEntries(Object.entries(data).filter(([slug, info]) => !info.bitcoinInfo && !ignoredChains.includes(slug)));
|
|
20
20
|
};
|
|
21
|
-
const ignoredList = ['bevm', 'bevmTest', 'bevm_testnet', 'layerEdge_testnet', 'merlinEvm', 'botanixEvmTest', 'syscoin_evm', 'rollux_evm'];
|
|
21
|
+
const ignoredList = ['bevm', 'bevmTest', 'bevm_testnet', 'layerEdge_testnet', 'merlinEvm', 'botanixEvmTest', 'syscoin_evm', 'syscoin_evm_testnet', 'rollux_evm', 'rollux_testnet', 'boolAlpha', 'boolBeta_testnet'];
|
|
22
22
|
const filterAssetInfoMap = (chainInfo, assets) => {
|
|
23
23
|
return Object.fromEntries(Object.entries(assets).filter(([, info]) => chainInfo[info.originChain]));
|
|
24
24
|
};
|
|
25
|
+
|
|
26
|
+
// const rawAssetRefMap = (assetRefMap: Record<string, _AssetRef>) => {
|
|
27
|
+
// const result: Record<string, _AssetRef> = {};
|
|
28
|
+
//
|
|
29
|
+
// Object.entries(assetRefMap).forEach(([key, assetRef]) => {
|
|
30
|
+
// const originChainInfo = ChainInfoMap[assetRef.srcChain];
|
|
31
|
+
// const destChainInfo = ChainInfoMap[assetRef.destChain];
|
|
32
|
+
// const isSnowBridgeXcm = assetRef.path === _AssetRefPath.XCM && _isSnowBridgeXcm(originChainInfo, destChainInfo);
|
|
33
|
+
//
|
|
34
|
+
// if (!isSnowBridgeXcm) {
|
|
35
|
+
// result[key] = assetRef;
|
|
36
|
+
// }
|
|
37
|
+
// });
|
|
38
|
+
//
|
|
39
|
+
// return result;
|
|
40
|
+
// };
|
|
41
|
+
|
|
25
42
|
export class ChainService {
|
|
26
43
|
dataMap = {
|
|
27
44
|
chainInfoMap: {},
|
|
@@ -444,10 +461,6 @@ export class ChainService {
|
|
|
444
461
|
|
|
445
462
|
// TODO: reconsider the flow of initiation
|
|
446
463
|
this.multiChainAssetMapSubject.next(MultiChainAssetMap);
|
|
447
|
-
// const storedAssetRefMap = await this.dbService.getAssetRefMap();
|
|
448
|
-
//
|
|
449
|
-
// this.dataMap.assetRefMap = storedAssetRefMap && Object.values(storedAssetRefMap).length > 0 ? storedAssetRefMap : AssetRefMap;
|
|
450
|
-
|
|
451
464
|
await this.initChains();
|
|
452
465
|
this.chainInfoMapSubject.next(this.getChainInfoMap());
|
|
453
466
|
this.assetRegistrySubject.next(this.getAssetRegistry());
|
|
@@ -642,6 +655,34 @@ export class ChainService {
|
|
|
642
655
|
}
|
|
643
656
|
const onUpdateStatus = status => {
|
|
644
657
|
const slug = chainInfo.slug;
|
|
658
|
+
const isActive = this.getChainStateByKey(slug).active;
|
|
659
|
+
const isConnectProblem = status !== _ChainConnectionStatus.CONNECTING && status !== _ChainConnectionStatus.CONNECTED;
|
|
660
|
+
const isLightRpc = endpoint.startsWith('light');
|
|
661
|
+
if (isActive && isConnectProblem && !isLightRpc) {
|
|
662
|
+
const reportApiUrl = 'https://api-cache.subwallet.app/api/health-check/report-rpc';
|
|
663
|
+
const requestBody = {
|
|
664
|
+
chainSlug: slug,
|
|
665
|
+
chainStatus: status,
|
|
666
|
+
rpcReport: {
|
|
667
|
+
[providerName]: endpoint
|
|
668
|
+
},
|
|
669
|
+
configStatus: {
|
|
670
|
+
countUnstable: 10,
|
|
671
|
+
countDie: 20
|
|
672
|
+
}
|
|
673
|
+
};
|
|
674
|
+
fetch(reportApiUrl, {
|
|
675
|
+
// can get status from this response
|
|
676
|
+
method: 'POST',
|
|
677
|
+
headers: {
|
|
678
|
+
'X-API-KEY': '9b1c94a5e1f3a2d9f8b2a4d6e1f3a2d9',
|
|
679
|
+
'Content-Type': 'application/json'
|
|
680
|
+
},
|
|
681
|
+
body: JSON.stringify(requestBody)
|
|
682
|
+
})
|
|
683
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
684
|
+
.then(() => {}).catch(error => console.error('Error connecting to the report API:', error));
|
|
685
|
+
}
|
|
645
686
|
this.updateChainConnectionStatus(slug, status);
|
|
646
687
|
};
|
|
647
688
|
if (chainInfo.substrateInfo !== null && chainInfo.substrateInfo !== undefined) {
|
|
@@ -651,6 +692,7 @@ export class ChainService {
|
|
|
651
692
|
//
|
|
652
693
|
// this.substrateChainHandler.setSubstrateApi(chainInfo.slug, chainApi);
|
|
653
694
|
// } else {
|
|
695
|
+
|
|
654
696
|
const chainApi = await this.substrateChainHandler.initApi(chainInfo.slug, endpoint, {
|
|
655
697
|
providerName,
|
|
656
698
|
onUpdateStatus
|
|
@@ -18,6 +18,11 @@ export declare enum _ChainConnectionStatus {
|
|
|
18
18
|
UNSTABLE = "UNSTABLE",
|
|
19
19
|
CONNECTING = "CONNECTING"
|
|
20
20
|
}
|
|
21
|
+
export interface ReportRpc {
|
|
22
|
+
runningRpc: Record<string, string>;
|
|
23
|
+
unstableRpc: Record<string, string>;
|
|
24
|
+
dieRpc: Record<string, string>;
|
|
25
|
+
}
|
|
21
26
|
export interface _ChainState {
|
|
22
27
|
slug: string;
|
|
23
28
|
active: boolean;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import { ChainType, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
|
|
5
|
+
import { _STAKING_ERA_LENGTH_MAP } from '@subwallet/extension-base/services/chain-service/constants';
|
|
5
6
|
import { _getTokenOnChainInfo } from '@subwallet/extension-base/services/chain-service/utils';
|
|
6
7
|
import { fakeAddress } from '@subwallet/extension-base/services/earning-service/constants';
|
|
7
8
|
import { EarningStatus, UnstakingStatus, YieldStepType } from '@subwallet/extension-base/types';
|
|
@@ -9,6 +10,9 @@ import { BN, BN_TEN, BN_ZERO } from '@polkadot/util';
|
|
|
9
10
|
import BaseLiquidStakingPoolHandler from "./base.js";
|
|
10
11
|
const GRAPHQL_API = 'https://api.polkawallet.io/acala-liquid-staking-subql';
|
|
11
12
|
const EXCHANGE_RATE_REQUEST = 'query { dailySummaries(first:30, orderBy:TIMESTAMP_DESC) {nodes { exchangeRate timestamp }}}';
|
|
13
|
+
function convertDerivativeToken(amount, exchangeRate, decimals) {
|
|
14
|
+
return amount.mul(new BN(exchangeRate)).div(BN_TEN.pow(new BN(decimals)));
|
|
15
|
+
}
|
|
12
16
|
export default class AcalaLiquidStakingPoolHandler extends BaseLiquidStakingPoolHandler {
|
|
13
17
|
altInputAsset = 'polkadot-NATIVE-DOT';
|
|
14
18
|
derivativeAssets = ['acala-LOCAL-LDOT'];
|
|
@@ -22,8 +26,7 @@ export default class AcalaLiquidStakingPoolHandler extends BaseLiquidStakingPool
|
|
|
22
26
|
defaultUnstake: true,
|
|
23
27
|
fastUnstake: true,
|
|
24
28
|
cancelUnstake: false,
|
|
25
|
-
withdraw:
|
|
26
|
-
// TODO: Change after verify unstake info
|
|
29
|
+
withdraw: true,
|
|
27
30
|
claimReward: false
|
|
28
31
|
};
|
|
29
32
|
constructor(state, chain) {
|
|
@@ -111,30 +114,55 @@ export default class AcalaLiquidStakingPoolHandler extends BaseLiquidStakingPool
|
|
|
111
114
|
return;
|
|
112
115
|
}
|
|
113
116
|
const balances = _balances;
|
|
114
|
-
const redeemRequests = await substrateApi.api.query.homa.redeemRequests.multi(useAddresses);
|
|
115
|
-
|
|
116
|
-
const exchangeRate = await this.getExchangeRate();
|
|
117
|
-
const decimals = BN_TEN.pow(new BN(this.rateDecimals));
|
|
117
|
+
const [redeemRequests, exchangeRate, _currentEra] = await Promise.all([substrateApi.api.query.homa.redeemRequests.multi(useAddresses), this.getExchangeRate(), substrateApi.api.query.homa.relayChainCurrentEra()]);
|
|
118
|
+
const currentEra = _currentEra.toPrimitive();
|
|
118
119
|
for (let i = 0; i < balances.length; i++) {
|
|
119
120
|
const balanceItem = balances[i];
|
|
120
121
|
const address = useAddresses[i];
|
|
121
122
|
const activeTotalBalance = balanceItem.free || BN_ZERO;
|
|
122
|
-
let totalBalance = activeTotalBalance
|
|
123
|
+
let totalBalance = convertDerivativeToken(activeTotalBalance, exchangeRate, this.rateDecimals);
|
|
123
124
|
let unlockingBalance = BN_ZERO;
|
|
124
125
|
const unstakings = [];
|
|
126
|
+
|
|
127
|
+
// Handle redeem request
|
|
125
128
|
const redeemRequest = redeemRequests[i].toPrimitive();
|
|
126
129
|
if (redeemRequest) {
|
|
127
|
-
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
const amount = new BN(redeemAmount).mul(new BN(exchangeRate)).div(decimals);
|
|
132
|
-
totalBalance = totalBalance.add(amount);
|
|
133
|
-
unlockingBalance = unlockingBalance.add(amount);
|
|
130
|
+
const [derivativeRedeemAmount, _] = redeemRequest;
|
|
131
|
+
const redeemAmount = convertDerivativeToken(new BN(derivativeRedeemAmount), exchangeRate, this.rateDecimals);
|
|
132
|
+
totalBalance = totalBalance.add(redeemAmount);
|
|
133
|
+
unlockingBalance = unlockingBalance.add(redeemAmount);
|
|
134
134
|
unstakings.push({
|
|
135
135
|
chain: this.chain,
|
|
136
|
-
status:
|
|
137
|
-
claimable:
|
|
136
|
+
status: UnstakingStatus.UNLOCKING,
|
|
137
|
+
claimable: redeemAmount.toString(),
|
|
138
|
+
waitingTime: 28 * _STAKING_ERA_LENGTH_MAP.polkadot // up to 29 day (in case non-fast-match
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Handle unbondings
|
|
143
|
+
const unbondings = await substrateApi.api.query.homa.unbondings.entries(address);
|
|
144
|
+
if (unbondings.length > 0) {
|
|
145
|
+
unbondings.forEach(([unbondingInfo, unbondingValue]) => {
|
|
146
|
+
// @ts-ignore
|
|
147
|
+
const _targetEra = unbondingInfo.toHuman()[1];
|
|
148
|
+
const targetEra = parseInt(_targetEra.replaceAll(',', ''));
|
|
149
|
+
const amount = new BN(unbondingValue.toPrimitive());
|
|
150
|
+
totalBalance = totalBalance.add(amount);
|
|
151
|
+
unlockingBalance = unlockingBalance.add(amount);
|
|
152
|
+
if (targetEra > currentEra) {
|
|
153
|
+
unstakings.push({
|
|
154
|
+
chain: this.chain,
|
|
155
|
+
status: UnstakingStatus.UNLOCKING,
|
|
156
|
+
claimable: amount.toString(),
|
|
157
|
+
waitingTime: (targetEra - currentEra) * _STAKING_ERA_LENGTH_MAP.polkadot // Todo: Handle exact timestamp?
|
|
158
|
+
});
|
|
159
|
+
} else {
|
|
160
|
+
unstakings.push({
|
|
161
|
+
chain: this.chain,
|
|
162
|
+
status: UnstakingStatus.CLAIMABLE,
|
|
163
|
+
claimable: amount.toString()
|
|
164
|
+
});
|
|
165
|
+
}
|
|
138
166
|
});
|
|
139
167
|
}
|
|
140
168
|
const result = {
|
|
@@ -225,7 +253,8 @@ export default class AcalaLiquidStakingPoolHandler extends BaseLiquidStakingPool
|
|
|
225
253
|
}
|
|
226
254
|
async handleYieldUnstake(amount, address, selectedTarget) {
|
|
227
255
|
const chainApi = await this.substrateApi.isReady;
|
|
228
|
-
const extrinsic = chainApi.api.tx.homa.requestRedeem(amount,
|
|
256
|
+
const extrinsic = chainApi.api.tx.homa.requestRedeem(amount, true); // set true to allow fast match
|
|
257
|
+
|
|
229
258
|
return [ExtrinsicType.UNSTAKE_LDOT, extrinsic];
|
|
230
259
|
}
|
|
231
260
|
async handleYieldWithdraw(address, unstakingInfo) {
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// Copyright 2019-2022 @subwallet/extension-koni authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import BaseMigrationJob from '@subwallet/extension-base/services/migration-service/Base';
|
|
5
|
+
export default class ReloadMetadata extends BaseMigrationJob {
|
|
6
|
+
chains = ['goldberg_testnet'];
|
|
7
|
+
async run() {
|
|
8
|
+
const activeChains = this.state.chainService.getActiveChains();
|
|
9
|
+
for (const chain of this.chains) {
|
|
10
|
+
const item = await this.state.dbService.stores.metadata.getMetadata(chain);
|
|
11
|
+
if (item) {
|
|
12
|
+
// @ts-ignore
|
|
13
|
+
await this.state.dbService.stores.metadata.remove(item.genesisHash);
|
|
14
|
+
const isActive = activeChains.includes(chain);
|
|
15
|
+
if (isActive) {
|
|
16
|
+
this.state.chainService.disableChain(chain);
|
|
17
|
+
setTimeout(() => {
|
|
18
|
+
this.state.chainService.enableChain(chain).catch(console.error);
|
|
19
|
+
}, 500);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
// Clear all old metadata data
|
|
24
|
+
|
|
25
|
+
return Promise.resolve();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import AutoEnableSomeTokens from '@subwallet/extension-base/services/migration-service/scripts/databases/AutoEnableSomeTokens';
|
|
5
|
+
import ReloadMetadata from '@subwallet/extension-base/services/migration-service/scripts/databases/ReloadMetadata';
|
|
5
6
|
import DeleteEarningData from '@subwallet/extension-base/services/migration-service/scripts/DeleteEarningData';
|
|
6
7
|
import MigrateRemoveGenesisHash from '@subwallet/extension-base/services/migration-service/scripts/MigrateRemoveGenesisHash';
|
|
7
8
|
import MigrateTransactionHistoryBySymbol from '@subwallet/extension-base/services/migration-service/scripts/MigrateTransactionHistoryBySymbol';
|
|
9
|
+
import ClearMetadataDatabase from "./databases/ClearMetadataDatabase.js";
|
|
8
10
|
import MigrateAssetSetting from "./databases/MigrateAssetSetting.js";
|
|
9
11
|
import MigrateEarningVersion from "./databases/MigrateEarningVersion.js";
|
|
10
12
|
import MigrateEthProvider from "./providers/MigrateEthProvider.js";
|
|
@@ -12,7 +14,6 @@ import MigratePioneerProvider from "./providers/MigratePioneerProvider.js";
|
|
|
12
14
|
import MigrateProvidersV1M1P24 from "./providers/MigrateProvidersV1M1P24.js";
|
|
13
15
|
import MigratePolygonUSDCProvider from "./tokens/MigratePolygonUSDCProvider.js";
|
|
14
16
|
import AutoEnableChainsTokens from "./AutoEnableChainsTokens.js";
|
|
15
|
-
import ClearMetadataDatabase from "./ClearMetadataDatabase.js";
|
|
16
17
|
import DeleteChain from "./DeleteChain.js";
|
|
17
18
|
import DeleteChainStaking from "./DeleteChainStaking.js";
|
|
18
19
|
import EnableVaraChain from "./EnableVaraChain.js";
|
|
@@ -55,7 +56,8 @@ export default {
|
|
|
55
56
|
'1.1.69-03': MigrateAssetSetting,
|
|
56
57
|
'1.1.69-02': MigrateTransactionHistoryBySymbol,
|
|
57
58
|
'1.2.69-01': MigrateRemoveGenesisHash,
|
|
58
|
-
'1.2.1-01': ClearMetadataDatabase
|
|
59
|
+
'1.2.1-01': ClearMetadataDatabase,
|
|
60
|
+
'1.2.13-01': ReloadMetadata
|
|
59
61
|
// [`${EVERYTIME}-1.1.42-02`]: MigrateTransactionHistoryBySymbol
|
|
60
62
|
// [`${EVERYTIME}-1`]: AutoEnableChainsTokens
|
|
61
63
|
};
|
|
@@ -2,12 +2,22 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import { staticData, StaticKey } from '@subwallet/extension-base/utils/staticData';
|
|
5
|
+
import { isArray } from '@polkadot/util';
|
|
5
6
|
const DEFAULT_CURRENCY = 'USD';
|
|
6
7
|
let useBackupApi = false;
|
|
7
8
|
export const getExchangeRateMap = async () => {
|
|
9
|
+
let response;
|
|
8
10
|
try {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
var _response, _response2;
|
|
12
|
+
try {
|
|
13
|
+
response = await fetch('https://api-cache.subwallet.app/exchange-rate');
|
|
14
|
+
} catch (e) {}
|
|
15
|
+
if (((_response = response) === null || _response === void 0 ? void 0 : _response.status) !== 200) {
|
|
16
|
+
try {
|
|
17
|
+
response = await fetch('https://static-cache.subwallet.app/exchange-rate/data.json');
|
|
18
|
+
} catch (e) {}
|
|
19
|
+
}
|
|
20
|
+
const responseDataExchangeRate = (await ((_response2 = response) === null || _response2 === void 0 ? void 0 : _response2.json())) || {};
|
|
11
21
|
const exchangeRateMap = Object.keys(responseDataExchangeRate.conversion_rates).reduce((map, exchangeKey) => {
|
|
12
22
|
if (!staticData[StaticKey.CURRENCY_SYMBOL][exchangeKey]) {
|
|
13
23
|
return map;
|
|
@@ -20,42 +30,54 @@ export const getExchangeRateMap = async () => {
|
|
|
20
30
|
}, {});
|
|
21
31
|
return exchangeRateMap;
|
|
22
32
|
} catch (e) {
|
|
23
|
-
console.warn('Failed to get exchange rate');
|
|
24
33
|
return {};
|
|
25
34
|
}
|
|
26
35
|
};
|
|
27
36
|
export const getPriceMap = async (priceIds, currency = 'USD') => {
|
|
28
|
-
var _rs, _rs2;
|
|
29
37
|
const idStr = Array.from(priceIds).join(',');
|
|
30
|
-
let
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
38
|
+
let response;
|
|
39
|
+
try {
|
|
40
|
+
var _response3, _response5;
|
|
41
|
+
if (!useBackupApi) {
|
|
42
|
+
try {
|
|
43
|
+
response = await fetch(`https://api.coingecko.com/api/v3/coins/markets?vs_currency=${currency.toLowerCase()}&per_page=250&ids=${idStr}`);
|
|
44
|
+
} catch (err) {
|
|
45
|
+
useBackupApi = true;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (useBackupApi || ((_response3 = response) === null || _response3 === void 0 ? void 0 : _response3.status) !== 200) {
|
|
49
|
+
var _response4;
|
|
35
50
|
useBackupApi = true;
|
|
51
|
+
try {
|
|
52
|
+
response = await fetch(`https://api-cache.subwallet.app/api/price/get?ids=${idStr}`);
|
|
53
|
+
} catch (e) {}
|
|
54
|
+
if (((_response4 = response) === null || _response4 === void 0 ? void 0 : _response4.status) !== 200) {
|
|
55
|
+
try {
|
|
56
|
+
response = await fetch('https://static-cache.subwallet.app/price/data.json');
|
|
57
|
+
} catch (e) {}
|
|
58
|
+
}
|
|
36
59
|
}
|
|
60
|
+
const generateDataPriceRaw = (await ((_response5 = response) === null || _response5 === void 0 ? void 0 : _response5.json())) || [];
|
|
61
|
+
const responseDataPrice = isArray(generateDataPriceRaw) ? generateDataPriceRaw : Object.entries(generateDataPriceRaw).map(([id, value]) => ({
|
|
62
|
+
...value,
|
|
63
|
+
id
|
|
64
|
+
}));
|
|
65
|
+
const currencyData = staticData[StaticKey.CURRENCY_SYMBOL][currency || DEFAULT_CURRENCY];
|
|
66
|
+
const priceMap = {};
|
|
67
|
+
const price24hMap = {};
|
|
68
|
+
responseDataPrice.forEach(val => {
|
|
69
|
+
const currentPrice = val.current_price || 0;
|
|
70
|
+
const price24h = currentPrice - (val.price_change_24h || 0);
|
|
71
|
+
priceMap[val.id] = currentPrice;
|
|
72
|
+
price24hMap[val.id] = price24h;
|
|
73
|
+
});
|
|
74
|
+
return {
|
|
75
|
+
currency,
|
|
76
|
+
currencyData,
|
|
77
|
+
priceMap,
|
|
78
|
+
price24hMap
|
|
79
|
+
};
|
|
80
|
+
} catch (e) {
|
|
81
|
+
return {};
|
|
37
82
|
}
|
|
38
|
-
if (useBackupApi || ((_rs = rs) === null || _rs === void 0 ? void 0 : _rs.status) !== 200) {
|
|
39
|
-
useBackupApi = true;
|
|
40
|
-
rs = await fetch(`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 = (await rs.json()) || [];
|
|
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
|
-
};
|
|
61
83
|
};
|
|
@@ -6,9 +6,10 @@ import { ServiceStatus } from '@subwallet/extension-base/services/base/types';
|
|
|
6
6
|
import { getExchangeRateMap, getPriceMap } from '@subwallet/extension-base/services/price-service/coingecko';
|
|
7
7
|
import { SWStorage } from '@subwallet/extension-base/storage';
|
|
8
8
|
import { CurrentCurrencyStore } from '@subwallet/extension-base/stores';
|
|
9
|
+
import { wait } from '@subwallet/extension-base/utils';
|
|
9
10
|
import { createPromiseHandler } from '@subwallet/extension-base/utils/promise';
|
|
10
11
|
import { staticData, StaticKey } from '@subwallet/extension-base/utils/staticData';
|
|
11
|
-
import { BehaviorSubject } from 'rxjs';
|
|
12
|
+
import { BehaviorSubject, combineLatest } from 'rxjs';
|
|
12
13
|
const DEFAULT_CURRENCY = 'USD';
|
|
13
14
|
const DEFAULT_PRICE_SUBJECT = {
|
|
14
15
|
currency: DEFAULT_CURRENCY,
|
|
@@ -22,6 +23,9 @@ const DEFAULT_PRICE_SUBJECT = {
|
|
|
22
23
|
price24hMap: {},
|
|
23
24
|
exchangeRateMap: {}
|
|
24
25
|
};
|
|
26
|
+
const checkFetchSuccess = (obj1, obj2) => {
|
|
27
|
+
return Object.keys(obj1).length > 0 && Object.keys(obj2).length > 0;
|
|
28
|
+
};
|
|
25
29
|
export class PriceService {
|
|
26
30
|
priceIds = new Set();
|
|
27
31
|
currency = new CurrentCurrencyStore();
|
|
@@ -43,10 +47,15 @@ export class PriceService {
|
|
|
43
47
|
this.init().then(() => this.getCurrentCurrency(updateCurrency)).catch(console.error);
|
|
44
48
|
}
|
|
45
49
|
async getTokenPrice(priceIds, currency, resolve, reject) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
+
const getPriceData = async () => {
|
|
51
|
+
await Promise.all([getExchangeRateMap(), getPriceMap(priceIds, currency)]).then(([exchangeRateMap, priceMap]) => {
|
|
52
|
+
if (checkFetchSuccess(priceMap, exchangeRateMap)) {
|
|
53
|
+
this.rawExchangeRateMap.next(exchangeRateMap);
|
|
54
|
+
this.rawPriceSubject.next(priceMap);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
};
|
|
58
|
+
await Promise.race([getPriceData(), wait(10 * 1000)]);
|
|
50
59
|
}
|
|
51
60
|
getCurrentCurrencySubject() {
|
|
52
61
|
return this.currency.getSubject();
|
|
@@ -82,17 +91,27 @@ export class PriceService {
|
|
|
82
91
|
})();
|
|
83
92
|
}
|
|
84
93
|
async calculatePriceMap(currency) {
|
|
85
|
-
|
|
94
|
+
let {
|
|
86
95
|
price24hMap,
|
|
87
96
|
priceMap
|
|
88
97
|
} = this.rawPriceSubject.value;
|
|
89
|
-
|
|
98
|
+
let exchangeRateData = this.rawExchangeRateMap.value;
|
|
99
|
+
const priceStored = await this.dbService.getPriceStore(currency);
|
|
90
100
|
const currencyKey = currency || DEFAULT_CURRENCY;
|
|
91
101
|
if (Object.keys(this.rawPriceSubject.value).length === 0) {
|
|
92
|
-
|
|
102
|
+
if (priceStored !== null && priceStored !== void 0 && priceStored.exchangeRateMap) {
|
|
103
|
+
exchangeRateData = priceStored.exchangeRateMap;
|
|
104
|
+
}
|
|
93
105
|
}
|
|
94
106
|
if (Object.keys(exchangeRateData).length === 0) {
|
|
95
|
-
|
|
107
|
+
if (priceStored !== null && priceStored !== void 0 && priceStored.price24hMap) {
|
|
108
|
+
price24hMap = {
|
|
109
|
+
...priceStored.price24hMap
|
|
110
|
+
};
|
|
111
|
+
priceMap = {
|
|
112
|
+
...priceStored.priceMap
|
|
113
|
+
};
|
|
114
|
+
}
|
|
96
115
|
}
|
|
97
116
|
const finalPriceMap = {
|
|
98
117
|
priceMap: {
|
|
@@ -158,8 +177,7 @@ export class PriceService {
|
|
|
158
177
|
this.refreshPriceMapByAction();
|
|
159
178
|
}
|
|
160
179
|
};
|
|
161
|
-
this.getCurrentCurrencySubject().subscribe(currency => {
|
|
162
|
-
console.log('Currency changed', currency);
|
|
180
|
+
combineLatest([this.getCurrentCurrencySubject(), this.rawPriceSubject, this.rawExchangeRateMap]).subscribe(([currency]) => {
|
|
163
181
|
this.calculatePriceMap(currency).then(data => {
|
|
164
182
|
if (data) {
|
|
165
183
|
this.priceSubject.next(data);
|
|
@@ -7,6 +7,9 @@ export default class BaseStore<T> {
|
|
|
7
7
|
get table(): Table<T, unknown>;
|
|
8
8
|
upsert(record: T): Promise<unknown>;
|
|
9
9
|
bulkUpsert(records: T[]): Promise<unknown>;
|
|
10
|
+
/**
|
|
11
|
+
* @todo Must update, delete function need the key not the record
|
|
12
|
+
* */
|
|
10
13
|
remove(record: T): Promise<void>;
|
|
11
14
|
clear(): Promise<void>;
|
|
12
15
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { SwapError } from '@subwallet/extension-base/background/errors/SwapError';
|
|
2
|
+
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
|
|
3
|
+
import { BalanceService } from '@subwallet/extension-base/services/balance-service';
|
|
4
|
+
import { ChainService } from '@subwallet/extension-base/services/chain-service';
|
|
5
|
+
import { BaseStepDetail, CommonOptimalPath, CommonStepFeeInfo } from '@subwallet/extension-base/types/service-base';
|
|
6
|
+
import { AssetHubSwapEarlyValidation, OptimalSwapPathParams, SwapProviderId, SwapQuote, SwapRequest, SwapSubmitParams, SwapSubmitStepData, ValidateSwapProcessParams } from '@subwallet/extension-base/types/swap';
|
|
7
|
+
import { SwapBaseInterface } from '../base-handler';
|
|
8
|
+
export declare class AssetHubSwapHandler implements SwapBaseInterface {
|
|
9
|
+
private swapBaseHandler;
|
|
10
|
+
private readonly chain;
|
|
11
|
+
private router;
|
|
12
|
+
isReady: boolean;
|
|
13
|
+
providerSlug: SwapProviderId;
|
|
14
|
+
constructor(chainService: ChainService, balanceService: BalanceService, chain: string);
|
|
15
|
+
get chainService(): ChainService;
|
|
16
|
+
get balanceService(): BalanceService;
|
|
17
|
+
get providerInfo(): import("@subwallet/extension-base/types/swap").SwapProvider;
|
|
18
|
+
get name(): string;
|
|
19
|
+
get slug(): string;
|
|
20
|
+
init(): Promise<void>;
|
|
21
|
+
getXcmStep(params: OptimalSwapPathParams): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
|
|
22
|
+
getSubmitStep(params: OptimalSwapPathParams): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
|
|
23
|
+
generateOptimalProcess(params: OptimalSwapPathParams): Promise<CommonOptimalPath>;
|
|
24
|
+
getSwapQuote(request: SwapRequest): Promise<SwapQuote | SwapError>;
|
|
25
|
+
handleXcmStep(params: SwapSubmitParams): Promise<SwapSubmitStepData>;
|
|
26
|
+
handleSubmitStep(params: SwapSubmitParams): Promise<SwapSubmitStepData>;
|
|
27
|
+
handleSwapProcess(params: SwapSubmitParams): Promise<SwapSubmitStepData>;
|
|
28
|
+
validateSwapStep(params: ValidateSwapProcessParams, isXcmOk: boolean, stepIndex: number): Promise<TransactionError[]>;
|
|
29
|
+
validateSwapProcess(params: ValidateSwapProcessParams): Promise<TransactionError[]>;
|
|
30
|
+
validateSwapRequest(request: SwapRequest): Promise<AssetHubSwapEarlyValidation>;
|
|
31
|
+
}
|