@subwallet/extension-base 1.3.30-0 → 1.3.31-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/background/KoniTypes.d.ts +12 -0
  2. package/cjs/constants/paraspell-chain-map.js +13 -0
  3. package/cjs/core/logic-validation/transfer.js +13 -1
  4. package/cjs/core/substrate/xcm-parser.js +5 -1
  5. package/cjs/core/utils.js +36 -15
  6. package/cjs/koni/background/handlers/Extension.js +136 -90
  7. package/cjs/koni/background/handlers/State.js +8 -1
  8. package/cjs/packageInfo.js +1 -1
  9. package/cjs/services/balance-service/helpers/process.js +27 -0
  10. package/cjs/services/balance-service/helpers/subscribe/substrate/index.js +33 -1
  11. package/cjs/services/balance-service/index.js +9 -0
  12. package/cjs/services/balance-service/transfer/xcm/acrossBridge/index.js +229 -0
  13. package/cjs/services/balance-service/transfer/xcm/index.js +96 -7
  14. package/cjs/services/balance-service/transfer/xcm/utils.js +213 -0
  15. package/cjs/services/chain-service/constants.js +2 -4
  16. package/cjs/services/chain-service/index.js +71 -17
  17. package/cjs/services/chain-service/utils/patch.js +1 -1
  18. package/cjs/services/earning-service/handlers/special.js +18 -9
  19. package/cjs/services/keyring-service/context/handlers/Ledger.js +1 -1
  20. package/cjs/services/keyring-service/context/state.js +3 -0
  21. package/cjs/services/migration-service/scripts/DisableZeroBalanceTokens.js +60 -0
  22. package/cjs/services/migration-service/scripts/EnableChain.js +1 -1
  23. package/cjs/services/migration-service/scripts/index.js +3 -2
  24. package/cjs/services/swap-service/handler/base-handler.js +24 -11
  25. package/cjs/services/transaction-service/utils.js +38 -14
  26. package/cjs/utils/fee/transfer.js +52 -28
  27. package/cjs/utils/staticData/index.js +7 -2
  28. package/constants/paraspell-chain-map.d.ts +1 -0
  29. package/constants/paraspell-chain-map.js +7 -0
  30. package/core/logic-validation/transfer.d.ts +1 -0
  31. package/core/logic-validation/transfer.js +12 -1
  32. package/core/substrate/xcm-parser.d.ts +1 -0
  33. package/core/substrate/xcm-parser.js +4 -1
  34. package/core/utils.d.ts +2 -2
  35. package/core/utils.js +36 -15
  36. package/koni/background/handlers/Extension.d.ts +1 -0
  37. package/koni/background/handlers/Extension.js +60 -15
  38. package/koni/background/handlers/State.d.ts +1 -0
  39. package/koni/background/handlers/State.js +7 -1
  40. package/package.json +23 -7
  41. package/packageInfo.js +1 -1
  42. package/services/balance-service/helpers/process.d.ts +2 -1
  43. package/services/balance-service/helpers/process.js +26 -0
  44. package/services/balance-service/helpers/subscribe/substrate/index.js +34 -2
  45. package/services/balance-service/index.js +11 -2
  46. package/services/balance-service/transfer/xcm/acrossBridge/index.d.ts +15 -0
  47. package/services/balance-service/transfer/xcm/acrossBridge/index.js +216 -0
  48. package/services/balance-service/transfer/xcm/index.d.ts +5 -1
  49. package/services/balance-service/transfer/xcm/index.js +85 -1
  50. package/services/balance-service/transfer/xcm/utils.d.ts +11 -0
  51. package/services/balance-service/transfer/xcm/utils.js +208 -0
  52. package/services/chain-service/constants.d.ts +0 -1
  53. package/services/chain-service/constants.js +1 -2
  54. package/services/chain-service/index.d.ts +9 -2
  55. package/services/chain-service/index.js +72 -18
  56. package/services/chain-service/utils/patch.js +1 -1
  57. package/services/earning-service/handlers/special.js +19 -10
  58. package/services/keyring-service/context/handlers/Ledger.js +1 -1
  59. package/services/keyring-service/context/state.d.ts +1 -0
  60. package/services/keyring-service/context/state.js +3 -0
  61. package/services/migration-service/scripts/DisableZeroBalanceTokens.d.ts +4 -0
  62. package/services/migration-service/scripts/DisableZeroBalanceTokens.js +51 -0
  63. package/services/migration-service/scripts/EnableChain.js +1 -1
  64. package/services/migration-service/scripts/index.js +3 -2
  65. package/services/swap-service/handler/base-handler.js +25 -12
  66. package/services/transaction-service/types.d.ts +3 -2
  67. package/services/transaction-service/utils.d.ts +1 -0
  68. package/services/transaction-service/utils.js +38 -15
  69. package/types/balance/transfer.d.ts +1 -0
  70. package/types/transaction/request.d.ts +7 -0
  71. package/utils/fee/transfer.d.ts +1 -0
  72. package/utils/fee/transfer.js +54 -30
  73. package/utils/staticData/index.d.ts +4 -1
  74. package/utils/staticData/index.js +5 -1
  75. package/utils/staticData/paraSpellChainMap.json +1 -0
