@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.
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/chain-service/constants.js +8 -3
- package/cjs/services/chain-service/handler/SubstrateChainHandler.js +3 -2
- package/cjs/services/chain-service/index.js +9 -0
- package/cjs/services/earning-service/constants/chains.js +2 -1
- package/cjs/services/earning-service/handlers/native-staking/mythos.js +337 -0
- package/cjs/services/earning-service/service.js +4 -0
- package/cjs/services/earning-service/utils/index.js +2 -0
- package/cjs/services/migration-service/scripts/databases/ClearMetadataDatabase.js +3 -23
- package/cjs/services/migration-service/scripts/databases/ClearMetadataForChains.js +40 -0
- package/cjs/services/migration-service/scripts/databases/ClearMetadataForMythos.js +15 -0
- package/cjs/services/migration-service/scripts/index.js +6 -2
- package/cjs/services/storage-service/DatabaseService.js +3 -0
- package/cjs/services/storage-service/db-stores/Metadata.js +3 -0
- package/cjs/services/storage-service/db-stores/Migration.js +6 -1
- package/package.json +36 -21
- package/packageInfo.js +1 -1
- package/services/chain-service/constants.js +8 -3
- package/services/chain-service/handler/SubstrateChainHandler.js +3 -2
- package/services/chain-service/index.d.ts +1 -0
- package/services/chain-service/index.js +9 -0
- package/services/earning-service/constants/chains.d.ts +1 -0
- package/services/earning-service/constants/chains.js +2 -1
- package/services/earning-service/handlers/native-staking/mythos.d.ts +35 -0
- package/services/earning-service/handlers/native-staking/mythos.js +329 -0
- package/services/earning-service/service.js +4 -0
- package/services/earning-service/utils/index.js +2 -0
- package/services/migration-service/scripts/databases/ClearMetadataDatabase.d.ts +3 -3
- package/services/migration-service/scripts/databases/ClearMetadataDatabase.js +3 -23
- package/services/migration-service/scripts/databases/ClearMetadataForChains.d.ts +5 -0
- package/services/migration-service/scripts/databases/ClearMetadataForChains.js +32 -0
- package/services/migration-service/scripts/databases/ClearMetadataForMythos.d.ts +4 -0
- package/services/migration-service/scripts/databases/ClearMetadataForMythos.js +7 -0
- package/services/migration-service/scripts/index.d.ts +1 -0
- package/services/migration-service/scripts/index.js +4 -1
- package/services/storage-service/DatabaseService.d.ts +1 -0
- package/services/storage-service/DatabaseService.js +3 -0
- package/services/storage-service/db-stores/Metadata.d.ts +1 -0
- package/services/storage-service/db-stores/Metadata.js +3 -0
- package/services/storage-service/db-stores/Migration.d.ts +1 -0
- 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.
|
|
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.
|
|
2563
|
-
"@polkadot/api-base": "^15.
|
|
2564
|
-
"@polkadot/api-contract": "^15.
|
|
2565
|
-
"@polkadot/api-derive": "^15.
|
|
2566
|
-
"@polkadot/apps-config": "^0.
|
|
2567
|
-
"@polkadot/hw-ledger": "^
|
|
2568
|
-
"@polkadot/networks": "^13.
|
|
2569
|
-
"@polkadot/phishing": "^0.
|
|
2570
|
-
"@polkadot/rpc-provider": "^15.
|
|
2571
|
-
"@polkadot/types": "^15.
|
|
2572
|
-
"@polkadot/types-augment": "^15.
|
|
2573
|
-
"@polkadot/types-known": "^15.
|
|
2574
|
-
"@polkadot/ui-settings": "^3.
|
|
2575
|
-
"@polkadot/util": "^13.
|
|
2576
|
-
"@polkadot/util-crypto": "^13.
|
|
2577
|
-
"@polkadot/x-global": "^
|
|
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.
|
|
2583
|
-
"@subwallet/extension-chains": "^1.3.
|
|
2584
|
-
"@subwallet/extension-dapp": "^1.3.
|
|
2585
|
-
"@subwallet/extension-inject": "^1.3.
|
|
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.
|
|
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
|
|
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
|
}
|
|
@@ -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
|
|
2
|
-
export default class ClearMetadataDatabase extends
|
|
3
|
-
|
|
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
|
|
5
|
-
|
|
6
|
-
|
|
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
|
}
|