@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.
- package/background/KoniTypes.d.ts +11 -3
- package/background/KoniTypes.js +1 -0
- package/background/errors/EvmProviderError.js +4 -0
- package/background/errors/ProviderError.d.ts +1 -1
- package/background/errors/ProviderError.js +2 -2
- package/cjs/background/KoniTypes.js +1 -0
- package/cjs/background/errors/EvmProviderError.js +4 -0
- package/cjs/background/errors/ProviderError.js +2 -2
- package/cjs/constants/environment.js +1 -1
- package/cjs/constants/index.js +21 -4
- package/cjs/core/logic-validation/transfer.js +23 -8
- package/cjs/koni/background/handlers/Extension.js +109 -89
- package/cjs/koni/background/handlers/State.js +2 -2
- package/cjs/koni/background/handlers/Tabs.js +4 -3
- package/cjs/packageInfo.js +1 -1
- package/cjs/page/index.js +1 -1
- package/cjs/services/balance-service/helpers/subscribe/substrate/index.js +3 -3
- package/cjs/services/balance-service/transfer/smart-contract.js +24 -3
- package/cjs/services/buy-service/constants/token.js +3 -0
- package/cjs/services/chain-service/index.js +11 -0
- package/cjs/services/earning-service/constants/chains.js +1 -1
- package/cjs/services/earning-service/handlers/base.js +11 -5
- package/cjs/services/earning-service/handlers/native-staking/base-para.js +7 -6
- package/cjs/services/earning-service/handlers/native-staking/base.js +6 -3
- package/cjs/services/earning-service/handlers/native-staking/dtao.js +444 -0
- package/cjs/services/earning-service/handlers/native-staking/index.js +8 -1
- package/cjs/services/earning-service/handlers/native-staking/tao.js +138 -125
- package/cjs/services/earning-service/service.js +14 -4
- package/cjs/services/fee-service/utils/tokenPayFee.js +151 -0
- package/cjs/services/inapp-notification-service/index.js +3 -0
- package/cjs/services/request-service/handler/MetadataRequestHandler.js +5 -13
- package/cjs/services/request-service/index.js +2 -2
- package/cjs/services/transaction-service/index.js +14 -5
- package/cjs/types/yield/info/base.js +1 -0
- package/cjs/utils/fee/transfer.js +47 -14
- package/cjs/utils/fetchEvmChainInfo.js +10 -5
- package/constants/environment.js +1 -1
- package/constants/index.d.ts +6 -1
- package/constants/index.js +14 -1
- package/core/logic-validation/transfer.d.ts +1 -1
- package/core/logic-validation/transfer.js +25 -10
- package/koni/background/handlers/Extension.js +82 -62
- package/koni/background/handlers/State.d.ts +1 -1
- package/koni/background/handlers/State.js +2 -2
- package/koni/background/handlers/Tabs.js +4 -3
- package/package.json +16 -6
- package/packageInfo.js +1 -1
- package/page/index.js +1 -1
- package/services/balance-service/helpers/subscribe/substrate/index.js +2 -2
- package/services/balance-service/transfer/smart-contract.d.ts +4 -2
- package/services/balance-service/transfer/smart-contract.js +24 -3
- package/services/buy-service/constants/token.js +3 -0
- package/services/chain-service/index.d.ts +1 -0
- package/services/chain-service/index.js +12 -1
- package/services/earning-service/constants/chains.js +1 -1
- package/services/earning-service/handlers/base.d.ts +7 -5
- package/services/earning-service/handlers/base.js +11 -7
- package/services/earning-service/handlers/native-staking/base-para.d.ts +1 -1
- package/services/earning-service/handlers/native-staking/base-para.js +7 -6
- package/services/earning-service/handlers/native-staking/base.d.ts +1 -1
- package/services/earning-service/handlers/native-staking/base.js +6 -3
- package/services/earning-service/handlers/native-staking/dtao.d.ts +64 -0
- package/services/earning-service/handlers/native-staking/dtao.js +434 -0
- package/services/earning-service/handlers/native-staking/index.d.ts +1 -0
- package/services/earning-service/handlers/native-staking/index.js +2 -1
- package/services/earning-service/handlers/native-staking/tao.d.ts +16 -4
- package/services/earning-service/handlers/native-staking/tao.js +136 -121
- package/services/earning-service/service.d.ts +1 -0
- package/services/earning-service/service.js +15 -5
- package/services/fee-service/interfaces.d.ts +25 -0
- package/services/fee-service/utils/tokenPayFee.d.ts +8 -0
- package/services/fee-service/utils/tokenPayFee.js +141 -0
- package/services/inapp-notification-service/index.js +3 -0
- package/services/request-service/handler/MetadataRequestHandler.d.ts +1 -1
- package/services/request-service/handler/MetadataRequestHandler.js +5 -13
- package/services/request-service/index.d.ts +1 -1
- package/services/request-service/index.js +2 -2
- package/services/transaction-service/index.js +16 -7
- package/types/bridge/index.d.ts +1 -0
- package/types/buy.d.ts +1 -1
- package/types/fee/option.d.ts +1 -1
- package/types/yield/actions/join/step.d.ts +1 -0
- package/types/yield/actions/join/submit.d.ts +1 -0
- package/types/yield/info/account/info.d.ts +14 -1
- package/types/yield/info/base.d.ts +3 -1
- package/types/yield/info/base.js +1 -0
- package/types/yield/info/chain/info.d.ts +5 -1
- package/utils/fee/transfer.d.ts +1 -1
- package/utils/fee/transfer.js +46 -13
- package/utils/fetchEvmChainInfo.d.ts +1 -1
- 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
|
|
@@ -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', '
|
|
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
|
-
|
|
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,
|
|
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;
|