@@ -4,11 +4,224 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.STABLE_XCM_VERSION = void 0;
7
+ exports.buildXcm = buildXcm;
8
+ exports.dryRunXcm = dryRunXcm;
9
+ exports.dryRunXcmV2 = dryRunXcmV2;
10
+ exports.isChainNotSupportDryRun = isChainNotSupportDryRun;
11
+ exports.isChainNotSupportPolkadotApi = isChainNotSupportPolkadotApi;
7
12
  exports.isUseTeleportProtocol = isUseTeleportProtocol;
13
+ var _TransactionError = require("@subwallet/extension-base/background/errors/TransactionError");
14
+ var _paraspellChainMap = require("@subwallet/extension-base/constants/paraspell-chain-map");
15
+ var _types = require("@subwallet/extension-base/types");
16
+ var _util = require("@polkadot/util");
8
17
  // Copyright 2019-2022 @subwallet/extension-base
9
18
  // SPDX-License-Identifier: Apache-2.0
10
19
 
20
+ const paraSpellEndpoint = 'https://api.lightspell.xyz';
21
+ const paraSpellApi = {
22
+ buildXcm: `${paraSpellEndpoint}/x-transfer`,
23
+ dryRunXcm: `${paraSpellEndpoint}/dry-run`
24
+ };
25
+ const paraSpellKey = process.env.PARASPELL_API_KEY || '';
26
+ function txHexToSubmittableExtrinsic(api, hex) {
27
+ try {
28
+ (0, _util.assert)((0, _util.isHex)(hex), 'Expected a hex-encoded call');
29
+ let extrinsicCall;
30
+ let extrinsicPayload = null;
31
+ let decoded = null;
32
+ try {
33
+ // attempt to decode with api.tx
34
+ const tx = api.tx(hex);
35
+
36
+ // ensure that the full data matches here
37
+ (0, _util.assert)(tx.toHex() === hex, 'Cannot decode data as extrinsic, length mismatch');
38
+ decoded = tx;
39
+ extrinsicCall = api.createType('Call', decoded.method);
40
+ } catch {
41
+ try {
42
+ // attempt to decode as Call
43
+ extrinsicCall = api.createType('Call', hex);
44
+ const callHex = extrinsicCall.toHex();
45
+ if (callHex === hex) {
46
+ // ok
47
+ } else if (hex.startsWith(callHex)) {
48
+ // this could be an un-prefixed payload...
49
+ const prefixed = (0, _util.u8aConcat)((0, _util.compactToU8a)(extrinsicCall.encodedLength), hex);
50
+ extrinsicPayload = api.createType('ExtrinsicPayload', prefixed);
51
+ (0, _util.assert)((0, _util.u8aEq)(extrinsicPayload.toU8a(), prefixed), 'Unable to decode data as un-prefixed ExtrinsicPayload');
52
+ extrinsicCall = api.createType('Call', extrinsicPayload.method.toHex());
53
+ } else {
54
+ console.error('Unable to decode data as Call, length mismatch in supplied data');
55
+ }
56
+ } catch {
57
+ // final attempt, we try this as-is as a (prefixed) payload
58
+ extrinsicPayload = api.createType('ExtrinsicPayload', hex);
59
+ (0, _util.assert)(extrinsicPayload.toHex() === hex, 'Unable to decode input data as Call, Extrinsic or ExtrinsicPayload');
60
+ extrinsicCall = api.createType('Call', extrinsicPayload.method.toHex());
61
+ }
62
+ }
63
+ const {
64
+ method,
65
+ section
66
+ } = api.registry.findMetaCall(extrinsicCall.callIndex);
67
+ const extrinsicFn = api.tx[section][method];
68
+ if (!decoded) {
69
+ decoded = extrinsicFn(...extrinsicCall.args);
70
+ }
71
+ return decoded;
72
+ } catch (e) {
73
+ console.error('Failed to decode extrinsic hex', e);
74
+ throw new Error('Failed to decode extrinsic hex');
75
+ }
76
+ }
77
+ async function buildXcm(request) {
78
+ var _originTokenInfo$meta, _originTokenInfo$meta2;
79
+ const {
80
+ destinationChain,
81
+ originChain,
82
+ originTokenInfo,
83
+ recipient,
84
+ sendingValue,
85
+ substrateApi
86
+ } = request;
87
+ if (!substrateApi) {
88
+ return Promise.reject(new Error('Substrate API is not available'));
89
+ }
90
+ const psAssetType = (_originTokenInfo$meta = originTokenInfo.metadata) === null || _originTokenInfo$meta === void 0 ? void 0 : _originTokenInfo$meta.paraSpellAssetType;
91
+ const psAssetValue = (_originTokenInfo$meta2 = originTokenInfo.metadata) === null || _originTokenInfo$meta2 === void 0 ? void 0 : _originTokenInfo$meta2.paraSpellValue;
92
+ if (!psAssetType || !psAssetValue) {
93
+ throw new Error('Token is not support XCM at this time');
94
+ }
95
+ const paraSpellChainMap = await (0, _paraspellChainMap.fetchParaSpellChainMap)();
96
+ const bodyData = {
97
+ address: recipient,
98
+ from: paraSpellChainMap[originChain.slug],
99
+ to: paraSpellChainMap[destinationChain.slug],
100
+ currency: createParaSpellCurrency(psAssetType, psAssetValue, sendingValue)
101
+ };
102
+ const response = await fetch(paraSpellApi.buildXcm, {
103
+ method: 'POST',
104
+ body: JSON.stringify(bodyData),
105
+ headers: {
106
+ 'Content-Type': 'application/json',
107
+ Accept: 'application/json',
108
+ 'X-API-KEY': paraSpellKey
109
+ }
110
+ });
111
+ if (!response.ok) {
112
+ const error = await response.json();
113
+ throw new Error(error.message);
114
+ }
115
+ const extrinsicHex = await response.text();
116
+ const chainApi = await substrateApi.isReady;
117
+ return txHexToSubmittableExtrinsic(chainApi.api, extrinsicHex);
118
+ }
119
+
120
+ // dry run can fail due to sender address & amount token
121
+ async function dryRunXcm(request) {
122
+ var _originTokenInfo$meta3, _originTokenInfo$meta4;
123
+ const {
124
+ destinationChain,
125
+ originChain,
126
+ originTokenInfo,
127
+ recipient,
128
+ sender,
129
+ sendingValue
130
+ } = request;
131
+ const paraSpellChainMap = await (0, _paraspellChainMap.fetchParaSpellChainMap)();
132
+ const psAssetType = (_originTokenInfo$meta3 = originTokenInfo.metadata) === null || _originTokenInfo$meta3 === void 0 ? void 0 : _originTokenInfo$meta3.paraSpellAssetType;
133
+ const psAssetValue = (_originTokenInfo$meta4 = originTokenInfo.metadata) === null || _originTokenInfo$meta4 === void 0 ? void 0 : _originTokenInfo$meta4.paraSpellValue;
134
+ if (!psAssetType || !psAssetValue) {
135
+ throw new Error('Token is not support XCM at this time'); // todo: content
136
+ }
137
+
138
+ let dryRunInfo;
139
+ try {
140
+ const bodyData = {
141
+ senderAddress: sender,
142
+ address: recipient,
143
+ from: paraSpellChainMap[originChain.slug],
144
+ to: paraSpellChainMap[destinationChain.slug],
145
+ currency: createParaSpellCurrency(psAssetType, psAssetValue, sendingValue)
146
+ };
147
+ const response = await fetch(paraSpellApi.dryRunXcm, {
148
+ method: 'POST',
149
+ body: JSON.stringify(bodyData),
150
+ headers: {
151
+ 'Content-Type': 'application/json',
152
+ Accept: 'application/json',
153
+ 'X-API-KEY': paraSpellKey
154
+ }
155
+ });
156
+ dryRunInfo = await response.json();
157
+ } catch (e) {
158
+ console.error('Unable to dry run', e);
159
+ }
160
+ if (!dryRunInfo || !dryRunInfo.success) {
161
+ throw new _TransactionError.TransactionError(_types.BasicTxErrorType.UNABLE_TO_SEND, 'Unable to perform transaction. Select another token or destination chain and try again');
162
+ }
163
+ return dryRunInfo;
164
+ }
165
+ async function dryRunXcmV2(request) {
166
+ var _originTokenInfo$meta5, _originTokenInfo$meta6;
167
+ const {
168
+ destinationChain,
169
+ originChain,
170
+ originTokenInfo,
171
+ recipient,
172
+ sender,
173
+ sendingValue
174
+ } = request;
175
+ const paraSpellChainMap = await (0, _paraspellChainMap.fetchParaSpellChainMap)();
176
+ const psAssetType = (_originTokenInfo$meta5 = originTokenInfo.metadata) === null || _originTokenInfo$meta5 === void 0 ? void 0 : _originTokenInfo$meta5.paraSpellAssetType;
177
+ const psAssetValue = (_originTokenInfo$meta6 = originTokenInfo.metadata) === null || _originTokenInfo$meta6 === void 0 ? void 0 : _originTokenInfo$meta6.paraSpellValue;
178
+ if (!psAssetType || !psAssetValue) {
179
+ throw new Error('Token is not support XCM at this time');
180
+ }
181
+ const bodyData = {
182
+ senderAddress: sender,
183
+ address: recipient,
184
+ from: paraSpellChainMap[originChain.slug],
185
+ to: paraSpellChainMap[destinationChain.slug],
186
+ currency: createParaSpellCurrency(psAssetType, psAssetValue, sendingValue)
187
+ };
188
+ const response = await fetch(paraSpellApi.dryRunXcm, {
189
+ method: 'POST',
190
+ body: JSON.stringify(bodyData),
191
+ headers: {
192
+ 'Content-Type': 'application/json',
193
+ Accept: 'application/json',
194
+ 'X-API-KEY': paraSpellKey
195
+ }
196
+ });
197
+ if (!response.ok) {
198
+ const error = await response.json();
199
+ throw new Error(error.message);
200
+ }
201
+ return await response.json();
202
+ }
203
+ function createParaSpellCurrency(assetType, assetValue, amount) {
204
+ // todo: handle complex conditions for asset has same symbol in a chain: Id, Multi-location, ...
205
+ return {
206
+ [assetType]: assetValue,
207
+ amount
208
+ };
209
+ }
210
+ function isChainNotSupportPolkadotApi(str) {
211
+ const regex = /(?=.*not yet supported)(?=.*Polkadot API).*/i; // Example: The node Interlay is not yet supported by the Polkadot API.
212
+
213
+ return regex.test(str);
214
+ }
215
+ function isChainNotSupportDryRun(str) {
216
+ const regex = /(?=.*DryRunApi)(?=.*not available).*/i; // Example: DryRunApi is not available on node Acala
217
+
218
+ return regex.test(str);
219
+ }
220
+
221
+ // todo: remove
11
222
  const STABLE_XCM_VERSION = 3;
