@subwallet/extension-base 1.3.16-0 → 1.3.17-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.
@@ -1300,6 +1300,10 @@ export interface RequestAddPspToken {
1300
1300
  logo?: string;
1301
1301
  };
1302
1302
  }
1303
+ export interface TokenPriorityDetails {
1304
+ tokenGroup: Record<string, number>;
1305
+ token: Record<string, number>;
1306
+ }
1303
1307
  export interface RequestConnectWalletConnect {
1304
1308
  uri: string;
1305
1309
  }
@@ -1701,6 +1705,7 @@ export interface KoniRequestSignatures {
1701
1705
  'pri(availBridge.submitClaimAvailBridgeOnAvail)': [RequestClaimBridge, SWTransactionResponse];
1702
1706
  'pri(polygonBridge.submitClaimPolygonBridge)': [RequestClaimBridge, SWTransactionResponse];
1703
1707
  'pri(ledger.generic.allow)': [null, string[], string[]];
1708
+ 'pri(tokens.subscribePriority)': [null, TokenPriorityDetails, TokenPriorityDetails];
1704
1709
  }
1705
1710
  export interface ApplicationMetadataType {
1706
1711
  version: string;
@@ -395,7 +395,7 @@ function getAvgValidatorEraReward(supportedDays, eraRewardHistory) {
395
395
  function getSupportedDaysByHistoryDepth(erasPerDay, maxSupportedEras, liveDay) {
396
396
  const maxSupportDay = Math.floor(maxSupportedEras / erasPerDay);
397
397
  if (liveDay && liveDay <= 30) {
398
- return Math.min(liveDay - 1, maxSupportDay);
398
+ return Math.min(Math.floor(liveDay - 1), maxSupportDay);
399
399
  }
400
400
  if (maxSupportDay > 30) {
401
401
  return 30;
@@ -1609,7 +1609,6 @@ class KoniExtension {
1609
1609
  const substrateApi = this.#koniState.chainService.getSubstrateApi(originTokenInfo.originChain);
1610
1610
  const chainInfoMap = this.#koniState.chainService.getChainInfoMap();
1611
1611
  const destinationTokenInfo = this.#koniState.getXcmEqualAssetByChain(destChain, originTokenInfo.slug);
1612
- const existentialDeposit = originTokenInfo.minAmount || '0';
1613
1612
 
1614
1613
  // todo: improve this case. Currently set 1 AVAIL for covering fee as default.
1615
1614
  const isSpecialBridgeFromAvail = originTokenInfo.slug === 'avail_mainnet-NATIVE-AVAIL' && destChain === _chainList.COMMON_CHAIN_SLUGS.ETHEREUM;
@@ -1624,8 +1623,8 @@ class KoniExtension {
1624
1623
  token: originTokenInfo.slug
1625
1624
  })]);
1626
1625
  const bnMaxTransferable = new _bignumber.default(value);
1627
- const estimatedFee = isSpecialBridgeFromAvail ? specialBridgeFromAvailFee : bnMockExecutionFee.multipliedBy(_constants.XCM_FEE_RATIO).plus(new _bignumber.default(existentialDeposit));
1628
- return bnMaxTransferable.minus(estimatedFee);
1626
+ const txFee = isSpecialBridgeFromAvail ? specialBridgeFromAvailFee : bnMockExecutionFee.multipliedBy(_constants.XCM_FEE_RATIO);
1627
+ return bnMaxTransferable.minus(txFee);
1629
1628
  }
1630
1629
  return new _bignumber.default(0);
1631
1630
  }
