@subwallet/extension-base 1.3.21-0 → 1.3.22-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 (41) hide show
  1. package/cjs/packageInfo.js +1 -1
  2. package/cjs/services/chain-service/constants.js +8 -3
  3. package/cjs/services/chain-service/handler/SubstrateChainHandler.js +3 -2
  4. package/cjs/services/chain-service/index.js +9 -0
  5. package/cjs/services/earning-service/constants/chains.js +2 -1
  6. package/cjs/services/earning-service/handlers/native-staking/mythos.js +337 -0
  7. package/cjs/services/earning-service/service.js +4 -0
  8. package/cjs/services/earning-service/utils/index.js +2 -0
  9. package/cjs/services/migration-service/scripts/databases/ClearMetadataDatabase.js +3 -23
  10. package/cjs/services/migration-service/scripts/databases/ClearMetadataForChains.js +40 -0
  11. package/cjs/services/migration-service/scripts/databases/ClearMetadataForMythos.js +15 -0
  12. package/cjs/services/migration-service/scripts/index.js +6 -2
  13. package/cjs/services/storage-service/DatabaseService.js +3 -0
  14. package/cjs/services/storage-service/db-stores/Metadata.js +3 -0
  15. package/cjs/services/storage-service/db-stores/Migration.js +6 -1
  16. package/package.json +36 -21
  17. package/packageInfo.js +1 -1
  18. package/services/chain-service/constants.js +8 -3
  19. package/services/chain-service/handler/SubstrateChainHandler.js +3 -2
  20. package/services/chain-service/index.d.ts +1 -0
  21. package/services/chain-service/index.js +9 -0
  22. package/services/earning-service/constants/chains.d.ts +1 -0
  23. package/services/earning-service/constants/chains.js +2 -1
  24. package/services/earning-service/handlers/native-staking/mythos.d.ts +35 -0
  25. package/services/earning-service/handlers/native-staking/mythos.js +329 -0
  26. package/services/earning-service/service.js +4 -0
  27. package/services/earning-service/utils/index.js +2 -0
  28. package/services/migration-service/scripts/databases/ClearMetadataDatabase.d.ts +3 -3
  29. package/services/migration-service/scripts/databases/ClearMetadataDatabase.js +3 -23
  30. package/services/migration-service/scripts/databases/ClearMetadataForChains.d.ts +5 -0
  31. package/services/migration-service/scripts/databases/ClearMetadataForChains.js +32 -0
  32. package/services/migration-service/scripts/databases/ClearMetadataForMythos.d.ts +4 -0
  33. package/services/migration-service/scripts/databases/ClearMetadataForMythos.js +7 -0
  34. package/services/migration-service/scripts/index.d.ts +1 -0
  35. package/services/migration-service/scripts/index.js +4 -1
  36. package/services/storage-service/DatabaseService.d.ts +1 -0
  37. package/services/storage-service/DatabaseService.js +3 -0
  38. package/services/storage-service/db-stores/Metadata.d.ts +1 -0
  39. package/services/storage-service/db-stores/Metadata.js +3 -0
  40. package/services/storage-service/db-stores/Migration.d.ts +1 -0
  41. package/services/storage-service/db-stores/Migration.js +6 -1
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "./cjs/detectPackage.js"
18
18
  ],
19
19
  "type": "module",
20
- "version": "1.3.21-0",
20
+ "version": "1.3.22-0",
21
21
  "main": "./cjs/index.js",
22
22
  "module": "./index.js",
23
23
  "types": "./index.d.ts",
@@ -1041,6 +1041,11 @@
1041
1041
  "require": "./cjs/services/earning-service/handlers/native-staking/base-para.js",
1042
1042
  "default": "./services/earning-service/handlers/native-staking/base-para.js"
1043
1043
  },
1044
+ "./services/earning-service/handlers/native-staking/mythos": {
1045
+ "types": "./services/earning-service/handlers/native-staking/mythos.d.ts",
1046
+ "require": "./cjs/services/earning-service/handlers/native-staking/mythos.js",
1047
+ "default": "./services/earning-service/handlers/native-staking/mythos.js"
1048
+ },
1044
1049
  "./services/earning-service/handlers/native-staking/para-chain": {
1045
1050
  "types": "./services/earning-service/handlers/native-staking/para-chain.d.ts",
1046
1051
  "require": "./cjs/services/earning-service/handlers/native-staking/para-chain.js",
@@ -1296,6 +1301,16 @@
1296
1301
  "require": "./cjs/services/migration-service/scripts/databases/ClearMetadataDatabase.js",
1297
1302
  "default": "./services/migration-service/scripts/databases/ClearMetadataDatabase.js"
1298
1303
  },