223
+
224
+ // todo: remove
12
225
  exports.STABLE_XCM_VERSION = STABLE_XCM_VERSION;
13
226
  function isUseTeleportProtocol(originChainInfo, destChainInfo, tokenSlug) {
14
227
  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);
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports._ZK_ASSET_PREFIX = exports._XCM_TYPE = exports._XCM_CHAIN_GROUP = exports._TRANSFER_NOT_SUPPORTED_CHAINS = exports._TRANSFER_CHAIN_GROUP = exports._SUBSTRATE_DEFAULT_INFLATION_PARAMS = exports._STAKING_ERA_LENGTH_MAP = exports._PURE_EVM_CHAINS = exports._PREDEFINED_SINGLE_MODES = exports._PARACHAIN_INFLATION_DISTRIBUTION = exports._NFT_CHAIN_GROUP = exports._MULTI_CHAIN_ASSET_SRC = exports._MANTA_ZK_CHAIN_GROUP = exports._KNOWN_CHAIN_INFLATION_PARAMS = exports._EXPECTED_BLOCK_TIME = exports._DEFAULT_MANTA_ZK_CHAIN = exports._DEFAULT_ACTIVE_CHAINS = exports._CHAIN_LOGO_MAP_SRC = exports._CHAIN_INFO_SRC = exports._CHAIN_ASSET_SRC = exports._BALANCE_TOKEN_GROUP = exports._BALANCE_PARSING_CHAIN_GROUP = exports._BALANCE_CHAIN_GROUP = exports._ASSET_REF_SRC = exports._ASSET_LOGO_MAP_SRC = exports._API_OPTIONS_CHAIN_GROUP = exports.SUFFICIENT_CHAIN = exports.LATEST_CHAIN_DATA_FETCHING_INTERVAL = exports.EVM_REFORMAT_DECIMALS = exports.EVM_PASS_CONNECT_STATUS = exports.API_MAX_RETRY = exports.API_CONNECT_TIMEOUT = exports.API_AUTO_CONNECT_MS = void 0;
6
+ exports._ZK_ASSET_PREFIX = exports._XCM_TYPE = exports._XCM_CHAIN_GROUP = exports._TRANSFER_NOT_SUPPORTED_CHAINS = exports._TRANSFER_CHAIN_GROUP = exports._SUBSTRATE_DEFAULT_INFLATION_PARAMS = exports._STAKING_ERA_LENGTH_MAP = exports._PURE_EVM_CHAINS = exports._PREDEFINED_SINGLE_MODES = exports._PARACHAIN_INFLATION_DISTRIBUTION = exports._NFT_CHAIN_GROUP = exports._MULTI_CHAIN_ASSET_SRC = exports._MANTA_ZK_CHAIN_GROUP = exports._KNOWN_CHAIN_INFLATION_PARAMS = exports._EXPECTED_BLOCK_TIME = exports._DEFAULT_MANTA_ZK_CHAIN = exports._DEFAULT_ACTIVE_CHAINS = exports._CHAIN_LOGO_MAP_SRC = exports._CHAIN_INFO_SRC = exports._CHAIN_ASSET_SRC = exports._BALANCE_TOKEN_GROUP = exports._BALANCE_PARSING_CHAIN_GROUP = exports._BALANCE_CHAIN_GROUP = exports._ASSET_REF_SRC = exports._ASSET_LOGO_MAP_SRC = exports._API_OPTIONS_CHAIN_GROUP = exports.LATEST_CHAIN_DATA_FETCHING_INTERVAL = exports.EVM_REFORMAT_DECIMALS = exports.EVM_PASS_CONNECT_STATUS = exports.API_MAX_RETRY = exports.API_CONNECT_TIMEOUT = exports.API_AUTO_CONNECT_MS = void 0;
7
7
  var _chainList = require("@subwallet/chain-list");
