@subwallet/extension-base 1.3.74-1 → 1.3.76-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 (39) hide show
  1. package/background/KoniTypes.d.ts +9 -1
  2. package/background/KoniTypes.js +1 -0
  3. package/cjs/background/KoniTypes.js +1 -0
  4. package/cjs/constants/environment.js +4 -2
  5. package/cjs/koni/background/handlers/Extension.js +70 -37
  6. package/cjs/koni/background/handlers/State.js +82 -0
  7. package/cjs/packageInfo.js +1 -1
  8. package/cjs/services/balance-service/index.js +6 -1
  9. package/cjs/services/chain-service/index.js +1 -1
  10. package/cjs/services/earning-service/handlers/native-staking/dtao.js +85 -113
  11. package/cjs/services/earning-service/handlers/native-staking/tanssi.js +2 -1
  12. package/cjs/services/earning-service/handlers/native-staking/tao.js +85 -100
  13. package/cjs/services/earning-service/service.js +17 -2
  14. package/cjs/services/subscan-service/index.js +34 -6
  15. package/cjs/services/substrate-proxy-service/constant.js +1 -1
  16. package/cjs/utils/account/transform.js +3 -3
  17. package/constants/environment.d.ts +1 -0
  18. package/constants/environment.js +2 -1
  19. package/koni/background/handlers/Extension.d.ts +3 -0
  20. package/koni/background/handlers/Extension.js +33 -1
  21. package/koni/background/handlers/State.d.ts +5 -0
  22. package/koni/background/handlers/State.js +82 -0
  23. package/package.json +6 -6
  24. package/packageInfo.js +1 -1
  25. package/services/balance-service/index.js +6 -1
  26. package/services/chain-service/index.js +1 -1
  27. package/services/earning-service/handlers/native-staking/dtao.d.ts +2 -10
  28. package/services/earning-service/handlers/native-staking/dtao.js +86 -116
  29. package/services/earning-service/handlers/native-staking/tanssi.js +2 -1
  30. package/services/earning-service/handlers/native-staking/tao.d.ts +4 -3
  31. package/services/earning-service/handlers/native-staking/tao.js +84 -101
  32. package/services/earning-service/service.d.ts +2 -1
  33. package/services/earning-service/service.js +17 -2
  34. package/services/subscan-service/index.d.ts +2 -0
  35. package/services/subscan-service/index.js +33 -5
  36. package/services/substrate-proxy-service/constant.js +1 -1
  37. package/types/yield/actions/join/submit.d.ts +8 -1
  38. package/types/yield/info/account/info.d.ts +11 -5
  39. package/utils/account/transform.js +3 -3
@@ -6,4 +6,5 @@ const branchName = process.env.BRANCH_NAME || 'subwallet-dev';
6
6
  export const APP_VERSION = process.env.PKG_VERSION || '';
7
7
  export const isProductionMode = PRODUCTION_BRANCHES.indexOf(branchName) > -1;
8
8
  export const BACKEND_API_URL = process.env.SUBWALLET_API || (isProductionMode ? 'https://sw-services.subwallet.app/api' : 'https://be-dev.subwallet.app/api');
