@subwallet/extension-base 1.3.52-0 → 1.3.54-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/background/KoniTypes.d.ts +10 -3
  2. package/cjs/koni/background/handlers/Extension.js +4 -4
  3. package/cjs/koni/background/handlers/State.js +1 -0
  4. package/cjs/packageInfo.js +1 -1
  5. package/cjs/services/balance-service/transfer/xcm/snowBridge.js +21 -10
  6. package/cjs/services/chain-online-service/index.js +168 -15
  7. package/cjs/services/chain-service/index.js +39 -10
  8. package/cjs/services/chain-service/utils/patch.js +2 -2
  9. package/cjs/services/earning-service/constants/chains.js +2 -4
  10. package/cjs/services/earning-service/handlers/base.js +1 -1
  11. package/cjs/services/earning-service/handlers/native-staking/base.js +4 -2
  12. package/cjs/services/earning-service/handlers/native-staking/dtao.js +9 -3
  13. package/cjs/services/earning-service/handlers/native-staking/relay-chain.js +1 -10
  14. package/cjs/services/earning-service/handlers/native-staking/tao.js +24 -14
  15. package/cjs/services/earning-service/service.js +2 -2
  16. package/cjs/services/keyring-service/context/handlers/Json.js +28 -3
  17. package/cjs/services/migration-service/scripts/MigrateTransactionHistoryBySymbol.js +6 -2
  18. package/cjs/services/migration-service/scripts/databases/MigrateAssetSetting.js +6 -2
  19. package/cjs/services/migration-service/scripts/index.js +2 -2
  20. package/cjs/services/swap-service/index.js +24 -18
  21. package/cjs/services/transaction-service/utils.js +25 -16
  22. package/cjs/services/wallet-connect-service/constants.js +6 -2
  23. package/cjs/services/wallet-connect-service/index.js +62 -45
  24. package/koni/background/handlers/Extension.d.ts +1 -1
  25. package/koni/background/handlers/Extension.js +4 -4
  26. package/koni/background/handlers/State.js +1 -0
  27. package/package.json +30 -29
  28. package/packageInfo.js +1 -1
  29. package/services/balance-service/transfer/xcm/snowBridge.js +21 -10
  30. package/services/chain-online-service/index.d.ts +4 -1
  31. package/services/chain-online-service/index.js +168 -15
  32. package/services/chain-service/index.js +39 -10
  33. package/services/chain-service/utils/patch.d.ts +1 -1
  34. package/services/chain-service/utils/patch.js +2 -2
  35. package/services/earning-service/constants/chains.d.ts +0 -1
  36. package/services/earning-service/constants/chains.js +1 -2
  37. package/services/earning-service/handlers/base.d.ts +3 -3
  38. package/services/earning-service/handlers/base.js +1 -1
  39. package/services/earning-service/handlers/native-staking/base.js +4 -2
  40. package/services/earning-service/handlers/native-staking/dtao.d.ts +4 -3
  41. package/services/earning-service/handlers/native-staking/dtao.js +9 -3
  42. package/services/earning-service/handlers/native-staking/relay-chain.d.ts +0 -2
  43. package/services/earning-service/handlers/native-staking/relay-chain.js +2 -11
  44. package/services/earning-service/handlers/native-staking/tao.d.ts +1 -0
  45. package/services/earning-service/handlers/native-staking/tao.js +24 -14
  46. package/services/earning-service/service.d.ts +3 -3
  47. package/services/earning-service/service.js +2 -2
  48. package/services/keyring-service/context/handlers/Json.js +28 -3
  49. package/services/migration-service/scripts/MigrateTransactionHistoryBySymbol.js +6 -2
  50. package/services/migration-service/scripts/databases/MigrateAssetSetting.js +6 -2
  51. package/services/migration-service/scripts/index.js +2 -2
  52. package/services/swap-service/index.js +24 -18
  53. package/services/transaction-service/utils.js +25 -16
  54. package/services/wallet-connect-service/constants.d.ts +2 -0
  55. package/services/wallet-connect-service/constants.js +3 -1
  56. package/services/wallet-connect-service/index.js +50 -33
  57. package/types/yield/actions/join/submit.d.ts +5 -0
  58. package/types/yield/actions/others.d.ts +7 -2
  59. package/types/yield/info/account/info.d.ts +1 -0
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "./cjs/detectPackage.js"
18
18
  ],
19
19
  "type": "module",
20
- "version": "1.3.52-0",
20
+ "version": "1.3.54-0",
21
21
  "main": "./cjs/index.js",
22
22
  "module": "./index.js",
23
23
  "types": "./index.d.ts",
