@subwallet/extension-base 1.3.23-0 → 1.3.25-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 (91) hide show
  1. package/background/KoniTypes.d.ts +11 -3
  2. package/background/KoniTypes.js +1 -0
  3. package/background/errors/EvmProviderError.js +4 -0
  4. package/background/errors/ProviderError.d.ts +1 -1
  5. package/background/errors/ProviderError.js +2 -2
  6. package/cjs/background/KoniTypes.js +1 -0
  7. package/cjs/background/errors/EvmProviderError.js +4 -0
  8. package/cjs/background/errors/ProviderError.js +2 -2
  9. package/cjs/constants/environment.js +1 -1
  10. package/cjs/constants/index.js +21 -4
  11. package/cjs/core/logic-validation/transfer.js +23 -8
  12. package/cjs/koni/background/handlers/Extension.js +109 -89
  13. package/cjs/koni/background/handlers/State.js +2 -2
  14. package/cjs/koni/background/handlers/Tabs.js +4 -3
  15. package/cjs/packageInfo.js +1 -1
  16. package/cjs/page/index.js +1 -1
  17. package/cjs/services/balance-service/helpers/subscribe/substrate/index.js +3 -3
  18. package/cjs/services/balance-service/transfer/smart-contract.js +24 -3
  19. package/cjs/services/buy-service/constants/token.js +3 -0
  20. package/cjs/services/chain-service/index.js +11 -0
  21. package/cjs/services/earning-service/constants/chains.js +1 -1
  22. package/cjs/services/earning-service/handlers/base.js +11 -5
  23. package/cjs/services/earning-service/handlers/native-staking/base-para.js +7 -6
  24. package/cjs/services/earning-service/handlers/native-staking/base.js +6 -3
  25. package/cjs/services/earning-service/handlers/native-staking/dtao.js +444 -0
  26. package/cjs/services/earning-service/handlers/native-staking/index.js +8 -1
  27. package/cjs/services/earning-service/handlers/native-staking/tao.js +138 -125
  28. package/cjs/services/earning-service/service.js +14 -4
  29. package/cjs/services/fee-service/utils/tokenPayFee.js +151 -0
  30. package/cjs/services/inapp-notification-service/index.js +3 -0
  31. package/cjs/services/request-service/handler/MetadataRequestHandler.js +5 -13
  32. package/cjs/services/request-service/index.js +2 -2
  33. package/cjs/services/transaction-service/index.js +14 -5
  34. package/cjs/types/yield/info/base.js +1 -0
  35. package/cjs/utils/fee/transfer.js +47 -14
  36. package/cjs/utils/fetchEvmChainInfo.js +10 -5
  37. package/constants/environment.js +1 -1
  38. package/constants/index.d.ts +6 -1
  39. package/constants/index.js +14 -1
  40. package/core/logic-validation/transfer.d.ts +1 -1
  41. package/core/logic-validation/transfer.js +25 -10
  42. package/koni/background/handlers/Extension.js +82 -62
  43. package/koni/background/handlers/State.d.ts +1 -1
  44. package/koni/background/handlers/State.js +2 -2
  45. package/koni/background/handlers/Tabs.js +4 -3
  46. package/package.json +16 -6
  47. package/packageInfo.js +1 -1
  48. package/page/index.js +1 -1
  49. package/services/balance-service/helpers/subscribe/substrate/index.js +2 -2
  50. package/services/balance-service/transfer/smart-contract.d.ts +4 -2
  51. package/services/balance-service/transfer/smart-contract.js +24 -3
  52. package/services/buy-service/constants/token.js +3 -0
  53. package/services/chain-service/index.d.ts +1 -0
  54. package/services/chain-service/index.js +12 -1
  55. package/services/earning-service/constants/chains.js +1 -1
  56. package/services/earning-service/handlers/base.d.ts +7 -5
  57. package/services/earning-service/handlers/base.js +11 -7
  58. package/services/earning-service/handlers/native-staking/base-para.d.ts +1 -1
  59. package/services/earning-service/handlers/native-staking/base-para.js +7 -6
  60. package/services/earning-service/handlers/native-staking/base.d.ts +1 -1
  61. package/services/earning-service/handlers/native-staking/base.js +6 -3
  62. package/services/earning-service/handlers/native-staking/dtao.d.ts +64 -0
  63. package/services/earning-service/handlers/native-staking/dtao.js +434 -0
  64. package/services/earning-service/handlers/native-staking/index.d.ts +1 -0
  65. package/services/earning-service/handlers/native-staking/index.js +2 -1
  66. package/services/earning-service/handlers/native-staking/tao.d.ts +16 -4
  67. package/services/earning-service/handlers/native-staking/tao.js +136 -121
  68. package/services/earning-service/service.d.ts +1 -0
  69. package/services/earning-service/service.js +15 -5
  70. package/services/fee-service/interfaces.d.ts +25 -0
  71. package/services/fee-service/utils/tokenPayFee.d.ts +8 -0
  72. package/services/fee-service/utils/tokenPayFee.js +141 -0
  73. package/services/inapp-notification-service/index.js +3 -0
  74. package/services/request-service/handler/MetadataRequestHandler.d.ts +1 -1
  75. package/services/request-service/handler/MetadataRequestHandler.js +5 -13
  76. package/services/request-service/index.d.ts +1 -1
  77. package/services/request-service/index.js +2 -2
  78. package/services/transaction-service/index.js +16 -7
  79. package/types/bridge/index.d.ts +1 -0
  80. package/types/buy.d.ts +1 -1
  81. package/types/fee/option.d.ts +1 -1
  82. package/types/yield/actions/join/step.d.ts +1 -0
  83. package/types/yield/actions/join/submit.d.ts +1 -0
  84. package/types/yield/info/account/info.d.ts +14 -1
  85. package/types/yield/info/base.d.ts +3 -1
  86. package/types/yield/info/base.js +1 -0
  87. package/types/yield/info/chain/info.d.ts +5 -1
  88. package/utils/fee/transfer.d.ts +1 -1
  89. package/utils/fee/transfer.js +46 -13
  90. package/utils/fetchEvmChainInfo.d.ts +1 -1
  91. package/utils/fetchEvmChainInfo.js +10 -5