9
- export const SW_EXTERNAL_SERVICES_API = process.env.SW_EXTERNAL_SERVICES_API || (isProductionMode ? 'https://external-services.subwallet.app' : 'https://external-services-dev.subwallet.app');
9
+ export const SW_EXTERNAL_SERVICES_API = process.env.SW_EXTERNAL_SERVICES_API || (isProductionMode ? 'https://external-services.subwallet.app' : 'https://external-services-dev.subwallet.app');
10
+ export const SUBSCAN_GATEWAY_URL = process.env.SUBSCAN_GATEWAY_URL || 'https://gateway-dev.konistudio.xyz';
@@ -225,6 +225,8 @@ export default class KoniExtension {
225
225
  private saveAppConfig;
226
226
  private saveBrowserConfig;
227
227
  private saveOSConfig;
228
+ private saveSubscanApiKey;
229
+ private getSubscanApiKey;
228
230
  private connectWalletConnect;
229
231
  private connectWCSubscribe;
230
232
  private approveWalletConnectSession;
@@ -263,6 +265,7 @@ export default class KoniExtension {
263
265
  private yieldSubmitClaimReward;
264
266
  private yieldGetEarningImpact;
265
267
  private handleYieldChangeValidator;
268
+ private handleChangeBittensorRootClaimType;
266
269
  private unlockDotCheckCanMint;
267
270
  private unlockDotSubscribeMintedData;
268
271
  private subscribeProcessingBanner;
@@ -3806,6 +3806,14 @@ export default class KoniExtension {
3806
3806
  this.#koniState.saveEnvConfig('osConfig', request.osConfig);
3807
3807
  return true;
3808
3808
  }
3809
+ async saveSubscanApiKey({
3810
+ apiKey
3811
+ }) {
3812
+ return await this.#koniState.saveSubscanApiKey(apiKey);
3813
+ }
3814
+ async getSubscanApiKey() {
3815
+ return await this.#koniState.getSubscanApiKey();
3816
+ }
3809
3817
 
3810
3818
  /// Wallet connect
3811
3819
 
@@ -4500,7 +4508,25 @@ export default class KoniExtension {
4500
4508
  chainType: ChainType.SUBSTRATE
4501
4509
  });
4502
4510
  }
4503
-
4511
+ async handleChangeBittensorRootClaimType(params) {
4512
+ const {
4513
+ address,
4514
+ slug
4515
+ } = params;
4516
+ const poolHandler = this.#koniState.earningService.getPoolHandler(slug);
4517
+ if (!poolHandler) {
4518
+ return this.#koniState.transactionService.generateBeforeHandleResponseErrors([new TransactionError(BasicTxErrorType.INVALID_PARAMS)]);
4519
+ }
4520
+ const extrinsic = await this.#koniState.earningService.handleChangeRootClaimType(params);
4521
+ return await this.#koniState.transactionService.handleTransaction({
4522
+ address,
4523
+ chain: poolHandler.chain,
4524
+ transaction: extrinsic,
4525
+ data: params,
4526
+ extrinsicType: ExtrinsicType.CHANGE_BITTENSOR_ROOT_CLAIM_TYPE,
4527
+ chainType: ChainType.SUBSTRATE
4528
+ });
4529
+ }
4504
4530
  /* Campaign */
4505
4531
 