@@ -2838,7 +2838,7 @@
2838
2838
  "dependencies": {
2839
2839
  "@acala-network/api": "^5.0.2",
2840
2840
  "@apollo/client": "^3.7.14",
2841
- "@azns/resolver-core": "^1.4.0",
2841
+ "@azns/resolver-core": "2.1.0",
2842
2842
  "@emurgo/cardano-serialization-lib-nodejs": "^13.2.0",
2843
2843
  "@equilab/api": "~1.14.25",
2844
2844
  "@ethereumjs/common": "^4.1.0",
@@ -2851,41 +2851,42 @@
2851
2851
  "@metaverse-network-sdk/type-definitions": "^0.0.1-13",
2852
2852
  "@oak-foundation/types": "^0.0.23",
2853
2853
  "@polkadot-api/merkleize-metadata": "^1.1.0",
2854
- "@polkadot/api": "^15.7.2",
2855
- "@polkadot/api-base": "^15.7.2",
2856
- "@polkadot/api-contract": "^15.7.2",
2857
- "@polkadot/api-derive": "^15.7.2",
2858
- "@polkadot/apps-config": "^0.150.2",
2859
- "@polkadot/hw-ledger": "^13.4.3",
2860
- "@polkadot/networks": "^13.4.3",
2861
- "@polkadot/phishing": "^0.25.4",
2862
- "@polkadot/rpc-provider": "^15.7.2",
2863
- "@polkadot/types": "^15.7.2",
2864
- "@polkadot/types-augment": "^15.7.2",
2865
- "@polkadot/types-known": "^15.7.2",
2866
- "@polkadot/ui-settings": "^3.12.2",
2867
- "@polkadot/util": "^13.4.3",
2868
- "@polkadot/util-crypto": "^13.4.3",
2869
- "@polkadot/x-global": "^13.4.3",
2854
+ "@polkadot/api": "^16.4.2",
2855
+ "@polkadot/api-base": "^16.4.2",
2856
+ "@polkadot/api-contract": "^16.4.2",
2857
+ "@polkadot/api-derive": "^16.4.2",
2858
+ "@polkadot/apps-config": "^0.161.1",
2859
+ "@polkadot/hw-ledger": "^13.5.3",
2860
+ "@polkadot/networks": "^13.5.3",
2861
+ "@polkadot/phishing": "^0.25.15",
2862
+ "@polkadot/rpc-provider": "^16.4.2",
2863
+ "@polkadot/types": "^16.4.2",
2864
+ "@polkadot/types-augment": "^16.4.2",
2865
+ "@polkadot/types-known": "^16.4.2",
2866
+ "@polkadot/ui-settings": "^3.15.2",
2867
+ "@polkadot/util": "^13.5.3",
2868
+ "@polkadot/util-crypto": "^13.5.3",
2869
+ "@polkadot/x-global": "^13.5.3",
2870
2870
  "@reduxjs/toolkit": "^1.9.1",
2871
+ "@snowbridge/api": "^0.2.0",
2872
+ "@snowbridge/registry": "^0.2.0",
2871
2873
  "@sora-substrate/type-definitions": "^1.17.7",
2872
2874
  "@substrate/connect": "^0.8.9",
2873
2875
  "@subwallet-monorepos/subwallet-services-sdk": "^0.1.8",
2874
- "@subwallet/chain-list": "0.2.111",
2875
- "@subwallet/extension-base": "^1.3.52-0",
2876
- "@subwallet/extension-chains": "^1.3.52-0",
2877
- "@subwallet/extension-dapp": "^1.3.52-0",
2878
- "@subwallet/extension-inject": "^1.3.52-0",
2879
- "@subwallet/keyring": "^0.1.12",
2880
- "@subwallet/subwallet-api-sdk": "^1.3.51-0",
2881
- "@subwallet/ui-keyring": "^0.1.12",
2876
+ "@subwallet/chain-list": "0.2.112-beta.9",
2877
+ "@subwallet/extension-base": "^1.3.54-0",
2878
+ "@subwallet/extension-chains": "^1.3.54-0",
2879
+ "@subwallet/extension-dapp": "^1.3.54-0",
2880
+ "@subwallet/extension-inject": "^1.3.54-0",
2881
+ "@subwallet/keyring": "^0.1.13",
2882
+ "@subwallet/ui-keyring": "^0.1.13",
2882
2883
  "@ton/core": "^0.56.3",
2883
2884
  "@ton/crypto": "^3.2.0",
2884
2885
  "@ton/ton": "^15.0.0",
2885
2886
  "@walletconnect/keyvaluestorage": "^1.1.1",
2886
- "@walletconnect/sign-client": "^2.20.2",
2887
- "@walletconnect/types": "^2.20.2",
2888
- "@walletconnect/utils": "^2.20.2",
2887
+ "@walletconnect/sign-client": "2.21.5",
2888
+ "@walletconnect/types": "2.21.5",
2889
+ "@walletconnect/utils": "2.21.5",
2889
2890
  "avail-js-sdk": "^0.2.12",
2890
2891
  "axios": "^1.6.2",
2891
2892
  "bignumber.js": "^9.1.1",
package/packageInfo.js CHANGED
@@ -7,5 +7,5 @@ export const packageInfo = {
7
7
  name: '@subwallet/extension-base',
8
8
  path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto',
9
9
  type: 'esm',
10
- version: '1.3.52-0'
10
+ version: '1.3.54-0'
11
11
  };
@@ -1,19 +1,14 @@
1
1
  // Copyright 2019-2022 @subwallet/extension-base
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
+ import { Context, contextConfigFor, toPolkadotV2 } from '@snowbridge/api';
5
+ import { assetRegistryFor } from '@snowbridge/registry';
4
6
  import { getWeb3Contract } from '@subwallet/extension-base/koni/api/contract-handler/evm/web3';
5
7
  import { _SNOWBRIDGE_GATEWAY_ABI, getSnowBridgeGatewayContract } from '@subwallet/extension-base/koni/api/contract-handler/utils';
6
8
  import { _getContractAddressOfToken, _getSubstrateParaId, _isChainEvmCompatible } from '@subwallet/extension-base/services/chain-service/utils';
7
9
  import { combineEthFee } from '@subwallet/extension-base/utils';
8
10
  import { u8aToHex } from '@polkadot/util';
9
11
  import { decodeAddress } from '@polkadot/util-crypto';
10
- async function getSendFeeToken(contract, tokenContract, destChainParaId, destinationFee) {
11
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
12
- const quoteSendTokenFee = contract.methods.quoteSendTokenFee(tokenContract, destChainParaId, destinationFee);
13
-
14
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
15
- return await quoteSendTokenFee.call();
16
- }
17
12
  export async function getSnowBridgeEvmTransfer(tokenInfo, originChainInfo, destinationChainInfo, sender, recipientAddress, value, evmApi, _feeInfo, feeCustom, feeOption) {
18
13
  const snowBridgeContractAddress = getSnowBridgeGatewayContract(originChainInfo.slug);
19
14
  const snowBridgeContract = getWeb3Contract(snowBridgeContractAddress, evmApi, _SNOWBRIDGE_GATEWAY_ABI);
@@ -23,7 +18,24 @@ export async function getSnowBridgeEvmTransfer(tokenInfo, originChainInfo, desti
23
18
  kind: 1,
24
19
  data: _isChainEvmCompatible(destinationChainInfo) ? recipientAddress : u8aToHex(decodeAddress(recipientAddress))
25
20
  };
26
- const destinationFee = '0';
21
+ let destinationFee;
22
+ let totalFee;
23
+ try {
24
+ const environment = 'polkadot_mainnet';
25
+ const context = new Context(contextConfigFor(environment));
26
+ const registry = assetRegistryFor(environment);
27
+ const deliveryFee = await toPolkadotV2.getDeliveryFee(context, registry, tokenContract, destinationChainParaId);
28
+ console.log('deliveryFee', deliveryFee);
29
+ totalFee = deliveryFee.totalFeeInWei.toString();
30
+ destinationFee = (deliveryFee.destinationDeliveryFeeDOT + deliveryFee.destinationExecutionFeeDOT).toString();
31
+
32
+ // Clean up all open connections
33
+ await context.destroyContext();
34
+ } catch (error) {
35
+ console.error('Cannot get snow-bridge delivery fees with error:', error);
36
+ totalFee = '0';
37
+ destinationFee = '0';
38
+ }
27
39
 
28
40
  // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
29
41
  const transferCall = snowBridgeContract.methods.sendToken(tokenContract, destinationChainParaId, recipient, destinationFee, value);
@@ -32,11 +44,10 @@ export async function getSnowBridgeEvmTransfer(tokenInfo, originChainInfo, desti
32
44
  const feeInfo = _feeInfo;
33
45
  const _feeCustom = feeCustom;
34
46
  const feeCombine = combineEthFee(feeInfo, feeOption, _feeCustom);
35
- const sendTokenFee = await getSendFeeToken(snowBridgeContract, tokenContract, destinationChainParaId, destinationFee);
36
47
  const transactionConfig = {
37
48
  from: sender,
38
49
  to: snowBridgeContractAddress,
39
- value: sendTokenFee,
50
+ value: totalFee,
40
51
  data: transferEncodedCall,
41
52
  ...feeCombine
42
53
  };
@@ -1,5 +1,5 @@
1
1
  /// <reference types="node" />
2
- import { _ChainAsset, _ChainInfo } from '@subwallet/chain-list/types';
2
+ import { _AssetType, _ChainAsset, _ChainInfo } from '@subwallet/chain-list/types';
3
3
  import { ChainService } from '@subwallet/extension-base/services/chain-service';
4
4
  import { PatchInfo } from '@subwallet/extension-base/services/chain-service/utils';
5
5
  import { EventService } from '@subwallet/extension-base/services/event-service';
@@ -13,9 +13,12 @@ export declare class ChainOnlineService {
13
13
  private firstApplied;
14
14
  refreshLatestChainDataTimeOut: NodeJS.Timer | undefined;
15
15
  constructor(chainService: ChainService, settingService: SettingService, eventService: EventService, dbService: DatabaseService);
16
+ resetFirstApplied(): void;
16
17
  validatePatchWithHash(latestPatch: PatchInfo): boolean;
17
18
  validatePatchBeforeStore(candidateChainInfoMap: Record<string, _ChainInfo>, candidateAssetRegistry: Record<string, _ChainAsset>, latestPatch: PatchInfo): boolean;
18
19
  mergeChainList(oldChainInfoMap: Record<string, _ChainInfo>, latestChainInfo: Record<string, _ChainInfo>): Record<string, _ChainInfo>;
20
+ checkExistedPredefinedChain(latestChainInfoMap: Record<string, _ChainInfo>, genesisHash?: string, evmChainId?: number): string;
21
+ generateSlugForSmartContractAsset(originChain: string, assetType: _AssetType, symbol: string, contractAddress: string): string;
19
22
  handleLatestPatch(latestPatch: PatchInfo): Promise<void>;
20
23
  private fetchLatestPatchData;
21
24
  handleLatestPatchData(): void;
@@ -2,10 +2,11 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import { AssetLogoMap, ChainLogoMap } from '@subwallet/chain-list';
5
+ import { _ChainStatus } from '@subwallet/chain-list/types';
5
6
  import { LATEST_CHAIN_PATCH_FETCHING_INTERVAL, md5HashChainAsset, md5HashChainInfo } from '@subwallet/extension-base/services/chain-online-service/constants';
6
7
  import { filterAssetInfoMap } from '@subwallet/extension-base/services/chain-service';
7
8
  import { _ChainConnectionStatus } from '@subwallet/extension-base/services/chain-service/types';
8
- import { fetchPatchData, randomizeProvider } from '@subwallet/extension-base/services/chain-service/utils';
9
+ import { _isCustomAsset, _isCustomChain, _isEqualSmartContractAsset, fetchPatchData, randomizeProvider } from '@subwallet/extension-base/services/chain-service/utils';
9
10
  export class ChainOnlineService {
10
11
  constructor(chainService, settingService, eventService, dbService) {
11
12
  this.chainService = chainService;
@@ -14,6 +15,9 @@ export class ChainOnlineService {
14
15
  this.dbService = dbService;
15
16
  this.firstApplied = false;
16
17
  }
18
+ resetFirstApplied() {
19
+ this.firstApplied = false;
20
+ }
17
21
  validatePatchWithHash(latestPatch) {
18
22
  const {
19
23
  ChainAsset,
@@ -61,7 +65,7 @@ export class ChainOnlineService {
61
65
  providers: _providers,
62
66
  ...info
63
67
  } = _info;
64
- const providers = Object.assign(((_rs$slug = rs[slug]) === null || _rs$slug === void 0 ? void 0 : _rs$slug.providers) || {}, _providers);
68
+ const providers = rs[slug] ? (_rs$slug = rs[slug]) === null || _rs$slug === void 0 ? void 0 : _rs$slug.providers : _providers;
65
69
  rs[slug] = {
66
70
  ...info,
67
71
  providers
@@ -69,6 +73,26 @@ export class ChainOnlineService {
69
73
  }
70
74
  return rs;
71
75
  }
76
+ checkExistedPredefinedChain(latestChainInfoMap, genesisHash, evmChainId) {
77
+ let duplicatedSlug = '';
78
+ if (genesisHash) {
79
+ for (const chainInfo of Object.values(latestChainInfoMap)) {
80
+ if (chainInfo.substrateInfo && chainInfo.substrateInfo.genesisHash === genesisHash) {
81
+ duplicatedSlug = chainInfo.slug;
82
+ }
83
+ }
84
+ } else if (evmChainId) {
85
+ for (const chainInfo of Object.values(latestChainInfoMap)) {
86
+ if (chainInfo.evmInfo && chainInfo.evmInfo.evmChainId === evmChainId) {
87
+ duplicatedSlug = chainInfo.slug;
88
+ }
89
+ }
90
+ }
91
+ return duplicatedSlug;
92
+ }
93
+ generateSlugForSmartContractAsset(originChain, assetType, symbol, contractAddress) {
94
+ return `${originChain}-${assetType}-${symbol}-${contractAddress}`;
95
+ }
72
96
  async handleLatestPatch(latestPatch) {
73
97
  try {
74
98
  var _await$this$settingSe;
@@ -88,31 +112,151 @@ export class ChainOnlineService {
88
112
  let assetRegistry = structuredClone(this.chainService.getAssetRegistry());
89
113
  const currentChainStateMap = structuredClone(this.chainService.getChainStateMap());
90
114
  const currentChainStatusMap = structuredClone(this.chainService.getChainStatusMap());
115
+ const assetSetting = structuredClone(await this.chainService.getAssetSettings());
116
+ const migratedAssetSetting = {};
91
117
  let addedChain = [];
118
+ const customChains = [];
119
+ const deprecatedChains = [];
120
+ const deprecatedChainMap = {};
121
+ const deprecatedAssets = [];
92
122
  if (isSafePatch && (!this.firstApplied || currentPatchVersion !== latestPatchVersion)) {
93
123
  this.firstApplied = true;
94
124
 
95
125
  // 2. merge data map
96
126
  if (latestChainInfo && Object.keys(latestChainInfo).length > 0) {
127
+ const storedChainSettings = await this.dbService.getAllChainStore();
128
+ const storedChainSettingMap = {};
129
+ storedChainSettings.forEach(chainStoredSetting => {
130
+ storedChainSettingMap[chainStoredSetting.slug] = chainStoredSetting;
131
+ });
132
+ if (storedChainSettings.length > 0) {
133
+ for (const [storedSlug, storedChainInfo] of Object.entries(storedChainSettingMap)) {
134
+ if (_isCustomChain(storedSlug)) {
135
+ var _storedChainInfo$subs, _storedChainInfo$evmI;
136
+ // Check if this custom chain duplicates any of the latest chainInfo from patch based on genesisHash (for Substrate) or EVM chain ID.
137
+ const duplicatedDefaultSlug = this.checkExistedPredefinedChain(latestChainInfo, (_storedChainInfo$subs = storedChainInfo.substrateInfo) === null || _storedChainInfo$subs === void 0 ? void 0 : _storedChainInfo$subs.genesisHash, (_storedChainInfo$evmI = storedChainInfo.evmInfo) === null || _storedChainInfo$evmI === void 0 ? void 0 : _storedChainInfo$evmI.evmChainId);
138
+ if (duplicatedDefaultSlug.length > 0) {
139
+ // Add the old custom chain slug to the list of deprecated chains.
140
+ deprecatedChainMap[storedSlug] = duplicatedDefaultSlug;
141
+ deprecatedChains.push(storedSlug);
142
+ const storedChainState = currentChainStateMap[storedSlug];
143
+ const storedChainStatus = currentChainStatusMap[storedSlug];
144
+
145
+ // Update the current chain state to use the new chain slug, inheriting the active/inactive status from custom chain and randomly assigning a provider
146
+ currentChainStateMap[duplicatedDefaultSlug] = {
147
+ slug: duplicatedDefaultSlug,
148
+ active: storedChainState.active,
149
+ currentProvider: randomizeProvider(latestChainInfo[duplicatedDefaultSlug].providers).providerKey,
150
+ manualTurnOff: storedChainState.manualTurnOff
151
+ };
152
+
153
+ // Update the current chain status to use the new chain slug, inheriting the connection status from custom chain and updating the last updated timestamp
154
+ currentChainStatusMap[duplicatedDefaultSlug] = {
155
+ slug: duplicatedDefaultSlug,
156
+ connectionStatus: storedChainStatus.connectionStatus,
157
+ lastUpdated: Date.now()
158
+ };
159
+ customChains.push(duplicatedDefaultSlug);
160
+
161
+ // Remove the deprecated custom chain's info from the old chain info map and the current state/status maps.
162
+ delete oldChainInfoMap[storedSlug];
163
+ delete currentChainStateMap[storedSlug];
164
+ delete currentChainStatusMap[storedSlug];
165
+ }
166
+ }
167
+ }
168
+ }
97
169
  chainInfoMap = this.mergeChainList(oldChainInfoMap, latestChainInfo);
98
170
  const [currentChainStateKey, newChainKey] = [Object.keys(currentChainStateMap), Object.keys(chainInfoMap)];
99
- addedChain = newChainKey.filter(chain => !currentChainStateKey.includes(chain));
171
+ addedChain = newChainKey.filter(chain => !currentChainStateKey.includes(chain) || customChains.includes(chain));
100
172
  addedChain.forEach(key => {
101
- currentChainStateMap[key] = {
102
- active: false,
103
- currentProvider: randomizeProvider(chainInfoMap[key].providers).providerKey,
104
- manualTurnOff: false,
105
- slug: key
106
- };
107
- currentChainStatusMap[key] = {
108
- slug: key,
109
- connectionStatus: _ChainConnectionStatus.DISCONNECTED,
110
- lastUpdated: Date.now()
111
- };
173
+ if (!currentChainStateMap[key] && !currentChainStatusMap[key]) {
174
+ currentChainStateMap[key] = {
175
+ active: false,
176
+ currentProvider: randomizeProvider(chainInfoMap[key].providers).providerKey,
177
+ manualTurnOff: false,
178
+ slug: key
179
+ };
180
+ currentChainStatusMap[key] = {
181
+ slug: key,
182
+ connectionStatus: _ChainConnectionStatus.DISCONNECTED,
183
+ lastUpdated: Date.now()
184
+ };
185
+ }
112
186
  });
113
187
  }
114
188
  if (latestAssetInfo && Object.keys(latestAssetInfo).length > 0) {
115
- assetRegistry = filterAssetInfoMap(oldChainInfoMap, Object.assign({}, oldAssetRegistry, latestAssetInfo), addedChain);
189
+ // Get all previously stored asset registry entries from the database.
190
+ const storedAssetRegistry = await this.dbService.getAllAssetStore();
191
+ const availableChains = Object.values(chainInfoMap).filter(info => info.chainStatus === _ChainStatus.ACTIVE).map(chainInfo => chainInfo.slug);
192
+ let finalAssetRegistry;
193
+ if (storedAssetRegistry.length === 0) {
194
+ finalAssetRegistry = oldAssetRegistry;
195
+ } else {
196
+ const mergedAssetRegistry = oldAssetRegistry;
197
+ const parsedStoredAssetRegistry = {};
198
+
199
+ // Update custom assets of merged custom chains
200
+ for (const storedAsset of Object.values(storedAssetRegistry)) {
201
+ var _storedAsset$metadata;
202
+ // If the stored asset is a custom asset and its origin chain is marked as deprecated, and its assetType is ERC20
203
+ if (_isCustomAsset(storedAsset.slug) && Object.keys(deprecatedChainMap).includes(storedAsset.originChain) && (_storedAsset$metadata = storedAsset.metadata) !== null && _storedAsset$metadata !== void 0 && _storedAsset$metadata.contractAddress) {
204
+ const newOriginChain = deprecatedChainMap[storedAsset.originChain];
205
+ // const newSlug = this.generateSlugForSmartContractAsset(newOriginChain, storedAsset.assetType, storedAsset.symbol, storedAsset.metadata?.contractAddress);
206
+
207
+ // Mark the old custom asset slug as deprecated.
208
+ deprecatedAssets.push(storedAsset.slug);
209
+ parsedStoredAssetRegistry[storedAsset.slug] = {
210
+ ...storedAsset,
211
+ originChain: newOriginChain
212
+ };
213
+ } else {
214
+ parsedStoredAssetRegistry[storedAsset.slug] = storedAsset;
215
+ }
216
+ }
217
+ for (const storedAssetInfo of Object.values(parsedStoredAssetRegistry)) {
218
+ let duplicated = false;
219
+ let deprecated = false;
220
+ let defaultSlugForMigration;
221
+ for (const defaultChainAsset of Object.values(latestAssetInfo)) {
222
+ // case: the stored asset is the same to a smart contract asset from patch
223
+ if (_isEqualSmartContractAsset(storedAssetInfo, defaultChainAsset)) {
224
+ duplicated = true;
225
+ defaultSlugForMigration = defaultChainAsset.slug;
226
+ break;
227
+ }
228
+
229
+ // case: the origin chain of the stored asset is no longer active (Exp: custom chain is deprecated)
230
+ if (availableChains.indexOf(storedAssetInfo.originChain) === -1) {
231
+ deprecated = true;
232
+ defaultSlugForMigration = defaultChainAsset.slug;
233
+ break;
234
+ }
235
+ }
236
+
237
+ // If the stored asset is a duplicate of a default asset or its origin chain is deprecated.
238
+ if (duplicated || deprecated) {
239
+ if (Object.keys(assetSetting).includes(storedAssetInfo.slug)) {
240
+ const isVisible = assetSetting[storedAssetInfo.slug].visible;
241
+
242
+ // Migrate assetSetting from custom token to token from patch
243
+ if (defaultSlugForMigration) {
244
+ migratedAssetSetting[defaultSlugForMigration] = {
245
+ visible: isVisible
246
+ };
247
+ delete assetSetting[storedAssetInfo.slug];
248
+ }
249
+ }
250
+ delete mergedAssetRegistry[storedAssetInfo.slug];
251
+ deprecatedAssets.push(storedAssetInfo.slug);
252
+ } else {
253
+ // If the stored asset is not a duplicate and its origin chain is active, keep it in the merged registry.
254
+ mergedAssetRegistry[storedAssetInfo.slug] = storedAssetInfo;
255
+ }
256
+ }
257
+ finalAssetRegistry = mergedAssetRegistry;
258
+ }
259
+ assetRegistry = filterAssetInfoMap(oldChainInfoMap, Object.assign({}, finalAssetRegistry, latestAssetInfo), addedChain);
116
260
  }
117
261
 
118
262
  // 3. validate data before write
@@ -130,6 +274,15 @@ export class ChainOnlineService {
130
274
  this.chainService.setChainStateMap(currentChainStateMap);
131
275
  this.chainService.subscribeChainStateMap().next(currentChainStateMap);
132
276
  this.chainService.subscribeChainStatusMap().next(currentChainStatusMap);
277
+ // Migrate assetSetting
278
+ this.chainService.setAssetSettings({
279
+ ...assetSetting,
280
+ ...migratedAssetSetting
281
+ });
282
+
283
+ // Remove all custom chains and custom tokens that is duplicated from chains or tokens in patch
284
+ await this.dbService.removeFromChainStore(deprecatedChains);
285
+ await this.dbService.removeFromAssetStore(deprecatedAssets);
133
286
  const storedChainInfoList = Object.keys(chainInfoMap).map(chainSlug => {
134
287
  return {
135
288
  ...chainInfoMap[chainSlug],
@@ -1229,8 +1229,11 @@ export class ChainService {
1229
1229
  async initAssetRegistry(deprecatedCustomChainMap) {
1230
1230
  const storedAssetRegistry = await this.dbService.getAllAssetStore();
1231
1231
  const latestAssetRegistry = filterAssetInfoMap(this.getChainInfoMap(), ChainAssetMap);
1232
+ const assetSetting = await this.getAssetSettings();
1232
1233
  const availableChains = Object.values(this.dataMap.chainInfoMap).filter(info => info.chainStatus === _ChainStatus.ACTIVE).map(chainInfo => chainInfo.slug);
1234
+ const customChains = Object.keys(deprecatedCustomChainMap).filter(chain => _isCustomChain(chain));
1233
1235
  let finalAssetRegistry = {};
1236
+ const migratedAssetSetting = {};
1234
1237
  if (storedAssetRegistry.length === 0) {
1235
1238
  finalAssetRegistry = latestAssetRegistry;
1236
1239
  } else {
@@ -1240,15 +1243,18 @@ export class ChainService {
1240
1243
 
1241
1244
  // Update custom assets of merged custom chains
1242
1245
  Object.values(storedAssetRegistry).forEach(storedAsset => {
1243
- if (_isCustomAsset(storedAsset.slug) && Object.keys(deprecatedCustomChainMap).includes(storedAsset.originChain)) {
1244
- var _storedAsset$metadata;
1246
+ var _storedAsset$metadata;
1247
+ const isFromCustomChain = customChains ? customChains.includes(storedAsset.originChain) : false;
1248
+
1249
+ // If the stored asset is a custom asset, from a deprecated custom chain, and has a contract address.
1250
+ if (_isCustomAsset(storedAsset.slug) && isFromCustomChain && (_storedAsset$metadata = storedAsset.metadata) !== null && _storedAsset$metadata !== void 0 && _storedAsset$metadata.contractAddress) {
1245
1251
  const newOriginChain = deprecatedCustomChainMap[storedAsset.originChain];
1246
- const newSlug = this.generateSlugForSmartContractAsset(newOriginChain, storedAsset.assetType, storedAsset.symbol, (_storedAsset$metadata = storedAsset.metadata) === null || _storedAsset$metadata === void 0 ? void 0 : _storedAsset$metadata.contractAddress);
1252
+ // const newSlug = this.generateSlugForSmartContractAsset(newOriginChain, storedAsset.assetType, storedAsset.symbol, storedAsset.metadata?.contractAddress);
1253
+
1247
1254
  deprecatedAssets.push(storedAsset.slug);
1248
- parsedStoredAssetRegistry[newSlug] = {
1255
+ parsedStoredAssetRegistry[storedAsset.slug] = {
1249
1256
  ...storedAsset,
1250
- originChain: newOriginChain,
1251
- slug: newSlug
1257
+ originChain: newOriginChain
1252
1258
  };
1253
1259
  } else {
1254
1260
  parsedStoredAssetRegistry[storedAsset.slug] = storedAsset;
@@ -1257,25 +1263,48 @@ export class ChainService {
1257
1263
  for (const storedAssetInfo of Object.values(parsedStoredAssetRegistry)) {
1258
1264
  let duplicated = false;
1259
1265
  let deprecated = false;
1266
+ let defaultSlugForMigration;
1260
1267
  for (const defaultChainAsset of Object.values(latestAssetRegistry)) {
1261
- // case merge custom asset with default asset
1268
+ // Case: The stored asset is the same to a smart contract asset from new stable chainlist
1262
1269
  if (_isEqualSmartContractAsset(storedAssetInfo, defaultChainAsset)) {
1263
1270
  duplicated = true;
1271
+ defaultSlugForMigration = defaultChainAsset.slug;
1264
1272
  break;
1265
1273
  }
1274
+
1275
+ // Case: If the origin chain of the stored asset is no longer active. (custom chain is deprecated)
1266
1276
  if (availableChains.indexOf(storedAssetInfo.originChain) === -1) {
1267
1277
  deprecated = true;
1278
+ defaultSlugForMigration = defaultChainAsset.slug;
1268
1279
  break;
1269
1280
  }
1281
+
1282
+ // Case: If a default asset already exists with the same slug as the stored asset (from patch)
1270
1283
  if (defaultChainAsset.slug === storedAssetInfo.slug) {
1271
1284
  duplicated = true;
1285
+ defaultSlugForMigration = defaultChainAsset.slug;
1272
1286
  break;
1273
1287
  }
1274
1288
  }
1275
- if (!duplicated && !deprecated) {
1276
- mergedAssetRegistry[storedAssetInfo.slug] = storedAssetInfo;
1277
- } else {
1289
+
1290
+ // If the stored asset is a duplicate of a default asset or its origin chain is deprecated.
1291
+ if (duplicated || deprecated) {
1292
+ if (Object.keys(assetSetting).includes(storedAssetInfo.slug)) {
1293
+ const isVisible = assetSetting[storedAssetInfo.slug].visible;
1294
+
1295
+ // Migrate assetSetting from custom token to new default token
1296
+ if (defaultSlugForMigration) {
1297
+ migratedAssetSetting[defaultSlugForMigration] = {
1298
+ visible: isVisible
1299
+ };
1300
+ delete assetSetting[storedAssetInfo.slug];
1301
+ }
1302
+ }
1303
+ delete mergedAssetRegistry[storedAssetInfo.slug];
1278
1304
  deprecatedAssets.push(storedAssetInfo.slug);
1305
+ } else {
1306
+ // If the stored asset is not a duplicate and its origin chain is active, keep it in the merged registry.
1307
+ mergedAssetRegistry[storedAssetInfo.slug] = storedAssetInfo;
1279
1308
  }
1280
1309
  }
1281
1310
  finalAssetRegistry = mergedAssetRegistry;
@@ -1,5 +1,5 @@
1
1
  import { _ChainAsset, _ChainInfo, _MultiChainAsset } from '@subwallet/chain-list/types';
2
- export declare const ChainListVersion = "0.2.111";
2
+ export declare const ChainListVersion = "0.2.112";
3
3
  export interface PatchInfo {
4
4
  patchVersion: string;
5
5
  appliedVersion: string;
@@ -3,9 +3,9 @@
3
3
 
4
4
  const PRODUCTION_BRANCHES = ['master', 'webapp', 'webapp-dev'];
5
5
  const branchName = process.env.BRANCH_NAME || 'subwallet-dev';
6
- const fetchDomain = PRODUCTION_BRANCHES.indexOf(branchName) > -1 ? 'https://chain-list-assets.subwallet.app' : 'https://dev.sw-chain-list-assets.pages.dev';
6
+ const fetchDomain = process.env.PATCH_CHAIN_LIST_URL || (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
- export const ChainListVersion = '0.2.111'; // update this when build chain-list
8
+ export const ChainListVersion = '0.2.112'; // update this when build chain-list
9
9
 
10
10
  // todo: move this interface to chainlist
11
11
 
@@ -23,4 +23,3 @@ export declare const MANTA_VALIDATOR_POINTS_PER_BLOCK = 20;
23
23
  export declare const MANTA_MIN_DELEGATION = 500;
24
24
  export declare const CHANNEL_ID = 7;
25
25
  export declare const STAKING_IDENTITY_API_SLUG: Record<string, string>;
26
- export declare const _SUPPORT_CHANGE_VALIDATOR_CHAIN: string[];
@@ -32,5 +32,4 @@ export const CHANNEL_ID = 7;
32
32
  export const STAKING_IDENTITY_API_SLUG = {
33
33
  polkadot: 'polkadot_people',
34
34
  kusama: 'peopleKusama'
35
- };
36
- export const _SUPPORT_CHANGE_VALIDATOR_CHAIN = ['polkadot', 'kusama'];
35
+ };
@@ -3,8 +3,8 @@ import { TransactionError } from '@subwallet/extension-base/background/errors/Tr
3
3
  import { ChainType, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
4
4
  import KoniState from '@subwallet/extension-base/koni/background/handlers/State';
5
5
  import { _EvmApi, _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
6
- import { BasePoolInfo, BaseYieldPoolMetadata, EarningRewardHistoryItem, EarningRewardItem, HandleYieldStepData, OptimalYieldPath, OptimalYieldPathParams, RequestEarlyValidateYield, RequestEarningSlippage, ResponseEarlyValidateYield, StakeCancelWithdrawalParams, SubmitChangeValidatorStaking, SubmitYieldJoinData, TransactionData, UnstakingInfo, YieldPoolInfo, YieldPoolMethodInfo, YieldPoolTarget, YieldPoolType, YieldPositionInfo, YieldStepBaseInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
7
- import { EarningSlippageResult } from './native-staking/dtao';
6
+ import { BasePoolInfo, BaseYieldPoolMetadata, EarningRewardHistoryItem, EarningRewardItem, HandleYieldStepData, OptimalYieldPath, OptimalYieldPathParams, RequestEarlyValidateYield, RequestEarningImpact, ResponseEarlyValidateYield, StakeCancelWithdrawalParams, SubmitChangeValidatorStaking, SubmitYieldJoinData, TransactionData, UnstakingInfo, YieldPoolInfo, YieldPoolMethodInfo, YieldPoolTarget, YieldPoolType, YieldPositionInfo, YieldStepBaseInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
7
+ import { EarningImpactResult } from './native-staking/dtao';
8
8
  /**
9
9
  * @class BasePoolHandler
10
10
  * @description Base pool handler
@@ -120,5 +120,5 @@ export default abstract class BasePoolHandler {
120
120
  abstract handleChangeEarningValidator(data: SubmitChangeValidatorStaking): Promise<TransactionData>;
121
121
  /** Check handler can handle slug */
122
122
  canHandleSlug(slug: string): boolean;
123
- getEarningSlippage(params: RequestEarningSlippage): Promise<EarningSlippageResult>;
123
+ getEarningImpact(params: RequestEarningImpact): Promise<EarningImpactResult>;
124
124
  }
@@ -280,7 +280,7 @@ export default class BasePoolHandler {
280
280
  canHandleSlug(slug) {
281
281
  return this.slug === slug;
282
282
  }
283
- getEarningSlippage(params) {
283
+ getEarningImpact(params) {
284
284
  return Promise.resolve({
285
285
  slippage: 0,
286
286
  rate: 1
@@ -131,7 +131,8 @@ export default class BaseNativeStakingPoolHandler extends BasePoolHandler {
131
131
  address,
132
132
  amount,
133
133
  selectedValidators,
134
- slug
134
+ slug,
135
+ subnetData
135
136
  } = data;
136
137
  const positionInfo = await this.getPoolPosition(address, slug);
137
138
  const [extrinsic] = await this.createJoinExtrinsic(data, positionInfo);
@@ -140,7 +141,8 @@ export default class BaseNativeStakingPoolHandler extends BasePoolHandler {
140
141
  slug: this.slug,
141
142
  amount,
142
143
  address,
143
- selectedValidators
144
+ selectedValidators,
145
+ subnetData
144
146
  };
145
147
  return {
146
148
  txChain: this.chain,
@@ -1,6 +1,6 @@
1
1
  import { _ChainInfo } from '@subwallet/chain-list/types';
2
2
  import KoniState from '@subwallet/extension-base/koni/background/handlers/State';
3
- import { BaseYieldPositionInfo, RequestEarningSlippage, YieldPoolInfo, YieldPoolType, YieldPositionInfo } from '@subwallet/extension-base/types';
3
+ import { BaseYieldPositionInfo, RequestEarningImpact, YieldPoolInfo, YieldPoolType, YieldPositionInfo } from '@subwallet/extension-base/types';
4
4
  import TaoNativeStakingPoolHandler, { TaoStakingStakeOption } from './tao';
5
5
  export interface SubnetData {
6
6
  netuid: number;
@@ -20,9 +20,10 @@ export interface RawDelegateState {
20
20
  stake: string;
21
21
  }>;
22
22
  }
23
- export interface EarningSlippageResult {
23
+ export interface EarningImpactResult {
24
24
  slippage: number;
25
25
  rate: number;
26
+ stakingTaoFee?: string;
26
27
  }
27
28
  export default class SubnetTaoStakingPoolHandler extends TaoNativeStakingPoolHandler {
28
29
  readonly type = YieldPoolType.SUBNET_STAKING;
@@ -33,7 +34,7 @@ export default class SubnetTaoStakingPoolHandler extends TaoNativeStakingPoolHan
33
34
  private isInit;
34
35
  constructor(state: KoniState, chain: string);
35
36
  canHandleSlug(slug: string): boolean;
36
- getEarningSlippage(params: RequestEarningSlippage): Promise<EarningSlippageResult>;
37
+ getEarningImpact(params: RequestEarningImpact): Promise<EarningImpactResult>;
37
38
  private init;
38
39
  protected getDescription(): string;
39
40
  subscribePoolInfo(callback: (data: YieldPoolInfo) => void): Promise<VoidFunction>;