8
8
  var _types = require("@subwallet/chain-list/types");
9
9
  var _KoniTypes = require("@subwallet/extension-base/background/KoniTypes");
@@ -40,7 +40,7 @@ const _BALANCE_CHAIN_GROUP = {
40
40
  kintsugi: ['kintsugi', 'interlay', 'kintsugi_test', 'mangatax_para'],
41
41
  genshiro: ['genshiro_testnet', 'genshiro'],
42
42
  equilibrium_parachain: ['equilibrium_parachain'],
43
- bifrost: ['bifrost', 'acala', 'karura', 'acala_testnet', 'pioneer', 'bitcountry', 'bifrost_dot', 'hydradx_main', 'hydradx_rococo', 'pendulum', 'amplitude', 'continuum_network'],
43
+ bifrost: ['bifrost', 'acala', 'karura', 'acala_testnet', 'pioneer', 'bitcountry', 'bifrost_dot', 'hydradx_main', 'hydradx_rococo', 'pendulum', 'amplitude', 'continuum_network', 'truth_network'],
44
44
  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'],
45
45
  kusama: ['kusama', 'kintsugi', 'kintsugi_test', 'interlay', 'acala', 'statemint', 'karura', 'bifrost'],
46
46
  // perhaps there are some runtime updates
@@ -300,8 +300,6 @@ const _XCM_CHAIN_GROUP = {
300
300
  // default is xTokens pallet
301
301
  };
302
302
  exports._XCM_CHAIN_GROUP = _XCM_CHAIN_GROUP;
303
- const SUFFICIENT_CHAIN = ['astar', 'calamari', 'parallel', 'darwinia2', 'crabParachain', 'pangolin', 'statemint', 'moonriver', 'shiden', 'moonbeam', 'statemine', 'liberland', 'dentnet', 'phala', 'crust', 'dbcchain', 'rococo_assethub'];
304
- exports.SUFFICIENT_CHAIN = SUFFICIENT_CHAIN;
305
303
  const _XCM_TYPE = {
306
304
  RP: `${_types._SubstrateChainType.RELAYCHAIN}-${_types._SubstrateChainType.PARACHAIN}`,
307
305
  // DMP
@@ -64,6 +64,7 @@ class ChainService {
64
64
  chainLogoMapSubject = new _rxjs.BehaviorSubject(_chainList.ChainLogoMap);
65
65
  ledgerGenericAllowChainsSubject = new _rxjs.BehaviorSubject([]);
66
66
  priorityTokensSubject = new _rxjs.BehaviorSubject({});
67
+ sufficientChainsSubject = new _rxjs.BehaviorSubject({});
67
68
 
68
69
  // Todo: Update to new store indexed DB
69
70
  store = new _AssetSetting.default();
@@ -89,24 +90,32 @@ class ChainService {
89
90
  get value() {
90
91
  const ledgerGenericAllowChains = this.ledgerGenericAllowChainsSubject;
91
92
  const priorityTokens = this.priorityTokensSubject;
93
+ const sufficientChains = this.sufficientChainsSubject;
92
94
  return {
93
95
  get ledgerGenericAllowChains() {
94
96
  return ledgerGenericAllowChains.value;
95
97
  },
96
98
  get priorityTokens() {
97
99
  return priorityTokens.value;
100
+ },
101
+ get sufficientChains() {
102
+ return sufficientChains.value;
98
103
  }
99
104
  };
100
105
  }
101
106
  get observable() {
102
107
  const ledgerGenericAllowChains = this.ledgerGenericAllowChainsSubject;
103
108
  const priorityTokens = this.priorityTokensSubject;
109
+ const sufficientChains = this.sufficientChainsSubject;
104
110
  return {
105
111
  get ledgerGenericAllowChains() {
106
112
  return ledgerGenericAllowChains.asObservable();
107
113
  },
108
114
  get priorityTokens() {
109
115
  return priorityTokens.asObservable();
116
+ },
117
+ get sufficientChains() {
118
+ return sufficientChains.asObservable();
110
119
  }
111
120
  };
112
121
  }
@@ -550,7 +559,7 @@ class ChainService {
550
559
  this.initAssetRefMap();
551
560
  this.xcmRefMapSubject.next(this.xcmRefMap);
552
561
  await this.initApis();
553
- await this.initAssetSettings();
562
+ this.initAssetSettings();
554
563
  await this.autoEnableTokens();
555
564
  }
556
565
  initAssetRefMap() {
@@ -629,14 +638,47 @@ class ChainService {
629
638
  }
630
639
  }
631
640
  }
641
+ async enablePopularTokens() {
642
+ const assetSettings = this.assetSettingSubject.value;
643
+ const chainStateMap = this.getChainStateMap();
644
+ const priorityTokensMap = this.priorityTokensSubject.value || {};
645
+ const priorityTokensList = priorityTokensMap.token && typeof priorityTokensMap.token === 'object' ? Object.keys(priorityTokensMap.token) : [];
646
+ for (const assetSlug of priorityTokensList) {
647
+ const assetState = assetSettings[assetSlug];
648
+ const assetInfo = this.getAssetBySlug(assetSlug);
649
+ const chainState = chainStateMap[assetInfo.originChain];
650
+ if (!assetState) {
651
+ // If this asset not has asset setting, this token is not enabled before (not turned off before)
652
+ if (!chainState || !chainState.manualTurnOff) {
653
+ await this.updateAssetSetting(assetSlug, {
654
+ visible: true
655
+ }, true);
656
+ }
657
+ }
658
+ }
659
+ }
632
660
  handleLatestLedgerGenericAllowChains(latestledgerGenericAllowChains) {
633
661
  this.ledgerGenericAllowChainsSubject.next(latestledgerGenericAllowChains);
634
662
  this.eventService.emit('ledger.ready', true);
635
663
  this.logger.log('Finished updating latest ledger generic allow chains');
636
664
  }
637
665
  handleLatestPriorityTokens(latestPriorityTokens) {
666
+ const currentTokens = this.priorityTokensSubject.value || {};
638
667
  this.priorityTokensSubject.next(latestPriorityTokens);
639
668
  this.logger.log('Finished updating latest popular tokens');
669
+ const currentTokenKeys = Object.keys(currentTokens.token || {}); // Extract keys from current tokens
670
+ const newTokenKeys = Object.keys(latestPriorityTokens.token || {}); // Extract keys from new tokens
671
+
672
+ if (JSON.stringify(currentTokenKeys) !== JSON.stringify(newTokenKeys)) {
673
+ // Check if token keys have changed
674
+ this.enablePopularTokens().then(() => this.logger.log('Popular tokens enabled due to priority tokens change')) // Log success after enabling tokens
675
+ .catch(e => console.error('Error enabling popular tokens:', e)); // Log error if enabling fails
676
+ }
677
+ }
678
+
679
+ handleLatestSufficientChains(latestSufficientChains) {
680
+ this.sufficientChainsSubject.next(latestSufficientChains);
681
+ this.logger.log('Finished updating latest supported sufficient chains');
640
682
  }
641
683
  handleLatestData() {
642
684
  this.fetchLatestChainData().then(latestChainInfo => {
@@ -658,6 +700,9 @@ class ChainService {
658
700
  this.fetchLatestPriorityTokens().then(latestPriorityTokens => {
659
701
  this.handleLatestPriorityTokens(latestPriorityTokens);
660
702
  }).catch(console.error);
703
+ this.fetchLatestSufficientChains().then(latestSufficientChains => {
704
+ this.handleLatestSufficientChains(latestSufficientChains);
705
+ }).catch(console.error);
661
706
  }
662
707
  async initApis() {
663
708
  const chainInfoMap = this.getChainInfoMap();
@@ -940,6 +985,9 @@ class ChainService {
940
985
  token: {}
941
986
  };
942
987
  }
988
+ async fetchLatestSufficientChains() {
989
+ return (await (0, _utils2.fetchStaticData)('chains/supported-sufficient-chains')) || [];
990
+ }
943
991
  async initChains() {
944
992
  const storedChainSettings = await this.dbService.getAllChainStore();
945
993
  const defaultChainInfoMap = filterChainInfoMap(_chainList.ChainInfoMap, ignoredList);
@@ -1646,22 +1694,7 @@ class ChainService {
1646
1694
  await Promise.all([this.substrateChainHandler.wakeUp(), this.evmChainHandler.wakeUp(), this.tonChainHandler.wakeUp(), this.cardanoChainHandler.wakeUp()]);
1647
1695
  this.checkLatestData();
1648
1696
  }
1649
- async initAssetSettings() {
1650
- const assetSettings = await this.getAssetSettings();
1651
- const activeChainSlugs = this.getActiveChainSlugs();
1652
- const assetRegistry = this.getAssetRegistry();
1653
- Object.values(assetRegistry).forEach(assetInfo => {
1654
- const isSettingExisted = (assetInfo.slug in assetSettings);
1655
-
1656
- // Set visible for every enabled chains
1657
- if (activeChainSlugs.includes(assetInfo.originChain) && !isSettingExisted) {
1658
- // Setting only exist when set either by chain settings or user
1659
- assetSettings[assetInfo.slug] = {
1660
- visible: true
1661
- };
1662
- }
1663
- });
1664
- this.setAssetSettings(assetSettings, false);
1697
+ initAssetSettings() {
1665
1698
  this.eventService.emit('asset.ready', true);
1666
1699
  }
1667
1700
  setAssetSettings(assetSettings) {
@@ -1750,6 +1783,27 @@ class ChainService {
1750
1783
  });
1751
1784
  this.setAssetSettings(assetSettings);
1752
1785
  }
1786
+ async updatePriorityAssetsByChain(chainSlug, visible) {
1787
+ const currentAssetSettings = await this.getAssetSettings();
1788
+ const assetsByChain = this.getFungibleTokensByChain(chainSlug);
1789
+ const priorityTokensMap = this.priorityTokensSubject.value || {};
1790
+ const priorityTokensList = priorityTokensMap.token && typeof priorityTokensMap.token === 'object' ? Object.keys(priorityTokensMap.token) : [];
1791
+ for (const asset of Object.values(assetsByChain)) {
1792
+ if (visible) {
1793
+ const isPriorityToken = priorityTokensList.includes(asset.slug);
1794
+ if (isPriorityToken || (0, _utils._isNativeToken)(asset)) {
1795
+ currentAssetSettings[asset.slug] = {
1796
+ visible: true
1797
+ };
1798
+ }
1799
+ } else {
1800
+ currentAssetSettings[asset.slug] = {
1801
+ visible: false
1802
+ };
1803
+ }
1804
+ }
1805
+ this.setAssetSettings(currentAssetSettings);
1806
+ }
1753
1807
  subscribeAssetSettings() {
1754
1808
  return this.assetSettingSubject;
1755
1809
  }
@@ -11,7 +11,7 @@ const PRODUCTION_BRANCHES = ['master', 'webapp', 'webapp-dev'];
11
11
  const branchName = process.env.BRANCH_NAME || 'subwallet-dev';
12
12
  const fetchDomain = PRODUCTION_BRANCHES.indexOf(branchName) > -1 ? 'https://chain-list-assets.subwallet.app' : 'https://dev.sw-chain-list-assets.pages.dev';
13
13
  const fetchFile = PRODUCTION_BRANCHES.indexOf(branchName) > -1 ? 'list.json' : 'preview.json';
14
- const ChainListVersion = '0.2.102'; // update this when build chainlist
14
+ const ChainListVersion = '0.2.103'; // update this when build chainlist
15
15
 
16
16
  // todo: move this interface to chainlist
17
17
 
@@ -14,6 +14,7 @@ var _utils2 = require("@subwallet/extension-base/services/chain-service/utils");
14
14
  var _types = require("@subwallet/extension-base/types");
15
15
  var _utils3 = require("@subwallet/extension-base/utils");
16
16
  var _getId = require("@subwallet/extension-base/utils/getId");
17
+ var _bignumber = _interopRequireDefault(require("bignumber.js"));
17
18
  var _i18next = require("i18next");
18
19
  var _util = require("@polkadot/util");
19
20
  var _base = _interopRequireDefault(require("./base"));
@@ -226,7 +227,7 @@ class BaseSpecialStakingPoolHandler extends _base.default {
226
227
  const xcmOriginSubstrateApi = await this.state.getSubstrateApi(altInputTokenInfo.originChain).isReady;
227
228
  const id = (0, _getId.getId)();
228
229
  const feeInfo = await this.state.feeService.subscribeChainFee(id, altChainInfo.slug, 'substrate');
229
- const xcmTransfer = await (0, _xcm.createXcmExtrinsic)({
230
+ const xcmRequest = {
230
231
  sender: address,
231
232
  originTokenInfo: altInputTokenInfo,
232
233
  destinationTokenInfo: inputTokenInfo,
@@ -236,16 +237,20 @@ class BaseSpecialStakingPoolHandler extends _base.default {
236
237
  originChain: altChainInfo,
237
238
  substrateApi: xcmOriginSubstrateApi,
238
239
  feeInfo
239
- });
240
- const _xcmFeeInfo = await xcmTransfer.paymentInfo(address);
241
- const xcmFeeInfo = _xcmFeeInfo.toPrimitive();
242
- // TODO: calculate fee for destination chain
240
+ };
243
241
 
242
+ // TODO: calculate fee for destination chain
243
+ let xcmFee;
244
+ const xcmFeeByDryRun = await (0, _xcm.dryRunXcmExtrinsicV2)(xcmRequest);
245
+ if (xcmFeeByDryRun.fee) {
246
+ xcmFee = (0, _bignumber.default)(xcmFeeByDryRun.fee).multipliedBy(_constants.XCM_MIN_AMOUNT_RATIO).toFixed(0, 1);
247
+ } else {
248
+ throw new Error('Error estimating XCM fee');
249
+ }
244
250
  const fee = {
245
251
  slug: altInputTokenSlug,
246
- amount: Math.round(xcmFeeInfo.partialFee * _constants.XCM_MIN_AMOUNT_RATIO).toString() // TODO
252
+ amount: xcmFee
247
253
  };
248
-
249
254
  let bnTransferAmount = bnAmount.sub(bnInputTokenBalance);
250
255
  if ((0, _utils2._isNativeToken)(altInputTokenInfo)) {
251
256
  const bnXcmFee = new _util.BN(fee.amount || 0); // xcm fee is paid in native token but swap token is not always native token
@@ -449,7 +454,7 @@ class BaseSpecialStakingPoolHandler extends _base.default {
449
454
  const bnTotalAmount = bnAmount.sub(bnInputTokenBalance).add(bnXcmFee);
450
455
  const id = (0, _getId.getId)();
451
456
  const feeInfo = await this.state.feeService.subscribeChainFee(id, originChainInfo.slug, 'substrate');
452
- const extrinsic = await (0, _xcm.createXcmExtrinsic)({
457
+ const xcmRequest = {
453
458
  destinationTokenInfo,
454
459
  originTokenInfo,
455
460
  recipient: address,
@@ -459,7 +464,11 @@ class BaseSpecialStakingPoolHandler extends _base.default {
459
464
  originChain: originChainInfo,
460
465
  destinationChain: this.chainInfo,
461
466
  feeInfo
462
- });
467
+ };
468
+ const extrinsic = await (0, _xcm.createXcmExtrinsicV2)(xcmRequest);
469
+ if (!extrinsic) {
470
+ throw new Error('Error handling XCM extrinsic');
471
+ }
463
472
  const xcmData = {
464
473
  originNetworkKey: originChainInfo.slug,
465
474
  destinationNetworkKey: destinationTokenInfo.originChain,
@@ -156,7 +156,7 @@ class AccountLedgerHandler extends _Base.AccountBaseHandler {
156
156
  }
157
157
  if (Object.keys(slugMap).length) {
158
158
  for (const chainSlug of Object.keys(slugMap)) {
159
- this.state.enableChain(chainSlug);
159
+ this.state.enableChainWithPriorityAssets(chainSlug);
160
160
  }
161
161
  }
162
162
  return true;
@@ -638,6 +638,9 @@ class AccountState {
638
638
  enableChain(slug) {
639
639
  this.koniState.enableChain(slug, true).catch(console.error);
640
640
  }
641
+ enableChainWithPriorityAssets(slug) {
642
+ this.koniState.enableChainWithPriorityAssets(slug, true).catch(console.error);
643
+ }
641
644
 
642
645
  /* Others */
643
646
 
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = void 0;
8
+ var _utils = require("@subwallet/extension-base/services/chain-service/utils");
9
+ var _Base = _interopRequireDefault(require("@subwallet/extension-base/services/migration-service/Base"));
10
+ var _utils2 = require("@subwallet/extension-base/utils");
11
+ // Copyright 2019-2022 @subwallet/extension-koni authors & contributors
12
+ // SPDX-License-Identifier: Apache-2.0
13
+
14
+ // Usage:
15
+ // 1. Disable tokens with a balance of 0
16
+ // 2. Exclude tokens that belong to the popular list
17
+ // 3. Exclude tokens with the "auto enable" attribute
18
+
19
+ class DisableZeroBalanceTokens extends _Base.default {
20
+ async run() {
21
+ const state = this.state;
22
+ try {
23
+ const rawBalanceMap = await state.dbService.getStoredBalance();
24
+ const tokensList = await state.chainService.getAssetSettings();
25
+ const filteredEnabledTokens = Object.entries(tokensList).reduce((acc, _ref) => {
26
+ let [key, value] = _ref;
27
+ if (value.visible) {
28
+ acc[key] = value;
29
+ }
30
+ return acc;
31
+ }, {});
32
+ const balanceNonZero = rawBalanceMap.filter(item => {
33
+ return BigInt(item.free) + BigInt(item.locked) > 0;
34
+ });
35
+ const priorityTokensMap = (await (0, _utils2.fetchStaticData)('chain-assets/priority-tokens')) || {
36
+ tokenGroup: {},
37
+ token: {}
38
+ };
39
+ const priorityTokensList = priorityTokensMap.token && typeof priorityTokensMap.token === 'object' ? Object.keys(priorityTokensMap.token) : [];
40
+ const autoEnableTokenSlugs = Object.values(this.state.chainService.getAssetRegistry()).filter(asset => (0, _utils._isAssetAutoEnable)(asset)).map(asset => asset.slug);
41
+ // Extract the slugs of tokens with balance > 0
42
+ const nonZeroBalanceSlugs = new Set(balanceNonZero.map(item => item.tokenSlug));
43
+ const updatedSettings = structuredClone(tokensList);
44
+ Object.keys(filteredEnabledTokens).forEach(slug => {
45
+ const hasBalance = nonZeroBalanceSlugs.has(slug);
46
+ const isPopularToken = priorityTokensList.includes(slug);
47
+ const isAutoEnableToken = autoEnableTokenSlugs.includes(slug);
48
+ if (!hasBalance && !isPopularToken && !isAutoEnableToken) {
49
+ updatedSettings[slug] = {
50
+ visible: false
51
+ };
52
+ }
53
+ });
54
+ state.chainService.setAssetSettings(updatedSettings);
55
+ } catch (error) {
56
+ console.error(error);
57
+ }
58
+ }
59
+ }
60
+ exports.default = DisableZeroBalanceTokens;
@@ -12,7 +12,7 @@ var _Base = _interopRequireDefault(require("@subwallet/extension-base/services/m
12
12
  class EnableChain extends _Base.default {
13
13
  async run() {
14
14
  const state = this.state;
15
- await state.enableChain(this.slug, true);
15
+ await state.enableChainWithPriorityAssets(this.slug, true);
16
16
  }
17
17
  }
18
18
  exports.default = EnableChain;
@@ -5,7 +5,6 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.default = exports.MYTHOS_MIGRATION_KEY = exports.EVERYTIME = void 0;
8
- var _AutoEnableSomeTokens = _interopRequireDefault(require("./databases/AutoEnableSomeTokens"));
9
8
  var _ClearMetadataDatabase = _interopRequireDefault(require("./databases/ClearMetadataDatabase"));
10
9
  var _ClearMetadataForMythos = _interopRequireDefault(require("./databases/ClearMetadataForMythos"));
11
10
  var _MigrateAssetSetting = _interopRequireDefault(require("./databases/MigrateAssetSetting"));
@@ -22,6 +21,7 @@ var _MigratePolygonUSDCProvider = _interopRequireDefault(require("./tokens/Migra
22
21
  var _DeleteChain = _interopRequireDefault(require("./DeleteChain"));
23
22
  var _DeleteChainStaking = _interopRequireDefault(require("./DeleteChainStaking"));
24
23
  var _DeleteEarningData = _interopRequireDefault(require("./DeleteEarningData"));
24
+ var _DisableZeroBalanceTokens = _interopRequireDefault(require("./DisableZeroBalanceTokens"));
25
25
  var _EnableVaraChain = _interopRequireDefault(require("./EnableVaraChain"));
26
26
  var _MigrateAuthUrls = _interopRequireDefault(require("./MigrateAuthUrls"));
27
27
  var _MigrateImportedToken = _interopRequireDefault(require("./MigrateImportedToken"));
@@ -61,7 +61,7 @@ var _default = {
61
61
  '1.1.28-01': _MigrateEarningVersion.default,
62
62
  '1.1.33-01': _MigrateLedgerAccountV.default,
63
63
  '1.1.41-01': _DeleteChainStaking.default,
64
- '1.1.46-01': _AutoEnableSomeTokens.default,
64
+ // '1.1.46-01': AutoEnableSomeTokens,
65
65
  '1.2.28-01': _MigrateAssetSetting.default,
66
66
  '1.2.28-02': _MigrateTransactionHistoryBySymbol.default,
67
67
  '1.2.69-01': _MigrateRemoveGenesisHash.default,
@@ -69,6 +69,7 @@ var _default = {
69
69
  '1.2.32-01': _MigratePairData.default,
70
70
  '1.3.6-01': _MigrateTransactionHistoryBridge.default,
71
71
  '1.3.10-01': _ClearMetadataDatabase.default,
72
+ '1.3.26-01': _DisableZeroBalanceTokens.default,
72
73
  [MYTHOS_MIGRATION_KEY]: _ClearMetadataForMythos.default
73
74
  // [`${EVERYTIME}-1.1.42-02`]: MigrateTransactionHistoryBySymbol
74
75
  // [`${EVERYTIME}-1`]: AutoEnableChainsTokens