@subwallet/extension-base 1.3.24-0 → 1.3.26-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 +9 -1
- 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/koni/background/handlers/Tabs.js +3 -2
- 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/buy-service/constants/token.js +3 -0
- package/cjs/services/chain-service/constants.js +1 -1
- 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/inapp-notification-service/index.js +3 -0
- package/cjs/services/transaction-service/index.js +6 -0
- package/cjs/services/transaction-service/utils.js +3 -3
- package/cjs/types/yield/info/base.js +1 -0
- package/cjs/utils/fetchEvmChainInfo.js +10 -5
- package/koni/background/handlers/Tabs.js +3 -2
- package/package.json +11 -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/buy-service/constants/token.js +3 -0
- package/services/chain-service/constants.js +1 -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/inapp-notification-service/index.js +3 -0
- package/services/transaction-service/index.js +6 -0
- package/services/transaction-service/utils.js +3 -3
- package/types/bridge/index.d.ts +1 -0
- package/types/buy.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/fetchEvmChainInfo.d.ts +1 -1
- package/utils/fetchEvmChainInfo.js +10 -5
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { _ChainInfo } from '@subwallet/chain-list/types';
|
|
2
2
|
import { ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
|
|
3
|
-
import
|
|
3
|
+
import KoniState from '@subwallet/extension-base/koni/background/handlers/State';
|
|
4
4
|
import BaseParaStakingPoolHandler from '@subwallet/extension-base/services/earning-service/handlers/native-staking/base-para';
|
|
5
|
-
import { BaseYieldPositionInfo, StakeCancelWithdrawalParams, SubmitJoinNativeStaking, TransactionData, UnstakingInfo, ValidatorInfo, YieldPoolInfo, YieldPositionInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
|
|
5
|
+
import { BaseYieldPositionInfo, StakeCancelWithdrawalParams, SubmitJoinNativeStaking, TransactionData, UnstakingInfo, ValidatorInfo, YieldPoolInfo, YieldPoolMethodInfo, YieldPositionInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
|
|
6
6
|
export interface TaoStakeInfo {
|
|
7
7
|
hotkey: string;
|
|
8
8
|
stake: string;
|
|
@@ -11,6 +11,7 @@ export interface TaoStakeInfo {
|
|
|
11
11
|
interface TaoStakingStakeOption {
|
|
12
12
|
owner: string;
|
|
13
13
|
amount: string;
|
|
14
|
+
identity?: string;
|
|
14
15
|
}
|
|
15
16
|
export interface RawDelegateState {
|
|
16
17
|
data: Array<{
|
|
@@ -35,7 +36,6 @@ interface Validator {
|
|
|
35
36
|
take: string;
|
|
36
37
|
apr: string;
|
|
37
38
|
}
|
|
38
|
-
export declare const getTaoToAlphaMapping: (substrateApi: _SubstrateApi) => Promise<Record<number, string>>;
|
|
39
39
|
export declare const BITTENSOR_API_KEY_1: string;
|
|
40
40
|
export declare const BITTENSOR_API_KEY_2: string;
|
|
41
41
|
export declare const BITTENSOR_API_KEY_3: string;
|
|
@@ -47,8 +47,20 @@ export declare const BITTENSOR_API_KEY_8: string;
|
|
|
47
47
|
export declare const BITTENSOR_API_KEY_9: string;
|
|
48
48
|
export declare const BITTENSOR_API_KEY_10: string;
|
|
49
49
|
export declare const bittensorApiKey: () => string;
|
|
50
|
-
export declare
|
|
50
|
+
export declare class BittensorCache {
|
|
51
|
+
private static instance;
|
|
52
|
+
private cache;
|
|
53
|
+
private cacheTimeout;
|
|
54
|
+
private promise;
|
|
55
|
+
private constructor();
|
|
56
|
+
static getInstance(): BittensorCache;
|
|
57
|
+
get(): Promise<ValidatorResponse>;
|
|
58
|
+
private fetchData;
|
|
59
|
+
}
|
|
51
60
|
export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHandler {
|
|
61
|
+
protected readonly availableMethod: YieldPoolMethodInfo;
|
|
62
|
+
private bittensorCache;
|
|
63
|
+
constructor(state: KoniState, chain: string);
|
|
52
64
|
handleYieldWithdraw(address: string, unstakingInfo: UnstakingInfo): Promise<TransactionData>;
|
|
53
65
|
handleYieldCancelUnstake(params: StakeCancelWithdrawalParams): Promise<TransactionData>;
|
|
54
66
|
get maintainBalance(): string;
|
|
@@ -11,25 +11,6 @@ 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
|
-
};
|
|
33
14
|
export const BITTENSOR_API_KEY_1 = process.env.BITTENSOR_API_KEY_1 || '';
|
|
34
15
|
export const BITTENSOR_API_KEY_2 = process.env.BITTENSOR_API_KEY_2 || '';
|
|
35
16
|
export const BITTENSOR_API_KEY_3 = process.env.BITTENSOR_API_KEY_3 || '';
|
|
@@ -50,20 +31,71 @@ export const bittensorApiKey = () => {
|
|
|
50
31
|
};
|
|
51
32
|
|
|
52
33
|
/* Fetch data */
|
|
34
|
+
export class BittensorCache {
|
|
35
|
+
static instance = null;
|
|
36
|
+
cache = null;
|
|
37
|
+
cacheTimeout = null;
|
|
38
|
+
promise = null;
|
|
53
39
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
40
|
+
// eslint-disable-next-line no-useless-constructor, @typescript-eslint/no-empty-function
|
|
41
|
+
constructor() {}
|
|
42
|
+
static getInstance() {
|
|
43
|
+
if (!BittensorCache.instance) {
|
|
44
|
+
BittensorCache.instance = new BittensorCache();
|
|
45
|
+
}
|
|
46
|
+
return BittensorCache.instance;
|
|
47
|
+
}
|
|
48
|
+
async get() {
|
|
49
|
+
if (this.cache) {
|
|
50
|
+
return this.cache;
|
|
51
|
+
}
|
|
52
|
+
if (this.promise) {
|
|
53
|
+
return this.promise;
|
|
54
|
+
}
|
|
55
|
+
this.promise = this.fetchData();
|
|
56
|
+
return this.promise;
|
|
57
|
+
}
|
|
58
|
+
async fetchData() {
|
|
59
|
+
const apiKey = bittensorApiKey();
|
|
60
|
+
try {
|
|
61
|
+
const resp = await fetch('https://api.taostats.io/api/validator/latest/v1?limit=200', {
|
|
62
|
+
method: 'GET',
|
|
63
|
+
headers: {
|
|
64
|
+
'Content-Type': 'application/json',
|
|
65
|
+
Authorization: `${apiKey}`
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
if (!resp.ok) {
|
|
69
|
+
console.error('Fetch bittensor delegates fail:', resp.status);
|
|
70
|
+
return this.cache || {
|
|
71
|
+
data: []
|
|
72
|
+
};
|
|
62
73
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
74
|
+
const rawData = await resp.json();
|
|
75
|
+
const data = {
|
|
76
|
+
data: rawData.data.filter(validator => parseFloat(validator.apr) > 0.0001)
|
|
77
|
+
};
|
|
78
|
+
this.cache = data;
|
|
79
|
+
this.promise = null;
|
|
80
|
+
if (this.cacheTimeout) {
|
|
81
|
+
clearTimeout(this.cacheTimeout);
|
|
82
|
+
}
|
|
83
|
+
this.cacheTimeout = setTimeout(() => {
|
|
84
|
+
this.fetchData().then(newData => {
|
|
85
|
+
if (newData.data.length > 0) {
|
|
86
|
+
this.cache = newData;
|
|
87
|
+
}
|
|
88
|
+
}).catch(console.error);
|
|
89
|
+
}, 60 * 2000);
|
|
90
|
+
return data;
|
|
91
|
+
} catch (error) {
|
|
92
|
+
console.error(error);
|
|
93
|
+
this.promise = null;
|
|
94
|
+
return this.cache || {
|
|
95
|
+
data: []
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
}
|
|
67
99
|
}
|
|
68
100
|
|
|
69
101
|
// export async function fetchTaoDelegateState (address: string): Promise<RawDelegateState> {
|
|
@@ -84,17 +116,31 @@ export async function fetchDelegates() {
|
|
|
84
116
|
|
|
85
117
|
/* Fetch data */
|
|
86
118
|
|
|
87
|
-
const testnetDelegate = {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
};
|
|
119
|
+
// const testnetDelegate = {
|
|
120
|
+
// '5G6wdAdS7hpBuH1tjuZDhpzrGw9Wf71WEVakDCxHDm1cxEQ2': {
|
|
121
|
+
// name: '0x436c6f776e4e616d65f09fa4a1',
|
|
122
|
+
// url: 'https://example.com ',
|
|
123
|
+
// image: 'https://example.com/image.png',
|
|
124
|
+
// discord: '0xe28094446973636f7264',
|
|
125
|
+
// description: 'This is an example identity.',
|
|
126
|
+
// additional: ''
|
|
127
|
+
// }
|
|
128
|
+
// };
|
|
129
|
+
|
|
97
130
|
export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHandler {
|
|
131
|
+
availableMethod = {
|
|
132
|
+
join: true,
|
|
133
|
+
defaultUnstake: true,
|
|
134
|
+
fastUnstake: false,
|
|
135
|
+
cancelUnstake: false,
|
|
136
|
+
withdraw: false,
|
|
137
|
+
claimReward: false
|
|
138
|
+
};
|
|
139
|
+
constructor(state, chain) {
|
|
140
|
+
super(state, chain);
|
|
141
|
+
this.bittensorCache = BittensorCache.getInstance();
|
|
142
|
+
}
|
|
143
|
+
|
|
98
144
|
/* Unimplemented function */
|
|
99
145
|
handleYieldWithdraw(address, unstakingInfo) {
|
|
100
146
|
return Promise.reject(new TransactionError(BasicTxErrorType.UNSUPPORTED));
|
|
@@ -121,29 +167,33 @@ export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHand
|
|
|
121
167
|
if (cancel) {
|
|
122
168
|
return;
|
|
123
169
|
}
|
|
124
|
-
const minDelegatorStake = await substrateApi.api.query.subtensorModule.nominatorMinRequiredStake();
|
|
170
|
+
const minDelegatorStake = (await substrateApi.api.query.subtensorModule.nominatorMinRequiredStake()).toPrimitive() || 0;
|
|
171
|
+
const maxValidatorPerNominator = (await substrateApi.api.query.subtensorModule.maxAllowedValidators(0)).toPrimitive();
|
|
172
|
+
const taoIn = (await substrateApi.api.query.subtensorModule.subnetTAO(0)).toPrimitive();
|
|
173
|
+
const bnTaoIn = new BN(taoIn);
|
|
125
174
|
const BNminDelegatorStake = new BigN(minDelegatorStake.toString());
|
|
126
175
|
const data = {
|
|
127
176
|
...this.baseInfo,
|
|
128
177
|
type: this.type,
|
|
129
178
|
metadata: {
|
|
130
179
|
...this.metadataInfo,
|
|
131
|
-
description: this.getDescription(
|
|
180
|
+
description: this.getDescription()
|
|
132
181
|
},
|
|
133
182
|
statistic: {
|
|
134
183
|
assetEarning: [{
|
|
135
184
|
slug: this.nativeToken.slug
|
|
136
185
|
}],
|
|
137
|
-
maxCandidatePerFarmer:
|
|
186
|
+
maxCandidatePerFarmer: Number(maxValidatorPerNominator),
|
|
138
187
|
maxWithdrawalRequestPerFarmer: 1,
|
|
139
188
|
earningThreshold: {
|
|
140
189
|
join: BNminDelegatorStake.toString(),
|
|
141
190
|
defaultUnstake: '0',
|
|
142
191
|
fastUnstake: '0'
|
|
143
192
|
},
|
|
144
|
-
eraTime:
|
|
193
|
+
eraTime: 24,
|
|
145
194
|
era: 0,
|
|
146
|
-
unstakingPeriod: 1.2
|
|
195
|
+
unstakingPeriod: 1.2,
|
|
196
|
+
tvl: bnTaoIn.toString()
|
|
147
197
|
}
|
|
148
198
|
};
|
|
149
199
|
callback(data);
|
|
@@ -181,12 +231,11 @@ export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHand
|
|
|
181
231
|
chain: chainInfo.slug,
|
|
182
232
|
validatorAddress: delegate.owner,
|
|
183
233
|
activeStake: activeStake,
|
|
184
|
-
validatorMinStake: minDelegatorStake
|
|
185
|
-
|
|
234
|
+
validatorMinStake: minDelegatorStake,
|
|
235
|
+
validatorIdentity: delegate.identity
|
|
186
236
|
});
|
|
187
237
|
}
|
|
188
238
|
}
|
|
189
|
-
|
|
190
239
|
const stakingStatus = getEarningStatusByNominations(allActiveStake, nominationList);
|
|
191
240
|
return {
|
|
192
241
|
status: stakingStatus,
|
|
@@ -204,44 +253,9 @@ export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHand
|
|
|
204
253
|
const substrateApi = await this.substrateApi.isReady;
|
|
205
254
|
const defaultInfo = this.baseInfo;
|
|
206
255
|
const chainInfo = this.chainInfo;
|
|
207
|
-
const
|
|
208
|
-
|
|
209
|
-
const delegatorState = [];
|
|
210
|
-
let bnTotalBalance = BN_ZERO;
|
|
211
|
-
const stakePromises = useAddresses.map(async address => {
|
|
212
|
-
const stakeAmount = (await substrateApi.api.query.subtensorModule.stake(testnetAddress, address)).toString();
|
|
213
|
-
const bnStakeAmount = new BN(stakeAmount);
|
|
214
|
-
bnTotalBalance = bnTotalBalance.add(bnStakeAmount);
|
|
215
|
-
delegatorState.push({
|
|
216
|
-
owner: testnetAddress,
|
|
217
|
-
amount: bnStakeAmount.toString()
|
|
218
|
-
// identity: testnetAddress
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
rsCallback({
|
|
222
|
-
...defaultInfo,
|
|
223
|
-
type: this.type,
|
|
224
|
-
address: address,
|
|
225
|
-
balanceToken: this.nativeToken.slug,
|
|
226
|
-
totalStake: bnTotalBalance.toString(),
|
|
227
|
-
activeStake: bnStakeAmount.toString(),
|
|
228
|
-
unstakeBalance: '0',
|
|
229
|
-
status: EarningStatus.EARNING_REWARD,
|
|
230
|
-
isBondedBefore: true,
|
|
231
|
-
nominations: delegatorState.map(delegate => ({
|
|
232
|
-
chain: this.chain,
|
|
233
|
-
validatorAddress: delegate.owner,
|
|
234
|
-
activeStake: delegate.amount,
|
|
235
|
-
status: EarningStatus.EARNING_REWARD
|
|
236
|
-
})),
|
|
237
|
-
unstakings: []
|
|
238
|
-
});
|
|
239
|
-
});
|
|
240
|
-
await Promise.all(stakePromises);
|
|
241
|
-
};
|
|
242
|
-
const getMainnetPoolPosition = async () => {
|
|
256
|
+
const _delegateInfo = await this.bittensorCache.get();
|
|
257
|
+
const getPoolPosition = async () => {
|
|
243
258
|
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
259
|
if (rawDelegateStateInfos && rawDelegateStateInfos.length > 0) {
|
|
246
260
|
rawDelegateStateInfos.forEach((rawDelegateStateInfo, i) => {
|
|
247
261
|
const owner = reformatAddress(useAddresses[i], 42);
|
|
@@ -253,19 +267,26 @@ export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHand
|
|
|
253
267
|
const hotkey = delegate.hotkey;
|
|
254
268
|
const netuid = delegate.netuid;
|
|
255
269
|
const stake = new BigN(delegate.stake);
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
270
|
+
if (netuid === 0) {
|
|
271
|
+
const taoStake = stake.toFixed(0);
|
|
272
|
+
if (totalDelegate[hotkey]) {
|
|
273
|
+
totalDelegate[hotkey] = new BigN(totalDelegate[hotkey]).plus(taoStake).toFixed();
|
|
274
|
+
} else {
|
|
275
|
+
totalDelegate[hotkey] = taoStake;
|
|
276
|
+
}
|
|
262
277
|
}
|
|
263
278
|
}
|
|
264
279
|
for (const hotkey in totalDelegate) {
|
|
265
280
|
bnTotalBalance = bnTotalBalance.add(new BN(totalDelegate[hotkey]));
|
|
281
|
+
let identity = '';
|
|
282
|
+
if (_delegateInfo) {
|
|
283
|
+
const delegateInfo = _delegateInfo.data.find(info => info.hotkey.ss58 === hotkey);
|
|
284
|
+
identity = delegateInfo ? delegateInfo.name : '';
|
|
285
|
+
}
|
|
266
286
|
delegatorState.push({
|
|
267
287
|
owner: hotkey,
|
|
268
|
-
amount: totalDelegate[hotkey]
|
|
288
|
+
amount: totalDelegate[hotkey],
|
|
289
|
+
identity: identity
|
|
269
290
|
});
|
|
270
291
|
}
|
|
271
292
|
if (delegateStateInfo && delegateStateInfo.length > 0) {
|
|
@@ -354,11 +375,7 @@ export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHand
|
|
|
354
375
|
if (cancel) {
|
|
355
376
|
return;
|
|
356
377
|
}
|
|
357
|
-
|
|
358
|
-
await getDevnetPoolPosition();
|
|
359
|
-
} else {
|
|
360
|
-
await getMainnetPoolPosition();
|
|
361
|
-
}
|
|
378
|
+
await getPoolPosition();
|
|
362
379
|
};
|
|
363
380
|
getStakingPositionInterval().catch(console.error);
|
|
364
381
|
const intervalId = setInterval(() => {
|
|
@@ -376,28 +393,26 @@ export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHand
|
|
|
376
393
|
|
|
377
394
|
// eslint-disable-next-line @typescript-eslint/require-await
|
|
378
395
|
async getDevnetPoolTargets() {
|
|
379
|
-
const
|
|
380
|
-
const
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
};
|
|
397
|
-
});
|
|
396
|
+
const testnetDelegate = (await this.substrateApi.api.call.delegateInfoRuntimeApi.getDelegates()).toJSON();
|
|
397
|
+
const getNominatorMinRequiredStake = this.substrateApi.api.query.subtensorModule.nominatorMinRequiredStake();
|
|
398
|
+
const nominatorMinRequiredStake = (await getNominatorMinRequiredStake).toString();
|
|
399
|
+
const bnMinBond = new BN(nominatorMinRequiredStake);
|
|
400
|
+
return testnetDelegate.map(delegate => ({
|
|
401
|
+
address: delegate.delegateSs58,
|
|
402
|
+
totalStake: '0',
|
|
403
|
+
ownStake: '0',
|
|
404
|
+
otherStake: '0',
|
|
405
|
+
minBond: bnMinBond.toString(),
|
|
406
|
+
nominatorCount: delegate.nominators.length,
|
|
407
|
+
commission: delegate.take / 1000,
|
|
408
|
+
blocked: false,
|
|
409
|
+
isVerified: false,
|
|
410
|
+
chain: this.chain,
|
|
411
|
+
isCrowded: false
|
|
412
|
+
}));
|
|
398
413
|
}
|
|
399
414
|
async getMainnetPoolTargets() {
|
|
400
|
-
const _topValidator = await
|
|
415
|
+
const _topValidator = await this.bittensorCache.get();
|
|
401
416
|
const topValidator = _topValidator;
|
|
402
417
|
const getNominatorMinRequiredStake = this.substrateApi.api.query.subtensorModule.nominatorMinRequiredStake();
|
|
403
418
|
const nominatorMinRequiredStake = (await getNominatorMinRequiredStake).toString();
|
|
@@ -434,10 +449,10 @@ export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHand
|
|
|
434
449
|
return results;
|
|
435
450
|
}
|
|
436
451
|
async getPoolTargets() {
|
|
437
|
-
if (this.chain === '
|
|
438
|
-
return this.getDevnetPoolTargets();
|
|
439
|
-
} else {
|
|
452
|
+
if (this.chain === 'bittensor') {
|
|
440
453
|
return this.getMainnetPoolTargets();
|
|
454
|
+
} else {
|
|
455
|
+
return this.getDevnetPoolTargets();
|
|
441
456
|
}
|
|
442
457
|
}
|
|
443
458
|
|
|
@@ -10,6 +10,7 @@ import { BasePoolHandler } from './handlers';
|
|
|
10
10
|
export default class EarningService implements StoppableServiceInterface, PersistDataServiceInterface {
|
|
11
11
|
protected readonly state: KoniState;
|
|
12
12
|
protected handlers: Record<string, BasePoolHandler>;
|
|
13
|
+
private handlerCache;
|
|
13
14
|
private earningRewardSubject;
|
|
14
15
|
private earningRewardHistorySubject;
|
|
15
16
|
private minAmountPercentSubject;
|
|
@@ -13,7 +13,7 @@ import { BasicTxErrorType, YieldPoolType } from '@subwallet/extension-base/types
|
|
|
13
13
|
import { addLazy, createPromiseHandler, getAddressesByChainType, removeLazy } from '@subwallet/extension-base/utils';
|
|
14
14
|
import { fetchStaticCache } from '@subwallet/extension-base/utils/fetchStaticCache';
|
|
15
15
|
import { BehaviorSubject } from 'rxjs';
|
|
16
|
-
import { AcalaLiquidStakingPoolHandler, AmplitudeNativeStakingPoolHandler, AstarNativeStakingPoolHandler, BifrostLiquidStakingPoolHandler, BifrostMantaLiquidStakingPoolHandler, InterlayLendingPoolHandler, NominationPoolHandler, ParallelLiquidStakingPoolHandler, ParaNativeStakingPoolHandler, RelayNativeStakingPoolHandler, StellaSwapLiquidStakingPoolHandler, TaoNativeStakingPoolHandler } from "./handlers/index.js";
|
|
16
|
+
import { AcalaLiquidStakingPoolHandler, AmplitudeNativeStakingPoolHandler, AstarNativeStakingPoolHandler, BifrostLiquidStakingPoolHandler, BifrostMantaLiquidStakingPoolHandler, InterlayLendingPoolHandler, NominationPoolHandler, ParallelLiquidStakingPoolHandler, ParaNativeStakingPoolHandler, RelayNativeStakingPoolHandler, StellaSwapLiquidStakingPoolHandler, SubnetTaoStakingPoolHandler, TaoNativeStakingPoolHandler } from "./handlers/index.js";
|
|
17
17
|
const fetchPoolsData = async () => {
|
|
18
18
|
const fetchData = await fetchStaticCache('earning/yield-pools.json', {
|
|
19
19
|
data: {}
|
|
@@ -22,6 +22,7 @@ const fetchPoolsData = async () => {
|
|
|
22
22
|
};
|
|
23
23
|
export default class EarningService {
|
|
24
24
|
handlers = {};
|
|
25
|
+
handlerCache = new Map();
|
|
25
26
|
earningRewardSubject = new BehaviorSubject({
|
|
26
27
|
ready: false,
|
|
27
28
|
data: {}
|
|
@@ -67,7 +68,10 @@ export default class EarningService {
|
|
|
67
68
|
handlers.push(new AmplitudeNativeStakingPoolHandler(this.state, chain));
|
|
68
69
|
}
|
|
69
70
|
if (_STAKING_CHAIN_GROUP.bittensor.includes(chain)) {
|
|
71
|
+
// todo: check support for testnet
|
|
72
|
+
// Mainnet only
|
|
70
73
|
handlers.push(new TaoNativeStakingPoolHandler(this.state, chain));
|
|
74
|
+
handlers.push(new SubnetTaoStakingPoolHandler(this.state, chain));
|
|
71
75
|
}
|
|
72
76
|
if (_STAKING_CHAIN_GROUP.mythos.includes(chain)) {
|
|
73
77
|
handlers.push(new MythosNativeStakingPoolHandler(this.state, chain));
|
|
@@ -253,7 +257,12 @@ export default class EarningService {
|
|
|
253
257
|
/* Pools' info methods */
|
|
254
258
|
|
|
255
259
|
getPoolHandler(slug) {
|
|
256
|
-
|
|
260
|
+
if (this.handlerCache.has(slug)) {
|
|
261
|
+
return this.handlerCache.get(slug);
|
|
262
|
+
}
|
|
263
|
+
const handler = Object.values(this.handlers).find(h => h.canHandleSlug(slug));
|
|
264
|
+
this.handlerCache.set(slug, handler);
|
|
265
|
+
return handler;
|
|
257
266
|
}
|
|
258
267
|
isPoolSupportAlternativeFee(slug) {
|
|
259
268
|
const handler = this.getPoolHandler(slug);
|
|
@@ -733,24 +742,25 @@ export default class EarningService {
|
|
|
733
742
|
} = params;
|
|
734
743
|
const handler = this.getPoolHandler(slug);
|
|
735
744
|
if (handler) {
|
|
736
|
-
return handler.validateYieldLeave(params.amount, params.address, params.fastLeave, params.selectedTarget);
|
|
745
|
+
return handler.validateYieldLeave(params.amount, params.address, params.fastLeave, params.selectedTarget, slug);
|
|
737
746
|
} else {
|
|
738
747
|
return Promise.reject(new TransactionError(BasicTxErrorType.INTERNAL_ERROR));
|
|
739
748
|
}
|
|
740
749
|
}
|
|
741
750
|
async handleYieldLeave(params) {
|
|
751
|
+
var _params$poolInfo$meta;
|
|
742
752
|
await this.eventService.waitChainReady;
|
|
743
753
|
const {
|
|
744
754
|
slug
|
|
745
755
|
} = params;
|
|
746
756
|
const handler = this.getPoolHandler(slug);
|
|
757
|
+
const netuid = (_params$poolInfo$meta = params.poolInfo.metadata.subnetData) === null || _params$poolInfo$meta === void 0 ? void 0 : _params$poolInfo$meta.netuid;
|
|
747
758
|
if (handler) {
|
|
748
|
-
return handler.handleYieldLeave(params.fastLeave, params.amount, params.address, params.selectedTarget);
|
|
759
|
+
return handler.handleYieldLeave(params.fastLeave, params.amount, params.address, params.selectedTarget, netuid);
|
|
749
760
|
} else {
|
|
750
761
|
return Promise.reject(new TransactionError(BasicTxErrorType.INTERNAL_ERROR));
|
|
751
762
|
}
|
|
752
763
|
}
|
|
753
|
-
|
|
754
764
|
/* Leave */
|
|
755
765
|
|
|
756
766
|
/* Other */
|
|
@@ -383,6 +383,9 @@ export class InappNotificationService {
|
|
|
383
383
|
case YieldPoolType.NATIVE_STAKING:
|
|
384
384
|
method = _STAKING_CHAIN_GROUP.astar.includes(chain.slug) ? 'dApp staking' : 'Direct nomination';
|
|
385
385
|
break;
|
|
386
|
+
case YieldPoolType.SUBNET_STAKING:
|
|
387
|
+
method = 'Subnet staking'; // todo: confirm with tester
|
|
388
|
+
break;
|
|
386
389
|
}
|
|
387
390
|
title = '[{{accountName}}] STAKED {{asset}}'.replace('{{asset}}', asset.symbol);
|
|
388
391
|
description = '{{amount}} {{asset}} on {{chain}} staked via {{method}}. Click to view details'.replace('{{amount}}', formatNumber(amount, asset.decimals || 0)).replace('{{asset}}', asset.symbol).replace('{{chain}}', chain.name).replace('{{method}}', method);
|
|
@@ -613,7 +613,13 @@ export default class TransactionService {
|
|
|
613
613
|
break;
|
|
614
614
|
case ExtrinsicType.STAKING_UNBOND:
|
|
615
615
|
{
|
|
616
|
+
var _data$poolInfo;
|
|
616
617
|
const data = parseTransactionData(transaction.data);
|
|
618
|
+
if ((_data$poolInfo = data.poolInfo) !== null && _data$poolInfo !== void 0 && _data$poolInfo.metadata.subnetData) {
|
|
619
|
+
historyItem.additionalInfo = {
|
|
620
|
+
symbol: data.poolInfo.metadata.subnetData.subnetSymbol
|
|
621
|
+
};
|
|
622
|
+
}
|
|
617
623
|
if (data.isLiquidStaking && data.derivativeTokenInfo && data.exchangeRate && data.inputTokenInfo) {
|
|
618
624
|
historyItem.amount = {
|
|
619
625
|
decimals: _getAssetDecimals(data.derivativeTokenInfo),
|
|
@@ -42,6 +42,9 @@ function getBlockExplorerAccountRoute(explorerLink) {
|
|
|
42
42
|
if (explorerLink.includes('astral.autonomys')) {
|
|
43
43
|
return 'accounts';
|
|
44
44
|
}
|
|
45
|
+
if (explorerLink.includes('taostats.io')) {
|
|
46
|
+
return 'account';
|
|
47
|
+
}
|
|
45
48
|
return 'address';
|
|
46
49
|
}
|
|
47
50
|
function getBlockExplorerTxRoute(chainInfo) {
|
|
@@ -66,9 +69,6 @@ export function getExplorerLink(chainInfo, value, type) {
|
|
|
66
69
|
return `${explorerLink}${explorerLink.endsWith('/') ? '' : '/'}${route}/${value}`;
|
|
67
70
|
}
|
|
68
71
|
if (explorerLink && isHex(hexAddPrefix(value))) {
|
|
69
|
-
if (chainInfo.slug === 'bittensor') {
|
|
70
|
-
return undefined;
|
|
71
|
-
}
|
|
72
72
|
const route = getBlockExplorerTxRoute(chainInfo);
|
|
73
73
|
if (chainInfo.slug === 'tangle') {
|
|
74
74
|
return `${explorerLink}${explorerLink.endsWith('/') ? '' : '/'}extrinsic/${value}${route}/${value}`;
|
package/types/bridge/index.d.ts
CHANGED
package/types/buy.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export interface BuyService {
|
|
|
3
3
|
network: string;
|
|
4
4
|
symbol: string;
|
|
5
5
|
}
|
|
6
|
-
export declare type SupportService = 'transak' | 'banxa' | 'coinbase' | 'moonpay' | 'onramper';
|
|
6
|
+
export declare type SupportService = 'transak' | 'banxa' | 'coinbase' | 'moonpay' | 'onramper' | 'meld';
|
|
7
7
|
export declare type OnrampAccountSupportType = 'ETHEREUM' | 'SUBSTRATE';
|
|
8
8
|
export interface BuyTokenInfo {
|
|
9
9
|
network: string;
|
|
@@ -17,6 +17,7 @@ export interface AbstractSubmitYieldJoinData {
|
|
|
17
17
|
}
|
|
18
18
|
export interface SubmitJoinNativeStaking extends AbstractSubmitYieldJoinData {
|
|
19
19
|
selectedValidators: ValidatorInfo[];
|
|
20
|
+
netuid?: number;
|
|
20
21
|
}
|
|
21
22
|
export interface SubmitJoinNominationPool extends AbstractSubmitYieldJoinData {
|
|
22
23
|
selectedPool: NominationPoolInfo;
|
|
@@ -43,6 +43,11 @@ export interface AbstractYieldPositionInfo extends BaseYieldPositionInfo {
|
|
|
43
43
|
status: EarningStatus;
|
|
44
44
|
/** List unstake request of the account - use for nomination pool and native staking */
|
|
45
45
|
unstakings: UnstakingInfo[];
|
|
46
|
+
subnetData?: {
|
|
47
|
+
subnetSymbol: string;
|
|
48
|
+
subnetShortName: string;
|
|
49
|
+
originalTotalStake: string;
|
|
50
|
+
};
|
|
46
51
|
}
|
|
47
52
|
/**
|
|
48
53
|
* @interface SpecialYieldPositionInfo
|
|
@@ -86,7 +91,15 @@ export interface NominationYieldPositionInfo extends AbstractYieldPositionInfo {
|
|
|
86
91
|
export interface NativeYieldPositionInfo extends AbstractYieldPositionInfo {
|
|
87
92
|
type: YieldPoolType.NATIVE_STAKING;
|
|
88
93
|
}
|
|
94
|
+
export interface SubnetYieldPositionInfo extends AbstractYieldPositionInfo {
|
|
95
|
+
type: YieldPoolType.SUBNET_STAKING;
|
|
96
|
+
subnetData?: {
|
|
97
|
+
subnetSymbol: string;
|
|
98
|
+
subnetShortName: string;
|
|
99
|
+
originalTotalStake: string;
|
|
100
|
+
};
|
|
101
|
+
}
|
|
89
102
|
/**
|
|
90
103
|
* Info of yield pool
|
|
91
104
|
* */
|
|
92
|
-
export declare type YieldPositionInfo = NativeYieldPositionInfo | NominationYieldPositionInfo | LiquidYieldPositionInfo | LendingYieldPositionInfo;
|
|
105
|
+
export declare type YieldPositionInfo = NativeYieldPositionInfo | NominationYieldPositionInfo | LiquidYieldPositionInfo | LendingYieldPositionInfo | SubnetYieldPositionInfo;
|
|
@@ -14,7 +14,9 @@ export declare enum YieldPoolType {
|
|
|
14
14
|
/** Native staking */
|
|
15
15
|
NATIVE_STAKING = "NATIVE_STAKING",
|
|
16
16
|
/** Parachain staking */
|
|
17
|
-
PARACHAIN_STAKING = "PARACHAIN_STAKING"
|
|
17
|
+
PARACHAIN_STAKING = "PARACHAIN_STAKING",
|
|
18
|
+
/** Subnet stakingg */
|
|
19
|
+
SUBNET_STAKING = "SUBNET_STAKING"
|
|
18
20
|
}
|
|
19
21
|
/**
|
|
20
22
|
* @enum {number}
|
package/types/yield/info/base.js
CHANGED
|
@@ -18,6 +18,7 @@ export let YieldPoolType;
|
|
|
18
18
|
YieldPoolType["NOMINATION_POOL"] = "NOMINATION_POOL";
|
|
19
19
|
YieldPoolType["NATIVE_STAKING"] = "NATIVE_STAKING";
|
|
20
20
|
YieldPoolType["PARACHAIN_STAKING"] = "PARACHAIN_STAKING";
|
|
21
|
+
YieldPoolType["SUBNET_STAKING"] = "SUBNET_STAKING";
|
|
21
22
|
})(YieldPoolType || (YieldPoolType = {}));
|
|
22
23
|
export let YieldCompoundingPeriod;
|
|
23
24
|
|
|
@@ -84,6 +84,10 @@ export interface BaseYieldPoolMetadata {
|
|
|
84
84
|
maintainBalance: string;
|
|
85
85
|
/** Pool's available method */
|
|
86
86
|
availableMethod: YieldPoolMethodInfo;
|
|
87
|
+
subnetData?: {
|
|
88
|
+
netuid: number;
|
|
89
|
+
subnetSymbol: string;
|
|
90
|
+
};
|
|
87
91
|
}
|
|
88
92
|
/**
|
|
89
93
|
* @interface NormalYieldPoolMetadata
|
|
@@ -235,7 +239,7 @@ export interface NominationYieldPoolInfo extends AbstractYieldPoolInfo {
|
|
|
235
239
|
* @prop {NormalYieldPoolStatistic} [statistic] - Pool's metadata
|
|
236
240
|
* */
|
|
237
241
|
export interface NativeYieldPoolInfo extends AbstractYieldPoolInfo {
|
|
238
|
-
type: YieldPoolType.NATIVE_STAKING;
|
|
242
|
+
type: YieldPoolType.NATIVE_STAKING | YieldPoolType.SUBNET_STAKING;
|
|
239
243
|
metadata: NormalYieldPoolMetadata;
|
|
240
244
|
statistic?: NormalYieldPoolStatistic;
|
|
241
245
|
maxPoolMembers?: number;
|