@@ -23,6 +23,7 @@ async function getEVMTransactionObject(_ref) {
23
23
  let {
24
24
  chain,
25
25
  evmApi,
26
+ fallbackFee,
26
27
  feeCustom: _feeCustom,
27
28
  feeInfo: _feeInfo,
28
29
  feeOption,
@@ -34,13 +35,22 @@ async function getEVMTransactionObject(_ref) {
34
35
  const feeCustom = _feeCustom;
35
36
  const feeInfo = _feeInfo;
36
37
  const feeCombine = (0, _utils3.combineEthFee)(feeInfo, feeOption, feeCustom);
38
+ let errorOnEstimateFee = '';
37
39
  const transactionObject = {
38
40
  to: to,
39
41
  value: value,
40
42
  from: from,
41
43
  ...feeCombine
42
44
  };
43
- const gasLimit = await evmApi.api.eth.estimateGas(transactionObject);
45
+ const gasLimit = await evmApi.api.eth.estimateGas(transactionObject).catch(e => {
46
+ console.log('Cannot estimate fee with native transfer on', chain, e);
47
+ if (fallbackFee) {
48
+ errorOnEstimateFee = e.message;
49
+ return 21000;
50
+ } else {
51
+ throw Error('Unable to estimate fee for this transaction. Edit fee and try again.');
52
+ }
53
+ });
44
54
  transactionObject.gas = gasLimit;
45
55
  let estimateFee;
46
56
  if (feeCombine.maxFeePerGas) {
@@ -54,12 +64,14 @@ async function getEVMTransactionObject(_ref) {
54
64
  const numberReplace = 18 - 12;
55
65
  transactionObject.value = transactionObject.value.substring(0, transactionObject.value.length - 6) + new Array(numberReplace).fill('0').join('');
56
66
  }
57
- return [transactionObject, transactionObject.value.toString()];
67
+ return [transactionObject, transactionObject.value.toString(), errorOnEstimateFee];
58
68
  }
59
69
  async function getERC20TransactionObject(_ref2) {
60
70
  let {
61
71
  assetAddress,
72
+ chain,
62
73
  evmApi,
74
+ fallbackFee,
63
75
  feeCustom: _feeCustom,
64
76
  feeInfo: _feeInfo,
65
77
  feeOption,
@@ -72,6 +84,7 @@ async function getERC20TransactionObject(_ref2) {
72
84
  const feeCustom = _feeCustom;
73
85
  let freeAmount = new _bignumber.default(0);
74
86
  let transferValue = value;
87
+ let errorOnEstimateFee = '';
75
88
  if (transferAll) {
76
89
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
77
90
  const bal = await erc20Contract.methods.balanceOf(from).call();
@@ -86,6 +99,14 @@ async function getERC20TransactionObject(_ref2) {
86
99
  // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
87
100
  const gasLimit = await erc20Contract.methods.transfer(to, transferValue).estimateGas({
88
101
  from
102
+ }).catch(e => {
103
+ console.log('Cannot estimate fee with token contract', assetAddress, chain, e);
104
+ if (fallbackFee) {
105
+ errorOnEstimateFee = e.message;
106
+ return 70000;
107
+ } else {
108
+ throw Error('Unable to estimate fee for this transaction. Edit fee and try again.');
109
+ }
89
110
  });
90
111
  const feeInfo = _feeInfo;
91
112
  const feeCombine = (0, _utils3.combineEthFee)(feeInfo, feeOption, feeCustom);
@@ -101,7 +122,7 @@ async function getERC20TransactionObject(_ref2) {
101
122
  transferValue = freeAmount.toFixed(0);
102
123
  transactionObject.data = generateTransferData(to, transferValue);
103
124
  }
104
- return [transactionObject, transferValue];
125
+ return [transactionObject, transferValue, errorOnEstimateFee];
105
126
  }
106
127
  async function getERC721Transaction(web3Api, chain, contractAddress, senderAddress, recipientAddress, tokenId, _feeInfo) {
107
128
  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
@@ -26,6 +26,9 @@ const DEFAULT_SERVICE_INFO = {
26
26
  },
27
27
  moonpay: {
28
28
  ...DEFAULT_BUY_SERVICE
29
+ },
30
+ meld: {
31
+ ...DEFAULT_BUY_SERVICE
29
32
  }
30
33
  };
31
34
  exports.DEFAULT_SERVICE_INFO = DEFAULT_SERVICE_INFO;
@@ -219,6 +219,17 @@ class ChainService {
219
219
  });
220
220
  return assetHubToken;
221
221
  }
222
+ getHydrationAssetIdMap(chain) {
223
+ const hydrationAssetIdMap = {};
224
+ Object.values(this.getAssetRegistry()).forEach(asset => {
225
+ const originChain = (0, _utils._getAssetOriginChain)(asset);
226
+ const assetId = (0, _utils._getTokenOnChainAssetId)(asset);
227
+ if (originChain === chain && assetId !== '-1') {
228
+ hydrationAssetIdMap[asset.slug] = assetId;
229
+ }
230
+ });
231
+ return hydrationAssetIdMap;
232
+ }
222
233
  getChainInfoMap() {
223
234
  return this.dataMap.chainInfoMap;
224
235
  }
@@ -23,7 +23,7 @@ const _STAKING_CHAIN_GROUP = {
23
23
  lending: ['interlay'],
24
24
  krest_network: ['krest_network'],
25
25
  manta: ['manta_network'],
26
- bittensor: ['bittensor', 'bittensor_devnet'],
26
+ bittensor: ['bittensor', 'bittensor_testnet'],
27
27
  mythos: ['mythos', 'muse_testnet']
28
28
  };
29
29
  exports._STAKING_CHAIN_GROUP = _STAKING_CHAIN_GROUP;
@@ -113,11 +113,13 @@ class BasePoolHandler {
113
113
  return false;
114
114
  }
115
115
  async getPoolInfo() {
116
- return await this.state.earningService.getYieldPool(this.slug);
116
+ let slug = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.slug;
117
+ return await this.state.earningService.getYieldPool(slug);
117
118
  }
118
119
  async getPoolPosition(address) {
120
+ let slug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.slug;
119
121
  const originAddress = (0, _utils2.reformatAddress)(address);
120
- return await this.state.earningService.getYieldPosition(originAddress, this.slug);
122
+ return await this.state.earningService.getYieldPosition(originAddress, slug);
121
123
  }
122
124
 
123
125
  /* Subscribe data */
@@ -132,7 +134,7 @@ class BasePoolHandler {
132
134
 
133
135
  async earlyValidate(request) {
134
136
  var _poolInfo$statistic, _poolInfo$statistic2, _poolInfo$statistic2$;
135
- const poolInfo = await this.getPoolInfo();
137
+ const poolInfo = await this.getPoolInfo(request.slug);
136
138
  if (!poolInfo || !((_poolInfo$statistic = poolInfo.statistic) !== null && _poolInfo$statistic !== void 0 && _poolInfo$statistic.earningThreshold.join)) {
137
139
  return {
138
140
  passed: false,
@@ -254,11 +256,11 @@ class BasePoolHandler {
254
256
  /** Validate param to join the pool */
255
257
 
256
258
  /** Create `transaction` to leave the pool */
257
- async handleYieldLeave(fastLeave, amount, address, selectedTarget) {
259
+ async handleYieldLeave(fastLeave, amount, address, selectedTarget, netuid) {
258
260
  if (fastLeave) {
259
261
  return this.handleYieldRedeem(amount, address, selectedTarget);
260
262
  } else {
261
- return this.handleYieldUnstake(amount, address, selectedTarget);
263
+ return this.handleYieldUnstake(amount, address, selectedTarget, netuid);
262
264
  }
263
265
  }
264
266
 
@@ -268,6 +270,10 @@ class BasePoolHandler {
268
270
 
269
271
  /** Create `transaction` to withdraw unstaked amount */
270
272
 
273
+ /** Check handler can handle slug */
274
+ canHandleSlug(slug) {
275
+ return this.slug === slug;
276
+ }
271
277
  /* Other actions */
272
278
  }
273
279
  exports.default = BasePoolHandler;
@@ -32,10 +32,11 @@ class BaseParaNativeStakingPoolHandler extends _base.default {
32
32
  const {
33
33
  address,
34
34
  amount,
35
- selectedValidators
35
+ selectedValidators,
36
+ slug
36
37
  } = data;
37
- const poolInfo = await this.getPoolInfo();
38
- const poolPosition = await this.getPoolPosition(address);
38
+ const poolInfo = await this.getPoolInfo(slug);
39
+ const poolPosition = await this.getPoolPosition(address, slug);
39
40
  const chainInfo = this.chainInfo;
40
41
  const bnAmount = new _util.BN(amount);
41
42
  if (bnAmount.lte(_util.BN_ZERO)) {
@@ -101,10 +102,10 @@ class BaseParaNativeStakingPoolHandler extends _base.default {
101
102
  /**
102
103
  * @todo Recheck
103
104
  * */
104
- async validateYieldLeave(amount, address, fastLeave, selectedTarget) {
105
+ async validateYieldLeave(amount, address, fastLeave, selectedTarget, slug) {
105
106
  const errors = [];
106
- const poolInfo = await this.getPoolInfo();
107
- const poolPosition = await this.getPoolPosition(address);
107
+ const poolInfo = await this.getPoolInfo(slug);
108
+ const poolPosition = await this.getPoolPosition(address, slug);
108
109
  if (!poolInfo || !poolInfo.statistic || !poolPosition || fastLeave || !selectedTarget) {
109
110
  return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
110
111
  }
@@ -100,6 +100,7 @@ class BaseNativeStakingPoolHandler extends _base.default {
100
100
  const {
101
101
  address,
102
102
  amount,
103
+ netuid,
103
104
  slug,
104
105
  targets
105
106
  } = params;
@@ -108,7 +109,8 @@ class BaseNativeStakingPoolHandler extends _base.default {
108
109
  amount,
109
110
  address,
110
111
  slug,
111
- selectedValidators
112
+ selectedValidators,
113
+ netuid
112
114
  };
113
115
  const positionInfo = await this.getPoolPosition(address);
114
116
  const [, fee] = await this.createJoinExtrinsic(data, positionInfo);
@@ -119,9 +121,10 @@ class BaseNativeStakingPoolHandler extends _base.default {
119
121
  const {
120
122
  address,
121
123
  amount,
122
- selectedValidators
124
+ selectedValidators,
125
+ slug
123
126
  } = data;
124
- const positionInfo = await this.getPoolPosition(address);
127
+ const positionInfo = await this.getPoolPosition(address, slug);
125
128
  const [extrinsic] = await this.createJoinExtrinsic(data, positionInfo);
126
129
  const bondingData = {
127
130
  poolPosition: positionInfo,
@@ -0,0 +1,444 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.getTaoToAlphaMapping = exports.default = void 0;
8
+ var _TransactionError = require("@subwallet/extension-base/background/errors/TransactionError");
9
+ var _KoniTypes = require("@subwallet/extension-base/background/KoniTypes");
10
+ var _constants = require("@subwallet/extension-base/constants");
11
+ var _utils = require("@subwallet/extension-base/koni/api/staking/bonding/utils");
12
+ var _basePara = _interopRequireDefault(require("@subwallet/extension-base/services/earning-service/handlers/native-staking/base-para"));
13
+ var _types = require("@subwallet/extension-base/types");
14
+ var _utils2 = require("@subwallet/extension-base/utils");
15
+ var _bignumber = _interopRequireDefault(require("bignumber.js"));
16
+ var _util = require("@polkadot/util");
17
+ var _utils3 = require("../../utils");
18
+ var _tao = require("./tao");
19
+ // Copyright 2019-2022 @subwallet/extension-base
20
+ // SPDX-License-Identifier: Apache-2.0
21
+
22
+ const getTaoToAlphaMapping = async substrateApi => {
23
+ const allSubnets = (await substrateApi.api.call.subnetInfoRuntimeApi.getAllDynamicInfo()).toJSON();
24
+ if (!allSubnets) {
25
+ return {};
26
+ }
27
+ return allSubnets.reduce((acc, subnet) => {
28
+ const netuid = subnet === null || subnet === void 0 ? void 0 : subnet.netuid;
29
+ const taoIn = subnet !== null && subnet !== void 0 && subnet.taoIn ? new _bignumber.default(subnet.taoIn) : new _bignumber.default(0);
30
+ const alphaIn = subnet !== null && subnet !== void 0 && subnet.alphaIn ? new _bignumber.default(subnet.alphaIn) : new _bignumber.default(0);
31
+ if (netuid === 0) {
32
+ acc[netuid] = '1';
33
+ } else if (alphaIn.gt(0)) {
34
+ acc[netuid] = taoIn.dividedBy(alphaIn).toString();
35
+ } else {
36
+ acc[netuid] = '1';
37
+ }
38
+ return acc;
39
+ }, {});
40
+ };
41
+ exports.getTaoToAlphaMapping = getTaoToAlphaMapping;
42
+ class SubnetTaoStakingPoolHandler extends _basePara.default {
43
+ /* Unimplemented function */
44
+ handleYieldWithdraw(address, unstakingInfo) {
45
+ throw new Error('Method not implemented.');
46
+ }
47
+ handleYieldCancelUnstake(params) {
48
+ throw new Error('Method not implemented.');
49
+ }
50
+ /* Unimplemented function */
51
+
52
+ // @ts-ignore
53
+ type = _types.YieldPoolType.SUBNET_STAKING;
54
+ subnetData = [];
55
+ isInit = false;
56
+ availableMethod = {
57
+ join: true,
58
+ defaultUnstake: true,
59
+ fastUnstake: false,
60
+ cancelUnstake: false,
61
+ withdraw: false,
62
+ claimReward: false
63
+ };
64
+ constructor(state, chain) {
65
+ super(state, chain);
66
+ const _chainAsset = this.nativeToken;
67
+ const _chainInfo = this.chainInfo;
68
+ const symbol = _chainAsset.symbol;
69
+ this.slug = this.slug = `${symbol}___subnet_staking___${_chainInfo.slug}`;
70
+ this.name = 'Subnet Tao Staking';
71
+ this.shortName = 'dTAO Staking';
72
+ this.bittensorCache = _tao.BittensorCache.getInstance();
73
+ }
74
+ canHandleSlug(slug) {
75
+ return slug.startsWith(`${this.slug}__`);
76
+ }
77
+ get maintainBalance() {
78
+ const ed = new _util.BN(this.nativeToken.minAmount || '0');
79
+ const calculateMaintainBalance = new _util.BN(15).mul(ed).div(_util.BN_TEN);
80
+ const maintainBalance = calculateMaintainBalance;
81
+ return maintainBalance.toString();
82
+ }
83
+ async init() {
84
+ try {
85
+ const substrateApi = await this.substrateApi.isReady;
86
+ const dynamicInfo = (await substrateApi.api.call.subnetInfoRuntimeApi.getAllDynamicInfo()).toJSON();
87
+ const subnetsInfo = (await substrateApi.api.call.subnetInfoRuntimeApi.getSubnetsInfoV2()).toJSON();
88
+ if (dynamicInfo && subnetsInfo) {
89
+ const mergedData = dynamicInfo.filter(dynInfo => dynInfo.netuid !== 0).map(dynInfo => {
90
+ var _dynInfo$subnetIdenti, _dynInfo$subnetIdenti2;
91
+ const extraInfo = subnetsInfo.find(subnet => subnet.netuid === dynInfo.netuid);
92
+ const nameRaw = ((_dynInfo$subnetIdenti = dynInfo.subnetIdentity) === null || _dynInfo$subnetIdenti === void 0 ? void 0 : _dynInfo$subnetIdenti.subnetName) || String.fromCharCode(...dynInfo.subnetName);
93
+ const identityName = (_dynInfo$subnetIdenti2 = dynInfo.subnetIdentity) !== null && _dynInfo$subnetIdenti2 !== void 0 && _dynInfo$subnetIdenti2.subnetName ? Buffer.from(dynInfo.subnetIdentity.subnetName.slice(2), 'hex').toString('utf-8') : '';
94
+ const formattedIdentityName = identityName ? identityName.charAt(0).toUpperCase() + identityName.slice(1).toLowerCase() : '';
95
+ const name = formattedIdentityName || nameRaw.charAt(0).toUpperCase() + nameRaw.slice(1);
96
+ const symbol = new TextDecoder('utf-8').decode(Uint8Array.from(dynInfo.tokenSymbol));
97
+ return {
98
+ netuid: dynInfo.netuid,
99
+ name,
100
+ symbol,
101
+ ownerHotkey: dynInfo.ownerHotkey,
102
+ maxAllowedValidators: extraInfo ? extraInfo.maxAllowedValidators : 0,
103
+ taoIn: dynInfo.taoIn
104
+ };
105
+ });
106
+ this.subnetData = mergedData;
107
+ this.isInit = true;
108
+ }
109
+ } catch (err) {
110
+ console.error(err);
111
+ this.isInit = false;
112
+ }
113
+ }
114
+ getDescription() {
115
+ return 'Stake TAO to earn yield on dTAO';
116
+ }
117
+
118
+ /* Subscribe pool info */
119
+
120
+ async subscribePoolInfo(callback) {
121
+ if (!this.isInit) {
122
+ await this.init();
123
+ }
124
+ let cancel = false;
125
+ const substrateApi = await this.substrateApi.isReady;
126
+ const updateStakingInfo = async () => {
127
+ try {
128
+ if (cancel) {
129
+ return;
130
+ }
131
+ const minDelegatorStake = (await substrateApi.api.query.subtensorModule.nominatorMinRequiredStake()).toPrimitive() || 0;
132
+ const BNminDelegatorStake = new _bignumber.default(minDelegatorStake.toString());
133
+ this.subnetData.forEach(subnet => {
134
+ const netuid = subnet.netuid.toString().padStart(2, '0');
135
+ const subnetSlug = `${this.slug}__subnet_${netuid.padStart(2, '0')}`;
136
+ const subnetName = `${subnet.name || 'Unknown'} ${netuid}`;
137
+ const bnTaoIn = new _util.BN(subnet.taoIn);
138
+ const data = {
139
+ ...this.baseInfo,
140
+ type: this.type,
141
+ slug: subnetSlug,
142
+ metadata: {
143
+ ...this.metadataInfo,
144
+ name: subnetName,
145
+ shortName: subnetName,
146
+ description: this.getDescription(),
147
+ subnetData: {
148
+ netuid: subnet.netuid,
149
+ subnetSymbol: subnet.symbol || 'dTAO'
150
+ }
151
+ },
152
+ statistic: {
153
+ assetEarning: [{
154
+ slug: this.nativeToken.slug
155
+ }],
156
+ maxCandidatePerFarmer: subnet.maxAllowedValidators,
157
+ maxWithdrawalRequestPerFarmer: 1,
158
+ earningThreshold: {
159
+ join: BNminDelegatorStake.toString(),
160
+ defaultUnstake: '0',
161
+ fastUnstake: '0'
162
+ },
163
+ eraTime: 24,
164
+ era: 0,
165
+ unstakingPeriod: 1.2,
166
+ tvl: bnTaoIn.toString()
167
+ }
168
+ };
169
+ callback(data);
170
+ });
171
+ } catch (error) {
172
+ console.error('Error updating staking info:', error);
173
+ }
174
+ };
175
+ const subscribeStakingMetadataInterval = () => {
176
+ updateStakingInfo().catch(console.error);
177
+ };
178
+ await substrateApi.isReady;
179
+ subscribeStakingMetadataInterval();
180
+ const interval = setInterval(subscribeStakingMetadataInterval, _constants.BITTENSOR_REFRESH_STAKE_APY);
181
+ return () => {
182
+ cancel = true;
183
+ clearInterval(interval);
184
+ };
185
+ }
186
+
187
+ /* Subscribe pool position */
188
+
189
+ async parseNominatorMetadata(chainInfo, address, delegatorState) {
190
+ const nominationList = [];
191
+ const getMinDelegatorStake = this.substrateApi.api.query.subtensorModule.nominatorMinRequiredStake();
192
+ const minDelegatorStake = (await getMinDelegatorStake).toString();
193
+ let allActiveStake = _util.BN_ZERO;
194
+ for (const delegate of delegatorState) {
195
+ const stake = new _bignumber.default(delegate.amount);
196
+ const originActiveStake = stake.multipliedBy(delegate.rate || new _bignumber.default(1)).toFixed(0).toString();
197
+ const bnActiveStake = new _util.BN(originActiveStake);
198
+ if (bnActiveStake.gt(_util.BN_ZERO)) {
199
+ const delegationStatus = _types.EarningStatus.EARNING_REWARD;
200
+ allActiveStake = allActiveStake.add(bnActiveStake);
201
+ nominationList.push({
202
+ status: delegationStatus,
203
+ chain: chainInfo.slug,
204
+ validatorAddress: delegate.owner,
205
+ activeStake: delegate.amount,
206
+ validatorMinStake: minDelegatorStake,
207
+ originActiveStake: originActiveStake,
208
+ validatorIdentity: delegate.identity
209
+ });
210
+ }
211
+ }
212
+ const stakingStatus = (0, _utils.getEarningStatusByNominations)(allActiveStake, nominationList);
213
+ return {
214
+ status: stakingStatus,
215
+ balanceToken: this.nativeToken.slug,
216
+ totalStake: allActiveStake.toString(),
217
+ activeStake: allActiveStake.toString(),
218
+ unstakeBalance: '0',
219
+ isBondedBefore: true,
220
+ nominations: nominationList,
221
+ unstakings: []
222
+ };
223
+ }
224
+ async subscribePoolPosition(useAddresses, rsCallback) {
225
+ if (!this.isInit) {
226
+ await this.init();
227
+ }
228
+ let cancel = false;
229
+ const substrateApi = await this.substrateApi.isReady;
230
+ const defaultInfo = this.baseInfo;
231
+ const chainInfo = this.chainInfo;
232
+ const _delegateInfo = await this.bittensorCache.get();
233
+ const getPoolPosition = async () => {
234
+ const rawDelegateStateInfos = await Promise.all(useAddresses.map(async address => (await substrateApi.api.call.stakeInfoRuntimeApi.getStakeInfoForColdkey(address)).toJSON()));
235
+ const price = await getTaoToAlphaMapping(this.substrateApi);
236
+ if (rawDelegateStateInfos && rawDelegateStateInfos.length > 0) {
237
+ rawDelegateStateInfos.forEach((rawDelegateStateInfo, i) => {
238
+ const owner = (0, _utils2.reformatAddress)(useAddresses[i], 42);
239
+ const delegateStateInfo = rawDelegateStateInfo;
240
+ const subnetPositions = {};
241
+ for (const delegate of delegateStateInfo) {
242
+ const hotkey = delegate.hotkey;
243
+ const netuid = delegate.netuid;
244
+ const stake = new _bignumber.default(delegate.stake);
245
+ const taoToAlphaPrice = new _bignumber.default(price[netuid]);
246
+ if (!subnetPositions[netuid]) {
247
+ subnetPositions[netuid] = {
248
+ delegatorState: [],
249
+ totalBalance: _util.BN_ZERO,
250
+ originalTotalStake: _util.BN_ZERO
251
+ };
252
+ }
253
+ let identity = '';
254
+ if (_delegateInfo) {
255
+ const delegateInfo = _delegateInfo.data.find(info => info.hotkey.ss58 === hotkey);
256
+ identity = delegateInfo ? delegateInfo.name : '';
257
+ }
258
+ subnetPositions[netuid].delegatorState.push({
259
+ owner: hotkey,
260
+ amount: stake.toString(),
261
+ rate: taoToAlphaPrice,
262
+ identity: identity
263
+ });
264
+ subnetPositions[netuid].totalBalance = subnetPositions[netuid].totalBalance.add(new _util.BN(stake.toString()));
265
+ subnetPositions[netuid].originalTotalStake = subnetPositions[netuid].originalTotalStake.add(new _util.BN(stake.toString()));
266
+ }
267
+ Object.values(this.subnetData).forEach(subnet => {
268
+ const netuid = subnet.netuid;
269
+ const subnetSlug = `${this.slug}__subnet_${netuid.toString().padStart(2, '0')}`;
270
+ const subnetName = `${subnet.name || 'Unknown'} ${netuid}`;
271
+ const subnetSymbol = subnet.symbol || 'dTAO';
272
+ const {
273
+ delegatorState = [],
274
+ originalTotalStake = _util.BN_ZERO
275
+ } = subnetPositions[netuid] || {};
276
+ if (delegatorState.length > 0) {
277
+ this.parseNominatorMetadata(chainInfo, owner, delegatorState).then(nominatorMetadata => {
278
+ rsCallback({
279
+ ...defaultInfo,
280
+ ...nominatorMetadata,
281
+ address: owner,
282
+ type: this.type,
283
+ slug: subnetSlug,
284
+ subnetData: {
285
+ subnetSymbol,
286
+ subnetShortName: subnetName,
287
+ originalTotalStake: originalTotalStake.toString()
288
+ }
289
+ });
290
+ }).catch(console.error);
291
+ } else {
292
+ rsCallback({
293
+ ...defaultInfo,
294
+ type: this.type,
295
+ address: owner,
296
+ balanceToken: this.nativeToken.slug,
297
+ totalStake: '0',
298
+ activeStake: '0',
299
+ unstakeBalance: '0',
300
+ status: _types.EarningStatus.NOT_STAKING,
301
+ isBondedBefore: false,
302
+ nominations: [],
303
+ unstakings: [],
304
+ slug: subnetSlug,
305
+ subnetData: {
306
+ subnetSymbol,
307
+ subnetShortName: subnetName,
308
+ originalTotalStake: '0'
309
+ }
310
+ });
311
+ }
312
+ });
313
+ });
314
+ }
315
+ };
316
+ const getStakingPositionInterval = async () => {
317
+ if (cancel) {
318
+ return;
319
+ }
320
+ await getPoolPosition();
321
+ };
322
+ getStakingPositionInterval().catch(console.error);
323
+ const intervalId = setInterval(() => {
324
+ getStakingPositionInterval().catch(console.error);
325
+ }, _constants.BITTENSOR_REFRESH_STAKE_INFO);
326
+ return () => {
327
+ cancel = true;
328
+ clearInterval(intervalId);
329
+ };
330
+ }
331
+
332
+ /* Subscribe pool position */
333
+
334
+ /* Get pool targets */
335
+ // eslint-disable-next-line @typescript-eslint/require-await
336
+ async getDevnetPoolTargets() {
337
+ const testnetDelegate = (await this.substrateApi.api.call.delegateInfoRuntimeApi.getDelegates()).toJSON();
338
+ const getNominatorMinRequiredStake = this.substrateApi.api.query.subtensorModule.nominatorMinRequiredStake();
339
+ const nominatorMinRequiredStake = (await getNominatorMinRequiredStake).toString();
340
+ const bnMinBond = new _util.BN(nominatorMinRequiredStake);
341
+ const filteredDelegates = testnetDelegate.filter(delegate => {
342
+ return delegate.returnPer1000 !== 0;
343
+ });
344
+ return filteredDelegates.map(delegate => ({
345
+ address: delegate.delegateSs58,
346
+ totalStake: '0',
347
+ ownStake: '0',
348
+ otherStake: '0',
349
+ minBond: bnMinBond.toString(),
350
+ nominatorCount: delegate.nominators.length,
351
+ commission: delegate.take / 1000,
352
+ blocked: false,
353
+ isVerified: false,
354
+ chain: this.chain,
355
+ isCrowded: false
356
+ }));
357
+ }
358
+ async getMainnetPoolTargets() {
359
+ const _topValidator = await this.bittensorCache.get();
360
+ const topValidator = _topValidator;
361
+ const getNominatorMinRequiredStake = this.substrateApi.api.query.subtensorModule.nominatorMinRequiredStake();
362
+ const nominatorMinRequiredStake = (await getNominatorMinRequiredStake).toString();
363
+ const bnMinBond = new _util.BN(nominatorMinRequiredStake);
364
+ const validatorList = topValidator.data;
365
+ const validatorAddresses = Object.keys(validatorList);
366
+ const results = await Promise.all(validatorAddresses.map(i => {
367
+ const address = validatorList[i].hotkey.ss58;
368
+ const bnTotalStake = new _util.BN(validatorList[i].stake);
369
+ const bnOwnStake = new _util.BN(validatorList[i].validator_stake);
370
+ const otherStake = bnTotalStake.sub(bnOwnStake);
371
+ const nominatorCount = validatorList[i].nominators;
372
+ const commission = validatorList[i].take;
373
+ const roundedCommission = (parseFloat(commission) * 100).toFixed(0);
374
+ const apr = (parseFloat(validatorList[i].apr) / 10 ** 9 * 100).toFixed(2);
375
+ const apyCalculate = (0, _utils3.calculateReward)(parseFloat(apr));
376
+ const name = validatorList[i].name || address;
377
+ return {
378
+ address: address,
379
+ totalStake: bnTotalStake.toString(),
380
+ ownStake: bnOwnStake.toString(),
381
+ otherStake: otherStake.toString(),
382
+ minBond: bnMinBond.toString(),
383
+ nominatorCount: nominatorCount,
384
+ commission: roundedCommission,
385
+ expectedReturn: apyCalculate.apy,
386
+ blocked: false,
387
+ isVerified: false,
388
+ chain: this.chain,
389
+ isCrowded: false,
390
+ identity: name
391
+ };
392
+ }));
393
+ return results;
394
+ }
395
+ async getPoolTargets() {
396
+ if (!this.isInit) {
397
+ await this.init();
398
+ }
399
+ if (this.chain === 'bittensor') {
400
+ return this.getMainnetPoolTargets();
401
+ } else {
402
+ return this.getDevnetPoolTargets();
403
+ }
404
+ }
405
+
406
+ /* Get pool targets */
407
+
408
+ /* Join pool action */
409
+
410
+ async createJoinExtrinsic(data, positionInfo) {
411
+ let bondDest = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'Staked';
412
+ const {
413
+ amount,
414
+ netuid,
415
+ selectedValidators: targetValidators
416
+ } = data;
417
+ const chainApi = await this.substrateApi.isReady;
418
+ const binaryAmount = new _util.BN(amount);
419
+ const selectedValidatorInfo = targetValidators[0];
420
+ const hotkey = selectedValidatorInfo.address;
421
+ const extrinsic = chainApi.api.tx.subtensorModule.addStake(hotkey, netuid, binaryAmount);
422
+ return [extrinsic, {
423
+ slug: this.nativeToken.slug,
424
+ amount: '0'
425
+ }];
426
+ }
427
+
428
+ /* Join pool action */
429
+
430
+ /* Leave pool action */
431
+
432
+ async handleYieldUnstake(amount, address, selectedTarget, netuid) {
433
+ const apiPromise = await this.substrateApi.isReady;
434
+ const binaryAmount = new _util.BN(amount);
435
+ if (!selectedTarget) {
436
+ return Promise.reject(new _TransactionError.TransactionError(_types.BasicTxErrorType.INVALID_PARAMS));
437
+ }
438
+ const extrinsic = apiPromise.api.tx.subtensorModule.removeStake(selectedTarget, netuid, binaryAmount);
439
+ return [_KoniTypes.ExtrinsicType.STAKING_UNBOND, extrinsic];
440
+ }
441
+
442
+ /* Leave pool action */
443
+ }
444
+ exports.default = SubnetTaoStakingPoolHandler;