@subwallet/extension-base 1.3.30-0 → 1.3.31-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 +12 -0
- package/cjs/constants/paraspell-chain-map.js +13 -0
- package/cjs/core/logic-validation/transfer.js +13 -1
- package/cjs/core/substrate/xcm-parser.js +5 -1
- package/cjs/core/utils.js +36 -15
- package/cjs/koni/background/handlers/Extension.js +136 -90
- package/cjs/koni/background/handlers/State.js +8 -1
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/balance-service/helpers/process.js +27 -0
- package/cjs/services/balance-service/index.js +9 -0
- package/cjs/services/balance-service/transfer/xcm/acrossBridge/index.js +229 -0
- package/cjs/services/balance-service/transfer/xcm/index.js +96 -7
- package/cjs/services/balance-service/transfer/xcm/utils.js +213 -0
- package/cjs/services/chain-service/constants.js +2 -4
- package/cjs/services/chain-service/index.js +71 -17
- package/cjs/services/chain-service/utils/patch.js +1 -1
- package/cjs/services/earning-service/handlers/special.js +18 -9
- package/cjs/services/keyring-service/context/handlers/Ledger.js +1 -1
- package/cjs/services/keyring-service/context/state.js +3 -0
- package/cjs/services/migration-service/scripts/DisableZeroBalanceTokens.js +60 -0
- package/cjs/services/migration-service/scripts/EnableChain.js +1 -1
- package/cjs/services/migration-service/scripts/index.js +3 -2
- package/cjs/services/swap-service/handler/base-handler.js +24 -11
- package/cjs/services/transaction-service/utils.js +38 -14
- package/cjs/utils/fee/transfer.js +52 -28
- package/cjs/utils/staticData/index.js +7 -2
- package/constants/paraspell-chain-map.d.ts +1 -0
- package/constants/paraspell-chain-map.js +7 -0
- package/core/logic-validation/transfer.d.ts +1 -0
- package/core/logic-validation/transfer.js +12 -1
- package/core/substrate/xcm-parser.d.ts +1 -0
- package/core/substrate/xcm-parser.js +4 -1
- package/core/utils.d.ts +2 -2
- package/core/utils.js +36 -15
- package/koni/background/handlers/Extension.d.ts +1 -0
- package/koni/background/handlers/Extension.js +60 -15
- package/koni/background/handlers/State.d.ts +1 -0
- package/koni/background/handlers/State.js +7 -1
- package/package.json +23 -7
- package/packageInfo.js +1 -1
- package/services/balance-service/helpers/process.d.ts +2 -1
- package/services/balance-service/helpers/process.js +26 -0
- package/services/balance-service/index.js +11 -2
- package/services/balance-service/transfer/xcm/acrossBridge/index.d.ts +15 -0
- package/services/balance-service/transfer/xcm/acrossBridge/index.js +216 -0
- package/services/balance-service/transfer/xcm/index.d.ts +5 -1
- package/services/balance-service/transfer/xcm/index.js +85 -1
- package/services/balance-service/transfer/xcm/utils.d.ts +11 -0
- package/services/balance-service/transfer/xcm/utils.js +208 -0
- package/services/chain-service/constants.d.ts +0 -1
- package/services/chain-service/constants.js +1 -2
- package/services/chain-service/index.d.ts +9 -2
- package/services/chain-service/index.js +72 -18
- package/services/chain-service/utils/patch.js +1 -1
- package/services/earning-service/handlers/special.js +19 -10
- package/services/keyring-service/context/handlers/Ledger.js +1 -1
- package/services/keyring-service/context/state.d.ts +1 -0
- package/services/keyring-service/context/state.js +3 -0
- package/services/migration-service/scripts/DisableZeroBalanceTokens.d.ts +4 -0
- package/services/migration-service/scripts/DisableZeroBalanceTokens.js +51 -0
- package/services/migration-service/scripts/EnableChain.js +1 -1
- package/services/migration-service/scripts/index.js +3 -2
- package/services/swap-service/handler/base-handler.js +25 -12
- package/services/transaction-service/types.d.ts +3 -2
- package/services/transaction-service/utils.d.ts +1 -0
- package/services/transaction-service/utils.js +38 -15
- package/types/balance/transfer.d.ts +1 -0
- package/types/transaction/request.d.ts +7 -0
- package/utils/fee/transfer.d.ts +1 -0
- package/utils/fee/transfer.js +54 -30
- package/utils/staticData/index.d.ts +4 -1
- package/utils/staticData/index.js +5 -1
- package/utils/staticData/paraSpellChainMap.json +1 -0
|
@@ -1,7 +1,215 @@
|
|
|
1
1
|
// Copyright 2019-2022 @subwallet/extension-base
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
+
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
|
|
5
|
+
import { fetchParaSpellChainMap } from '@subwallet/extension-base/constants/paraspell-chain-map';
|
|
6
|
+
import { BasicTxErrorType } from '@subwallet/extension-base/types';
|
|
7
|
+
import { assert, compactToU8a, isHex, u8aConcat, u8aEq } from '@polkadot/util';
|
|
8
|
+
const paraSpellEndpoint = 'https://api.lightspell.xyz';
|
|
9
|
+
const paraSpellApi = {
|
|
10
|
+
buildXcm: `${paraSpellEndpoint}/x-transfer`,
|
|
11
|
+
dryRunXcm: `${paraSpellEndpoint}/dry-run`
|
|
12
|
+
};
|
|
13
|
+
const paraSpellKey = process.env.PARASPELL_API_KEY || '';
|
|
14
|
+
function txHexToSubmittableExtrinsic(api, hex) {
|
|
15
|
+
try {
|
|
16
|
+
assert(isHex(hex), 'Expected a hex-encoded call');
|
|
17
|
+
let extrinsicCall;
|
|
18
|
+
let extrinsicPayload = null;
|
|
19
|
+
let decoded = null;
|
|
20
|
+
try {
|
|
21
|
+
// attempt to decode with api.tx
|
|
22
|
+
const tx = api.tx(hex);
|
|
23
|
+
|
|
24
|
+
// ensure that the full data matches here
|
|
25
|
+
assert(tx.toHex() === hex, 'Cannot decode data as extrinsic, length mismatch');
|
|
26
|
+
decoded = tx;
|
|
27
|
+
extrinsicCall = api.createType('Call', decoded.method);
|
|
28
|
+
} catch {
|
|
29
|
+
try {
|
|
30
|
+
// attempt to decode as Call
|
|
31
|
+
extrinsicCall = api.createType('Call', hex);
|
|
32
|
+
const callHex = extrinsicCall.toHex();
|
|
33
|
+
if (callHex === hex) {
|
|
34
|
+
// ok
|
|
35
|
+
} else if (hex.startsWith(callHex)) {
|
|
36
|
+
// this could be an un-prefixed payload...
|
|
37
|
+
const prefixed = u8aConcat(compactToU8a(extrinsicCall.encodedLength), hex);
|
|
38
|
+
extrinsicPayload = api.createType('ExtrinsicPayload', prefixed);
|
|
39
|
+
assert(u8aEq(extrinsicPayload.toU8a(), prefixed), 'Unable to decode data as un-prefixed ExtrinsicPayload');
|
|
40
|
+
extrinsicCall = api.createType('Call', extrinsicPayload.method.toHex());
|
|
41
|
+
} else {
|
|
42
|
+
console.error('Unable to decode data as Call, length mismatch in supplied data');
|
|
43
|
+
}
|
|
44
|
+
} catch {
|
|
45
|
+
// final attempt, we try this as-is as a (prefixed) payload
|
|
46
|
+
extrinsicPayload = api.createType('ExtrinsicPayload', hex);
|
|
47
|
+
assert(extrinsicPayload.toHex() === hex, 'Unable to decode input data as Call, Extrinsic or ExtrinsicPayload');
|
|
48
|
+
extrinsicCall = api.createType('Call', extrinsicPayload.method.toHex());
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const {
|
|
52
|
+
method,
|
|
53
|
+
section
|
|
54
|
+
} = api.registry.findMetaCall(extrinsicCall.callIndex);
|
|
55
|
+
const extrinsicFn = api.tx[section][method];
|
|
56
|
+
if (!decoded) {
|
|
57
|
+
decoded = extrinsicFn(...extrinsicCall.args);
|
|
58
|
+
}
|
|
59
|
+
return decoded;
|
|
60
|
+
} catch (e) {
|
|
61
|
+
console.error('Failed to decode extrinsic hex', e);
|
|
62
|
+
throw new Error('Failed to decode extrinsic hex');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
export async function buildXcm(request) {
|
|
66
|
+
var _originTokenInfo$meta, _originTokenInfo$meta2;
|
|
67
|
+
const {
|
|
68
|
+
destinationChain,
|
|
69
|
+
originChain,
|
|
70
|
+
originTokenInfo,
|
|
71
|
+
recipient,
|
|
72
|
+
sendingValue,
|
|
73
|
+
substrateApi
|
|
74
|
+
} = request;
|
|
75
|
+
if (!substrateApi) {
|
|
76
|
+
return Promise.reject(new Error('Substrate API is not available'));
|
|
77
|
+
}
|
|
78
|
+
const psAssetType = (_originTokenInfo$meta = originTokenInfo.metadata) === null || _originTokenInfo$meta === void 0 ? void 0 : _originTokenInfo$meta.paraSpellAssetType;
|
|
79
|
+
const psAssetValue = (_originTokenInfo$meta2 = originTokenInfo.metadata) === null || _originTokenInfo$meta2 === void 0 ? void 0 : _originTokenInfo$meta2.paraSpellValue;
|
|
80
|
+
if (!psAssetType || !psAssetValue) {
|
|
81
|
+
throw new Error('Token is not support XCM at this time');
|
|
82
|
+
}
|
|
83
|
+
const paraSpellChainMap = await fetchParaSpellChainMap();
|
|
84
|
+
const bodyData = {
|
|
85
|
+
address: recipient,
|
|
86
|
+
from: paraSpellChainMap[originChain.slug],
|
|
87
|
+
to: paraSpellChainMap[destinationChain.slug],
|
|
88
|
+
currency: createParaSpellCurrency(psAssetType, psAssetValue, sendingValue)
|
|
89
|
+
};
|
|
90
|
+
const response = await fetch(paraSpellApi.buildXcm, {
|
|
91
|
+
method: 'POST',
|
|
92
|
+
body: JSON.stringify(bodyData),
|
|
93
|
+
headers: {
|
|
94
|
+
'Content-Type': 'application/json',
|
|
95
|
+
Accept: 'application/json',
|
|
96
|
+
'X-API-KEY': paraSpellKey
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
if (!response.ok) {
|
|
100
|
+
const error = await response.json();
|
|
101
|
+
throw new Error(error.message);
|
|
102
|
+
}
|
|
103
|
+
const extrinsicHex = await response.text();
|
|
104
|
+
const chainApi = await substrateApi.isReady;
|
|
105
|
+
return txHexToSubmittableExtrinsic(chainApi.api, extrinsicHex);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// dry run can fail due to sender address & amount token
|
|
109
|
+
export async function dryRunXcm(request) {
|
|
110
|
+
var _originTokenInfo$meta3, _originTokenInfo$meta4;
|
|
111
|
+
const {
|
|
112
|
+
destinationChain,
|
|
113
|
+
originChain,
|
|
114
|
+
originTokenInfo,
|
|
115
|
+
recipient,
|
|
116
|
+
sender,
|
|
117
|
+
sendingValue
|
|
118
|
+
} = request;
|
|
119
|
+
const paraSpellChainMap = await fetchParaSpellChainMap();
|
|
120
|
+
const psAssetType = (_originTokenInfo$meta3 = originTokenInfo.metadata) === null || _originTokenInfo$meta3 === void 0 ? void 0 : _originTokenInfo$meta3.paraSpellAssetType;
|
|
121
|
+
const psAssetValue = (_originTokenInfo$meta4 = originTokenInfo.metadata) === null || _originTokenInfo$meta4 === void 0 ? void 0 : _originTokenInfo$meta4.paraSpellValue;
|
|
122
|
+
if (!psAssetType || !psAssetValue) {
|
|
123
|
+
throw new Error('Token is not support XCM at this time'); // todo: content
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
let dryRunInfo;
|
|
127
|
+
try {
|
|
128
|
+
const bodyData = {
|
|
129
|
+
senderAddress: sender,
|
|
130
|
+
address: recipient,
|
|
131
|
+
from: paraSpellChainMap[originChain.slug],
|
|
132
|
+
to: paraSpellChainMap[destinationChain.slug],
|
|
133
|
+
currency: createParaSpellCurrency(psAssetType, psAssetValue, sendingValue)
|
|
134
|
+
};
|
|
135
|
+
const response = await fetch(paraSpellApi.dryRunXcm, {
|
|
136
|
+
method: 'POST',
|
|
137
|
+
body: JSON.stringify(bodyData),
|
|
138
|
+
headers: {
|
|
139
|
+
'Content-Type': 'application/json',
|
|
140
|
+
Accept: 'application/json',
|
|
141
|
+
'X-API-KEY': paraSpellKey
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
dryRunInfo = await response.json();
|
|
145
|
+
} catch (e) {
|
|
146
|
+
console.error('Unable to dry run', e);
|
|
147
|
+
}
|
|
148
|
+
if (!dryRunInfo || !dryRunInfo.success) {
|
|
149
|
+
throw new TransactionError(BasicTxErrorType.UNABLE_TO_SEND, 'Unable to perform transaction. Select another token or destination chain and try again');
|
|
150
|
+
}
|
|
151
|
+
return dryRunInfo;
|
|
152
|
+
}
|
|
153
|
+
export async function dryRunXcmV2(request) {
|
|
154
|
+
var _originTokenInfo$meta5, _originTokenInfo$meta6;
|
|
155
|
+
const {
|
|
156
|
+
destinationChain,
|
|
157
|
+
originChain,
|
|
158
|
+
originTokenInfo,
|
|
159
|
+
recipient,
|
|
160
|
+
sender,
|
|
161
|
+
sendingValue
|
|
162
|
+
} = request;
|
|
163
|
+
const paraSpellChainMap = await fetchParaSpellChainMap();
|
|
164
|
+
const psAssetType = (_originTokenInfo$meta5 = originTokenInfo.metadata) === null || _originTokenInfo$meta5 === void 0 ? void 0 : _originTokenInfo$meta5.paraSpellAssetType;
|
|
165
|
+
const psAssetValue = (_originTokenInfo$meta6 = originTokenInfo.metadata) === null || _originTokenInfo$meta6 === void 0 ? void 0 : _originTokenInfo$meta6.paraSpellValue;
|
|
166
|
+
if (!psAssetType || !psAssetValue) {
|
|
167
|
+
throw new Error('Token is not support XCM at this time');
|
|
168
|
+
}
|
|
169
|
+
const bodyData = {
|
|
170
|
+
senderAddress: sender,
|
|
171
|
+
address: recipient,
|
|
172
|
+
from: paraSpellChainMap[originChain.slug],
|
|
173
|
+
to: paraSpellChainMap[destinationChain.slug],
|
|
174
|
+
currency: createParaSpellCurrency(psAssetType, psAssetValue, sendingValue)
|
|
175
|
+
};
|
|
176
|
+
const response = await fetch(paraSpellApi.dryRunXcm, {
|
|
177
|
+
method: 'POST',
|
|
178
|
+
body: JSON.stringify(bodyData),
|
|
179
|
+
headers: {
|
|
180
|
+
'Content-Type': 'application/json',
|
|
181
|
+
Accept: 'application/json',
|
|
182
|
+
'X-API-KEY': paraSpellKey
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
if (!response.ok) {
|
|
186
|
+
const error = await response.json();
|
|
187
|
+
throw new Error(error.message);
|
|
188
|
+
}
|
|
189
|
+
return await response.json();
|
|
190
|
+
}
|
|
191
|
+
function createParaSpellCurrency(assetType, assetValue, amount) {
|
|
192
|
+
// todo: handle complex conditions for asset has same symbol in a chain: Id, Multi-location, ...
|
|
193
|
+
return {
|
|
194
|
+
[assetType]: assetValue,
|
|
195
|
+
amount
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
export function isChainNotSupportPolkadotApi(str) {
|
|
199
|
+
const regex = /(?=.*not yet supported)(?=.*Polkadot API).*/i; // Example: The node Interlay is not yet supported by the Polkadot API.
|
|
200
|
+
|
|
201
|
+
return regex.test(str);
|
|
202
|
+
}
|
|
203
|
+
export function isChainNotSupportDryRun(str) {
|
|
204
|
+
const regex = /(?=.*DryRunApi)(?=.*not available).*/i; // Example: DryRunApi is not available on node Acala
|
|
205
|
+
|
|
206
|
+
return regex.test(str);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// todo: remove
|
|
4
210
|
export const STABLE_XCM_VERSION = 3;
|
|
211
|
+
|
|
212
|
+
// todo: remove
|
|
5
213
|
export function isUseTeleportProtocol(originChainInfo, destChainInfo, tokenSlug) {
|
|
6
214
|
const relayChainToSystemChain = ['polkadot'].includes(originChainInfo.slug) && ['statemint'].includes(destChainInfo.slug) || ['kusama'].includes(originChainInfo.slug) && ['statemine'].includes(destChainInfo.slug) || ['rococo'].includes(originChainInfo.slug) && ['rococo_assethub'].includes(destChainInfo.slug) || ['westend'].includes(originChainInfo.slug) && ['westend_assethub'].includes(destChainInfo.slug);
|
|
7
215
|
const systemChainToRelayChain = ['polkadot'].includes(destChainInfo.slug) && ['statemint'].includes(originChainInfo.slug) || ['kusama'].includes(destChainInfo.slug) && ['statemine'].includes(originChainInfo.slug) || ['rococo'].includes(destChainInfo.slug) && ['rococo_assethub'].includes(originChainInfo.slug) || ['westend'].includes(destChainInfo.slug) && ['westend_assethub'].includes(originChainInfo.slug);
|
|
@@ -29,7 +29,7 @@ export const _BALANCE_CHAIN_GROUP = {
|
|
|
29
29
|
kintsugi: ['kintsugi', 'interlay', 'kintsugi_test', 'mangatax_para'],
|
|
30
30
|
genshiro: ['genshiro_testnet', 'genshiro'],
|
|
31
31
|
equilibrium_parachain: ['equilibrium_parachain'],
|
|
32
|
-
bifrost: ['bifrost', 'acala', 'karura', 'acala_testnet', 'pioneer', 'bitcountry', 'bifrost_dot', 'hydradx_main', 'hydradx_rococo', 'pendulum', 'amplitude', 'continuum_network'],
|
|
32
|
+
bifrost: ['bifrost', 'acala', 'karura', 'acala_testnet', 'pioneer', 'bitcountry', 'bifrost_dot', 'hydradx_main', 'hydradx_rococo', 'pendulum', 'amplitude', 'continuum_network', 'truth_network'],
|
|
33
33
|
statemine: ['statemine', 'astar', 'shiden', 'statemint', 'moonbeam', 'moonbase', 'moonriver', 'crabParachain', 'darwinia2', 'parallel', 'calamari', 'manta_network', 'rococo_assethub', 'liberlandTest', 'liberland', 'dentnet', 'pangolin', 'crust', 'phala', 'shibuya', 'dbcchain', 'westend_assethub'],
|
|
34
34
|
kusama: ['kusama', 'kintsugi', 'kintsugi_test', 'interlay', 'acala', 'statemint', 'karura', 'bifrost'],
|
|
35
35
|
// perhaps there are some runtime updates
|
|
@@ -278,7 +278,6 @@ export const _XCM_CHAIN_GROUP = {
|
|
|
278
278
|
// default is xTokens pallet
|
|
279
279
|
};
|
|
280
280
|
|
|
281
|
-
export const SUFFICIENT_CHAIN = ['astar', 'calamari', 'parallel', 'darwinia2', 'crabParachain', 'pangolin', 'statemint', 'moonriver', 'shiden', 'moonbeam', 'statemine', 'liberland', 'dentnet', 'phala', 'crust', 'dbcchain', 'rococo_assethub'];
|
|
282
281
|
export const _XCM_TYPE = {
|
|
283
282
|
RP: `${_SubstrateChainType.RELAYCHAIN}-${_SubstrateChainType.PARACHAIN}`,
|
|
284
283
|
// DMP
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { _AssetRef, _AssetType, _ChainAsset, _ChainInfo, _MultiChainAsset } from '@subwallet/chain-list/types';
|
|
3
|
-
import { AssetSetting, MetadataItem, TokenPriorityDetails, ValidateNetworkResponse } from '@subwallet/extension-base/background/KoniTypes';
|
|
3
|
+
import { AssetSetting, MetadataItem, SufficientChainsDetails, TokenPriorityDetails, ValidateNetworkResponse } from '@subwallet/extension-base/background/KoniTypes';
|
|
4
4
|
import { MantaPrivateHandler } from '@subwallet/extension-base/services/chain-service/handler/manta/MantaPrivateHandler';
|
|
5
5
|
import { _ChainApiStatus, _ChainConnectionStatus, _ChainState, _NetworkUpsertParams, _SubstrateApi, _ValidateCustomAssetRequest, _ValidateCustomAssetResponse } from '@subwallet/extension-base/services/chain-service/types';
|
|
6
6
|
import { EventService } from '@subwallet/extension-base/services/event-service';
|
|
@@ -32,6 +32,7 @@ export declare class ChainService {
|
|
|
32
32
|
private chainLogoMapSubject;
|
|
33
33
|
private ledgerGenericAllowChainsSubject;
|
|
34
34
|
private priorityTokensSubject;
|
|
35
|
+
private sufficientChainsSubject;
|
|
35
36
|
private store;
|
|
36
37
|
private assetSettingSubject;
|
|
37
38
|
private logger;
|
|
@@ -39,10 +40,12 @@ export declare class ChainService {
|
|
|
39
40
|
get value(): {
|
|
40
41
|
readonly ledgerGenericAllowChains: string[];
|
|
41
42
|
readonly priorityTokens: TokenPriorityDetails;
|
|
43
|
+
readonly sufficientChains: SufficientChainsDetails;
|
|
42
44
|
};
|
|
43
45
|
get observable(): {
|
|
44
46
|
readonly ledgerGenericAllowChains: import("rxjs").Observable<string[]>;
|
|
45
47
|
readonly priorityTokens: import("rxjs").Observable<TokenPriorityDetails>;
|
|
48
|
+
readonly sufficientChains: import("rxjs").Observable<SufficientChainsDetails>;
|
|
46
49
|
};
|
|
47
50
|
subscribeSwapRefMap(): Subject<Record<string, _AssetRef>>;
|
|
48
51
|
get xcmRefMap(): Record<string, _AssetRef>;
|
|
@@ -111,8 +114,10 @@ export declare class ChainService {
|
|
|
111
114
|
stopCheckLatestChainData(): void;
|
|
112
115
|
handleLatestChainData(latestChainInfo: _ChainInfo[]): void;
|
|
113
116
|
autoEnableTokens(): Promise<void>;
|
|
117
|
+
enablePopularTokens(): Promise<void>;
|
|
114
118
|
handleLatestLedgerGenericAllowChains(latestledgerGenericAllowChains: string[]): void;
|
|
115
119
|
handleLatestPriorityTokens(latestPriorityTokens: TokenPriorityDetails): void;
|
|
120
|
+
handleLatestSufficientChains(latestSufficientChains: SufficientChainsDetails): void;
|
|
116
121
|
handleLatestData(): void;
|
|
117
122
|
private initApis;
|
|
118
123
|
initSingleApi(slug: string): Promise<boolean>;
|
|
@@ -127,6 +132,7 @@ export declare class ChainService {
|
|
|
127
132
|
private fetchLatestPriceIdsData;
|
|
128
133
|
private fetchLatestLedgerGenericAllowChains;
|
|
129
134
|
private fetchLatestPriorityTokens;
|
|
135
|
+
private fetchLatestSufficientChains;
|
|
130
136
|
private initChains;
|
|
131
137
|
private initAssetRegistry;
|
|
132
138
|
private updateChainStateMapSubscription;
|
|
@@ -148,13 +154,14 @@ export declare class ChainService {
|
|
|
148
154
|
refreshEvmApi(slug: string): void;
|
|
149
155
|
stopAllChainApis(): Promise<void>;
|
|
150
156
|
resumeAllChainApis(): Promise<void>;
|
|
151
|
-
initAssetSettings():
|
|
157
|
+
initAssetSettings(): void;
|
|
152
158
|
setAssetSettings(assetSettings: Record<string, AssetSetting>, emitEvent?: boolean): void;
|
|
153
159
|
setMantaZkAssetSettings(visible: boolean): void;
|
|
154
160
|
getStoreAssetSettings(): Promise<Record<string, AssetSetting>>;
|
|
155
161
|
getAssetSettings(): Promise<Record<string, AssetSetting>>;
|
|
156
162
|
updateAssetSetting(assetSlug: string, assetSetting: AssetSetting, autoEnableNativeToken?: boolean): Promise<boolean | undefined>;
|
|
157
163
|
updateAssetSettingByChain(chainSlug: string, visible: boolean): Promise<void>;
|
|
164
|
+
updatePriorityAssetsByChain(chainSlug: string, visible: boolean): Promise<void>;
|
|
158
165
|
subscribeAssetSettings(): BehaviorSubject<Record<string, AssetSetting>>;
|
|
159
166
|
getAssetLogoMap(): Record<string, string>;
|
|
160
167
|
subscribeAssetLogoMap(): BehaviorSubject<Record<string, string>>;
|
|
@@ -11,7 +11,7 @@ import { SubstrateChainHandler } from '@subwallet/extension-base/services/chain-
|
|
|
11
11
|
import { TonChainHandler } from '@subwallet/extension-base/services/chain-service/handler/TonChainHandler';
|
|
12
12
|
import { _CHAIN_VALIDATION_ERROR } from '@subwallet/extension-base/services/chain-service/handler/types';
|
|
13
13
|
import { _ChainConnectionStatus, _CUSTOM_PREFIX, _NFT_CONTRACT_STANDARDS, _SMART_CONTRACT_STANDARDS } from '@subwallet/extension-base/services/chain-service/types';
|
|
14
|
-
import { _getAssetOriginChain, _getTokenOnChainAssetId, _isAssetAutoEnable, _isAssetCanPayTxFee, _isAssetFungibleToken, _isChainEnabled, _isCustomAsset, _isCustomChain, _isCustomProvider, _isEqualContractAddress, _isEqualSmartContractAsset, _isLocalToken, _isMantaZkAsset, _isPureEvmChain, _isPureSubstrateChain, _parseAssetRefKey, randomizeProvider, updateLatestChainInfo } from '@subwallet/extension-base/services/chain-service/utils';
|
|
14
|
+
import { _getAssetOriginChain, _getTokenOnChainAssetId, _isAssetAutoEnable, _isAssetCanPayTxFee, _isAssetFungibleToken, _isChainEnabled, _isCustomAsset, _isCustomChain, _isCustomProvider, _isEqualContractAddress, _isEqualSmartContractAsset, _isLocalToken, _isMantaZkAsset, _isNativeToken, _isPureEvmChain, _isPureSubstrateChain, _parseAssetRefKey, randomizeProvider, updateLatestChainInfo } from '@subwallet/extension-base/services/chain-service/utils';
|
|
15
15
|
import { MYTHOS_MIGRATION_KEY } from '@subwallet/extension-base/services/migration-service/scripts';
|
|
16
16
|
import AssetSettingStore from '@subwallet/extension-base/stores/AssetSetting';
|
|
17
17
|
import { addLazy, calculateMetadataHash, fetchStaticData, filterAssetsByChainAndType, getShortMetadata, MODULE_SUPPORT } from '@subwallet/extension-base/utils';
|
|
@@ -50,6 +50,7 @@ export class ChainService {
|
|
|
50
50
|
chainLogoMapSubject = new BehaviorSubject(ChainLogoMap);
|
|
51
51
|
ledgerGenericAllowChainsSubject = new BehaviorSubject([]);
|
|
52
52
|
priorityTokensSubject = new BehaviorSubject({});
|
|
53
|
+
sufficientChainsSubject = new BehaviorSubject({});
|
|
53
54
|
|
|
54
55
|
// Todo: Update to new store indexed DB
|
|
55
56
|
store = new AssetSettingStore();
|
|
@@ -75,24 +76,32 @@ export class ChainService {
|
|
|
75
76
|
get value() {
|
|
76
77
|
const ledgerGenericAllowChains = this.ledgerGenericAllowChainsSubject;
|
|
77
78
|
const priorityTokens = this.priorityTokensSubject;
|
|
79
|
+
const sufficientChains = this.sufficientChainsSubject;
|
|
78
80
|
return {
|
|
79
81
|
get ledgerGenericAllowChains() {
|
|
80
82
|
return ledgerGenericAllowChains.value;
|
|
81
83
|
},
|
|
82
84
|
get priorityTokens() {
|
|
83
85
|
return priorityTokens.value;
|
|
86
|
+
},
|
|
87
|
+
get sufficientChains() {
|
|
88
|
+
return sufficientChains.value;
|
|
84
89
|
}
|
|
85
90
|
};
|
|
86
91
|
}
|
|
87
92
|
get observable() {
|
|
88
93
|
const ledgerGenericAllowChains = this.ledgerGenericAllowChainsSubject;
|
|
89
94
|
const priorityTokens = this.priorityTokensSubject;
|
|
95
|
+
const sufficientChains = this.sufficientChainsSubject;
|
|
90
96
|
return {
|
|
91
97
|
get ledgerGenericAllowChains() {
|
|
92
98
|
return ledgerGenericAllowChains.asObservable();
|
|
93
99
|
},
|
|
94
100
|
get priorityTokens() {
|
|
95
101
|
return priorityTokens.asObservable();
|
|
102
|
+
},
|
|
103
|
+
get sufficientChains() {
|
|
104
|
+
return sufficientChains.asObservable();
|
|
96
105
|
}
|
|
97
106
|
};
|
|
98
107
|
}
|
|
@@ -526,7 +535,7 @@ export class ChainService {
|
|
|
526
535
|
this.initAssetRefMap();
|
|
527
536
|
this.xcmRefMapSubject.next(this.xcmRefMap);
|
|
528
537
|
await this.initApis();
|
|
529
|
-
|
|
538
|
+
this.initAssetSettings();
|
|
530
539
|
await this.autoEnableTokens();
|
|
531
540
|
}
|
|
532
541
|
initAssetRefMap() {
|
|
@@ -605,14 +614,47 @@ export class ChainService {
|
|
|
605
614
|
}
|
|
606
615
|
}
|
|
607
616
|
}
|
|
617
|
+
async enablePopularTokens() {
|
|
618
|
+
const assetSettings = this.assetSettingSubject.value;
|
|
619
|
+
const chainStateMap = this.getChainStateMap();
|
|
620
|
+
const priorityTokensMap = this.priorityTokensSubject.value || {};
|
|
621
|
+
const priorityTokensList = priorityTokensMap.token && typeof priorityTokensMap.token === 'object' ? Object.keys(priorityTokensMap.token) : [];
|
|
622
|
+
for (const assetSlug of priorityTokensList) {
|
|
623
|
+
const assetState = assetSettings[assetSlug];
|
|
624
|
+
const assetInfo = this.getAssetBySlug(assetSlug);
|
|
625
|
+
const chainState = chainStateMap[assetInfo.originChain];
|
|
626
|
+
if (!assetState) {
|
|
627
|
+
// If this asset not has asset setting, this token is not enabled before (not turned off before)
|
|
628
|
+
if (!chainState || !chainState.manualTurnOff) {
|
|
629
|
+
await this.updateAssetSetting(assetSlug, {
|
|
630
|
+
visible: true
|
|
631
|
+
}, true);
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
}
|
|
608
636
|
handleLatestLedgerGenericAllowChains(latestledgerGenericAllowChains) {
|
|
609
637
|
this.ledgerGenericAllowChainsSubject.next(latestledgerGenericAllowChains);
|
|
610
638
|
this.eventService.emit('ledger.ready', true);
|
|
611
639
|
this.logger.log('Finished updating latest ledger generic allow chains');
|
|
612
640
|
}
|
|
613
641
|
handleLatestPriorityTokens(latestPriorityTokens) {
|
|
642
|
+
const currentTokens = this.priorityTokensSubject.value || {};
|
|
614
643
|
this.priorityTokensSubject.next(latestPriorityTokens);
|
|
615
644
|
this.logger.log('Finished updating latest popular tokens');
|
|
645
|
+
const currentTokenKeys = Object.keys(currentTokens.token || {}); // Extract keys from current tokens
|
|
646
|
+
const newTokenKeys = Object.keys(latestPriorityTokens.token || {}); // Extract keys from new tokens
|
|
647
|
+
|
|
648
|
+
if (JSON.stringify(currentTokenKeys) !== JSON.stringify(newTokenKeys)) {
|
|
649
|
+
// Check if token keys have changed
|
|
650
|
+
this.enablePopularTokens().then(() => this.logger.log('Popular tokens enabled due to priority tokens change')) // Log success after enabling tokens
|
|
651
|
+
.catch(e => console.error('Error enabling popular tokens:', e)); // Log error if enabling fails
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
handleLatestSufficientChains(latestSufficientChains) {
|
|
656
|
+
this.sufficientChainsSubject.next(latestSufficientChains);
|
|
657
|
+
this.logger.log('Finished updating latest supported sufficient chains');
|
|
616
658
|
}
|
|
617
659
|
handleLatestData() {
|
|
618
660
|
this.fetchLatestChainData().then(latestChainInfo => {
|
|
@@ -634,6 +676,9 @@ export class ChainService {
|
|
|
634
676
|
this.fetchLatestPriorityTokens().then(latestPriorityTokens => {
|
|
635
677
|
this.handleLatestPriorityTokens(latestPriorityTokens);
|
|
636
678
|
}).catch(console.error);
|
|
679
|
+
this.fetchLatestSufficientChains().then(latestSufficientChains => {
|
|
680
|
+
this.handleLatestSufficientChains(latestSufficientChains);
|
|
681
|
+
}).catch(console.error);
|
|
637
682
|
}
|
|
638
683
|
async initApis() {
|
|
639
684
|
const chainInfoMap = this.getChainInfoMap();
|
|
@@ -913,6 +958,9 @@ export class ChainService {
|
|
|
913
958
|
token: {}
|
|
914
959
|
};
|
|
915
960
|
}
|
|
961
|
+
async fetchLatestSufficientChains() {
|
|
962
|
+
return (await fetchStaticData('chains/supported-sufficient-chains')) || [];
|
|
963
|
+
}
|
|
916
964
|
async initChains() {
|
|
917
965
|
const storedChainSettings = await this.dbService.getAllChainStore();
|
|
918
966
|
const defaultChainInfoMap = filterChainInfoMap(ChainInfoMap, ignoredList);
|
|
@@ -1616,22 +1664,7 @@ export class ChainService {
|
|
|
1616
1664
|
await Promise.all([this.substrateChainHandler.wakeUp(), this.evmChainHandler.wakeUp(), this.tonChainHandler.wakeUp(), this.cardanoChainHandler.wakeUp()]);
|
|
1617
1665
|
this.checkLatestData();
|
|
1618
1666
|
}
|
|
1619
|
-
|
|
1620
|
-
const assetSettings = await this.getAssetSettings();
|
|
1621
|
-
const activeChainSlugs = this.getActiveChainSlugs();
|
|
1622
|
-
const assetRegistry = this.getAssetRegistry();
|
|
1623
|
-
Object.values(assetRegistry).forEach(assetInfo => {
|
|
1624
|
-
const isSettingExisted = (assetInfo.slug in assetSettings);
|
|
1625
|
-
|
|
1626
|
-
// Set visible for every enabled chains
|
|
1627
|
-
if (activeChainSlugs.includes(assetInfo.originChain) && !isSettingExisted) {
|
|
1628
|
-
// Setting only exist when set either by chain settings or user
|
|
1629
|
-
assetSettings[assetInfo.slug] = {
|
|
1630
|
-
visible: true
|
|
1631
|
-
};
|
|
1632
|
-
}
|
|
1633
|
-
});
|
|
1634
|
-
this.setAssetSettings(assetSettings, false);
|
|
1667
|
+
initAssetSettings() {
|
|
1635
1668
|
this.eventService.emit('asset.ready', true);
|
|
1636
1669
|
}
|
|
1637
1670
|
setAssetSettings(assetSettings, emitEvent = true) {
|
|
@@ -1719,6 +1752,27 @@ export class ChainService {
|
|
|
1719
1752
|
});
|
|
1720
1753
|
this.setAssetSettings(assetSettings);
|
|
1721
1754
|
}
|
|
1755
|
+
async updatePriorityAssetsByChain(chainSlug, visible) {
|
|
1756
|
+
const currentAssetSettings = await this.getAssetSettings();
|
|
1757
|
+
const assetsByChain = this.getFungibleTokensByChain(chainSlug);
|
|
1758
|
+
const priorityTokensMap = this.priorityTokensSubject.value || {};
|
|
1759
|
+
const priorityTokensList = priorityTokensMap.token && typeof priorityTokensMap.token === 'object' ? Object.keys(priorityTokensMap.token) : [];
|
|
1760
|
+
for (const asset of Object.values(assetsByChain)) {
|
|
1761
|
+
if (visible) {
|
|
1762
|
+
const isPriorityToken = priorityTokensList.includes(asset.slug);
|
|
1763
|
+
if (isPriorityToken || _isNativeToken(asset)) {
|
|
1764
|
+
currentAssetSettings[asset.slug] = {
|
|
1765
|
+
visible: true
|
|
1766
|
+
};
|
|
1767
|
+
}
|
|
1768
|
+
} else {
|
|
1769
|
+
currentAssetSettings[asset.slug] = {
|
|
1770
|
+
visible: false
|
|
1771
|
+
};
|
|
1772
|
+
}
|
|
1773
|
+
}
|
|
1774
|
+
this.setAssetSettings(currentAssetSettings);
|
|
1775
|
+
}
|
|
1722
1776
|
subscribeAssetSettings() {
|
|
1723
1777
|
return this.assetSettingSubject;
|
|
1724
1778
|
}
|
|
@@ -5,7 +5,7 @@ const PRODUCTION_BRANCHES = ['master', 'webapp', 'webapp-dev'];
|
|
|
5
5
|
const branchName = process.env.BRANCH_NAME || 'subwallet-dev';
|
|
6
6
|
const fetchDomain = PRODUCTION_BRANCHES.indexOf(branchName) > -1 ? 'https://chain-list-assets.subwallet.app' : 'https://dev.sw-chain-list-assets.pages.dev';
|
|
7
7
|
const fetchFile = PRODUCTION_BRANCHES.indexOf(branchName) > -1 ? 'list.json' : 'preview.json';
|
|
8
|
-
const ChainListVersion = '0.2.
|
|
8
|
+
const ChainListVersion = '0.2.103'; // update this when build chainlist
|
|
9
9
|
|
|
10
10
|
// todo: move this interface to chainlist
|
|
11
11
|
|
|
@@ -5,11 +5,12 @@ import { TransactionError } from '@subwallet/extension-base/background/errors/Tr
|
|
|
5
5
|
import { ChainType, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
|
|
6
6
|
import { ALL_ACCOUNT_KEY, XCM_FEE_RATIO, XCM_MIN_AMOUNT_RATIO } from '@subwallet/extension-base/constants';
|
|
7
7
|
import { YIELD_POOL_STAT_REFRESH_INTERVAL } from '@subwallet/extension-base/koni/api/yield/helper/utils';
|
|
8
|
-
import {
|
|
8
|
+
import { createXcmExtrinsicV2, dryRunXcmExtrinsicV2 } from '@subwallet/extension-base/services/balance-service/transfer/xcm';
|
|
9
9
|
import { _getAssetDecimals, _getAssetExistentialDeposit, _getAssetName, _getAssetSymbol, _getChainNativeTokenSlug, _isNativeToken } from '@subwallet/extension-base/services/chain-service/utils';
|
|
10
10
|
import { BasicTxErrorType, YieldStepType, YieldValidationStatus } from '@subwallet/extension-base/types';
|
|
11
11
|
import { createPromiseHandler, formatNumber } from '@subwallet/extension-base/utils';
|
|
12
12
|
import { getId } from '@subwallet/extension-base/utils/getId';
|
|
13
|
+
import BigN from 'bignumber.js';
|
|
13
14
|
import { t } from 'i18next';
|
|
14
15
|
import { BN, BN_TEN, BN_ZERO, noop } from '@polkadot/util';
|
|
15
16
|
import BasePoolHandler from "./base.js";
|
|
@@ -219,7 +220,7 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
|
|
|
219
220
|
const xcmOriginSubstrateApi = await this.state.getSubstrateApi(altInputTokenInfo.originChain).isReady;
|
|
220
221
|
const id = getId();
|
|
221
222
|
const feeInfo = await this.state.feeService.subscribeChainFee(id, altChainInfo.slug, 'substrate');
|
|
222
|
-
const
|
|
223
|
+
const xcmRequest = {
|
|
223
224
|
sender: address,
|
|
224
225
|
originTokenInfo: altInputTokenInfo,
|
|
225
226
|
destinationTokenInfo: inputTokenInfo,
|
|
@@ -229,16 +230,20 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
|
|
|
229
230
|
originChain: altChainInfo,
|
|
230
231
|
substrateApi: xcmOriginSubstrateApi,
|
|
231
232
|
feeInfo
|
|
232
|
-
}
|
|
233
|
-
const _xcmFeeInfo = await xcmTransfer.paymentInfo(address);
|
|
234
|
-
const xcmFeeInfo = _xcmFeeInfo.toPrimitive();
|
|
235
|
-
// TODO: calculate fee for destination chain
|
|
233
|
+
};
|
|
236
234
|
|
|
235
|
+
// TODO: calculate fee for destination chain
|
|
236
|
+
let xcmFee;
|
|
237
|
+
const xcmFeeByDryRun = await dryRunXcmExtrinsicV2(xcmRequest);
|
|
238
|
+
if (xcmFeeByDryRun.fee) {
|
|
239
|
+
xcmFee = BigN(xcmFeeByDryRun.fee).multipliedBy(XCM_MIN_AMOUNT_RATIO).toFixed(0, 1);
|
|
240
|
+
} else {
|
|
241
|
+
throw new Error('Error estimating XCM fee');
|
|
242
|
+
}
|
|
237
243
|
const fee = {
|
|
238
244
|
slug: altInputTokenSlug,
|
|
239
|
-
amount:
|
|
245
|
+
amount: xcmFee
|
|
240
246
|
};
|
|
241
|
-
|
|
242
247
|
let bnTransferAmount = bnAmount.sub(bnInputTokenBalance);
|
|
243
248
|
if (_isNativeToken(altInputTokenInfo)) {
|
|
244
249
|
const bnXcmFee = new BN(fee.amount || 0); // xcm fee is paid in native token but swap token is not always native token
|
|
@@ -442,7 +447,7 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
|
|
|
442
447
|
const bnTotalAmount = bnAmount.sub(bnInputTokenBalance).add(bnXcmFee);
|
|
443
448
|
const id = getId();
|
|
444
449
|
const feeInfo = await this.state.feeService.subscribeChainFee(id, originChainInfo.slug, 'substrate');
|
|
445
|
-
const
|
|
450
|
+
const xcmRequest = {
|
|
446
451
|
destinationTokenInfo,
|
|
447
452
|
originTokenInfo,
|
|
448
453
|
recipient: address,
|
|
@@ -452,7 +457,11 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
|
|
|
452
457
|
originChain: originChainInfo,
|
|
453
458
|
destinationChain: this.chainInfo,
|
|
454
459
|
feeInfo
|
|
455
|
-
}
|
|
460
|
+
};
|
|
461
|
+
const extrinsic = await createXcmExtrinsicV2(xcmRequest);
|
|
462
|
+
if (!extrinsic) {
|
|
463
|
+
throw new Error('Error handling XCM extrinsic');
|
|
464
|
+
}
|
|
456
465
|
const xcmData = {
|
|
457
466
|
originNetworkKey: originChainInfo.slug,
|
|
458
467
|
destinationNetworkKey: destinationTokenInfo.originChain,
|
|
@@ -150,7 +150,7 @@ export class AccountLedgerHandler extends AccountBaseHandler {
|
|
|
150
150
|
}
|
|
151
151
|
if (Object.keys(slugMap).length) {
|
|
152
152
|
for (const chainSlug of Object.keys(slugMap)) {
|
|
153
|
-
this.state.
|
|
153
|
+
this.state.enableChainWithPriorityAssets(chainSlug);
|
|
154
154
|
}
|
|
155
155
|
}
|
|
156
156
|
return true;
|
|
@@ -88,6 +88,7 @@ export declare class AccountState {
|
|
|
88
88
|
updateMetadataForProxy(): void;
|
|
89
89
|
findNetworkKeyByGenesisHash(genesisHash?: string): string | undefined;
|
|
90
90
|
enableChain(slug: string): void;
|
|
91
|
+
enableChainWithPriorityAssets(slug: string): void;
|
|
91
92
|
resetWallet(): void;
|
|
92
93
|
}
|
|
93
94
|
export {};
|
|
@@ -619,6 +619,9 @@ export class AccountState {
|
|
|
619
619
|
enableChain(slug) {
|
|
620
620
|
this.koniState.enableChain(slug, true).catch(console.error);
|
|
621
621
|
}
|
|
622
|
+
enableChainWithPriorityAssets(slug) {
|
|
623
|
+
this.koniState.enableChainWithPriorityAssets(slug, true).catch(console.error);
|
|
624
|
+
}
|
|
622
625
|
|
|
623
626
|
/* Others */
|
|
624
627
|
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// Copyright 2019-2022 @subwallet/extension-koni authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { _isAssetAutoEnable } from '@subwallet/extension-base/services/chain-service/utils';
|
|
5
|
+
import BaseMigrationJob from '@subwallet/extension-base/services/migration-service/Base';
|
|
6
|
+
import { fetchStaticData } from '@subwallet/extension-base/utils';
|
|
7
|
+
// Usage:
|
|
8
|
+
// 1. Disable tokens with a balance of 0
|
|
9
|
+
// 2. Exclude tokens that belong to the popular list
|
|
10
|
+
// 3. Exclude tokens with the "auto enable" attribute
|
|
11
|
+
|
|
12
|
+
export default class DisableZeroBalanceTokens extends BaseMigrationJob {
|
|
13
|
+
async run() {
|
|
14
|
+
const state = this.state;
|
|
15
|
+
try {
|
|
16
|
+
const rawBalanceMap = await state.dbService.getStoredBalance();
|
|
17
|
+
const tokensList = await state.chainService.getAssetSettings();
|
|
18
|
+
const filteredEnabledTokens = Object.entries(tokensList).reduce((acc, [key, value]) => {
|
|
19
|
+
if (value.visible) {
|
|
20
|
+
acc[key] = value;
|
|
21
|
+
}
|
|
22
|
+
return acc;
|
|
23
|
+
}, {});
|
|
24
|
+
const balanceNonZero = rawBalanceMap.filter(item => {
|
|
25
|
+
return BigInt(item.free) + BigInt(item.locked) > 0;
|
|
26
|
+
});
|
|
27
|
+
const priorityTokensMap = (await fetchStaticData('chain-assets/priority-tokens')) || {
|
|
28
|
+
tokenGroup: {},
|
|
29
|
+
token: {}
|
|
30
|
+
};
|
|
31
|
+
const priorityTokensList = priorityTokensMap.token && typeof priorityTokensMap.token === 'object' ? Object.keys(priorityTokensMap.token) : [];
|
|
32
|
+
const autoEnableTokenSlugs = Object.values(this.state.chainService.getAssetRegistry()).filter(asset => _isAssetAutoEnable(asset)).map(asset => asset.slug);
|
|
33
|
+
// Extract the slugs of tokens with balance > 0
|
|
34
|
+
const nonZeroBalanceSlugs = new Set(balanceNonZero.map(item => item.tokenSlug));
|
|
35
|
+
const updatedSettings = structuredClone(tokensList);
|
|
36
|
+
Object.keys(filteredEnabledTokens).forEach(slug => {
|
|
37
|
+
const hasBalance = nonZeroBalanceSlugs.has(slug);
|
|
38
|
+
const isPopularToken = priorityTokensList.includes(slug);
|
|
39
|
+
const isAutoEnableToken = autoEnableTokenSlugs.includes(slug);
|
|
40
|
+
if (!hasBalance && !isPopularToken && !isAutoEnableToken) {
|
|
41
|
+
updatedSettings[slug] = {
|
|
42
|
+
visible: false
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
state.chainService.setAssetSettings(updatedSettings);
|
|
47
|
+
} catch (error) {
|
|
48
|
+
console.error(error);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -5,6 +5,6 @@ import BaseMigrationJob from '@subwallet/extension-base/services/migration-servi
|
|
|
5
5
|
export default class EnableChain extends BaseMigrationJob {
|
|
6
6
|
async run() {
|
|
7
7
|
const state = this.state;
|
|
8
|
-
await state.
|
|
8
|
+
await state.enableChainWithPriorityAssets(this.slug, true);
|
|
9
9
|
}
|
|
10
10
|
}
|