1304
+ "./services/migration-service/scripts/databases/ClearMetadataForChains": {
1305
+ "types": "./services/migration-service/scripts/databases/ClearMetadataForChains.d.ts",
1306
+ "require": "./cjs/services/migration-service/scripts/databases/ClearMetadataForChains.js",
1307
+ "default": "./services/migration-service/scripts/databases/ClearMetadataForChains.js"
1308
+ },
1309
+ "./services/migration-service/scripts/databases/ClearMetadataForMythos": {
1310
+ "types": "./services/migration-service/scripts/databases/ClearMetadataForMythos.d.ts",
1311
+ "require": "./cjs/services/migration-service/scripts/databases/ClearMetadataForMythos.js",
1312
+ "default": "./services/migration-service/scripts/databases/ClearMetadataForMythos.js"
1313
+ },
1299
1314
  "./services/migration-service/scripts/databases/MigrateAssetSetting": {
1300
1315
  "types": "./services/migration-service/scripts/databases/MigrateAssetSetting.d.ts",
1301
1316
  "require": "./cjs/services/migration-service/scripts/databases/MigrateAssetSetting.js",
@@ -2559,30 +2574,30 @@
2559
2574
  "@metaverse-network-sdk/type-definitions": "^0.0.1-13",
2560
2575
  "@oak-foundation/types": "^0.0.23",
2561
2576
  "@polkadot-api/merkleize-metadata": "^1.1.0",
2562
- "@polkadot/api": "^15.0.1",
2563
- "@polkadot/api-base": "^15.0.1",
2564
- "@polkadot/api-contract": "^15.0.1",
2565
- "@polkadot/api-derive": "^15.0.1",
2566
- "@polkadot/apps-config": "^0.137.1",
2567
- "@polkadot/hw-ledger": "^12.6.2",
2568
- "@polkadot/networks": "^13.2.3",
2569
- "@polkadot/phishing": "^0.22.7",
2570
- "@polkadot/rpc-provider": "^15.0.1",
2571
- "@polkadot/types": "^15.0.1",
2572
- "@polkadot/types-augment": "^15.0.1",
2573
- "@polkadot/types-known": "^15.0.1",
2574
- "@polkadot/ui-settings": "^3.6.6",
2575
- "@polkadot/util": "^13.2.3",
2576
- "@polkadot/util-crypto": "^13.2.3",
2577
- "@polkadot/x-global": "^12.2.1",
2577
+ "@polkadot/api": "^15.7.2",
2578
+ "@polkadot/api-base": "^15.7.2",
2579
+ "@polkadot/api-contract": "^15.7.2",
2580
+ "@polkadot/api-derive": "^15.7.2",
2581
+ "@polkadot/apps-config": "^0.150.2",
2582
+ "@polkadot/hw-ledger": "^13.4.3",
2583
+ "@polkadot/networks": "^13.4.3",
2584
+ "@polkadot/phishing": "^0.25.4",
2585
+ "@polkadot/rpc-provider": "^15.7.2",
2586
+ "@polkadot/types": "^15.7.2",
2587
+ "@polkadot/types-augment": "^15.7.2",
2588
+ "@polkadot/types-known": "^15.7.2",
2589
+ "@polkadot/ui-settings": "^3.12.2",
2590
+ "@polkadot/util": "^13.4.3",
2591
+ "@polkadot/util-crypto": "^13.4.3",
2592
+ "@polkadot/x-global": "^13.4.3",
2578
2593
  "@reduxjs/toolkit": "^1.9.1",
2579
2594
  "@sora-substrate/type-definitions": "^1.17.7",
2580
2595
  "@substrate/connect": "^0.8.9",
2581
2596
  "@subwallet/chain-list": "0.2.99",
2582
- "@subwallet/extension-base": "^1.3.21-0",
2583
- "@subwallet/extension-chains": "^1.3.21-0",
2584
- "@subwallet/extension-dapp": "^1.3.21-0",
2585
- "@subwallet/extension-inject": "^1.3.21-0",
2597
+ "@subwallet/extension-base": "^1.3.22-0",
2598
+ "@subwallet/extension-chains": "^1.3.22-0",
2599
+ "@subwallet/extension-dapp": "^1.3.22-0",
2600
+ "@subwallet/extension-inject": "^1.3.22-0",
2586
2601
  "@subwallet/keyring": "^0.1.8-beta.0",
2587
2602
  "@subwallet/ui-keyring": "^0.1.8-beta.0",
2588
2603
  "@ton/core": "^0.56.3",
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.21-0'
10
+ version: '1.3.22-0'
11
11
  };
@@ -102,7 +102,10 @@ export const _STAKING_ERA_LENGTH_MAP = {
102
102
  polkadex: 24,
103
103
  avail_mainnet: 24,
104
104
  cere: 24,
105
- analog_timechain: 12
105
+ analog_timechain: 12,
106
+ muse_testnet: 25 * 6 / 60 / 60,
107
+ // 25 blocks per session
108
+ mythos: 24
106
109
  };