@@ -3516,6 +3515,20 @@ class KoniExtension {
3516
3515
 
3517
3516
  /* Ledger */
3518
3517
 
3518
+ /* Popular tokens */
3519
+
3520
+ subscribePriorityTokens(id, port) {
3521
+ const cb = (0, _subscriptions.createSubscription)(id, port);
3522
+ const subscription = this.#koniState.chainService.observable.priorityTokens.subscribe(cb);
3523
+ this.createUnsubscriptionHandle(id, subscription.unsubscribe);
3524
+ port.onDisconnect.addListener(() => {
3525
+ this.cancelSubscription(id);
3526
+ });
3527
+ return this.#koniState.chainService.value.priorityTokens;
3528
+ }
3529
+
3530
+ /* Popular tokens */
3531
+
3519
3532
  // --------------------------------------------------------------
3520
3533
  // eslint-disable-next-line @typescript-eslint/require-await
3521
3534
  async handle(id, type, request, port) {
@@ -4107,6 +4120,12 @@ class KoniExtension {
4107
4120
  case 'pri(ledger.generic.allow)':
4108
4121
  return this.subscribeLedgerGenericAllowChains(id, port);
4109
4122
  /* Ledger */
4123
+
4124
+ /* Priority tokens */
4125
+ case 'pri(tokens.subscribePriority)':
4126
+ return this.subscribePriorityTokens(id, port);
4127
+ /* Priority tokens */
4128
+
4110
4129
  // Default
4111
4130
  default:
4112
4131
  throw new Error(`Unable to handle message of type ${type}`);
@@ -13,6 +13,6 @@ const packageInfo = {
13
13
  name: '@subwallet/extension-base',
14
14
  path: typeof __dirname === 'string' ? __dirname : 'auto',
15
15
  type: 'cjs',
16
- version: '1.3.16-0'
16
+ version: '1.3.17-0'
17
17
  };
18
18
  exports.packageInfo = packageInfo;
@@ -19,6 +19,7 @@ var _wasm = require("@subwallet/extension-base/koni/api/contract-handler/wasm");
19
19
  var _utils = require("@subwallet/extension-base/koni/api/contract-handler/wasm/utils");
20
20
  var _constants2 = require("@subwallet/extension-base/services/chain-service/constants");
21
21
  var _utils2 = require("@subwallet/extension-base/services/chain-service/utils");
22
+ var _tao = require("@subwallet/extension-base/services/earning-service/handlers/native-staking/tao");
22
23
  var _utils3 = require("@subwallet/extension-base/utils");
23
24
  var _bignumber = _interopRequireDefault(require("bignumber.js"));
24
25
  var _evm = require("../evm");
@@ -141,7 +142,18 @@ const subscribeWithSystemAccountPallet = async _ref => {
141
142
  let bittensorStakingBalances = new Array(addresses.length).fill(new _bignumber.default(0));
142
143
  if (['bittensor'].includes(chainInfo.slug)) {
143
144
  bittensorStakingBalances = await Promise.all(addresses.map(async address => {
144
- const TaoTotalStake = await substrateApi.api.query.subtensorModule.totalColdkeyStake(address);
145
+ const stakeInfo = (await substrateApi.api.call.stakeInfoRuntimeApi.getStakeInfoForColdkey(address)).toJSON();
146
+ const price = await (0, _tao.getTaoToAlphaMapping)(substrateApi);
147
+ let TaoTotalStake = new _bignumber.default(0);
148
+ if (stakeInfo) {
149
+ for (const validator of Object.values(stakeInfo)) {
150
+ const stake = new _bignumber.default(validator.stake);
151
+ const netuid = validator.netuid;
152
+ const taoToAlphaPrice = price[netuid] ? new _bignumber.default(price[netuid]) : new _bignumber.default(1);
153
+ const taoStake = stake.multipliedBy(taoToAlphaPrice).toFixed(0).toString();
154
+ TaoTotalStake = TaoTotalStake.plus(taoStake);
155
+ }
156
+ }
145
157
  return new _bignumber.default(TaoTotalStake.toString());
146
158
  }));
147
159
  }
@@ -61,6 +61,7 @@ class ChainService {
61
61
  assetLogoMapSubject = new _rxjs.BehaviorSubject(_chainList.AssetLogoMap);
62
62
  chainLogoMapSubject = new _rxjs.BehaviorSubject(_chainList.ChainLogoMap);
63
63
  ledgerGenericAllowChainsSubject = new _rxjs.BehaviorSubject([]);
64
+ priorityTokensSubject = new _rxjs.BehaviorSubject({});
64
65
 
65
66
  // Todo: Update to new store indexed DB
66
67
  store = new _AssetSetting.default();
@@ -84,17 +85,25 @@ class ChainService {
84
85
  }
85
86
  get value() {
86
87
  const ledgerGenericAllowChains = this.ledgerGenericAllowChainsSubject;
88
+ const priorityTokens = this.priorityTokensSubject;
87
89
  return {
88
90
  get ledgerGenericAllowChains() {
89
91
  return ledgerGenericAllowChains.value;
92
+ },
93
+ get priorityTokens() {
94
+ return priorityTokens.value;
90
95
  }
91
96
  };
92
97
  }
93
98
  get observable() {
94
99
  const ledgerGenericAllowChains = this.ledgerGenericAllowChainsSubject;
100
+ const priorityTokens = this.priorityTokensSubject;
95
101
  return {
96
102
  get ledgerGenericAllowChains() {
97
103
  return ledgerGenericAllowChains.asObservable();
104
+ },
105
+ get priorityTokens() {
106
+ return priorityTokens.asObservable();
98
107
  }
99
108
  };
100
109
  }
@@ -605,6 +614,10 @@ class ChainService {
605
614
  this.eventService.emit('ledger.ready', true);
606
615
  this.logger.log('Finished updating latest ledger generic allow chains');
607
616
  }
617
+ handleLatestPriorityTokens(latestPriorityTokens) {
618
+ this.priorityTokensSubject.next(latestPriorityTokens);
619
+ this.logger.log('Finished updating latest popular tokens');
620
+ }
608
621
  handleLatestData() {
609
622
  this.fetchLatestChainData().then(latestChainInfo => {
610
623
  this.lockChainInfoMap = true; // do not need to check current lockChainInfoMap because all remains action is fast enough and don't affect this feature.
@@ -622,6 +635,9 @@ class ChainService {
622
635
  this.fetchLatestLedgerGenericAllowChains().then(latestledgerGenericAllowChains => {
623
636
  this.handleLatestLedgerGenericAllowChains(latestledgerGenericAllowChains);
624
637
  }).catch(console.error);
638
+ this.fetchLatestPriorityTokens().then(latestPriorityTokens => {
639
+ this.handleLatestPriorityTokens(latestPriorityTokens);
640
+ }).catch(console.error);
625
641
  }
626
642
  async initApis() {
627
643
  const chainInfoMap = this.getChainInfoMap();
@@ -885,6 +901,12 @@ class ChainService {
885
901
  async fetchLatestLedgerGenericAllowChains() {
886
902
  return (await (0, _utils2.fetchStaticData)('chains/ledger-generic-allow-chains')) || [];
887
903
  }
904
+ async fetchLatestPriorityTokens() {
905
+ return (await (0, _utils2.fetchStaticData)('chain-assets/priority-tokens')) || {
906
+ tokenGroup: {},
907
+ token: {}
908
+ };
909
+ }
888
910
  async initChains() {
889
911
  const storedChainSettings = await this.dbService.getAllChainStore();
890
912
  const defaultChainInfoMap = filterChainInfoMap(_chainList.ChainInfoMap, ignoredList);
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.default = exports.bittensorApiKey = exports.BITTENSOR_API_KEY_9 = exports.BITTENSOR_API_KEY_8 = exports.BITTENSOR_API_KEY_7 = exports.BITTENSOR_API_KEY_6 = exports.BITTENSOR_API_KEY_5 = exports.BITTENSOR_API_KEY_4 = exports.BITTENSOR_API_KEY_3 = exports.BITTENSOR_API_KEY_2 = exports.BITTENSOR_API_KEY_10 = exports.BITTENSOR_API_KEY_1 = void 0;
8
8
  exports.fetchDelegates = fetchDelegates;
9
- exports.fetchTaoDelegateState = fetchTaoDelegateState;
9
+ exports.getTaoToAlphaMapping = void 0;
10
10
  var _TransactionError = require("@subwallet/extension-base/background/errors/TransactionError");
11
11
  var _KoniTypes = require("@subwallet/extension-base/background/KoniTypes");
12
12
  var _constants = require("@subwallet/extension-base/constants");
@@ -20,6 +20,26 @@ var _utils3 = require("../../utils");
20
20
  // Copyright 2019-2022 @subwallet/extension-base
21
21
  // SPDX-License-Identifier: Apache-2.0
22
22
 
23
+ const getTaoToAlphaMapping = async substrateApi => {
24
+ const allSubnets = (await substrateApi.api.call.subnetInfoRuntimeApi.getAllDynamicInfo()).toJSON();
25
+ if (!allSubnets) {
26
+ return {};
27
+ }
28
+ return allSubnets.reduce((acc, subnet) => {
29
+ const netuid = subnet === null || subnet === void 0 ? void 0 : subnet.netuid;
30
+ const taoIn = subnet !== null && subnet !== void 0 && subnet.taoIn ? new _bignumber.default(subnet.taoIn) : new _bignumber.default(0);
31
+ const alphaIn = subnet !== null && subnet !== void 0 && subnet.alphaIn ? new _bignumber.default(subnet.alphaIn) : new _bignumber.default(0);
32
+ if (netuid === 0) {
33
+ acc[netuid] = '1';
34
+ } else if (alphaIn.gt(0)) {
35
+ acc[netuid] = taoIn.dividedBy(alphaIn).toString();
36
+ } else {
37
+ acc[netuid] = '1';
38
+ }
39
+ return acc;
40
+ }, {});
41
+ };
42
+ exports.getTaoToAlphaMapping = getTaoToAlphaMapping;
23
43
  const BITTENSOR_API_KEY_1 = process.env.BITTENSOR_API_KEY_1 || '';
24
44
  exports.BITTENSOR_API_KEY_1 = BITTENSOR_API_KEY_1;
25
45
  const BITTENSOR_API_KEY_2 = process.env.BITTENSOR_API_KEY_2 || '';
@@ -49,7 +69,7 @@ function random() {
49
69
  return validKeys[randomIndex];
50
70
  }
51
71
  const bittensorApiKey = () => {
52
- return random(BITTENSOR_API_KEY_1, BITTENSOR_API_KEY_2, BITTENSOR_API_KEY_3, BITTENSOR_API_KEY_4, BITTENSOR_API_KEY_5, BITTENSOR_API_KEY_6);
72
+ return random(BITTENSOR_API_KEY_1, BITTENSOR_API_KEY_2, BITTENSOR_API_KEY_3, BITTENSOR_API_KEY_4, BITTENSOR_API_KEY_5, BITTENSOR_API_KEY_6, BITTENSOR_API_KEY_7, BITTENSOR_API_KEY_8, BITTENSOR_API_KEY_9, BITTENSOR_API_KEY_10);
53
73
  };
54
74
 
55
75
  /* Fetch data */
@@ -68,20 +88,22 @@ async function fetchDelegates() {
68
88
  }).catch(console.error);
69
89
  });
70
90
  }
71
- async function fetchTaoDelegateState(address) {
72
- const apiKey = bittensorApiKey();
73
- return new Promise(function (resolve) {
74
- fetch(`https://api.taostats.io/api/stake_balance/latest/v1?coldkey=${address}`, {
75
- method: 'GET',
76
- headers: {
77
- 'Content-Type': 'application/json',
78
- Authorization: `${apiKey}`
79
- }
80
- }).then(resp => {
81
- resolve(resp.json());
82
- }).catch(console.error);
83
- });
84
- }
91
+
92
+ // export async function fetchTaoDelegateState (address: string): Promise<RawDelegateState> {
93
+ // const apiKey = bittensorApiKey();
94
+
95
+ // return new Promise(function (resolve) {
96
+ // fetch(`https://api.taostats.io/api/stake_balance/latest/v1?coldkey=${address}`, {
97
+ // method: 'GET',
98
+ // headers: {
99
+ // 'Content-Type': 'application/json',
100
+ // Authorization: `${apiKey}`
101
+ // }
102
+ // }).then((resp) => {
103
+ // resolve(resp.json());
104
+ // }).catch(console.error);
105
+ // });
106
+ // }
85
107
 
86
108
  /* Fetch data */
87
109
 
@@ -182,11 +204,12 @@ class TaoNativeStakingPoolHandler extends _basePara.default {
182
204
  chain: chainInfo.slug,
183
205
  validatorAddress: delegate.owner,
184
206
  activeStake: activeStake,
185
- validatorMinStake: minDelegatorStake,
186
- validatorIdentity: delegate.identity
207
+ validatorMinStake: minDelegatorStake
208
+ // validatorIdentity: delegate.identity
187
209
  });
188
210
  }
189
211
  }
212
+
190
213
  const stakingStatus = (0, _utils.getEarningStatusByNominations)(allActiveStake, nominationList);
191
214
  return {
192
215
  status: stakingStatus,
@@ -214,9 +237,10 @@ class TaoNativeStakingPoolHandler extends _basePara.default {
214
237
  bnTotalBalance = bnTotalBalance.add(bnStakeAmount);
215
238
  delegatorState.push({
216
239
  owner: testnetAddress,
217
- amount: bnStakeAmount.toString(),
218
- identity: testnetAddress
240
+ amount: bnStakeAmount.toString()
241
+ // identity: testnetAddress
219
242
  });
243
+
220
244
  rsCallback({
221
245
  ...defaultInfo,
222
246
  type: this.type,
@@ -239,20 +263,32 @@ class TaoNativeStakingPoolHandler extends _basePara.default {
239
263
  await Promise.all(stakePromises);
240
264
  };
241
265
  const getMainnetPoolPosition = async () => {
242
- const rawDelegateStateInfos = await Promise.all(useAddresses.map(address => fetchTaoDelegateState(address)));
243
- if (rawDelegateStateInfos.length > 0) {
266
+ const rawDelegateStateInfos = await Promise.all(useAddresses.map(async address => (await substrateApi.api.call.stakeInfoRuntimeApi.getStakeInfoForColdkey(address)).toJSON()));
267
+ const price = await getTaoToAlphaMapping(this.substrateApi);
268
+ if (rawDelegateStateInfos && rawDelegateStateInfos.length > 0) {
244
269
  rawDelegateStateInfos.forEach((rawDelegateStateInfo, i) => {
245
270
  const owner = (0, _utils2.reformatAddress)(useAddresses[i], 42);
246
271
  const delegatorState = [];
247
272
  let bnTotalBalance = _util.BN_ZERO;
248
- const delegateStateInfo = rawDelegateStateInfo.data;
273
+ const delegateStateInfo = rawDelegateStateInfo;
274
+ const totalDelegate = {};
249
275
  for (const delegate of delegateStateInfo) {
250
- const name = delegate.hotkey_name || delegate.hotkey.ss58;
251
- bnTotalBalance = bnTotalBalance.add(new _util.BN(delegate.stake));
276
+ const hotkey = delegate.hotkey;
277
+ const netuid = delegate.netuid;
278
+ const stake = new _bignumber.default(delegate.stake);
279
+ const taoToAlphaPrice = price[netuid] ? new _bignumber.default(price[netuid]) : new _bignumber.default(1);
280
+ const taoStake = stake.multipliedBy(taoToAlphaPrice).toFixed(0).toString();
281
+ if (totalDelegate[hotkey]) {
282
+ totalDelegate[hotkey] = new _bignumber.default(totalDelegate[hotkey]).plus(taoStake).toString();
283
+ } else {
284
+ totalDelegate[hotkey] = taoStake;
285
+ }
286
+ }
287
+ for (const hotkey in totalDelegate) {
288
+ bnTotalBalance = bnTotalBalance.add(new _util.BN(totalDelegate[hotkey]));
252
289
  delegatorState.push({
253
- owner: delegate.hotkey.ss58,
254
- amount: delegate.stake,
255
- identity: name
290
+ owner: hotkey,
291
+ amount: totalDelegate[hotkey]
256
292
  });
257
293
  }
258
294
  if (delegateStateInfo && delegateStateInfo.length > 0) {
@@ -282,6 +318,61 @@ class TaoNativeStakingPoolHandler extends _basePara.default {
282
318
  });
283
319
  }
284
320
  };
321
+
322
+ // const getMainnetPoolPosition = async () => {
323
+ // const rawDelegateStateInfos = await Promise.all(
324
+ // useAddresses.map((address) => fetchTaoDelegateState(address))
325
+ // );
326
+
327
+ // if (rawDelegateStateInfos.length > 0) {
328
+ // rawDelegateStateInfos.forEach((rawDelegateStateInfo, i) => {
329
+ // const owner = reformatAddress(useAddresses[i], 42);
330
+ // const delegatorState: TaoStakingStakeOption[] = [];
331
+ // let bnTotalBalance = BN_ZERO;
332
+ // const delegateStateInfo = rawDelegateStateInfo.data;
333
+
334
+ // for (const delegate of delegateStateInfo) {
335
+ // const name = delegate.hotkey_name || delegate.hotkey.ss58;
336
+
337
+ // bnTotalBalance = bnTotalBalance.add(new BN(delegate.stake));
338
+
339
+ // delegatorState.push({
340
+ // owner: delegate.hotkey.ss58,
341
+ // amount: delegate.stake,
342
+ // identity: name
343
+ // });
344
+ // }
345
+
346
+ // if (delegateStateInfo && delegateStateInfo.length > 0) {
347
+ // this.parseNominatorMetadata(chainInfo, owner, delegatorState)
348
+ // .then((nominatorMetadata) => {
349
+ // rsCallback({
350
+ // ...defaultInfo,
351
+ // ...nominatorMetadata,
352
+ // address: owner,
353
+ // type: this.type
354
+ // });
355
+ // })
356
+ // .catch(console.error);
357
+ // } else {
358
+ // rsCallback({
359
+ // ...defaultInfo,
360
+ // type: this.type,
361
+ // address: owner,
362
+ // balanceToken: this.nativeToken.slug,
363
+ // totalStake: '0',
364
+ // activeStake: '0',
365
+ // unstakeBalance: '0',
366
+ // status: EarningStatus.NOT_STAKING,
367
+ // isBondedBefore: false,
368
+ // nominations: [],
369
+ // unstakings: []
370
+ // });
371
+ // }
372
+ // });
373
+ // }
374
+ // };
375
+
285
376
  const getStakingPositionInterval = async () => {
286
377
  if (cancel) {
287
378
  return;
@@ -387,7 +478,7 @@ class TaoNativeStakingPoolHandler extends _basePara.default {
387
478
  const binaryAmount = new _util.BN(amount);
388
479
  const selectedValidatorInfo = targetValidators[0];
389
480
  const hotkey = selectedValidatorInfo.address;
390
- const extrinsic = chainApi.api.tx.subtensorModule.addStake(hotkey, binaryAmount);
481
+ const extrinsic = chainApi.api.tx.subtensorModule.addStake(hotkey, 0, binaryAmount);
391
482
  return [extrinsic, {
392
483
  slug: this.nativeToken.slug,
393
484
  amount: '0'
@@ -405,7 +496,7 @@ class TaoNativeStakingPoolHandler extends _basePara.default {
405
496
  if (!selectedTarget || !poolPosition) {
406
497
  return Promise.reject(new _TransactionError.TransactionError(_types.BasicTxErrorType.INVALID_PARAMS));
407
498
  }
408
- const extrinsic = apiPromise.api.tx.subtensorModule.removeStake(selectedTarget, binaryAmount);
499
+ const extrinsic = apiPromise.api.tx.subtensorModule.removeStake(selectedTarget, 0, binaryAmount);
409
500
  return [_KoniTypes.ExtrinsicType.STAKING_UNBOND, extrinsic];
410
501
  }
411
502
 
@@ -91,7 +91,7 @@ class NominationPoolHandler extends _base.default {
91
91
 
92
92
  const supportedDays = (0, _utils.getSupportedDaysByHistoryDepth)(erasPerDay, parseInt(maxSupportedEras), parseInt(currentEra) / erasPerDay);
93
93
  const startEra = parseInt(currentEra) - supportedDays * erasPerDay;
94
- const [_maxPoolMember, _EraStakeInfo, _totalIssuance, _auctionCounter, _minPoolJoin, ..._eraReward] = await Promise.all([(_substrateApi$api$que2 = substrateApi.api.query.nominationPools) === null || _substrateApi$api$que2 === void 0 ? void 0 : _substrateApi$api$que2.maxPoolMembersPerPool(), substrateApi.api.query.staking.erasTotalStake.multi([parseInt(currentEra), parseInt(currentEra) - 1]), substrateApi.api.query.balances.totalIssuance(), (_substrateApi$api$que3 = substrateApi.api.query.auctions) === null || _substrateApi$api$que3 === void 0 ? void 0 : _substrateApi$api$que3.auctionCounter(), (_substrateApi$api$que4 = substrateApi.api.query.nominationPools) === null || _substrateApi$api$que4 === void 0 ? void 0 : _substrateApi$api$que4.minJoinBond(), substrateApi.api.query.staking.erasValidatorReward.multi([...Array(supportedDays.toString()).keys()].map(i => i + startEra))]);
94
+ const [_maxPoolMember, _EraStakeInfo, _totalIssuance, _auctionCounter, _minPoolJoin, ..._eraReward] = await Promise.all([(_substrateApi$api$que2 = substrateApi.api.query.nominationPools) === null || _substrateApi$api$que2 === void 0 ? void 0 : _substrateApi$api$que2.maxPoolMembersPerPool(), substrateApi.api.query.staking.erasTotalStake.multi([parseInt(currentEra), parseInt(currentEra) - 1]), substrateApi.api.query.balances.totalIssuance(), (_substrateApi$api$que3 = substrateApi.api.query.auctions) === null || _substrateApi$api$que3 === void 0 ? void 0 : _substrateApi$api$que3.auctionCounter(), (_substrateApi$api$que4 = substrateApi.api.query.nominationPools) === null || _substrateApi$api$que4 === void 0 ? void 0 : _substrateApi$api$que4.minJoinBond(), substrateApi.api.query.staking.erasValidatorReward.multi([...Array(supportedDays).keys()].map(i => i + startEra))]);
95
95
  const maxPoolMembers = _maxPoolMember ? parseInt(_maxPoolMember.toString()) : undefined;
96
96
  const [_totalEraStake, _lastTotalStaked] = _EraStakeInfo;
97
97
  const validatorEraReward = (0, _utils.getAvgValidatorEraReward)(supportedDays, _eraReward[0]);
@@ -80,17 +80,27 @@ class BaseSpecialStakingPoolHandler extends _base.default {
80
80
  value: '0'
81
81
  }), this.state.balanceService.getTransferableBalance(request.address, feeAssetInfo.originChain, feeAssetInfo.slug)]);
82
82
  const bnInputAssetBalance = new _util.BN(inputAssetBalance.value);
83
- const bnAltInputAssetBalance = new _util.BN(altInputAssetBalance.value);
84
83
  const bnMinJoinPool = new _util.BN(poolInfo.statistic.earningThreshold.join);
85
84
  const inputTokenInfo = this.state.chainService.getAssetBySlug(this.inputAsset);
86
85
  const altInputTokenInfo = this.state.chainService.getAssetBySlug(this.altInputAsset);
86
+ const existentialDeposit = new _util.BN((0, _utils2._getAssetExistentialDeposit)(altInputTokenInfo));
87
+ const bnAltInputAssetBalance = new _util.BN(altInputAssetBalance.value);
87
88
  if (bnInputAssetBalance.add(bnAltInputAssetBalance).lt(bnMinJoinPool)) {
89
+ const missingAmount = bnMinJoinPool.sub(bnInputAssetBalance).sub(bnAltInputAssetBalance);
90
+ const isTheSame = missingAmount.toString() === bnMinJoinPool.toString();
88
91
  const originChain = this.state.getChainInfo(inputTokenInfo.originChain);
89
92
  const altChain = this.state.getChainInfo(altInputTokenInfo.originChain);
90
- const parsedMinJoinPool = (0, _utils3.formatNumber)(bnMinJoinPool.toString(), inputAssetInfo.decimals || 0);
93
+ const originSymbol = (0, _utils2._getAssetSymbol)(inputTokenInfo);
94
+ const altSymbol = (0, _utils2._getAssetSymbol)(altInputTokenInfo);
95
+ const originName = originChain.name;
96
+ const altName = altChain.name;
97
+ const parsedMinJoinPool = (0, _utils3.formatNumber)(missingAmount.toString(), inputAssetInfo.decimals || 0);
98
+ const formatparsedMinJoinPool = isTheSame ? parsedMinJoinPool : Number(parsedMinJoinPool) + 0.01;
99
+ const parsedMinAltJoinPool = (0, _utils3.formatNumber)(missingAmount.add(existentialDeposit).toString(), inputAssetInfo.decimals || 0);
100
+ const formatParsedMinAltJoinPool = isTheSame ? parsedMinAltJoinPool : Number(parsedMinAltJoinPool) + 0.01;
91
101
  return {
92
102
  passed: false,
93
- errorMessage: `You need at least ${parsedMinJoinPool} ${inputTokenInfo.symbol} (${originChain.name}) or ${altInputTokenInfo.symbol} (${altChain.name}) to start earning`
103
+ errorMessage: `You need to deposit an additional ${formatparsedMinJoinPool} ${originSymbol} (${originName}) or ${formatParsedMinAltJoinPool} ${altSymbol} (${altName}) to start earning`
94
104
  };
95
105
  }
96
106
  if (this.feeAssets.length === 1) {
@@ -288,16 +298,15 @@ class BaseSpecialStakingPoolHandler extends _base.default {
288
298
  processValidation.failedStep = path.steps[1];
289
299
  processValidation.ok = false;
290
300
  processValidation.status = _types.YieldValidationStatus.NOT_ENOUGH_BALANCE;
301
+ const bnMaxXCM = new _util.BN(altInputTokenBalance.value).sub(xcmFee.mul(new _util.BN(_constants.XCM_FEE_RATIO)));
302
+ const inputTokenDecimal = (0, _utils2._getAssetDecimals)(inputTokenInfo);
291
303
  const maxBn = bnInputTokenBalance.add(new _util.BN(altInputTokenBalance.value)).sub(xcmFee).sub(xcmFee);
292
304
  const maxValue = (0, _utils3.formatNumber)(maxBn.toString(), inputTokenInfo.decimals || 0);
293
- const altInputTokenInfo = this.state.getAssetBySlug(altInputTokenSlug);
294
- const symbol = altInputTokenInfo.symbol;
295
- const altNetwork = this.state.getChainInfo(altInputTokenInfo.originChain);
305
+ const maxXCMValue = (0, _utils3.formatNumber)(bnMaxXCM.toString(), inputTokenDecimal);
306
+ const symbol = (0, _utils2._getAssetSymbol)(altInputTokenInfo);
296
307
  const inputNetworkName = this.chainInfo.name;
297
- const altNetworkName = altNetwork.name;
298
- const currentValue = (0, _utils3.formatNumber)(bnInputTokenBalance.toString(), inputTokenInfo.decimals || 0);
299
- const bnMaxXCM = new _util.BN(altInputTokenBalance.value).sub(xcmFee).sub(xcmFee);
300
- const maxXCMValue = (0, _utils3.formatNumber)(bnMaxXCM.toString(), inputTokenInfo.decimals || 0);
308
+ const altNetworkName = (0, _utils2._getAssetName)(altInputTokenInfo);
309
+ const currentValue = (0, _utils3.formatNumber)(bnInputTokenBalance.toString(), inputTokenDecimal);
301
310
  processValidation.message = (0, _i18next.t)('You can only enter a maximum of {{maxValue}} {{symbol}}, which is {{currentValue}} {{symbol}} ({{inputNetworkName}}) and {{maxXCMValue}} {{symbol}} ({{altNetworkName}}). Lower your amount and try again.', {
302
311
  replace: {
303
312
  symbol,
@@ -352,7 +352,7 @@ export function getAvgValidatorEraReward(supportedDays, eraRewardHistory) {
352
352
  export function getSupportedDaysByHistoryDepth(erasPerDay, maxSupportedEras, liveDay) {
353
353
  const maxSupportDay = Math.floor(maxSupportedEras / erasPerDay);
354
354
  if (liveDay && liveDay <= 30) {
355
- return Math.min(liveDay - 1, maxSupportDay);
355
+ return Math.min(Math.floor(liveDay - 1), maxSupportDay);
356
356
  }
357
357
  if (maxSupportDay > 30) {
358
358
  return 30;
@@ -262,5 +262,6 @@ export default class KoniExtension {
262
262
  private getIsClaimedPolygonBridge;
263
263
  private submitClaimPolygonBridge;
264
264
  private subscribeLedgerGenericAllowChains;
265
+ private subscribePriorityTokens;
265
266
  handle<TMessageType extends MessageTypes>(id: string, type: TMessageType, request: RequestTypes[TMessageType], port: chrome.runtime.Port): Promise<ResponseType<TMessageType>>;
266
267
  }
@@ -1564,7 +1564,6 @@ export default class KoniExtension {
1564
1564
  const substrateApi = this.#koniState.chainService.getSubstrateApi(originTokenInfo.originChain);
1565
1565
  const chainInfoMap = this.#koniState.chainService.getChainInfoMap();
1566
1566
  const destinationTokenInfo = this.#koniState.getXcmEqualAssetByChain(destChain, originTokenInfo.slug);
1567
- const existentialDeposit = originTokenInfo.minAmount || '0';
1568
1567
 
1569
1568
  // todo: improve this case. Currently set 1 AVAIL for covering fee as default.
1570
1569
  const isSpecialBridgeFromAvail = originTokenInfo.slug === 'avail_mainnet-NATIVE-AVAIL' && destChain === COMMON_CHAIN_SLUGS.ETHEREUM;
@@ -1579,8 +1578,8 @@ export default class KoniExtension {
1579
1578
  token: originTokenInfo.slug
1580
1579
  })]);
1581
1580
  const bnMaxTransferable = new BigN(value);
1582
- const estimatedFee = isSpecialBridgeFromAvail ? specialBridgeFromAvailFee : bnMockExecutionFee.multipliedBy(XCM_FEE_RATIO).plus(new BigN(existentialDeposit));
1583
- return bnMaxTransferable.minus(estimatedFee);
1581
+ const txFee = isSpecialBridgeFromAvail ? specialBridgeFromAvailFee : bnMockExecutionFee.multipliedBy(XCM_FEE_RATIO);
1582
+ return bnMaxTransferable.minus(txFee);
1584
1583
  }
1585
1584
  return new BigN(0);
1586
1585
  }
@@ -3438,6 +3437,20 @@ export default class KoniExtension {
3438
3437
 
3439
3438
  /* Ledger */
3440
3439
 
3440
+ /* Popular tokens */
3441
+
3442
+ subscribePriorityTokens(id, port) {
3443
+ const cb = createSubscription(id, port);
3444
+ const subscription = this.#koniState.chainService.observable.priorityTokens.subscribe(cb);
3445
+ this.createUnsubscriptionHandle(id, subscription.unsubscribe);
3446
+ port.onDisconnect.addListener(() => {
3447
+ this.cancelSubscription(id);
3448
+ });
3449
+ return this.#koniState.chainService.value.priorityTokens;
3450
+ }
3451
+
3452
+ /* Popular tokens */
3453
+
3441
3454
  // --------------------------------------------------------------
3442
3455
  // eslint-disable-next-line @typescript-eslint/require-await
3443
3456
  async handle(id, type, request, port) {
@@ -4029,6 +4042,12 @@ export default class KoniExtension {
4029
4042
  case 'pri(ledger.generic.allow)':
4030
4043
  return this.subscribeLedgerGenericAllowChains(id, port);
4031
4044
  /* Ledger */
4045
+
4046
+ /* Priority tokens */
4047
+ case 'pri(tokens.subscribePriority)':
4048
+ return this.subscribePriorityTokens(id, port);
4049
+ /* Priority tokens */
4050
+
4032
4051
  // Default
4033
4052
  default:
4034
4053
  throw new Error(`Unable to handle message of type ${type}`);
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "./cjs/detectPackage.js"
18
18
  ],
19
19
  "type": "module",
20
- "version": "1.3.16-0",
20
+ "version": "1.3.17-0",
21
21
  "main": "./cjs/index.js",
22
22
  "module": "./index.js",
23
23
  "types": "./index.d.ts",
@@ -2514,10 +2514,10 @@
2514
2514
  "@sora-substrate/type-definitions": "^1.17.7",
2515
2515
  "@substrate/connect": "^0.8.9",
2516
2516
  "@subwallet/chain-list": "0.2.99-beta.14",
2517
- "@subwallet/extension-base": "^1.3.16-0",
2518
- "@subwallet/extension-chains": "^1.3.16-0",
2519
- "@subwallet/extension-dapp": "^1.3.16-0",
2520
- "@subwallet/extension-inject": "^1.3.16-0",
2517
+ "@subwallet/extension-base": "^1.3.17-0",
2518
+ "@subwallet/extension-chains": "^1.3.17-0",
2519
+ "@subwallet/extension-dapp": "^1.3.17-0",
2520
+ "@subwallet/extension-inject": "^1.3.17-0",
2521
2521
  "@subwallet/keyring": "^0.1.8-beta.0",
2522
2522
  "@subwallet/ui-keyring": "^0.1.8-beta.0",
2523
2523
  "@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.16-0'
10
+ version: '1.3.17-0'
11
11
  };
@@ -15,6 +15,7 @@ import { getPSP22ContractPromise } from '@subwallet/extension-base/koni/api/cont
15
15
  import { getDefaultWeightV2 } from '@subwallet/extension-base/koni/api/contract-handler/wasm/utils';
16
16
  import { _BALANCE_CHAIN_GROUP, _MANTA_ZK_CHAIN_GROUP, _ZK_ASSET_PREFIX } from '@subwallet/extension-base/services/chain-service/constants';
17
17
  import { _checkSmartContractSupportByChain, _getAssetExistentialDeposit, _getChainExistentialDeposit, _getChainNativeTokenSlug, _getContractAddressOfToken, _getTokenOnChainAssetId, _getTokenOnChainInfo, _getTokenTypesSupportedByChain, _getXcmAssetMultilocation, _isBridgedToken, _isChainEvmCompatible } from '@subwallet/extension-base/services/chain-service/utils';
18
+ import { getTaoToAlphaMapping } from '@subwallet/extension-base/services/earning-service/handlers/native-staking/tao';
18
19
  import { filterAssetsByChainAndType } from '@subwallet/extension-base/utils';
19
20
  import BigN from 'bignumber.js';
20
21
  import { subscribeERC20Interval } from "../evm.js";
@@ -132,7 +133,18 @@ const subscribeWithSystemAccountPallet = async ({
132
133
  let bittensorStakingBalances = new Array(addresses.length).fill(new BigN(0));
133
134
  if (['bittensor'].includes(chainInfo.slug)) {
134
135
  bittensorStakingBalances = await Promise.all(addresses.map(async address => {
135
- const TaoTotalStake = await substrateApi.api.query.subtensorModule.totalColdkeyStake(address);
136
+ const stakeInfo = (await substrateApi.api.call.stakeInfoRuntimeApi.getStakeInfoForColdkey(address)).toJSON();
137
+ const price = await getTaoToAlphaMapping(substrateApi);
138
+ let TaoTotalStake = new BigN(0);
139
+ if (stakeInfo) {
140
+ for (const validator of Object.values(stakeInfo)) {
141
+ const stake = new BigN(validator.stake);
142
+ const netuid = validator.netuid;
143
+ const taoToAlphaPrice = price[netuid] ? new BigN(price[netuid]) : new BigN(1);
144
+ const taoStake = stake.multipliedBy(taoToAlphaPrice).toFixed(0).toString();
145
+ TaoTotalStake = TaoTotalStake.plus(taoStake);
146
+ }
147
+ }
136
148
  return new BigN(TaoTotalStake.toString());
137
149
  }));
138
150
  }
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  import { _AssetRef, _AssetType, _ChainAsset, _ChainInfo, _MultiChainAsset } from '@subwallet/chain-list/types';
3
- import { AssetSetting, MetadataItem, ValidateNetworkResponse } from '@subwallet/extension-base/background/KoniTypes';
3
+ import { AssetSetting, MetadataItem, TokenPriorityDetails, ValidateNetworkResponse } from '@subwallet/extension-base/background/KoniTypes';
4
4
  import { MantaPrivateHandler } from '@subwallet/extension-base/services/chain-service/handler/manta/MantaPrivateHandler';
5
5
  import { _ChainApiStatus, _ChainConnectionStatus, _ChainState, _NetworkUpsertParams, _SubstrateApi, _ValidateCustomAssetRequest, _ValidateCustomAssetResponse } from '@subwallet/extension-base/services/chain-service/types';
6
6
  import { EventService } from '@subwallet/extension-base/services/event-service';
@@ -30,15 +30,18 @@ export declare class ChainService {
30
30
  private assetLogoMapSubject;
31
31
  private chainLogoMapSubject;
32
32
  private ledgerGenericAllowChainsSubject;
33
+ private priorityTokensSubject;
33
34
  private store;
34
35
  private assetSettingSubject;
35
36
  private logger;
36
37
  constructor(dbService: DatabaseService, eventService: EventService);
37
38
  get value(): {
38
39
  readonly ledgerGenericAllowChains: string[];
40
+ readonly priorityTokens: TokenPriorityDetails;
39
41
  };
40
42
  get observable(): {
41
43
  readonly ledgerGenericAllowChains: import("rxjs").Observable<string[]>;
44
+ readonly priorityTokens: import("rxjs").Observable<TokenPriorityDetails>;
42
45
  };
43
46
  subscribeSwapRefMap(): Subject<Record<string, _AssetRef>>;
44
47
  get xcmRefMap(): Record<string, _AssetRef>;
@@ -105,6 +108,7 @@ export declare class ChainService {
105
108
  handleLatestChainData(latestChainInfo: _ChainInfo[]): void;
106
109
  autoEnableTokens(): Promise<void>;
107
110
  handleLatestLedgerGenericAllowChains(latestledgerGenericAllowChains: string[]): void;
111
+ handleLatestPriorityTokens(latestPriorityTokens: TokenPriorityDetails): void;
108
112
  handleLatestData(): void;
109
113
  private initApis;
110
114
  initSingleApi(slug: string): Promise<boolean>;
@@ -118,6 +122,7 @@ export declare class ChainService {
118
122
  private fetchLatestChainData;
119
123
  private fetchLatestPriceIdsData;
120
124
  private fetchLatestLedgerGenericAllowChains;
125
+ private fetchLatestPriorityTokens;
121
126
  private initChains;
122
127
  private initAssetRegistry;
123
128
  private updateChainStateMapSubscription;
@@ -47,6 +47,7 @@ export class ChainService {
47
47
  assetLogoMapSubject = new BehaviorSubject(AssetLogoMap);
48
48
  chainLogoMapSubject = new BehaviorSubject(ChainLogoMap);
49
49
  ledgerGenericAllowChainsSubject = new BehaviorSubject([]);
50
+ priorityTokensSubject = new BehaviorSubject({});
50
51
 
51
52
  // Todo: Update to new store indexed DB
52
53
  store = new AssetSettingStore();
@@ -70,17 +71,25 @@ export class ChainService {
70
71
  }
71
72
  get value() {
72
73
  const ledgerGenericAllowChains = this.ledgerGenericAllowChainsSubject;
74
+ const priorityTokens = this.priorityTokensSubject;
73
75
  return {
74
76
  get ledgerGenericAllowChains() {
75
77
  return ledgerGenericAllowChains.value;
78
+ },
79
+ get priorityTokens() {
80
+ return priorityTokens.value;
76
81
  }
77
82
  };
78
83
  }
79
84
  get observable() {
80
85
  const ledgerGenericAllowChains = this.ledgerGenericAllowChainsSubject;
86
+ const priorityTokens = this.priorityTokensSubject;
81
87
  return {
82
88
  get ledgerGenericAllowChains() {
83
89
  return ledgerGenericAllowChains.asObservable();
90
+ },
91
+ get priorityTokens() {
92
+ return priorityTokens.asObservable();
84
93
  }
85
94
  };
86
95
  }
@@ -581,6 +590,10 @@ export class ChainService {
581
590
  this.eventService.emit('ledger.ready', true);
582
591
  this.logger.log('Finished updating latest ledger generic allow chains');
583
592
  }
593
+ handleLatestPriorityTokens(latestPriorityTokens) {
594
+ this.priorityTokensSubject.next(latestPriorityTokens);
595
+ this.logger.log('Finished updating latest popular tokens');
596
+ }
584
597
  handleLatestData() {
585
598
  this.fetchLatestChainData().then(latestChainInfo => {
586
599
  this.lockChainInfoMap = true; // do not need to check current lockChainInfoMap because all remains action is fast enough and don't affect this feature.
@@ -598,6 +611,9 @@ export class ChainService {
598
611
  this.fetchLatestLedgerGenericAllowChains().then(latestledgerGenericAllowChains => {
599
612
  this.handleLatestLedgerGenericAllowChains(latestledgerGenericAllowChains);
600
613
  }).catch(console.error);
614
+ this.fetchLatestPriorityTokens().then(latestPriorityTokens => {
615
+ this.handleLatestPriorityTokens(latestPriorityTokens);
616
+ }).catch(console.error);
601
617
  }
602
618
  async initApis() {
603
619
  const chainInfoMap = this.getChainInfoMap();
@@ -859,6 +875,12 @@ export class ChainService {
859
875
  async fetchLatestLedgerGenericAllowChains() {
860
876
  return (await fetchStaticData('chains/ledger-generic-allow-chains')) || [];
861
877
  }
878
+ async fetchLatestPriorityTokens() {
879
+ return (await fetchStaticData('chain-assets/priority-tokens')) || {
880
+ tokenGroup: {},
881
+ token: {}
882
+ };
883
+ }
862
884
  async initChains() {
863
885
  const storedChainSettings = await this.dbService.getAllChainStore();
864
886
  const defaultChainInfoMap = filterChainInfoMap(ChainInfoMap, ignoredList);
@@ -1,11 +1,16 @@
1
1
  import { _ChainInfo } from '@subwallet/chain-list/types';
2
2
  import { ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
3
+ import { _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
3
4
  import BaseParaStakingPoolHandler from '@subwallet/extension-base/services/earning-service/handlers/native-staking/base-para';
4
5
  import { BaseYieldPositionInfo, StakeCancelWithdrawalParams, SubmitJoinNativeStaking, TransactionData, UnstakingInfo, ValidatorInfo, YieldPoolInfo, YieldPositionInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
6
+ export interface TaoStakeInfo {
7
+ hotkey: string;
8
+ stake: string;
9
+ netuid: number;
10
+ }
5
11
  interface TaoStakingStakeOption {
6
12
  owner: string;
7
13
  amount: string;
8
- identity: string;
9
14
  }
10
15
  export interface RawDelegateState {
11
16
  data: Array<{
@@ -30,6 +35,7 @@ interface Validator {
30
35
  take: string;
31
36
  apr: string;
32
37
  }
38
+ export declare const getTaoToAlphaMapping: (substrateApi: _SubstrateApi) => Promise<Record<number, string>>;
33
39
  export declare const BITTENSOR_API_KEY_1: string;
34
40
  export declare const BITTENSOR_API_KEY_2: string;
35
41
  export declare const BITTENSOR_API_KEY_3: string;
@@ -42,7 +48,6 @@ export declare const BITTENSOR_API_KEY_9: string;
42
48
  export declare const BITTENSOR_API_KEY_10: string;
43
49
  export declare const bittensorApiKey: () => string;
44
50
  export declare function fetchDelegates(): Promise<ValidatorResponse>;
45
- export declare function fetchTaoDelegateState(address: string): Promise<RawDelegateState>;
46
51
  export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHandler {
47
52
  handleYieldWithdraw(address: string, unstakingInfo: UnstakingInfo): Promise<TransactionData>;
48
53
  handleYieldCancelUnstake(params: StakeCancelWithdrawalParams): Promise<TransactionData>;
@@ -11,6 +11,25 @@ import { reformatAddress } from '@subwallet/extension-base/utils';
11
11
  import BigN from 'bignumber.js';
12
12
  import { BN, BN_TEN, BN_ZERO } from '@polkadot/util';
13
13
  import { calculateReward } from "../../utils/index.js";
14
+ export const getTaoToAlphaMapping = async substrateApi => {
15
+ const allSubnets = (await substrateApi.api.call.subnetInfoRuntimeApi.getAllDynamicInfo()).toJSON();
16
+ if (!allSubnets) {
17
+ return {};
18
+ }
19
+ return allSubnets.reduce((acc, subnet) => {
20
+ const netuid = subnet === null || subnet === void 0 ? void 0 : subnet.netuid;
21
+ const taoIn = subnet !== null && subnet !== void 0 && subnet.taoIn ? new BigN(subnet.taoIn) : new BigN(0);
22
+ const alphaIn = subnet !== null && subnet !== void 0 && subnet.alphaIn ? new BigN(subnet.alphaIn) : new BigN(0);
23
+ if (netuid === 0) {
24
+ acc[netuid] = '1';
25
+ } else if (alphaIn.gt(0)) {
26
+ acc[netuid] = taoIn.dividedBy(alphaIn).toString();
27
+ } else {
28
+ acc[netuid] = '1';
29
+ }
30
+ return acc;
31
+ }, {});
32
+ };
14
33
  export const BITTENSOR_API_KEY_1 = process.env.BITTENSOR_API_KEY_1 || '';
15
34
  export const BITTENSOR_API_KEY_2 = process.env.BITTENSOR_API_KEY_2 || '';
16
35
  export const BITTENSOR_API_KEY_3 = process.env.BITTENSOR_API_KEY_3 || '';
@@ -27,7 +46,7 @@ function random(...keys) {
27
46
  return validKeys[randomIndex];
28
47
  }
29
48
  export const bittensorApiKey = () => {
30
- return random(BITTENSOR_API_KEY_1, BITTENSOR_API_KEY_2, BITTENSOR_API_KEY_3, BITTENSOR_API_KEY_4, BITTENSOR_API_KEY_5, BITTENSOR_API_KEY_6);
49
+ return random(BITTENSOR_API_KEY_1, BITTENSOR_API_KEY_2, BITTENSOR_API_KEY_3, BITTENSOR_API_KEY_4, BITTENSOR_API_KEY_5, BITTENSOR_API_KEY_6, BITTENSOR_API_KEY_7, BITTENSOR_API_KEY_8, BITTENSOR_API_KEY_9, BITTENSOR_API_KEY_10);
31
50
  };
32
51
 
33
52
  /* Fetch data */
@@ -46,20 +65,22 @@ export async function fetchDelegates() {
46
65
  }).catch(console.error);
47
66
  });
48
67
  }
49
- export async function fetchTaoDelegateState(address) {
50
- const apiKey = bittensorApiKey();
51
- return new Promise(function (resolve) {
52
- fetch(`https://api.taostats.io/api/stake_balance/latest/v1?coldkey=${address}`, {
53
- method: 'GET',
54
- headers: {
55
- 'Content-Type': 'application/json',
56
- Authorization: `${apiKey}`
57
- }
58
- }).then(resp => {
59
- resolve(resp.json());
60
- }).catch(console.error);
61
- });
62
- }
68
+
69
+ // export async function fetchTaoDelegateState (address: string): Promise<RawDelegateState> {
70
+ // const apiKey = bittensorApiKey();
71
+
72
+ // return new Promise(function (resolve) {
73
+ // fetch(`https://api.taostats.io/api/stake_balance/latest/v1?coldkey=${address}`, {
74
+ // method: 'GET',
75
+ // headers: {
76
+ // 'Content-Type': 'application/json',
77
+ // Authorization: `${apiKey}`
78
+ // }
79
+ // }).then((resp) => {
80
+ // resolve(resp.json());
81
+ // }).catch(console.error);
82
+ // });
83
+ // }
63
84
 
64
85
  /* Fetch data */
65
86
 
@@ -160,11 +181,12 @@ export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHand
160
181
  chain: chainInfo.slug,
161
182
  validatorAddress: delegate.owner,
162
183
  activeStake: activeStake,
163
- validatorMinStake: minDelegatorStake,
164
- validatorIdentity: delegate.identity
184
+ validatorMinStake: minDelegatorStake
185
+ // validatorIdentity: delegate.identity
165
186
  });
166
187
  }
167
188
  }
189
+
168
190
  const stakingStatus = getEarningStatusByNominations(allActiveStake, nominationList);
169
191
  return {
170
192
  status: stakingStatus,
@@ -192,9 +214,10 @@ export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHand
192
214
  bnTotalBalance = bnTotalBalance.add(bnStakeAmount);
193
215
  delegatorState.push({
194
216
  owner: testnetAddress,
195
- amount: bnStakeAmount.toString(),
196
- identity: testnetAddress
217
+ amount: bnStakeAmount.toString()
218
+ // identity: testnetAddress
197
219
  });
220
+
198
221
  rsCallback({
199
222
  ...defaultInfo,
200
223
  type: this.type,
@@ -217,20 +240,32 @@ export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHand
217
240
  await Promise.all(stakePromises);
218
241
  };
219
242
  const getMainnetPoolPosition = async () => {
220
- const rawDelegateStateInfos = await Promise.all(useAddresses.map(address => fetchTaoDelegateState(address)));
221
- if (rawDelegateStateInfos.length > 0) {
243
+ const rawDelegateStateInfos = await Promise.all(useAddresses.map(async address => (await substrateApi.api.call.stakeInfoRuntimeApi.getStakeInfoForColdkey(address)).toJSON()));
244
+ const price = await getTaoToAlphaMapping(this.substrateApi);
245
+ if (rawDelegateStateInfos && rawDelegateStateInfos.length > 0) {
222
246
  rawDelegateStateInfos.forEach((rawDelegateStateInfo, i) => {
223
247
  const owner = reformatAddress(useAddresses[i], 42);
224
248
  const delegatorState = [];
225
249
  let bnTotalBalance = BN_ZERO;
226
- const delegateStateInfo = rawDelegateStateInfo.data;
250
+ const delegateStateInfo = rawDelegateStateInfo;
251
+ const totalDelegate = {};
227
252
  for (const delegate of delegateStateInfo) {
228
- const name = delegate.hotkey_name || delegate.hotkey.ss58;
229
- bnTotalBalance = bnTotalBalance.add(new BN(delegate.stake));
253
+ const hotkey = delegate.hotkey;
254
+ const netuid = delegate.netuid;
255
+ const stake = new BigN(delegate.stake);
256
+ const taoToAlphaPrice = price[netuid] ? new BigN(price[netuid]) : new BigN(1);
257
+ const taoStake = stake.multipliedBy(taoToAlphaPrice).toFixed(0).toString();
258
+ if (totalDelegate[hotkey]) {
259
+ totalDelegate[hotkey] = new BigN(totalDelegate[hotkey]).plus(taoStake).toString();
260
+ } else {
261
+ totalDelegate[hotkey] = taoStake;
262
+ }
263
+ }
264
+ for (const hotkey in totalDelegate) {
265
+ bnTotalBalance = bnTotalBalance.add(new BN(totalDelegate[hotkey]));
230
266
  delegatorState.push({
231
- owner: delegate.hotkey.ss58,
232
- amount: delegate.stake,
233
- identity: name
267
+ owner: hotkey,
268
+ amount: totalDelegate[hotkey]
234
269
  });
235
270
  }
236
271
  if (delegateStateInfo && delegateStateInfo.length > 0) {
@@ -260,6 +295,61 @@ export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHand
260
295
  });
261
296
  }
262
297
  };
298
+
299
+ // const getMainnetPoolPosition = async () => {
300
+ // const rawDelegateStateInfos = await Promise.all(
301
+ // useAddresses.map((address) => fetchTaoDelegateState(address))
302
+ // );
303
+
304
+ // if (rawDelegateStateInfos.length > 0) {
305
+ // rawDelegateStateInfos.forEach((rawDelegateStateInfo, i) => {
306
+ // const owner = reformatAddress(useAddresses[i], 42);
307
+ // const delegatorState: TaoStakingStakeOption[] = [];
308
+ // let bnTotalBalance = BN_ZERO;
309
+ // const delegateStateInfo = rawDelegateStateInfo.data;
310
+
311
+ // for (const delegate of delegateStateInfo) {
312
+ // const name = delegate.hotkey_name || delegate.hotkey.ss58;
313
+
314
+ // bnTotalBalance = bnTotalBalance.add(new BN(delegate.stake));
315
+
316
+ // delegatorState.push({
317
+ // owner: delegate.hotkey.ss58,
318
+ // amount: delegate.stake,
319
+ // identity: name
320
+ // });
321
+ // }
322
+
323
+ // if (delegateStateInfo && delegateStateInfo.length > 0) {
324
+ // this.parseNominatorMetadata(chainInfo, owner, delegatorState)
325
+ // .then((nominatorMetadata) => {
326
+ // rsCallback({
327
+ // ...defaultInfo,
328
+ // ...nominatorMetadata,
329
+ // address: owner,
330
+ // type: this.type
331
+ // });
332
+ // })
333
+ // .catch(console.error);
334
+ // } else {
335
+ // rsCallback({
336
+ // ...defaultInfo,
337
+ // type: this.type,
338
+ // address: owner,
339
+ // balanceToken: this.nativeToken.slug,
340
+ // totalStake: '0',
341
+ // activeStake: '0',
342
+ // unstakeBalance: '0',
343
+ // status: EarningStatus.NOT_STAKING,
344
+ // isBondedBefore: false,
345
+ // nominations: [],
346
+ // unstakings: []
347
+ // });
348
+ // }
349
+ // });
350
+ // }
351
+ // };
352
+
263
353
  const getStakingPositionInterval = async () => {
264
354
  if (cancel) {
265
355
  return;
@@ -364,7 +454,7 @@ export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHand
364
454
  const binaryAmount = new BN(amount);
365
455
  const selectedValidatorInfo = targetValidators[0];
366
456
  const hotkey = selectedValidatorInfo.address;
367
- const extrinsic = chainApi.api.tx.subtensorModule.addStake(hotkey, binaryAmount);
457
+ const extrinsic = chainApi.api.tx.subtensorModule.addStake(hotkey, 0, binaryAmount);
368
458
  return [extrinsic, {
369
459
  slug: this.nativeToken.slug,
370
460
  amount: '0'
@@ -382,7 +472,7 @@ export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHand
382
472
  if (!selectedTarget || !poolPosition) {
383
473
  return Promise.reject(new TransactionError(BasicTxErrorType.INVALID_PARAMS));
384
474
  }
385
- const extrinsic = apiPromise.api.tx.subtensorModule.removeStake(selectedTarget, binaryAmount);
475
+ const extrinsic = apiPromise.api.tx.subtensorModule.removeStake(selectedTarget, 0, binaryAmount);
386
476
  return [ExtrinsicType.STAKING_UNBOND, extrinsic];
387
477
  }
388
478
 
@@ -83,7 +83,7 @@ export default class NominationPoolHandler extends BasePoolHandler {
83
83
 
84
84
  const supportedDays = getSupportedDaysByHistoryDepth(erasPerDay, parseInt(maxSupportedEras), parseInt(currentEra) / erasPerDay);
85
85
  const startEra = parseInt(currentEra) - supportedDays * erasPerDay;
86
- const [_maxPoolMember, _EraStakeInfo, _totalIssuance, _auctionCounter, _minPoolJoin, ..._eraReward] = await Promise.all([(_substrateApi$api$que2 = substrateApi.api.query.nominationPools) === null || _substrateApi$api$que2 === void 0 ? void 0 : _substrateApi$api$que2.maxPoolMembersPerPool(), substrateApi.api.query.staking.erasTotalStake.multi([parseInt(currentEra), parseInt(currentEra) - 1]), substrateApi.api.query.balances.totalIssuance(), (_substrateApi$api$que3 = substrateApi.api.query.auctions) === null || _substrateApi$api$que3 === void 0 ? void 0 : _substrateApi$api$que3.auctionCounter(), (_substrateApi$api$que4 = substrateApi.api.query.nominationPools) === null || _substrateApi$api$que4 === void 0 ? void 0 : _substrateApi$api$que4.minJoinBond(), substrateApi.api.query.staking.erasValidatorReward.multi([...Array(supportedDays.toString()).keys()].map(i => i + startEra))]);
86
+ const [_maxPoolMember, _EraStakeInfo, _totalIssuance, _auctionCounter, _minPoolJoin, ..._eraReward] = await Promise.all([(_substrateApi$api$que2 = substrateApi.api.query.nominationPools) === null || _substrateApi$api$que2 === void 0 ? void 0 : _substrateApi$api$que2.maxPoolMembersPerPool(), substrateApi.api.query.staking.erasTotalStake.multi([parseInt(currentEra), parseInt(currentEra) - 1]), substrateApi.api.query.balances.totalIssuance(), (_substrateApi$api$que3 = substrateApi.api.query.auctions) === null || _substrateApi$api$que3 === void 0 ? void 0 : _substrateApi$api$que3.auctionCounter(), (_substrateApi$api$que4 = substrateApi.api.query.nominationPools) === null || _substrateApi$api$que4 === void 0 ? void 0 : _substrateApi$api$que4.minJoinBond(), substrateApi.api.query.staking.erasValidatorReward.multi([...Array(supportedDays).keys()].map(i => i + startEra))]);
87
87
  const maxPoolMembers = _maxPoolMember ? parseInt(_maxPoolMember.toString()) : undefined;
88
88
  const [_totalEraStake, _lastTotalStaked] = _EraStakeInfo;
89
89
  const validatorEraReward = getAvgValidatorEraReward(supportedDays, _eraReward[0]);
@@ -3,10 +3,10 @@
3
3
 
4
4
  import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
5
5
  import { ChainType, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
6
- import { ALL_ACCOUNT_KEY } from '@subwallet/extension-base/constants';
6
+ import { ALL_ACCOUNT_KEY, XCM_FEE_RATIO } from '@subwallet/extension-base/constants';
7
7
  import { YIELD_POOL_STAT_REFRESH_INTERVAL } from '@subwallet/extension-base/koni/api/yield/helper/utils';
8
8
  import { createXcmExtrinsic } from '@subwallet/extension-base/services/balance-service/transfer/xcm';
9
- import { _getChainNativeTokenSlug } from '@subwallet/extension-base/services/chain-service/utils';
9
+ import { _getAssetDecimals, _getAssetExistentialDeposit, _getAssetName, _getAssetSymbol, _getChainNativeTokenSlug } from '@subwallet/extension-base/services/chain-service/utils';
10
10
  import { BasicTxErrorType, YieldStepType, YieldValidationStatus } from '@subwallet/extension-base/types';
11
11
  import { createPromiseHandler, formatNumber } from '@subwallet/extension-base/utils';
12
12
  import { t } from 'i18next';
@@ -73,17 +73,27 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
73
73
  value: '0'
74
74
  }), this.state.balanceService.getTransferableBalance(request.address, feeAssetInfo.originChain, feeAssetInfo.slug)]);
75
75
  const bnInputAssetBalance = new BN(inputAssetBalance.value);
76
- const bnAltInputAssetBalance = new BN(altInputAssetBalance.value);
77
76
  const bnMinJoinPool = new BN(poolInfo.statistic.earningThreshold.join);
78
77
  const inputTokenInfo = this.state.chainService.getAssetBySlug(this.inputAsset);
79
78
  const altInputTokenInfo = this.state.chainService.getAssetBySlug(this.altInputAsset);
79
+ const existentialDeposit = new BN(_getAssetExistentialDeposit(altInputTokenInfo));
80
+ const bnAltInputAssetBalance = new BN(altInputAssetBalance.value);
80
81
  if (bnInputAssetBalance.add(bnAltInputAssetBalance).lt(bnMinJoinPool)) {
82
+ const missingAmount = bnMinJoinPool.sub(bnInputAssetBalance).sub(bnAltInputAssetBalance);
83
+ const isTheSame = missingAmount.toString() === bnMinJoinPool.toString();
81
84
  const originChain = this.state.getChainInfo(inputTokenInfo.originChain);
82
85
  const altChain = this.state.getChainInfo(altInputTokenInfo.originChain);
83
- const parsedMinJoinPool = formatNumber(bnMinJoinPool.toString(), inputAssetInfo.decimals || 0);
86
+ const originSymbol = _getAssetSymbol(inputTokenInfo);
87
+ const altSymbol = _getAssetSymbol(altInputTokenInfo);
88
+ const originName = originChain.name;
89
+ const altName = altChain.name;
90
+ const parsedMinJoinPool = formatNumber(missingAmount.toString(), inputAssetInfo.decimals || 0);
91
+ const formatparsedMinJoinPool = isTheSame ? parsedMinJoinPool : Number(parsedMinJoinPool) + 0.01;
92
+ const parsedMinAltJoinPool = formatNumber(missingAmount.add(existentialDeposit).toString(), inputAssetInfo.decimals || 0);
93
+ const formatParsedMinAltJoinPool = isTheSame ? parsedMinAltJoinPool : Number(parsedMinAltJoinPool) + 0.01;
84
94
  return {
85
95
  passed: false,
86
- errorMessage: `You need at least ${parsedMinJoinPool} ${inputTokenInfo.symbol} (${originChain.name}) or ${altInputTokenInfo.symbol} (${altChain.name}) to start earning`
96
+ errorMessage: `You need to deposit an additional ${formatparsedMinJoinPool} ${originSymbol} (${originName}) or ${formatParsedMinAltJoinPool} ${altSymbol} (${altName}) to start earning`
87
97
  };
88
98
  }
89
99
  if (this.feeAssets.length === 1) {
@@ -281,16 +291,15 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
281
291
  processValidation.failedStep = path.steps[1];
282
292
  processValidation.ok = false;
283
293
  processValidation.status = YieldValidationStatus.NOT_ENOUGH_BALANCE;
294
+ const bnMaxXCM = new BN(altInputTokenBalance.value).sub(xcmFee.mul(new BN(XCM_FEE_RATIO)));
295
+ const inputTokenDecimal = _getAssetDecimals(inputTokenInfo);
284
296
  const maxBn = bnInputTokenBalance.add(new BN(altInputTokenBalance.value)).sub(xcmFee).sub(xcmFee);
285
297
  const maxValue = formatNumber(maxBn.toString(), inputTokenInfo.decimals || 0);
286
- const altInputTokenInfo = this.state.getAssetBySlug(altInputTokenSlug);
287
- const symbol = altInputTokenInfo.symbol;
288
- const altNetwork = this.state.getChainInfo(altInputTokenInfo.originChain);
298
+ const maxXCMValue = formatNumber(bnMaxXCM.toString(), inputTokenDecimal);
299
+ const symbol = _getAssetSymbol(altInputTokenInfo);
289
300
  const inputNetworkName = this.chainInfo.name;
290
- const altNetworkName = altNetwork.name;
291
- const currentValue = formatNumber(bnInputTokenBalance.toString(), inputTokenInfo.decimals || 0);
292
- const bnMaxXCM = new BN(altInputTokenBalance.value).sub(xcmFee).sub(xcmFee);
293
- const maxXCMValue = formatNumber(bnMaxXCM.toString(), inputTokenInfo.decimals || 0);
301
+ const altNetworkName = _getAssetName(altInputTokenInfo);
302
+ const currentValue = formatNumber(bnInputTokenBalance.toString(), inputTokenDecimal);
294
303
  processValidation.message = t('You can only enter a maximum of {{maxValue}} {{symbol}}, which is {{currentValue}} {{symbol}} ({{inputNetworkName}}) and {{maxXCMValue}} {{symbol}} ({{altNetworkName}}). Lower your amount and try again.', {
295
304
  replace: {
296
305
  symbol,