4506
4532
  unlockDotCheckCanMint({
@@ -5482,6 +5508,8 @@ export default class KoniExtension {
5482
5508
  return await this.yieldGetEarningImpact(request);
5483
5509
  case 'pri(yield.changeValidator.submit)':
5484
5510
  return await this.handleYieldChangeValidator(request);
5511
+ case 'pri(yield.changeBittensorRootClaimType.submit)':
5512
+ return await this.handleChangeBittensorRootClaimType(request);
5485
5513
  /* Others */
5486
5514
 
5487
5515
  /* Actions */
@@ -5741,6 +5769,10 @@ export default class KoniExtension {
5741
5769
  return this.saveBrowserConfig(request);
5742
5770
  case 'pri(settings.saveOSConfig)':
5743
5771
  return this.saveOSConfig(request);
5772
+ case 'pri(settings.saveSubscanApiKey)':
5773
+ return await this.saveSubscanApiKey(request);
5774
+ case 'pri(settings.getSubscanApiKey)':
5775
+ return await this.getSubscanApiKey();
5744
5776
 
5745
5777
  /// Keyring state
5746
5778
  case 'pri(keyring.subscribe)':
@@ -252,6 +252,11 @@ export default class KoniState {
252
252
  private onHandleRemindExportAccount;
253
253
  setStorageFromWS({ key, value }: StorageDataInterface): Promise<boolean>;
254
254
  getStorageFromWS(key: string): Promise<string | null>;
255
+ private getExtensionSecret;
256
+ private getSubscanApiCipherPassword;
257
+ saveSubscanApiKey(apiKey: string): Promise<boolean>;
258
+ getSubscanApiKey(): Promise<string | null>;
259
+ private syncSubscanApiKey;
255
260
  onCheckToRemindUser(): void;
256
261
  onInstall(): void;
257
262
  get activeNetworks(): Record<string, _ChainInfo>;
@@ -62,6 +62,8 @@ import { KoniSubscription } from "../subscription.js";
62
62
  // eslint-disable-next-line @typescript-eslint/no-var-requires,@typescript-eslint/no-unsafe-assignment
63
63
  const passworder = require('browser-passworder');
64
64
  const ERROR_CONFIRMATION_TYPE = ['errorConnectNetwork'];
65
+ const SUBSCAN_API_KEY_STORAGE = 'subscan_api_key';
66
+ const SUBSCAN_SECRET_STORAGE = 'subscan_secret';
65
67
 
66
68
  // List of providers passed into constructor. This is the list of providers
67
69
  // exposed by the extension.
@@ -219,6 +221,8 @@ export default class KoniState {
219
221
  }
220
222
  afterChainServiceInit() {
221
223
  this.subscanService.setSubscanChainMap(this.chainService.getSubscanChainMap());
224
+ // Sync Subscan API key
225
+ this.syncSubscanApiKey().catch(console.error);
222
226
  }
223
227
  async init() {
224
228
  await this.eventService.waitCryptoReady;
@@ -1581,6 +1585,84 @@ export default class KoniState {
1581
1585
  return null;
1582
1586
  }
1583
1587
  }
1588
+ async getExtensionSecret() {
1589
+ const result = await SWStorage.instance.getItem(SUBSCAN_SECRET_STORAGE);
1590
+ let secret = result;
1591
+ if (!secret) {
1592
+ secret = crypto.randomUUID();
1593
+ await SWStorage.instance.setItem(SUBSCAN_SECRET_STORAGE, secret);
1594
+ }
1595
+ return secret;
1596
+ }
1597
+
1598
+ // Generate password used to encrypt/decrypt Subscan API key
1599
+ // Password = extensionId + extension secret
1600
+ // -> Bind encrypted data to THIS extension instance
1601
+ // -> Prevent other extensions/apps from decrypting the stored API key
1602
+ async getSubscanApiCipherPassword() {
1603
+ var _chrome, _chrome$runtime;
1604
+ const secret = await this.getExtensionSecret();
1605
+ const extensionId = ((_chrome = chrome) === null || _chrome === void 0 ? void 0 : (_chrome$runtime = _chrome.runtime) === null || _chrome$runtime === void 0 ? void 0 : _chrome$runtime.id) || 'subwallet';
1606
+ return `${extensionId}:${secret}`;
1607
+ }
1608
+ async saveSubscanApiKey(apiKey) {
1609
+ try {
1610
+ // Get cipher password used for encryption
1611
+ const cipherPassword = await this.getSubscanApiCipherPassword();
1612
+
1613
+ // Encrypt API key before saving to storage
1614
+ // -> Avoid storing API key as plain text
1615
+ // -> Prevent leakage if storage is inspected
1616
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
1617
+ const encryptedData = await passworder.encrypt(cipherPassword, {
1618
+ apiKey
1619
+ });
1620
+
1621
+ // Persist encrypted API key to extension storage
1622
+ await SWStorage.instance.setItem(SUBSCAN_API_KEY_STORAGE, JSON.stringify(encryptedData));
1623
+
1624
+ // Sync API key to Subscan service instance
1625
+ // -> Ensure API calls immediately use the latest key
1626
+ await this.syncSubscanApiKey();
1627
+ return true;
1628
+ } catch (e) {
1629
+ console.error(e);
1630
+ return false;
1631
+ }
1632
+ }
1633
+ async getSubscanApiKey() {
1634
+ try {
1635
+ // Read encrypted API key from storage
1636
+ const encryptedData = await SWStorage.instance.getItem(SUBSCAN_API_KEY_STORAGE);
1637
+ if (!encryptedData) {
1638
+ return null;
1639
+ }
1640
+
1641
+ // Recreate cipher password for decryption
1642
+ const cipherPassword = await this.getSubscanApiCipherPassword();
1643
+
1644
+ // Decrypt stored API key
1645
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
1646
+ const decryptedData = await passworder.decrypt(cipherPassword, JSON.parse(encryptedData));
1647
+
1648
+ // Return API key if exists
1649
+ return decryptedData.apiKey || null;
1650
+ } catch (e) {
1651
+ console.error(e);
1652
+ return null;
1653
+ }
1654
+ }
1655
+
1656
+ // Sync decrypted API key to Subscan service
1657
+ // -> Allows service layer to use API key for authenticated requests
1658
+ async syncSubscanApiKey() {
1659
+ try {
1660
+ const apiKey = await this.getSubscanApiKey();
1661
+ this.subscanService.setApiKey(apiKey);
1662
+ } catch (e) {
1663
+ console.error('Failed to sync Subscan API key:', e);
1664
+ }
1665
+ }
1584
1666
  onCheckToRemindUser() {
1585
1667
  this.onHandleRemindExportAccount().catch(console.error);
1586
1668
  }
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "./cjs/detectPackage.js"
18
18
  ],
19
19
  "type": "module",
20
- "version": "1.3.74-1",
20
+ "version": "1.3.76-0",
21
21
  "main": "./cjs/index.js",
22
22
  "module": "./index.js",
23
23
  "types": "./index.d.ts",
@@ -3008,11 +3008,11 @@
3008
3008
  "@sora-substrate/type-definitions": "^1.17.7",
3009
3009
  "@substrate/connect": "^0.8.9",
3010
3010
  "@subwallet-monorepos/subwallet-services-sdk": "0.1.16",
3011
- "@subwallet/chain-list": "0.2.124",
3012
- "@subwallet/extension-base": "^1.3.74-1",
3013
- "@subwallet/extension-chains": "^1.3.74-1",
3014
- "@subwallet/extension-dapp": "^1.3.74-1",
3015
- "@subwallet/extension-inject": "^1.3.74-1",
3011
+ "@subwallet/chain-list": "0.2.125",
3012
+ "@subwallet/extension-base": "^1.3.76-0",
3013
+ "@subwallet/extension-chains": "^1.3.76-0",
3014
+ "@subwallet/extension-dapp": "^1.3.76-0",
3015
+ "@subwallet/extension-inject": "^1.3.76-0",
3016
3016
  "@subwallet/keyring": "^0.1.14",
3017
3017
  "@subwallet/ui-keyring": "^0.1.14",
3018
3018
  "@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.74-1'
10
+ version: '1.3.76-0'
11
11
  };
@@ -795,7 +795,12 @@ export class BalanceService {
795
795
  /** Return token slugs with balance in substrate chain - only work with substrate chains that have subscanSlug **/
796
796
  async getSubstrateTokensBalanceByChain(address, chainSlug, assetsByChain) {
797
797
  const tokenBalanceSlugs = [];
798
- const balanceData = await this.state.subscanService.getMultiChainBalance(address);
798
+
799
+ // Do not block chain enabling flow when balance detection fails.
800
+ const balanceData = await this.state.subscanService.getMultiChainBalance(address).catch(e => {
801
+ console.error(e);
802
+ return [];
803
+ });
799
804
  if (!balanceData) {
800
805
  return [];
801
806
  }
@@ -1418,10 +1418,10 @@ export class ChainService {
1418
1418
  paraId: params.chainSpec.paraId,
1419
1419
  symbol: params.chainEditInfo.symbol,
1420
1420
  genesisHash: params.chainSpec.genesisHash,
1421
+ supportProxy: false,
1421
1422
  relaySlug: null,
1422
1423
  hasNativeNft: false,
1423
1424
  supportStaking: params.chainSpec.paraId === null,
1424
- supportProxy: false,
1425
1425
  supportMultisig: false,
1426
1426
  supportSmartContract: null
1427
1427
  };
@@ -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, RequestEarningImpact, YieldPoolInfo, YieldPoolType, YieldPositionInfo } from '@subwallet/extension-base/types';
3
+ import { BaseYieldPositionInfo, RequestEarningImpact, TransactionData, YieldPoolInfo, YieldPoolType, YieldPositionInfo } from '@subwallet/extension-base/types';
4
4
  import TaoNativeStakingPoolHandler, { TaoStakingStakeOption } from './tao';
5
5
  export interface SubnetData {
6
6
  netuid: number;
@@ -11,15 +11,6 @@ export interface SubnetData {
11
11
  taoIn: number;
12
12
  taoInEmission: number;
13
13
  }
14
- export interface RawDelegateState {
15
- data: Array<{
16
- hotkey_name: string;
17
- hotkey: {
18
- ss58: string;
19
- };
20
- stake: string;
21
- }>;
22
- }
23
14
  export interface EarningImpactResult {
24
15
  slippage: number;
25
16
  rate: number;
@@ -40,4 +31,5 @@ export default class SubnetTaoStakingPoolHandler extends TaoNativeStakingPoolHan
40
31
  subscribePoolInfo(callback: (data: YieldPoolInfo) => void): Promise<VoidFunction>;
41
32
  parseNominatorMetadata(chainInfo: _ChainInfo, delegatorState: TaoStakingStakeOption[], netuid?: number): Promise<Omit<YieldPositionInfo, keyof BaseYieldPositionInfo>>;
42
33
  subscribePoolPosition(useAddresses: string[], rsCallback: (rs: YieldPositionInfo) => void): Promise<VoidFunction>;
34
+ handleChangeRootClaimType(): Promise<TransactionData>;
43
35
  }
@@ -1,57 +1,15 @@
1
1
  // Copyright 2019-2022 @subwallet/extension-base
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
+ import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
4
5
  import { ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
5
6
  import { BITTENSOR_REFRESH_STAKE_APY, BITTENSOR_REFRESH_STAKE_INFO } from '@subwallet/extension-base/constants';
6
- import { EarningStatus, YieldPoolType } from '@subwallet/extension-base/types';
7
+ import { BasicTxErrorType, EarningStatus, YieldPoolType } from '@subwallet/extension-base/types';
7
8
  import { reformatAddress } from '@subwallet/extension-base/utils';
8
9
  import BigN from 'bignumber.js';
9
- import { BN, BN_ZERO } from '@polkadot/util';
10
+ import { BN_ZERO } from '@polkadot/util';
10
11
  import TaoNativeStakingPoolHandler, { DEFAULT_DTAO_MINBOND } from "./tao.js";
11
-
12
- // interface ApiResponse {
13
- // data: SubnetData[];
14
- // }
15
-
16
- // interface PoolData {
17
- // netuid: number;
18
- // name: string;
19
- // symbol: string;
20
- // }
21
-
22
- // interface PoolApiResponse {
23
- // data: PoolData[];
24
- // }
25
-
26
- // const SUBNET_API_URL = 'https://dash.taostats.io/api/subnet';
27
- // const POOL_API_URL = 'https://dash.taostats.io/api/dtao/pool';
28
-
29
- // export async function fetchSubnetData () {
30
- // try {
31
- // const [subnetResponse, poolResponse] = await Promise.all([
32
- // fetch(SUBNET_API_URL).then((res) => res.json()) as Promise<ApiResponse>,
33
- // fetch(POOL_API_URL).then((res) => res.json()) as Promise<PoolApiResponse>
34
- // ]);
35
-
36
- // const poolMap = new Map(poolResponse.data.map((pool) => [pool.netuid, pool]));
37
-
38
- // const filteredSubnets = subnetResponse.data.filter((subnet) => subnet.netuid !== 0);
39
-
40
- // const mergedData = filteredSubnets.map((subnet) => ({
41
- // ...subnet,
42
- // name: poolMap.get(subnet.netuid)?.name || 'Unknown',
43
- // symbol: poolMap.get(subnet.netuid)?.symbol || 'Unknown'
44
- // }));
45
-
46
- // return mergedData;
47
- // } catch (err) {
48
- // console.error('Error:', err);
49
-
50
- // return [];
51
- // }
52
- // }
53
-
54
- const getAlphaToTaoMapping = async substrateApi => {
12
+ const getAlphaToTaoRateMap = async substrateApi => {
55
13
  const allSubnets = (await substrateApi.api.call.subnetInfoRuntimeApi.getAllDynamicInfo()).toJSON();
56
14
  if (!allSubnets || allSubnets.length === 0) {
57
15
  return {};
@@ -244,87 +202,91 @@ export default class SubnetTaoStakingPoolHandler extends TaoNativeStakingPoolHan
244
202
  const chainInfo = this.chainInfo;
245
203
  const _delegateInfo = await this.bittensorCache.get();
246
204
  const getPoolPosition = async () => {
247
- const rawDelegateStateInfos = await Promise.all(useAddresses.map(async address => (await substrateApi.api.call.stakeInfoRuntimeApi.getStakeInfoForColdkey(address)).toJSON()));
248
- const price = await getAlphaToTaoMapping(this.substrateApi);
249
- if (rawDelegateStateInfos && rawDelegateStateInfos.length > 0) {
250
- rawDelegateStateInfos.forEach((rawDelegateStateInfo, i) => {
251
- const owner = reformatAddress(useAddresses[i], 42);
252
- const delegateStateInfo = rawDelegateStateInfo;
253
- const subnetPositions = {};
254
- for (const delegate of delegateStateInfo) {
255
- const hotkey = delegate.hotkey;
256
- const netuid = delegate.netuid;
257
- const stake = new BigN(delegate.stake);
258
- const aplhaToTaoPrice = new BigN(price[netuid]);
259
- if (!subnetPositions[netuid]) {
260
- subnetPositions[netuid] = {
261
- delegatorState: [],
262
- totalBalance: BN_ZERO,
263
- originalTotalStake: BN_ZERO
264
- };
265
- }
266
- let identity = '';
267
- if (_delegateInfo) {
268
- const delegateInfo = _delegateInfo.data.find(info => info.hotkey.ss58 === hotkey);
269
- identity = delegateInfo ? delegateInfo.name : '';
270
- }
271
- subnetPositions[netuid].delegatorState.push({
272
- owner: hotkey,
273
- amount: stake.toString(),
274
- rate: aplhaToTaoPrice,
275
- identity: identity
276
- });
277
- subnetPositions[netuid].totalBalance = subnetPositions[netuid].totalBalance.add(new BN(stake.toString()));
278
- subnetPositions[netuid].originalTotalStake = subnetPositions[netuid].originalTotalStake.add(new BN(stake.toString()));
205
+ const rawDelegateStateInfos = await substrateApi.api.call.stakeInfoRuntimeApi.getStakeInfoForColdkeys(useAddresses);
206
+ const delegateStateInfos = rawDelegateStateInfos.toPrimitive();
207
+ const alphaToTaoRateMap = await getAlphaToTaoRateMap(this.substrateApi);
208
+ if (!delegateStateInfos || delegateStateInfos.length === 0) {
209
+ return;
210
+ }
211
+ delegateStateInfos.forEach(([coldkey, stakeInfos]) => {
212
+ const owner = reformatAddress(coldkey, 42);
213
+ const subnetPositions = {};
214
+ for (const delegate of stakeInfos) {
215
+ const hotkey = delegate.hotkey;
216
+ const netuid = delegate.netuid;
217
+ if (netuid === 0) {
218
+ continue;
219
+ }
220
+ const stake = new BigN(delegate.stake);
221
+ const alphaToTaoPrice = new BigN(alphaToTaoRateMap[netuid]);
222
+ if (!subnetPositions[netuid]) {
223
+ subnetPositions[netuid] = {
224
+ delegatorState: [],
225
+ totalBalance: BigN(0),
226
+ originalTotalStake: BigN(0)
227
+ };
279
228
  }
280
- Object.values(this.subnetData).forEach(subnet => {
281
- const netuid = subnet.netuid;
282
- const subnetSlug = `${this.slug}__subnet_${netuid.toString().padStart(2, '0')}`;
283
- const subnetName = `${subnet.name || 'Unknown'} ${netuid}`;
284
- const subnetSymbol = subnet.symbol || 'dTAO';
285
- const {
286
- delegatorState = [],
287
- originalTotalStake = BN_ZERO
288
- } = subnetPositions[netuid] || {};
289
- if (delegatorState.length > 0) {
290
- this.parseNominatorMetadata(chainInfo, delegatorState, netuid).then(nominatorMetadata => {
291
- rsCallback({
292
- ...defaultInfo,
293
- ...nominatorMetadata,
294
- address: owner,
295
- type: this.type,
296
- slug: subnetSlug,
297
- subnetData: {
298
- subnetSymbol,
299
- subnetShortName: subnetName,
300
- originalTotalStake: originalTotalStake.toString()
301
- }
302
- });
303
- }).catch(console.error);
304
- } else {
229
+ let identity = '';
230
+ if (_delegateInfo) {
231
+ const delegateInfo = _delegateInfo.data.find(info => info.hotkey.ss58 === hotkey);
232
+ identity = delegateInfo ? delegateInfo.name : '';
233
+ }
234
+ subnetPositions[netuid].delegatorState.push({
235
+ owner: hotkey,
236
+ amount: stake.toString(),
237
+ rate: alphaToTaoPrice,
238
+ identity
239
+ });
240
+ subnetPositions[netuid].totalBalance = subnetPositions[netuid].totalBalance.plus(new BigN(stake.toString()));
241
+ subnetPositions[netuid].originalTotalStake = subnetPositions[netuid].originalTotalStake.plus(new BigN(stake.toString()));
242
+ }
243
+ Object.values(this.subnetData).forEach(subnet => {
244
+ const netuid = subnet.netuid;
245
+ const subnetSlug = `${this.slug}__subnet_${netuid.toString().padStart(2, '0')}`;
246
+ const subnetName = `${subnet.name || 'Unknown'} ${netuid}`;
247
+ const subnetSymbol = subnet.symbol || 'dTAO';
248
+ const {
249
+ delegatorState = [],
250
+ originalTotalStake = BN_ZERO
251
+ } = subnetPositions[netuid] || {};
252
+ if (delegatorState.length > 0) {
253
+ this.parseNominatorMetadata(chainInfo, delegatorState, netuid).then(nominatorMetadata => {
305
254
  rsCallback({
306
255
  ...defaultInfo,
307
- type: this.type,
256
+ ...nominatorMetadata,
308
257
  address: owner,
309
- balanceToken: this.nativeToken.slug,
310
- totalStake: '0',
311
- activeStake: '0',
312
- unstakeBalance: '0',
313
- status: EarningStatus.NOT_STAKING,
314
- isBondedBefore: false,
315
- nominations: [],
316
- unstakings: [],
258
+ type: this.type,
317
259
  slug: subnetSlug,
318
260
  subnetData: {
319
261
  subnetSymbol,
320
262
  subnetShortName: subnetName,
321
- originalTotalStake: '0'
263
+ originalTotalStake: originalTotalStake.toString()
322
264
  }
323
265
  });
324
- }
325
- });
266
+ }).catch(console.error);
267
+ } else {
268
+ rsCallback({
269
+ ...defaultInfo,
270
+ type: this.type,
271
+ address: owner,
272
+ balanceToken: this.nativeToken.slug,
273
+ totalStake: '0',
274
+ activeStake: '0',
275
+ unstakeBalance: '0',
276
+ status: EarningStatus.NOT_STAKING,
277
+ isBondedBefore: false,
278
+ nominations: [],
279
+ unstakings: [],
280
+ slug: subnetSlug,
281
+ subnetData: {
282
+ subnetSymbol,
283
+ subnetShortName: subnetName,
284
+ originalTotalStake: '0'
285
+ }
286
+ });
287
+ }
326
288
  });
327
- }
289
+ });
328
290
  };
329
291
  const getStakingPositionInterval = async () => {
330
292
  if (cancel) {
@@ -343,4 +305,12 @@ export default class SubnetTaoStakingPoolHandler extends TaoNativeStakingPoolHan
343
305
  }
344
306
 
345
307
  /* Subscribe pool position */
308
+
309
+ /* Unimplemented function */
310
+
311
+ handleChangeRootClaimType() {
312
+ return Promise.reject(new TransactionError(BasicTxErrorType.UNSUPPORTED));
313
+ }
314
+
315
+ /* Unimplemented function */
346
316
  }
@@ -291,7 +291,8 @@ export default class TanssiNativeStakingPoolHandler extends BaseParaNativeStakin
291
291
  metadata: {
292
292
  pendingStake: bnJoiningStake.toString(),
293
293
  compoundingStake: bnCompoundingStake.toString(),
294
- manualStake: bnManualStake.toString()
294
+ manualStake: bnManualStake.toString(),
295
+ isShowActiveStakeDetails: bnJoiningStake.gt(0) || bnCompoundingStake.gt(0) || !bnManualStake.gt(0)
295
296
  }
296
297
  });
297
298
  };
@@ -4,7 +4,7 @@ import { ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
4
4
  import KoniState from '@subwallet/extension-base/koni/background/handlers/State';
5
5
  import { _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
6
6
  import BaseParaStakingPoolHandler from '@subwallet/extension-base/services/earning-service/handlers/native-staking/base-para';
7
- import { BaseYieldPositionInfo, OptimalYieldPath, StakeCancelWithdrawalParams, SubmitBittensorChangeValidatorStaking, SubmitJoinNativeStaking, TransactionData, UnstakingInfo, ValidatorInfo, YieldPoolInfo, YieldPoolMethodInfo, YieldPositionInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
7
+ import { BaseYieldPositionInfo, BittensorRootClaimType, OptimalYieldPath, StakeCancelWithdrawalParams, SubmitBittensorChangeValidatorStaking, SubmitJoinNativeStaking, TransactionData, UnstakingInfo, ValidatorInfo, YieldPoolInfo, YieldPoolMethodInfo, YieldPositionInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
8
8
  import BigN from 'bignumber.js';
9
9
  declare type Nominators = [Array<[number, number]>];
10
10
  export interface TestnetBittensorDelegateInfo {
@@ -88,8 +88,6 @@ export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHand
88
88
  protected bittensorCache: BittensorCache;
89
89
  protected getMinBond(netuid?: number): Promise<BigN>;
90
90
  constructor(state: KoniState, chain: string);
91
- handleYieldWithdraw(address: string, unstakingInfo: UnstakingInfo): Promise<TransactionData>;
92
- handleYieldCancelUnstake(params: StakeCancelWithdrawalParams): Promise<TransactionData>;
93
91
  get maintainBalance(): string;
94
92
  subscribePoolInfo(callback: (data: YieldPoolInfo) => void): Promise<VoidFunction>;
95
93
  protected parseNominatorMetadataBase(chainInfo: _ChainInfo, delegatorState: TaoStakingStakeOption[], minBond: string, applyRate?: boolean): Omit<YieldPositionInfo, keyof BaseYieldPositionInfo>;
@@ -104,5 +102,8 @@ export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHand
104
102
  handleYieldUnstake(amount: string, address: string, selectedTarget?: string, netuid?: number, slippage?: number): Promise<[ExtrinsicType, TransactionData]>;
105
103
  validateYieldLeave(amount: string, address: string, fastLeave: boolean, selectedTarget?: string, slug?: string, poolInfo?: YieldPoolInfo): Promise<TransactionError[]>;
106
104
  handleChangeEarningValidator(data: SubmitBittensorChangeValidatorStaking): Promise<TransactionData>;
105
+ handleChangeRootClaimType(type: BittensorRootClaimType): Promise<TransactionData>;
106
+ handleYieldWithdraw(address: string, unstakingInfo: UnstakingInfo): Promise<TransactionData>;
107
+ handleYieldCancelUnstake(params: StakeCancelWithdrawalParams): Promise<TransactionData>;
107
108
  }
108
109
  export {};