107
110
  export const _EXPECTED_BLOCK_TIME = {
108
111
  // in seconds
@@ -135,7 +138,9 @@ export const _EXPECTED_BLOCK_TIME = {
135
138
  enjin_relaychain: 6,
136
139
  availTuringTest: 20,
137
140
  avail_mainnet: 20,
138
- dentnet: 3
141
+ dentnet: 3,
142
+ muse_testnet: 6,
143
+ mythos: 6
139
144
  };
140
145
  export const _PARACHAIN_INFLATION_DISTRIBUTION = {
141
146
  moonbeam: {
@@ -248,7 +253,7 @@ export const _TRANSFER_CHAIN_GROUP = {
248
253
  genshiro: ['genshiro_testnet', 'genshiro', 'equilibrium_parachain'],
249
254
  // crab: ['crab', 'pangolin'],
250
255
  bitcountry: ['pioneer', 'bitcountry'],
251
- statemine: ['statemint', 'statemine', 'darwinia2', 'astar', 'shiden', 'shibuya', 'parallel', 'liberland', 'liberlandTest', 'dentnet', 'dbcchain'],
256
+ statemine: ['statemint', 'statemine', 'darwinia2', 'astar', 'shiden', 'shibuya', 'parallel', 'liberland', 'liberlandTest', 'dentnet', 'dbcchain', 'westend_assethub'],
252
257
  riochain: ['riochain'],
253
258
  sora_substrate: ['sora_substrate'],
254
259
  avail: ['kate', 'goldberg_testnet'],
@@ -263,7 +263,7 @@ export class SubstrateChainHandler extends AbstractChainHandler {
263
263
  onUpdateStatus,
264
264
  providerName
265
265
  } = {}) {
266
- var _this$parent2;
266
+ var _this$parent2, _this$parent3;
267
267
  const existed = this.substrateApiMap[chainSlug];
268
268
  const updateMetadata = substrateApi => {
269
269
  // Update metadata to database with async methods
@@ -281,7 +281,8 @@ export class SubstrateChainHandler extends AbstractChainHandler {
281
281
  updateMetadata(existed);
282
282
  return existed;
283
283
  }
284
- const metadata = await ((_this$parent2 = this.parent) === null || _this$parent2 === void 0 ? void 0 : _this$parent2.getMetadata(chainSlug));
284
+ const useMetadata = await ((_this$parent2 = this.parent) === null || _this$parent2 === void 0 ? void 0 : _this$parent2.isUseMetadataToCreateApi(chainSlug));
285
+ const metadata = useMetadata === false ? undefined : await ((_this$parent3 = this.parent) === null || _this$parent3 === void 0 ? void 0 : _this$parent3.getMetadata(chainSlug));
285
286
  const apiObject = new SubstrateApi(chainSlug, apiUrl, {
286
287
  providerName,
287
288
  metadata,
@@ -169,4 +169,5 @@ export declare class ChainService {
169
169
  getSubscanChainMap(reverse?: boolean): Record<string, string>;
170
170
  get detectBalanceChainSlugMap(): Record<string, string>;
171
171
  getFeeTokensByChain(chainSlug: string): string[];
172
+ isUseMetadataToCreateApi(chain: string): Promise<boolean>;
172
173
  }
@@ -11,6 +11,7 @@ import { TonChainHandler } from '@subwallet/extension-base/services/chain-servic
11
11
  import { _CHAIN_VALIDATION_ERROR } from '@subwallet/extension-base/services/chain-service/handler/types';
12
12
  import { _ChainConnectionStatus, _CUSTOM_PREFIX, _NFT_CONTRACT_STANDARDS, _SMART_CONTRACT_STANDARDS } from '@subwallet/extension-base/services/chain-service/types';
13
13
  import { _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 { MYTHOS_MIGRATION_KEY } from '@subwallet/extension-base/services/migration-service/scripts';
14
15
  import AssetSettingStore from '@subwallet/extension-base/stores/AssetSetting';
15
16
  import { addLazy, calculateMetadataHash, fetchStaticData, filterAssetsByChainAndType, getShortMetadata, MODULE_SUPPORT } from '@subwallet/extension-base/utils';
16
17
  import { BehaviorSubject, Subject } from 'rxjs';
@@ -1827,4 +1828,12 @@ export class ChainService {
1827
1828
  return chainAsset.originChain === chainSlug && (chainAsset.assetType === _AssetType.NATIVE || _isAssetCanPayTxFee(chainAsset));
1828
1829
  }).map(chainAsset => chainAsset.slug);
1829
1830
  }
1831
+ async isUseMetadataToCreateApi(chain) {
1832
+ const isMythos = ['mythos', 'muse_testnet'].includes(chain);
1833
+ if (isMythos) {
1834
+ return this.dbService.hasRunScript(MYTHOS_MIGRATION_KEY);
1835
+ } else {
1836
+ return true;
1837
+ }
1838
+ }
1830
1839
  }
@@ -13,6 +13,7 @@ export declare const _STAKING_CHAIN_GROUP: {
13
13
  krest_network: string[];
14
14
  manta: string[];
15
15
  bittensor: string[];
16
+ mythos: string[];
16
17
  };
17
18
  export declare const TON_CHAINS: string[];
18
19
  export declare const MaxEraRewardPointsEras = 14;
@@ -17,7 +17,8 @@ export const _STAKING_CHAIN_GROUP = {
17
17
  lending: ['interlay'],
18
18
  krest_network: ['krest_network'],
19
19
  manta: ['manta_network'],
20
- bittensor: ['bittensor', 'bittensor_devnet']
20
+ bittensor: ['bittensor', 'bittensor_devnet'],
21
+ mythos: ['mythos', 'muse_testnet']
21
22
  };
22
23
  export const TON_CHAINS = ['ton', 'ton_testnet'];
23
24
  export const MaxEraRewardPointsEras = 14;
@@ -0,0 +1,35 @@
1
+ import { _ChainInfo } from '@subwallet/chain-list/types';
2
+ import { ExtrinsicType, NominationInfo } from '@subwallet/extension-base/background/KoniTypes';
3
+ import { _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
4
+ import BaseParaStakingPoolHandler from '@subwallet/extension-base/services/earning-service/handlers/native-staking/base-para';
5
+ import { EarningRewardItem, EarningStatus, SubmitJoinNativeStaking, TransactionData, UnstakingInfo, ValidatorInfo, YieldPoolInfo, YieldPoolMethodInfo, YieldPositionInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
6
+ import { SubmittableExtrinsic } from '@polkadot/api/types';
7
+ interface PalletCollatorStakingUserStakeInfo {
8
+ stake: string;
9
+ maybeLastUnstake: string[];
10
+ candidates: string[];
11
+ maybeLastRewardSession: string;
12
+ }
13
+ export default class MythosNativeStakingPoolHandler extends BaseParaStakingPoolHandler {
14
+ protected readonly availableMethod: YieldPoolMethodInfo;
15
+ subscribePoolInfo(callback: (data: YieldPoolInfo) => void): Promise<VoidFunction>;
16
+ subscribePoolPosition(useAddresses: string[], resultCallback: (rs: YieldPositionInfo) => void): Promise<VoidFunction>;
17
+ parseCollatorMetadata(chainInfo: _ChainInfo, stakerAddress: string, substrateApi: _SubstrateApi, userStake: PalletCollatorStakingUserStakeInfo): Promise<{
18
+ status: EarningStatus;
19
+ balanceToken: string;
20
+ totalStake: string;
21
+ activeStake: string;
22
+ unstakeBalance: string;
23
+ isBondedBefore: boolean;
24
+ nominations: NominationInfo[];
25
+ unstakings: UnstakingInfo[];
26
+ }>;
27
+ getPoolTargets(): Promise<ValidatorInfo[]>;
28
+ createJoinExtrinsic(data: SubmitJoinNativeStaking, positionInfo?: YieldPositionInfo): Promise<[TransactionData, YieldTokenBaseInfo]>;
29
+ handleYieldUnstake(amount: string, address: string, selectedTarget?: string): Promise<[ExtrinsicType, TransactionData]>;
30
+ getPoolReward(useAddresses: string[], callback: (rs: EarningRewardItem) => void): Promise<VoidFunction>;
31
+ handleYieldCancelUnstake(): Promise<never>;
32
+ handleYieldWithdraw(address: string, unstakingInfo: UnstakingInfo): Promise<SubmittableExtrinsic<"promise", import("@polkadot/types/types").ISubmittableResult>>;
33
+ handleYieldClaimReward(address: string, bondReward?: boolean): Promise<SubmittableExtrinsic<"promise", import("@polkadot/types/types").ISubmittableResult>>;
34
+ }
35
+ export {};
@@ -0,0 +1,329 @@
1
+ // Copyright 2019-2022 @subwallet/extension-base
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
5
+ import { APIItemState, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
6
+ import { getCommission } from '@subwallet/extension-base/koni/api/staking/bonding/utils';
7
+ import { _EXPECTED_BLOCK_TIME, _STAKING_ERA_LENGTH_MAP } from '@subwallet/extension-base/services/chain-service/constants';
8
+ import BaseParaStakingPoolHandler from '@subwallet/extension-base/services/earning-service/handlers/native-staking/base-para';
9
+ import { BasicTxErrorType, EarningStatus, UnstakingStatus } from '@subwallet/extension-base/types';
10
+ import { balanceFormatter, formatNumber, reformatAddress } from '@subwallet/extension-base/utils';
11
+ export default class MythosNativeStakingPoolHandler extends BaseParaStakingPoolHandler {
12
+ availableMethod = {
13
+ join: true,
14
+ defaultUnstake: true,
15
+ fastUnstake: false,
16
+ cancelUnstake: false,
17
+ withdraw: true,
18
+ claimReward: true
19
+ };
20
+
21
+ /* Subscribe pool info */
22
+
23
+ async subscribePoolInfo(callback) {
24
+ let cancel = false;
25
+ const substrateApi = this.substrateApi;
26
+ const nativeToken = this.nativeToken;
27
+ const defaultCallback = async () => {
28
+ const data = {
29
+ ...this.baseInfo,
30
+ type: this.type,
31
+ metadata: {
32
+ ...this.metadataInfo,
33
+ description: this.getDescription()
34
+ }
35
+ };
36
+ const poolInfo = await this.getPoolInfo();
37
+ !poolInfo && callback(data);
38
+ };
39
+ if (!this.isActive) {
40
+ await defaultCallback();
41
+ return () => {
42
+ cancel = true;
43
+ };
44
+ }
45
+ await defaultCallback();
46
+ await substrateApi.isReady;
47
+ const unsub = await substrateApi.api.query.collatorStaking.currentSession(async _session => {
48
+ if (cancel) {
49
+ unsub();
50
+ return;
51
+ }
52
+ const currentSession = _session.toString();
53
+ const maxStakers = substrateApi.api.consts.collatorStaking.maxStakers.toString();
54
+ const unstakeDelay = substrateApi.api.consts.collatorStaking.stakeUnlockDelay.toString();
55
+ const maxStakedCandidates = substrateApi.api.consts.collatorStaking.maxStakedCandidates.toString();
56
+ const sessionTime = _STAKING_ERA_LENGTH_MAP[this.chain] || _STAKING_ERA_LENGTH_MAP.default; // in hours
57
+ const blockTime = _EXPECTED_BLOCK_TIME[this.chain];
58
+ const unstakingPeriod = parseInt(unstakeDelay) * blockTime / 60 / 60;
59
+ const _minStake = await substrateApi.api.query.collatorStaking.minStake();
60
+ const minStake = _minStake.toString();
61
+ const minStakeToHuman = formatNumber(minStake, nativeToken.decimals || 0, balanceFormatter);
62
+ const data = {
63
+ ...this.baseInfo,
64
+ type: this.type,
65
+ metadata: {
66
+ ...this.metadataInfo,
67
+ description: this.getDescription(minStakeToHuman)
68
+ },
69
+ statistic: {
70
+ assetEarning: [{
71
+ slug: this.nativeToken.slug
72
+ }],
73
+ maxCandidatePerFarmer: parseInt(maxStakedCandidates),
74
+ maxWithdrawalRequestPerFarmer: 3,
75
+ earningThreshold: {
76
+ join: minStake,
77
+ defaultUnstake: '0',
78
+ fastUnstake: '0'
79
+ },
80
+ era: parseInt(currentSession),
81
+ eraTime: sessionTime,
82
+ unstakingPeriod: unstakingPeriod,
83
+ totalApy: undefined
84
+ // tvl: totalStake.toString(),
85
+ // inflation
86
+ },
87
+
88
+ maxPoolMembers: parseInt(maxStakers)
89
+ };
90
+ callback(data);
91
+ });
92
+ return () => {
93
+ cancel = true;
94
+ unsub();
95
+ };
96
+ }
97
+
98
+ /* Subscribe pool info */
99
+
100
+ /* Subscribe pool position */
101
+
102
+ async subscribePoolPosition(useAddresses, resultCallback) {
103
+ let cancel = false;
104
+ const substrateApi = await this.substrateApi.isReady;
105
+ const defaultInfo = this.baseInfo;
106
+ const unsub = await substrateApi.api.query.collatorStaking.userStake.multi(useAddresses, async userStakes => {
107
+ if (cancel) {
108
+ unsub();
109
+ return;
110
+ }
111
+ if (userStakes) {
112
+ await Promise.all(userStakes.map(async (_userStake, i) => {
113
+ const userStake = _userStake.toPrimitive();
114
+ const owner = reformatAddress(useAddresses[i], 42);
115
+ if (userStake) {
116
+ const nominatorMetadata = await this.parseCollatorMetadata(this.chainInfo, useAddresses[i], substrateApi, userStake);
117
+ resultCallback({
118
+ ...defaultInfo,
119
+ ...nominatorMetadata,
120
+ address: owner,
121
+ type: this.type
122
+ });
123
+ } else {
124
+ resultCallback({
125
+ ...defaultInfo,
126
+ type: this.type,
127
+ address: owner,
128
+ balanceToken: this.nativeToken.slug,
129
+ totalStake: '0',
130
+ activeStake: '0',
131
+ unstakeBalance: '0',
132
+ status: EarningStatus.NOT_STAKING,
133
+ isBondedBefore: false,
134
+ nominations: [],
135
+ unstakings: []
136
+ });
137
+ }
138
+ }));
139
+ }
140
+ });
141
+ return () => {
142
+ cancel = true;
143
+ unsub();
144
+ };
145
+ }
146
+ async parseCollatorMetadata(chainInfo, stakerAddress, substrateApi, userStake) {
147
+ const nominationList = [];
148
+ const unstakingList = [];
149
+ let unstakingBalance = BigInt(0);
150
+ const {
151
+ candidates,
152
+ stake
153
+ } = userStake;
154
+ const [_minStake, _unstaking, _currentBlock, _currentTimestamp] = await Promise.all([substrateApi.api.query.collatorStaking.minStake(), substrateApi.api.query.collatorStaking.releaseQueues(stakerAddress), substrateApi.api.query.system.number(), substrateApi.api.query.timestamp.now()]);
155
+ const minStake = _minStake.toPrimitive();
156
+ const stakingStatus = candidates && !!candidates.length ? EarningStatus.EARNING_REWARD : EarningStatus.NOT_EARNING;
157
+ const isBondedBefore = candidates && !!candidates.length;
158
+ const unstakings = _unstaking.toPrimitive();
159
+ const currentBlock = _currentBlock.toPrimitive();
160
+ const currentTimestamp = _currentTimestamp.toPrimitive();
161
+ const blockDuration = _EXPECTED_BLOCK_TIME[chainInfo.slug];
162
+ if (candidates.length) {
163
+ await Promise.all(candidates.map(async collatorAddress => {
164
+ const _stakeInfo = await substrateApi.api.query.collatorStaking.candidateStake(collatorAddress, stakerAddress);
165
+ const stakeInfo = _stakeInfo.toPrimitive();
166
+ const activeStake = stakeInfo.stake.toString();
167
+ const earningStatus = BigInt(activeStake) > BigInt(0) && BigInt(activeStake) >= BigInt(minStake) ? EarningStatus.EARNING_REWARD : EarningStatus.NOT_EARNING;
168
+ nominationList.push({
169
+ status: earningStatus,
170
+ chain: chainInfo.slug,
171
+ validatorAddress: collatorAddress,
172
+ activeStake,
173
+ validatorMinStake: minStake,
174
+ hasUnstaking: !!unstakings.length
175
+ });
176
+ }));
177
+ }
178
+ if (unstakings.length) {
179
+ unstakings.forEach(unstaking => {
180
+ const releaseBlock = unstaking.block;
181
+ const unstakeAmount = unstaking.amount;
182
+ const isClaimable = currentBlock >= releaseBlock;
183
+ const targetTimestampMs = (releaseBlock - currentBlock) * blockDuration * 1000 + currentTimestamp;
184
+ unstakingBalance = unstakingBalance + BigInt(unstakeAmount);
185
+ unstakingList.push({
186
+ chain: chainInfo.slug,
187
+ status: isClaimable ? UnstakingStatus.CLAIMABLE : UnstakingStatus.UNLOCKING,
188
+ claimable: unstakeAmount,
189
+ targetTimestampMs
190
+ });
191
+ });
192
+ }
193
+ return {
194
+ status: stakingStatus,
195
+ balanceToken: this.nativeToken.slug,
196
+ totalStake: (BigInt(stake) + unstakingBalance).toString(),
197
+ activeStake: stake,
198
+ unstakeBalance: unstakingBalance.toString() || '0',
199
+ isBondedBefore: isBondedBefore,
200
+ nominations: nominationList,
201
+ unstakings: unstakingList
202
+ };
203
+ }
204
+
205
+ /* Subscribe pool position */
206
+
207
+ /* Get pool targets */
208
+
209
+ async getPoolTargets() {
210
+ const substrateApi = await this.substrateApi.isReady;
211
+ const [_allCollators, _minStake, _commission] = await Promise.all([substrateApi.api.query.collatorStaking.candidates.entries(), substrateApi.api.query.collatorStaking.minStake(), substrateApi.api.query.collatorStaking.collatorRewardPercentage()]);
212
+ const maxStakersPerCollator = substrateApi.api.consts.collatorStaking.maxStakers.toPrimitive();
213
+ return _allCollators.map(_collator => {
214
+ const _collatorAddress = _collator[0].toHuman();
215
+ const collatorAddress = _collatorAddress[0];
216
+ const collatorInfo = _collator[1].toPrimitive();
217
+ const bnTotalStake = BigInt(collatorInfo.stake);
218
+ const numOfStakers = parseInt(collatorInfo.stakers);
219
+ const isCrowded = numOfStakers >= maxStakersPerCollator;
220
+ return {
221
+ address: collatorAddress,
222
+ chain: this.chain,
223
+ totalStake: bnTotalStake.toString(),
224
+ ownStake: '0',
225
+ otherStake: bnTotalStake.toString(),
226
+ minBond: _minStake.toPrimitive(),
227
+ nominatorCount: numOfStakers,
228
+ commission: getCommission(_commission.toString()),
229
+ blocked: false,
230
+ isVerified: false,
231
+ isCrowded
232
+ };
233
+ });
234
+ }
235
+
236
+ /* Get pool targets */
237
+
238
+ /* Join pool action */
239
+
240
+ async createJoinExtrinsic(data, positionInfo) {
241
+ var _substrateApi$api$cal, _substrateApi$api$cal2;
242
+ const substrateApi = await this.substrateApi.isReady;
243
+ const {
244
+ address,
245
+ amount,
246
+ selectedValidators
247
+ } = data;
248
+ const selectedValidatorInfo = selectedValidators[0];
249
+ const _hasReward = await ((_substrateApi$api$cal = substrateApi.api.call) === null || _substrateApi$api$cal === void 0 ? void 0 : (_substrateApi$api$cal2 = _substrateApi$api$cal.collatorStakingApi) === null || _substrateApi$api$cal2 === void 0 ? void 0 : _substrateApi$api$cal2.shouldClaim(address));
250
+ const hasReward = _hasReward === null || _hasReward === void 0 ? void 0 : _hasReward.toPrimitive();
251
+ const extrinsicList = [];
252
+ if (positionInfo !== null && positionInfo !== void 0 && positionInfo.isBondedBefore && hasReward) {
253
+ extrinsicList.push(substrateApi.api.tx.collatorStaking.claimRewards());
254
+ }
255
+ extrinsicList.push(...[substrateApi.api.tx.collatorStaking.lock(amount), substrateApi.api.tx.collatorStaking.stake([{
256
+ candidate: selectedValidatorInfo.address,
257
+ stake: amount
258
+ }])]);
259
+ return [substrateApi.api.tx.utility.batchAll(extrinsicList), {
260
+ slug: this.nativeToken.slug,
261
+ amount: '0'
262
+ }];
263
+ }
264
+
265
+ /* Join pool action */
266
+
267
+ /* Leave pool action */
268
+
269
+ async handleYieldUnstake(amount, address, selectedTarget) {
270
+ var _substrateApi$api$cal3, _substrateApi$api$cal4;
271
+ const substrateApi = await this.substrateApi.isReady;
272
+ const _hasReward = await ((_substrateApi$api$cal3 = substrateApi.api.call) === null || _substrateApi$api$cal3 === void 0 ? void 0 : (_substrateApi$api$cal4 = _substrateApi$api$cal3.collatorStakingApi) === null || _substrateApi$api$cal4 === void 0 ? void 0 : _substrateApi$api$cal4.shouldClaim(address));
273
+ const hasReward = _hasReward === null || _hasReward === void 0 ? void 0 : _hasReward.toPrimitive();
274
+ const extrinsicList = [];
275
+ if (hasReward) {
276
+ extrinsicList.push(substrateApi.api.tx.collatorStaking.claimRewards());
277
+ }
278
+ extrinsicList.push(...[substrateApi.api.tx.collatorStaking.unstakeFrom(selectedTarget), substrateApi.api.tx.collatorStaking.unlock(null) // ignore amount to unlock all
279
+ ]);
280
+
281
+ return [ExtrinsicType.STAKING_UNBOND, substrateApi.api.tx.utility.batchAll(extrinsicList)];
282
+ }
283
+
284
+ /* Leave pool action */
285
+
286
+ /* Get pool reward */
287
+ async getPoolReward(useAddresses, callback) {
288
+ let cancel = false;
289
+ const substrateApi = this.substrateApi;
290
+ await substrateApi.isReady;
291
+ if (substrateApi.api.call.collatorStakingApi) {
292
+ await Promise.all(useAddresses.map(async address => {
293
+ if (!cancel) {
294
+ const _unclaimedReward = await substrateApi.api.call.collatorStakingApi.totalRewards(address);
295
+ const earningRewardItem = {
296
+ ...this.baseInfo,
297
+ address: address,
298
+ type: this.type,
299
+ unclaimedReward: (_unclaimedReward === null || _unclaimedReward === void 0 ? void 0 : _unclaimedReward.toString()) || '0',
300
+ state: APIItemState.READY
301
+ };
302
+ if (_unclaimedReward.toString() !== '0') {
303
+ await this.createClaimNotification(earningRewardItem, this.nativeToken);
304
+ }
305
+ callback(earningRewardItem);
306
+ }
307
+ }));
308
+ }
309
+ return () => {
310
+ cancel = false;
311
+ };
312
+ }
313
+ /* Get pool reward */
314
+
315
+ /* Other action */
316
+
317
+ async handleYieldCancelUnstake() {
318
+ return Promise.reject(new TransactionError(BasicTxErrorType.UNSUPPORTED));
319
+ }
320
+ async handleYieldWithdraw(address, unstakingInfo) {
321
+ const substrateApi = await this.substrateApi.isReady;
322
+ return substrateApi.api.tx.collatorStaking.release();
323
+ }
324
+ async handleYieldClaimReward(address, bondReward) {
325
+ const substrateApi = await this.substrateApi.isReady;
326
+ return substrateApi.api.tx.collatorStaking.claimRewards();
327
+ }
328
+ /* Other action */
329
+ }
@@ -8,6 +8,7 @@ import { ServiceStatus } from '@subwallet/extension-base/services/base/types';
8
8
  import { _isChainEnabled, _isChainEvmCompatible } from '@subwallet/extension-base/services/chain-service/utils';
9
9
  import { _STAKING_CHAIN_GROUP } from '@subwallet/extension-base/services/earning-service/constants';
10
10
  import BaseLiquidStakingPoolHandler from '@subwallet/extension-base/services/earning-service/handlers/liquid-staking/base';
11
+ import MythosNativeStakingPoolHandler from '@subwallet/extension-base/services/earning-service/handlers/native-staking/mythos';
11
12
  import { BasicTxErrorType, YieldPoolType } from '@subwallet/extension-base/types';
12
13
  import { addLazy, categoryAddresses, createPromiseHandler, removeLazy } from '@subwallet/extension-base/utils';
13
14
  import { fetchStaticCache } from '@subwallet/extension-base/utils/fetchStaticCache';
@@ -68,6 +69,9 @@ export default class EarningService {
68
69
  if (_STAKING_CHAIN_GROUP.bittensor.includes(chain)) {
69
70
  handlers.push(new TaoNativeStakingPoolHandler(this.state, chain));
70
71
  }
72
+ if (_STAKING_CHAIN_GROUP.mythos.includes(chain)) {
73
+ handlers.push(new MythosNativeStakingPoolHandler(this.state, chain));
74
+ }
71
75
  if (_STAKING_CHAIN_GROUP.nominationPool.includes(chain)) {
72
76
  handlers.push(new NominationPoolHandler(this.state, chain));
73
77
  }
@@ -105,6 +105,8 @@ export function isActionFromValidator(stakingType, chain) {
105
105
  return true;
106
106
  } else if (_STAKING_CHAIN_GROUP.bittensor.includes(chain)) {
107
107
  return true;
108
+ } else if (_STAKING_CHAIN_GROUP.mythos.includes(chain)) {
109
+ return true;
108
110
  }
109
111
  return false;
110
112
  }
@@ -1,4 +1,4 @@
1
- import BaseMigrationJob from '@subwallet/extension-base/services/migration-service/Base';
2
- export default class ClearMetadataDatabase extends BaseMigrationJob {
3
- run(): Promise<void>;
1
+ import ClearMetadataForChains from './ClearMetadataForChains';
2
+ export default class ClearMetadataDatabase extends ClearMetadataForChains {
3
+ chains: string[];
4
4
  }
@@ -1,27 +1,7 @@
1
1
  // Copyright 2019-2022 @subwallet/extension-koni authors & contributors
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- import BaseMigrationJob from '@subwallet/extension-base/services/migration-service/Base';
5
- import { cacheMetadata, waitTimeout } from '@subwallet/extension-base/utils';
6
- export default class ClearMetadataDatabase extends BaseMigrationJob {
7
- async run() {
8
- // Clear all old metadata data
9
- await this.state.dbService.stores.metadata.clear();
10
- const activeChains = this.state.chainService.getActiveChains();
11
- const chainInfoMap = this.state.chainService.getChainInfoMap();
12
- const reloadChains = activeChains.filter(chain => {
13
- var _chainInfoMap$chain$s;
14
- return !!((_chainInfoMap$chain$s = chainInfoMap[chain].substrateInfo) !== null && _chainInfoMap$chain$s !== void 0 && _chainInfoMap$chain$s.genesisHash);
15
- });
16
- for (const chain of reloadChains) {
17
- const substrateApi = this.state.chainService.getSubstrateApi(chain);
18
- const callback = substrateApi => {
19
- cacheMetadata(chain, substrateApi, this.state.chainService);
20
- };
21
- Promise.race([substrateApi.isReady, waitTimeout(2000)]).finally(() => {
22
- substrateApi === null || substrateApi === void 0 ? void 0 : substrateApi.connect(callback);
23
- });
24
- }
25
- return Promise.resolve();
26
- }
4
+ import ClearMetadataForChains from "./ClearMetadataForChains.js";
5
+ export default class ClearMetadataDatabase extends ClearMetadataForChains {
6
+ chains = [];
27
7
  }
@@ -0,0 +1,5 @@
1
+ import BaseMigrationJob from '@subwallet/extension-base/services/migration-service/Base';
2
+ export default abstract class ClearMetadataForChains extends BaseMigrationJob {
3
+ protected abstract chains: string[];
4
+ run(): Promise<void>;
5
+ }