@subwallet/extension-base 1.1.31-beta.0 → 1.1.32-beta.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 +1 -0
- package/cjs/koni/api/staking/bonding/index.js +2 -0
- package/cjs/koni/api/staking/bonding/paraChain.js +6 -3
- package/cjs/koni/background/cron.js +0 -28
- package/cjs/koni/background/handlers/Extension.js +17 -11
- package/cjs/koni/background/handlers/State.js +4 -46
- package/cjs/koni/background/subscription.js +0 -155
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/campaign-service/index.js +19 -0
- package/cjs/services/chain-service/constants.js +3 -2
- package/cjs/services/earning-service/constants/chains.js +1 -1
- package/cjs/services/earning-service/handlers/base.js +9 -6
- package/cjs/services/earning-service/handlers/lending/base.js +61 -0
- package/cjs/services/earning-service/handlers/lending/interlay.js +3 -2
- package/cjs/services/earning-service/handlers/liquid-staking/acala.js +3 -2
- package/cjs/services/earning-service/handlers/liquid-staking/base.js +54 -0
- package/cjs/services/earning-service/handlers/liquid-staking/bifrost.js +3 -2
- package/cjs/services/earning-service/handlers/liquid-staking/parallel.js +3 -2
- package/cjs/services/earning-service/handlers/liquid-staking/stella-swap.js +16 -7
- package/cjs/services/earning-service/handlers/native-staking/amplitude.js +7 -2
- package/cjs/services/earning-service/handlers/native-staking/astar.js +7 -2
- package/cjs/services/earning-service/handlers/native-staking/base.js +4 -2
- package/cjs/services/earning-service/handlers/native-staking/para-chain.js +7 -2
- package/cjs/services/earning-service/handlers/native-staking/relay-chain.js +12 -3
- package/cjs/services/earning-service/handlers/nomination-pool/index.js +9 -3
- package/cjs/services/earning-service/handlers/special.js +57 -67
- package/cjs/services/earning-service/service.js +370 -37
- package/cjs/services/event-service/index.js +1 -0
- package/cjs/services/migration-service/scripts/index.js +1 -2
- package/cjs/services/storage-service/DatabaseService.js +15 -0
- package/cjs/services/storage-service/db-stores/Campaign.js +9 -3
- package/cjs/services/storage-service/db-stores/YieldPositionStore.js +6 -0
- package/cjs/services/transaction-service/index.js +15 -1
- package/cjs/utils/number.js +3 -1
- package/koni/api/staking/bonding/index.d.ts +1 -0
- package/koni/api/staking/bonding/index.js +2 -0
- package/koni/api/staking/bonding/paraChain.js +6 -3
- package/koni/background/cron.d.ts +0 -5
- package/koni/background/cron.js +1 -29
- package/koni/background/handlers/Extension.js +17 -11
- package/koni/background/handlers/State.d.ts +1 -12
- package/koni/background/handlers/State.js +4 -46
- package/koni/background/subscription.d.ts +1 -11
- package/koni/background/subscription.js +2 -157
- package/package.json +6 -6
- package/packageInfo.js +1 -1
- package/services/campaign-service/index.js +19 -0
- package/services/chain-service/constants.js +3 -2
- package/services/earning-service/constants/chains.js +1 -1
- package/services/earning-service/handlers/base.d.ts +1 -0
- package/services/earning-service/handlers/base.js +9 -6
- package/services/earning-service/handlers/lending/base.d.ts +2 -0
- package/services/earning-service/handlers/lending/base.js +61 -0
- package/services/earning-service/handlers/lending/interlay.js +4 -3
- package/services/earning-service/handlers/liquid-staking/acala.js +4 -3
- package/services/earning-service/handlers/liquid-staking/base.d.ts +2 -0
- package/services/earning-service/handlers/liquid-staking/base.js +55 -1
- package/services/earning-service/handlers/liquid-staking/bifrost.js +4 -3
- package/services/earning-service/handlers/liquid-staking/parallel.js +4 -3
- package/services/earning-service/handlers/liquid-staking/stella-swap.js +16 -7
- package/services/earning-service/handlers/native-staking/amplitude.js +7 -2
- package/services/earning-service/handlers/native-staking/astar.js +7 -2
- package/services/earning-service/handlers/native-staking/base.js +5 -3
- package/services/earning-service/handlers/native-staking/para-chain.js +7 -2
- package/services/earning-service/handlers/native-staking/relay-chain.js +12 -3
- package/services/earning-service/handlers/nomination-pool/index.js +10 -4
- package/services/earning-service/handlers/special.d.ts +0 -1
- package/services/earning-service/handlers/special.js +58 -68
- package/services/earning-service/service.d.ts +49 -1
- package/services/earning-service/service.js +358 -28
- package/services/event-service/index.d.ts +1 -0
- package/services/event-service/index.js +1 -0
- package/services/event-service/types.d.ts +1 -0
- package/services/migration-service/scripts/index.js +1 -2
- package/services/storage-service/DatabaseService.d.ts +5 -0
- package/services/storage-service/DatabaseService.js +15 -0
- package/services/storage-service/db-stores/Campaign.js +9 -3
- package/services/storage-service/db-stores/YieldPositionStore.d.ts +2 -0
- package/services/storage-service/db-stores/YieldPositionStore.js +6 -0
- package/services/transaction-service/index.js +15 -1
- package/types/yield/actions/join/submit.d.ts +2 -1
- package/types/yield/info/account/reward.d.ts +2 -0
- package/utils/number.d.ts +1 -0
- package/utils/number.js +1 -0
|
@@ -3,13 +3,25 @@
|
|
|
3
3
|
|
|
4
4
|
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
|
|
5
5
|
import { BasicTxErrorType } from '@subwallet/extension-base/background/KoniTypes';
|
|
6
|
+
import { CRON_REFRESH_EARNING_REWARD_HISTORY_INTERVAL, CRON_REFRESH_STAKING_REWARD_FAST_INTERVAL } from '@subwallet/extension-base/constants';
|
|
7
|
+
import { ServiceStatus } from '@subwallet/extension-base/services/base/types';
|
|
6
8
|
import { _isChainEvmCompatible } from '@subwallet/extension-base/services/chain-service/utils';
|
|
7
9
|
import { _STAKING_CHAIN_GROUP } from '@subwallet/extension-base/services/earning-service/constants';
|
|
8
10
|
import BaseLiquidStakingPoolHandler from '@subwallet/extension-base/services/earning-service/handlers/liquid-staking/base';
|
|
9
11
|
import { YieldPoolType } from '@subwallet/extension-base/types';
|
|
10
|
-
import { categoryAddresses } from '@subwallet/extension-base/utils';
|
|
12
|
+
import { addLazy, categoryAddresses, createPromiseHandler } from '@subwallet/extension-base/utils';
|
|
13
|
+
import fetch from 'cross-fetch';
|
|
11
14
|
import { BehaviorSubject } from 'rxjs';
|
|
12
15
|
import { AcalaLiquidStakingPoolHandler, AmplitudeNativeStakingPoolHandler, AstarNativeStakingPoolHandler, BifrostLiquidStakingPoolHandler, InterlayLendingPoolHandler, NominationPoolHandler, ParallelLiquidStakingPoolHandler, ParaNativeStakingPoolHandler, RelayNativeStakingPoolHandler, StellaSwapLiquidStakingPoolHandler } from "./handlers/index.js";
|
|
16
|
+
const POOLS_DATA_URLS = 'https://sw-static-cache.pages.dev/earning/yield-pools.json';
|
|
17
|
+
const fetchPoolsData = async () => {
|
|
18
|
+
const res = await fetch(POOLS_DATA_URLS);
|
|
19
|
+
if (res.status !== 200) {
|
|
20
|
+
return {};
|
|
21
|
+
}
|
|
22
|
+
const fetchData = await res.json();
|
|
23
|
+
return fetchData.data;
|
|
24
|
+
};
|
|
13
25
|
export default class EarningService {
|
|
14
26
|
handlers = {};
|
|
15
27
|
earningRewardSubject = new BehaviorSubject({
|
|
@@ -18,13 +30,25 @@ export default class EarningService {
|
|
|
18
30
|
});
|
|
19
31
|
earningRewardHistorySubject = new BehaviorSubject({});
|
|
20
32
|
minAmountPercentSubject = new BehaviorSubject({});
|
|
33
|
+
|
|
34
|
+
// earning
|
|
35
|
+
yieldPoolInfoSubject = new BehaviorSubject({});
|
|
36
|
+
yieldPositionSubject = new BehaviorSubject({});
|
|
37
|
+
yieldPositionListSubject = new BehaviorSubject([]); // virtual list of yieldPositionSubject with filter values
|
|
38
|
+
|
|
21
39
|
constructor(state) {
|
|
22
40
|
this.state = state;
|
|
23
|
-
this.
|
|
41
|
+
this.dbService = state.dbService;
|
|
42
|
+
this.eventService = state.eventService;
|
|
24
43
|
}
|
|
25
44
|
async initHandlers() {
|
|
26
|
-
await this.
|
|
27
|
-
const chains =
|
|
45
|
+
await this.eventService.waitChainReady;
|
|
46
|
+
const chains = [];
|
|
47
|
+
for (const chain of Object.values(this.state.getChainInfoMap())) {
|
|
48
|
+
if (chain.chainStatus === 'ACTIVE') {
|
|
49
|
+
chains.push(chain.slug);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
28
52
|
const minAmountPercent = {};
|
|
29
53
|
for (const chain of chains) {
|
|
30
54
|
const handlers = [];
|
|
@@ -73,7 +97,126 @@ export default class EarningService {
|
|
|
73
97
|
}
|
|
74
98
|
minAmountPercent.default = BaseLiquidStakingPoolHandler.defaultMinAmountPercent;
|
|
75
99
|
this.minAmountPercentSubject.next(minAmountPercent);
|
|
100
|
+
|
|
101
|
+
// Emit earning ready
|
|
102
|
+
this.eventService.emit('earning.ready', true);
|
|
76
103
|
}
|
|
104
|
+
startPromiseHandler = createPromiseHandler();
|
|
105
|
+
stopPromiseHandler = createPromiseHandler();
|
|
106
|
+
status = ServiceStatus.NOT_INITIALIZED;
|
|
107
|
+
async init() {
|
|
108
|
+
this.status = ServiceStatus.INITIALIZING;
|
|
109
|
+
await this.initHandlers();
|
|
110
|
+
|
|
111
|
+
// Load data from db
|
|
112
|
+
await this.loadData();
|
|
113
|
+
|
|
114
|
+
// Pin list with value from map
|
|
115
|
+
this.yieldPositionSubject.subscribe({
|
|
116
|
+
next: data => {
|
|
117
|
+
const activeMap = this.state.getActiveChainInfoMap();
|
|
118
|
+
const activePositions = Object.values(data).filter(item => {
|
|
119
|
+
return !!activeMap[item.chain];
|
|
120
|
+
});
|
|
121
|
+
this.yieldPositionListSubject.next(Object.values(activePositions));
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
this.status = ServiceStatus.INITIALIZED;
|
|
125
|
+
await this.start();
|
|
126
|
+
this.handleActions();
|
|
127
|
+
}
|
|
128
|
+
handleActions() {
|
|
129
|
+
this.eventService.onLazy((events, eventTypes) => {
|
|
130
|
+
(async () => {
|
|
131
|
+
const removedAddresses = [];
|
|
132
|
+
events.forEach(event => {
|
|
133
|
+
if (event.type === 'account.remove') {
|
|
134
|
+
removedAddresses.push(event.data[0]);
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
if (removedAddresses.length > 0) {
|
|
138
|
+
await this.removeYieldPositions(undefined, removedAddresses);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Account changed or chain changed (active or inactive)
|
|
142
|
+
// Chain changed (active or inactive)
|
|
143
|
+
// Todo: Optimize performance of chain active or inactive in the future
|
|
144
|
+
if (eventTypes.includes('account.updateCurrent') || eventTypes.includes('account.remove') || eventTypes.includes('chain.updateState')) {
|
|
145
|
+
await this.reloadEarning();
|
|
146
|
+
}
|
|
147
|
+
})().catch(console.error);
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
async loadData() {
|
|
151
|
+
await this.getYieldPoolInfoFromDBAndOnline();
|
|
152
|
+
await this.getYieldPositionFromDB();
|
|
153
|
+
}
|
|
154
|
+
persistData() {
|
|
155
|
+
// Data is auto persisted with lazy queue
|
|
156
|
+
return Promise.resolve(undefined);
|
|
157
|
+
}
|
|
158
|
+
async start() {
|
|
159
|
+
if (this.status === ServiceStatus.STOPPING) {
|
|
160
|
+
await this.waitForStopped();
|
|
161
|
+
}
|
|
162
|
+
if (this.status === ServiceStatus.STARTED || this.status === ServiceStatus.STARTING) {
|
|
163
|
+
return this.waitForStarted();
|
|
164
|
+
}
|
|
165
|
+
this.status = ServiceStatus.STARTING;
|
|
166
|
+
|
|
167
|
+
// Start subscribe pools' info
|
|
168
|
+
await this.runSubscribePoolsInfo();
|
|
169
|
+
|
|
170
|
+
// Start subscribe pools' position
|
|
171
|
+
await this.runSubscribePoolsPosition();
|
|
172
|
+
|
|
173
|
+
// Start subscribe pools' reward
|
|
174
|
+
this.runSubscribeStakingRewardInterval();
|
|
175
|
+
|
|
176
|
+
// Start subscribe pools' reward history
|
|
177
|
+
this.runSubscribeEarningRewardHistoryInterval();
|
|
178
|
+
|
|
179
|
+
// Update promise handler
|
|
180
|
+
this.startPromiseHandler.resolve();
|
|
181
|
+
this.stopPromiseHandler = createPromiseHandler();
|
|
182
|
+
this.status = ServiceStatus.STARTED;
|
|
183
|
+
}
|
|
184
|
+
async stop() {
|
|
185
|
+
if (this.status === ServiceStatus.STARTING) {
|
|
186
|
+
await this.waitForStarted();
|
|
187
|
+
}
|
|
188
|
+
if (this.status === ServiceStatus.STOPPED || this.status === ServiceStatus.STOPPING) {
|
|
189
|
+
return this.waitForStopped();
|
|
190
|
+
}
|
|
191
|
+
this.status = ServiceStatus.STOPPING;
|
|
192
|
+
await this.persistData();
|
|
193
|
+
|
|
194
|
+
// Stop subscribe pools' info
|
|
195
|
+
this.runUnsubscribePoolsInfo();
|
|
196
|
+
|
|
197
|
+
// Stop subscribe pools' position
|
|
198
|
+
this.runUnsubscribePoolsPosition();
|
|
199
|
+
|
|
200
|
+
// Stop subscribe pools' reward
|
|
201
|
+
this.runUnsubscribeStakingRewardInterval();
|
|
202
|
+
|
|
203
|
+
// Stop subscribe pools' reward history
|
|
204
|
+
this.runUnsubscribeEarningRewardHistoryInterval();
|
|
205
|
+
|
|
206
|
+
// Update promise handler
|
|
207
|
+
this.stopPromiseHandler.resolve();
|
|
208
|
+
this.startPromiseHandler = createPromiseHandler();
|
|
209
|
+
this.status = ServiceStatus.STOPPED;
|
|
210
|
+
}
|
|
211
|
+
waitForStarted() {
|
|
212
|
+
return this.startPromiseHandler.promise;
|
|
213
|
+
}
|
|
214
|
+
waitForStopped() {
|
|
215
|
+
return this.stopPromiseHandler.promise;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/* Pools' info methods */
|
|
219
|
+
|
|
77
220
|
getPoolHandler(slug) {
|
|
78
221
|
return this.handlers[slug];
|
|
79
222
|
}
|
|
@@ -91,19 +234,20 @@ export default class EarningService {
|
|
|
91
234
|
getMinAmountPercent() {
|
|
92
235
|
return this.minAmountPercentSubject.getValue();
|
|
93
236
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
237
|
+
async getYieldPool(slug) {
|
|
238
|
+
await this.eventService.waitEarningReady;
|
|
239
|
+
return this.yieldPoolInfoSubject.getValue()[slug];
|
|
240
|
+
}
|
|
97
241
|
async subscribePoolsInfo(callback) {
|
|
98
242
|
let cancel = false;
|
|
99
|
-
await this.
|
|
243
|
+
await this.eventService.waitChainReady;
|
|
100
244
|
const unsubList = [];
|
|
101
245
|
for (const handler of Object.values(this.handlers)) {
|
|
102
246
|
handler.subscribePoolInfo(callback).then(unsub => {
|
|
103
|
-
if (cancel) {
|
|
104
|
-
unsub();
|
|
105
|
-
} else {
|
|
247
|
+
if (!cancel) {
|
|
106
248
|
unsubList.push(unsub);
|
|
249
|
+
} else {
|
|
250
|
+
unsub();
|
|
107
251
|
}
|
|
108
252
|
}).catch(console.error);
|
|
109
253
|
}
|
|
@@ -114,14 +258,71 @@ export default class EarningService {
|
|
|
114
258
|
});
|
|
115
259
|
};
|
|
116
260
|
}
|
|
261
|
+
async getYieldPoolInfoFromDBAndOnline() {
|
|
262
|
+
// Get online pool data
|
|
263
|
+
const yieldPoolInfo = await Promise.race([fetchPoolsData(), new Promise(resolve => {
|
|
264
|
+
setTimeout(() => {
|
|
265
|
+
resolve({});
|
|
266
|
+
}, 1200);
|
|
267
|
+
})]);
|
|
268
|
+
const existedYieldPoolInfo = await this.dbService.getYieldPools();
|
|
269
|
+
existedYieldPoolInfo.forEach(info => {
|
|
270
|
+
if (!yieldPoolInfo[info.slug]) {
|
|
271
|
+
yieldPoolInfo[info.slug] = info;
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
this.yieldPoolInfoSubject.next(yieldPoolInfo);
|
|
275
|
+
}
|
|
276
|
+
subscribeYieldPoolInfo() {
|
|
277
|
+
return this.yieldPoolInfoSubject;
|
|
278
|
+
}
|
|
279
|
+
async getYieldPoolInfo() {
|
|
280
|
+
await this.eventService.waitEarningReady;
|
|
281
|
+
return Object.values(this.yieldPoolInfoSubject.getValue());
|
|
282
|
+
}
|
|
283
|
+
yieldPoolPersistQueue = [];
|
|
284
|
+
updateYieldPoolInfo(data) {
|
|
285
|
+
this.yieldPoolPersistQueue.push(data);
|
|
286
|
+
addLazy('persistYieldPoolInfo', () => {
|
|
287
|
+
const yieldPoolInfo = this.yieldPoolInfoSubject.getValue();
|
|
288
|
+
const queue = [...this.yieldPoolPersistQueue];
|
|
289
|
+
this.yieldPoolPersistQueue = [];
|
|
290
|
+
|
|
291
|
+
// Update yield pool info
|
|
292
|
+
queue.forEach(item => {
|
|
293
|
+
yieldPoolInfo[item.slug] = item;
|
|
294
|
+
});
|
|
295
|
+
this.yieldPoolInfoSubject.next(yieldPoolInfo);
|
|
296
|
+
|
|
297
|
+
// Persist data
|
|
298
|
+
this.dbService.updateYieldPoolsStore(queue).catch(console.warn);
|
|
299
|
+
}, 300, 900);
|
|
300
|
+
}
|
|
301
|
+
async runSubscribePoolsInfo() {
|
|
302
|
+
await this.eventService.waitChainReady;
|
|
303
|
+
this.runUnsubscribePoolsInfo();
|
|
304
|
+
this.subscribePoolsInfo(data => {
|
|
305
|
+
this.updateYieldPoolInfo(data);
|
|
306
|
+
}).then(rs => {
|
|
307
|
+
this.yieldPoolsInfoUnsub = rs;
|
|
308
|
+
}).catch(console.error);
|
|
309
|
+
}
|
|
310
|
+
runUnsubscribePoolsInfo() {
|
|
311
|
+
var _this$yieldPoolsInfoU;
|
|
312
|
+
(_this$yieldPoolsInfoU = this.yieldPoolsInfoUnsub) === null || _this$yieldPoolsInfoU === void 0 ? void 0 : _this$yieldPoolsInfoU.call(this);
|
|
313
|
+
}
|
|
117
314
|
|
|
118
|
-
/*
|
|
315
|
+
/* Pools' info methods */
|
|
119
316
|
|
|
120
|
-
/*
|
|
317
|
+
/* Pools' position methods */
|
|
121
318
|
|
|
319
|
+
async getYieldPosition(address, slug) {
|
|
320
|
+
await this.eventService.waitEarningReady;
|
|
321
|
+
return this.yieldPositionSubject.getValue()[`${slug}---${address}`];
|
|
322
|
+
}
|
|
122
323
|
async subscribePoolPositions(addresses, callback) {
|
|
123
324
|
let cancel = false;
|
|
124
|
-
await this.
|
|
325
|
+
await this.eventService.waitChainReady;
|
|
125
326
|
const [substrateAddresses, evmAddresses] = categoryAddresses(addresses);
|
|
126
327
|
const activeChains = this.state.activeChainSlugs;
|
|
127
328
|
const unsubList = [];
|
|
@@ -145,8 +346,102 @@ export default class EarningService {
|
|
|
145
346
|
});
|
|
146
347
|
};
|
|
147
348
|
}
|
|
349
|
+
async removeYieldPositions(chains, addresses) {
|
|
350
|
+
const removeKeys = [];
|
|
351
|
+
chains && chains.length > 0 && Object.entries(this.yieldPositionSubject.getValue()).forEach(([key, value]) => {
|
|
352
|
+
console.log('removeYieldPositions', key, value.chain, chains.indexOf(value.chain) > -1);
|
|
353
|
+
if (chains.indexOf(value.chain) > -1 && !removeKeys.includes(key)) {
|
|
354
|
+
removeKeys.push(key);
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
addresses && addresses.length > 0 && Object.entries(this.yieldPositionSubject.getValue()).forEach(([key, value]) => {
|
|
358
|
+
if (addresses.indexOf(value.address) > -1 && !removeKeys.includes(key)) {
|
|
359
|
+
removeKeys.push(key);
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
// Remove by keys
|
|
364
|
+
const yieldPositionInfo = this.yieldPositionSubject.getValue();
|
|
365
|
+
for (const key of removeKeys) {
|
|
366
|
+
delete yieldPositionInfo[key];
|
|
367
|
+
}
|
|
368
|
+
this.yieldPositionSubject.next(yieldPositionInfo);
|
|
369
|
+
addresses && addresses.length > 0 && (await this.dbService.removeYieldPositionByAddresses(addresses));
|
|
370
|
+
chains && chains.length > 0 && (await this.dbService.removeYieldPositionByChains(chains));
|
|
371
|
+
}
|
|
372
|
+
async getYieldPositionFromDB() {
|
|
373
|
+
await this.eventService.waitChainReady;
|
|
374
|
+
await this.eventService.waitKeyringReady;
|
|
375
|
+
const addresses = this.state.getDecodedAddresses();
|
|
376
|
+
const existedYieldPosition = await this.dbService.getYieldNominationPoolPosition(addresses, this.state.activeChainSlugs);
|
|
377
|
+
const yieldPositionInfo = this.yieldPositionSubject.getValue();
|
|
378
|
+
existedYieldPosition.forEach(item => {
|
|
379
|
+
yieldPositionInfo[this._getYieldPositionKey(item.slug, item.address)] = item;
|
|
380
|
+
});
|
|
381
|
+
this.yieldPositionSubject.next(yieldPositionInfo);
|
|
382
|
+
}
|
|
383
|
+
subscribeYieldPosition() {
|
|
384
|
+
return this.yieldPositionListSubject;
|
|
385
|
+
}
|
|
386
|
+
async getYieldPositionInfo() {
|
|
387
|
+
await this.eventService.waitEarningReady;
|
|
388
|
+
return Promise.resolve(this.yieldPositionListSubject.getValue());
|
|
389
|
+
}
|
|
390
|
+
yieldPositionPersistQueue = [];
|
|
391
|
+
resetYieldPositionQueue() {
|
|
392
|
+
this.yieldPositionPersistQueue = [];
|
|
393
|
+
}
|
|
394
|
+
resetYieldPosition() {
|
|
395
|
+
this.yieldPositionSubject.next({});
|
|
396
|
+
this.yieldPositionPersistQueue = [];
|
|
397
|
+
}
|
|
398
|
+
_getYieldPositionKey(slug, address) {
|
|
399
|
+
return `${slug}---${address}`;
|
|
400
|
+
}
|
|
401
|
+
updateYieldPosition(data) {
|
|
402
|
+
this.yieldPositionPersistQueue.push(data);
|
|
403
|
+
addLazy('persistYieldPositionInfo', () => {
|
|
404
|
+
const yieldPositionInfo = this.yieldPositionSubject.getValue();
|
|
405
|
+
const queue = [...this.yieldPositionPersistQueue];
|
|
406
|
+
this.yieldPositionPersistQueue = [];
|
|
407
|
+
|
|
408
|
+
// Update yield position info
|
|
409
|
+
queue.forEach(item => {
|
|
410
|
+
yieldPositionInfo[this._getYieldPositionKey(item.slug, item.address)] = item;
|
|
411
|
+
});
|
|
412
|
+
this.yieldPositionSubject.next(yieldPositionInfo);
|
|
413
|
+
|
|
414
|
+
// Persist data
|
|
415
|
+
this.dbService.updateYieldPositions(queue).catch(console.warn);
|
|
416
|
+
}, 300, 900);
|
|
417
|
+
}
|
|
418
|
+
async reloadEarning(reset = false) {
|
|
419
|
+
await this.waitForStarted();
|
|
420
|
+
this.runUnsubscribePoolsPosition();
|
|
421
|
+
this.runUnsubscribeStakingRewardInterval();
|
|
422
|
+
this.runUnsubscribeEarningRewardHistoryInterval();
|
|
423
|
+
reset && this.resetYieldPosition();
|
|
424
|
+
await this.runSubscribePoolsPosition();
|
|
425
|
+
this.runSubscribeStakingRewardInterval();
|
|
426
|
+
this.runSubscribeEarningRewardHistoryInterval();
|
|
427
|
+
}
|
|
428
|
+
async runSubscribePoolsPosition() {
|
|
429
|
+
await this.eventService.waitKeyringReady;
|
|
430
|
+
this.runUnsubscribePoolsPosition();
|
|
431
|
+
const addresses = this.state.getDecodedAddresses();
|
|
432
|
+
this.subscribePoolPositions(addresses, data => {
|
|
433
|
+
this.updateYieldPosition(data);
|
|
434
|
+
}).then(rs => {
|
|
435
|
+
this.yieldPositionUnsub = rs;
|
|
436
|
+
}).catch(console.error);
|
|
437
|
+
}
|
|
438
|
+
runUnsubscribePoolsPosition() {
|
|
439
|
+
var _this$yieldPositionUn;
|
|
440
|
+
(_this$yieldPositionUn = this.yieldPositionUnsub) === null || _this$yieldPositionUn === void 0 ? void 0 : _this$yieldPositionUn.call(this);
|
|
441
|
+
this.yieldPositionPersistQueue = [];
|
|
442
|
+
}
|
|
148
443
|
|
|
149
|
-
/*
|
|
444
|
+
/* Pools' position methods */
|
|
150
445
|
|
|
151
446
|
/* Get pools' reward */
|
|
152
447
|
|
|
@@ -159,7 +454,7 @@ export default class EarningService {
|
|
|
159
454
|
}
|
|
160
455
|
async getPoolReward(addresses, callback) {
|
|
161
456
|
let cancel = false;
|
|
162
|
-
await this.
|
|
457
|
+
await this.eventService.waitChainReady;
|
|
163
458
|
const [substrateAddresses, evmAddresses] = categoryAddresses(addresses);
|
|
164
459
|
const activeChains = this.state.activeChainSlugs;
|
|
165
460
|
const unsubList = [];
|
|
@@ -189,9 +484,26 @@ export default class EarningService {
|
|
|
189
484
|
getEarningRewards() {
|
|
190
485
|
return this.earningRewardSubject.getValue();
|
|
191
486
|
}
|
|
487
|
+
runSubscribeStakingRewardInterval() {
|
|
488
|
+
const addresses = this.state.getDecodedAddresses();
|
|
489
|
+
if (!addresses.length) {
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
|
+
this.getPoolReward(addresses, result => {
|
|
493
|
+
this.updateEarningReward(result);
|
|
494
|
+
}).catch(console.error);
|
|
495
|
+
this.earningsRewardInterval = setInterval(() => {
|
|
496
|
+
this.getPoolReward(addresses, result => {
|
|
497
|
+
this.updateEarningReward(result);
|
|
498
|
+
}).catch(console.error);
|
|
499
|
+
}, CRON_REFRESH_STAKING_REWARD_FAST_INTERVAL);
|
|
500
|
+
}
|
|
501
|
+
runUnsubscribeStakingRewardInterval() {
|
|
502
|
+
this.earningsRewardInterval && clearInterval(this.earningsRewardInterval);
|
|
503
|
+
}
|
|
192
504
|
async fetchPoolRewardHistory(addresses, callback) {
|
|
193
505
|
let cancel = false;
|
|
194
|
-
await this.
|
|
506
|
+
await this.eventService.waitChainReady;
|
|
195
507
|
const [substrateAddresses, evmAddresses] = categoryAddresses(addresses);
|
|
196
508
|
const activeChains = this.state.activeChainSlugs;
|
|
197
509
|
const unsubList = [];
|
|
@@ -217,7 +529,7 @@ export default class EarningService {
|
|
|
217
529
|
}
|
|
218
530
|
updateEarningRewardHistory(earningRewardHistory) {
|
|
219
531
|
const earningRewardHistoryState = this.earningRewardHistorySubject.getValue();
|
|
220
|
-
const key = `${earningRewardHistory.slug}---${earningRewardHistory.address}---${earningRewardHistory.
|
|
532
|
+
const key = `${earningRewardHistory.slug}---${earningRewardHistory.address}---${earningRewardHistory.eventIndex}`;
|
|
221
533
|
earningRewardHistoryState[key] = earningRewardHistory;
|
|
222
534
|
this.earningRewardHistorySubject.next(earningRewardHistoryState);
|
|
223
535
|
}
|
|
@@ -227,6 +539,24 @@ export default class EarningService {
|
|
|
227
539
|
getEarningRewardHistory() {
|
|
228
540
|
return this.earningRewardHistorySubject.getValue();
|
|
229
541
|
}
|
|
542
|
+
runSubscribeEarningRewardHistoryInterval() {
|
|
543
|
+
this.runUnsubscribeEarningRewardHistoryInterval();
|
|
544
|
+
const addresses = this.state.getDecodedAddresses();
|
|
545
|
+
if (!addresses.length) {
|
|
546
|
+
return;
|
|
547
|
+
}
|
|
548
|
+
this.fetchPoolRewardHistory(addresses, result => {
|
|
549
|
+
this.updateEarningRewardHistory(result);
|
|
550
|
+
}).catch(console.error);
|
|
551
|
+
this.earningsRewardHistoryInterval = setInterval(() => {
|
|
552
|
+
this.fetchPoolRewardHistory(addresses, result => {
|
|
553
|
+
this.updateEarningRewardHistory(result);
|
|
554
|
+
}).catch(console.error);
|
|
555
|
+
}, CRON_REFRESH_EARNING_REWARD_HISTORY_INTERVAL);
|
|
556
|
+
}
|
|
557
|
+
runUnsubscribeEarningRewardHistoryInterval() {
|
|
558
|
+
this.earningsRewardHistoryInterval && clearInterval(this.earningsRewardHistoryInterval);
|
|
559
|
+
}
|
|
230
560
|
|
|
231
561
|
/* Get pools' reward */
|
|
232
562
|
|
|
@@ -239,7 +569,7 @@ export default class EarningService {
|
|
|
239
569
|
* @return {Promise<YieldPoolTarget[]>} List of pool's target
|
|
240
570
|
* */
|
|
241
571
|
async getPoolTargets(slug) {
|
|
242
|
-
await this.
|
|
572
|
+
await this.eventService.waitChainReady;
|
|
243
573
|
const handler = this.getPoolHandler(slug);
|
|
244
574
|
if (handler) {
|
|
245
575
|
return await handler.getPoolTargets();
|
|
@@ -255,7 +585,7 @@ export default class EarningService {
|
|
|
255
585
|
/* Join */
|
|
256
586
|
|
|
257
587
|
async earlyValidateJoin(request) {
|
|
258
|
-
await this.
|
|
588
|
+
await this.eventService.waitChainReady;
|
|
259
589
|
const {
|
|
260
590
|
slug
|
|
261
591
|
} = request;
|
|
@@ -267,7 +597,7 @@ export default class EarningService {
|
|
|
267
597
|
}
|
|
268
598
|
}
|
|
269
599
|
async generateOptimalSteps(params) {
|
|
270
|
-
await this.
|
|
600
|
+
await this.eventService.waitChainReady;
|
|
271
601
|
const {
|
|
272
602
|
slug
|
|
273
603
|
} = params;
|
|
@@ -279,7 +609,7 @@ export default class EarningService {
|
|
|
279
609
|
}
|
|
280
610
|
}
|
|
281
611
|
async validateYieldJoin(params) {
|
|
282
|
-
await this.
|
|
612
|
+
await this.eventService.waitChainReady;
|
|
283
613
|
const {
|
|
284
614
|
slug
|
|
285
615
|
} = params.data;
|
|
@@ -291,7 +621,7 @@ export default class EarningService {
|
|
|
291
621
|
}
|
|
292
622
|
}
|
|
293
623
|
async handleYieldJoin(params) {
|
|
294
|
-
await this.
|
|
624
|
+
await this.eventService.waitChainReady;
|
|
295
625
|
const {
|
|
296
626
|
slug
|
|
297
627
|
} = params.data;
|
|
@@ -308,7 +638,7 @@ export default class EarningService {
|
|
|
308
638
|
/* Leave */
|
|
309
639
|
|
|
310
640
|
async validateYieldLeave(params) {
|
|
311
|
-
await this.
|
|
641
|
+
await this.eventService.waitChainReady;
|
|
312
642
|
const {
|
|
313
643
|
slug
|
|
314
644
|
} = params;
|
|
@@ -320,7 +650,7 @@ export default class EarningService {
|
|
|
320
650
|
}
|
|
321
651
|
}
|
|
322
652
|
async handleYieldLeave(params) {
|
|
323
|
-
await this.
|
|
653
|
+
await this.eventService.waitChainReady;
|
|
324
654
|
const {
|
|
325
655
|
slug
|
|
326
656
|
} = params;
|
|
@@ -337,7 +667,7 @@ export default class EarningService {
|
|
|
337
667
|
/* Other */
|
|
338
668
|
|
|
339
669
|
async handleYieldWithdraw(params) {
|
|
340
|
-
await this.
|
|
670
|
+
await this.eventService.waitChainReady;
|
|
341
671
|
const {
|
|
342
672
|
slug
|
|
343
673
|
} = params;
|
|
@@ -349,7 +679,7 @@ export default class EarningService {
|
|
|
349
679
|
}
|
|
350
680
|
}
|
|
351
681
|
async handleYieldCancelUnstake(params) {
|
|
352
|
-
await this.
|
|
682
|
+
await this.eventService.waitChainReady;
|
|
353
683
|
const {
|
|
354
684
|
slug
|
|
355
685
|
} = params;
|
|
@@ -361,7 +691,7 @@ export default class EarningService {
|
|
|
361
691
|
}
|
|
362
692
|
}
|
|
363
693
|
async handleYieldClaimReward(params) {
|
|
364
|
-
await this.
|
|
694
|
+
await this.eventService.waitChainReady;
|
|
365
695
|
const {
|
|
366
696
|
slug
|
|
367
697
|
} = params;
|
|
@@ -15,6 +15,7 @@ export declare class EventService extends EventEmitter<EventRegistry> {
|
|
|
15
15
|
readonly waitCampaignReady: Promise<boolean>;
|
|
16
16
|
readonly waitBuyTokenReady: Promise<boolean>;
|
|
17
17
|
readonly waitBuyServiceReady: Promise<boolean>;
|
|
18
|
+
readonly waitEarningReady: Promise<boolean>;
|
|
18
19
|
constructor();
|
|
19
20
|
private generateWaitPromise;
|
|
20
21
|
private setLazyTimeout;
|
|
@@ -26,6 +26,7 @@ export class EventService extends EventEmitter {
|
|
|
26
26
|
this.waitCampaignReady = this.generateWaitPromise('campaign.ready');
|
|
27
27
|
this.waitBuyTokenReady = this.generateWaitPromise('buy.tokens.ready');
|
|
28
28
|
this.waitBuyServiceReady = this.generateWaitPromise('buy.services.ready');
|
|
29
|
+
this.waitEarningReady = this.generateWaitPromise('earning.ready');
|
|
29
30
|
}
|
|
30
31
|
generateWaitPromise(eventType) {
|
|
31
32
|
return new Promise(resolve => {
|
|
@@ -35,6 +35,7 @@ export interface EventRegistry {
|
|
|
35
35
|
'campaign.ready': [boolean];
|
|
36
36
|
'buy.tokens.ready': [boolean];
|
|
37
37
|
'buy.services.ready': [boolean];
|
|
38
|
+
'earning.ready': [boolean];
|
|
38
39
|
}
|
|
39
40
|
export declare type EventType = keyof EventRegistry;
|
|
40
41
|
export declare const COMMON_RELOAD_EVENTS: EventType[];
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import DeleteEarningData from '@subwallet/extension-base/services/migration-service/scripts/DeleteEarningData';
|
|
5
|
-
import EnableEarningChains from '@subwallet/extension-base/services/migration-service/scripts/EnableEarningChains';
|
|
6
5
|
import MigrateEarningVersion from "./databases/MigrateEarningVersion.js";
|
|
7
6
|
import MigrateEthProvider from "./providers/MigrateEthProvider.js";
|
|
8
7
|
import MigratePioneerProvider from "./providers/MigratePioneerProvider.js";
|
|
@@ -36,7 +35,7 @@ export default {
|
|
|
36
35
|
'1.1.6-01': MigrateWalletReference,
|
|
37
36
|
'1.1.7': DeleteChain,
|
|
38
37
|
'1.1.13-01': MigrateTokenDecimals,
|
|
39
|
-
'1.1.13-02': EnableEarningChains,
|
|
38
|
+
// '1.1.13-02-2': EnableEarningChains,
|
|
40
39
|
'1.1.13-03': DeleteEarningData,
|
|
41
40
|
'1.1.17-01': MigratePioneerProvider,
|
|
42
41
|
'1.1.17-03': EnableVaraChain,
|
|
@@ -90,16 +90,21 @@ export default class DatabaseService {
|
|
|
90
90
|
getMantaPayFirstConfig(chain: string): Promise<any>;
|
|
91
91
|
removeOldEarningData(): Promise<void>;
|
|
92
92
|
updateYieldPoolStore(data: YieldPoolInfo): Promise<void>;
|
|
93
|
+
updateYieldPoolsStore(data: YieldPoolInfo[]): Promise<void>;
|
|
93
94
|
deleteYieldPoolInfo(slugs: string[]): Promise<void>;
|
|
94
95
|
getYieldPools(): Promise<YieldPoolInfo[]>;
|
|
95
96
|
getYieldPoolStakingInfo(chain: string, poolType: YieldPoolType): Promise<YieldPoolInfo | undefined>;
|
|
96
97
|
getYieldPool(slug: string): Promise<YieldPoolInfo | undefined>;
|
|
97
98
|
getYieldPositionByAddressAndSlug(address: string, slug: string): Promise<YieldPositionInfo | undefined>;
|
|
98
99
|
subscribeYieldPoolInfo(chains: string[], callback: (data: YieldPoolInfo[]) => void): Subscription;
|
|
100
|
+
removeYieldPositionByAddresses(addresses: string[]): import("dexie").PromiseExtended<number>;
|
|
101
|
+
removeYieldPositionByChains(chains: string[]): import("dexie").PromiseExtended<number>;
|
|
99
102
|
updateYieldPosition(data: YieldPositionInfo): Promise<void>;
|
|
103
|
+
updateYieldPositions(data: YieldPositionInfo[]): Promise<void>;
|
|
100
104
|
getYieldPositionByAddress(addresses: string[]): Promise<YieldPositionInfo[]>;
|
|
101
105
|
subscribeYieldPosition(addresses: string[], callback: (data: YieldPositionInfo[]) => void): Subscription;
|
|
102
106
|
getYieldNominationPoolPosition(addresses: string[], chains: string[]): Promise<YieldPositionInfo[]>;
|
|
107
|
+
getAllCampaign(): Promise<import("@subwallet/extension-base/background/KoniTypes").CampaignData[]>;
|
|
103
108
|
subscribeProcessingCampaign(): import("dexie").Observable<import("@subwallet/extension-base/background/KoniTypes").CampaignData[]>;
|
|
104
109
|
getProcessingCampaign(): Promise<import("@subwallet/extension-base/background/KoniTypes").CampaignData[]>;
|
|
105
110
|
getCampaign(slug: string): Promise<import("@subwallet/extension-base/background/KoniTypes").CampaignData | undefined>;
|
|
@@ -286,6 +286,9 @@ export default class DatabaseService {
|
|
|
286
286
|
async updateYieldPoolStore(data) {
|
|
287
287
|
await this.stores.yieldPoolInfo.upsert(data);
|
|
288
288
|
}
|
|
289
|
+
async updateYieldPoolsStore(data) {
|
|
290
|
+
await this.stores.yieldPoolInfo.bulkUpsert(data);
|
|
291
|
+
}
|
|
289
292
|
async deleteYieldPoolInfo(slugs) {
|
|
290
293
|
await this.stores.yieldPoolInfo.bulkDelete(slugs);
|
|
291
294
|
}
|
|
@@ -308,9 +311,18 @@ export default class DatabaseService {
|
|
|
308
311
|
});
|
|
309
312
|
return this.yieldInfoSubscription;
|
|
310
313
|
}
|
|
314
|
+
removeYieldPositionByAddresses(addresses) {
|
|
315
|
+
return this.stores.yieldPosition.removeByAddresses(addresses);
|
|
316
|
+
}
|
|
317
|
+
removeYieldPositionByChains(chains) {
|
|
318
|
+
return this.stores.yieldPosition.removeByChains(chains);
|
|
319
|
+
}
|
|
311
320
|
async updateYieldPosition(data) {
|
|
312
321
|
await this.stores.yieldPosition.upsert(data);
|
|
313
322
|
}
|
|
323
|
+
async updateYieldPositions(data) {
|
|
324
|
+
await this.stores.yieldPosition.bulkUpsert(data);
|
|
325
|
+
}
|
|
314
326
|
async getYieldPositionByAddress(addresses) {
|
|
315
327
|
return this.stores.yieldPosition.getByAddress(addresses);
|
|
316
328
|
}
|
|
@@ -325,6 +337,9 @@ export default class DatabaseService {
|
|
|
325
337
|
|
|
326
338
|
/* Campaign */
|
|
327
339
|
|
|
340
|
+
getAllCampaign() {
|
|
341
|
+
return this.stores.campaign.getAll();
|
|
342
|
+
}
|
|
328
343
|
subscribeProcessingCampaign() {
|
|
329
344
|
return this.stores.campaign.subscribeProcessingCampaign();
|
|
330
345
|
}
|
|
@@ -6,7 +6,13 @@ import { liveQuery } from 'dexie';
|
|
|
6
6
|
const filterProcessing = campaign => {
|
|
7
7
|
const now = new Date().getTime();
|
|
8
8
|
const isExpired = now <= campaign.startTime || now >= campaign.endTime;
|
|
9
|
-
return !(campaign.isDone || isExpired);
|
|
9
|
+
return !(campaign.isArchive || campaign.isDone || isExpired);
|
|
10
|
+
};
|
|
11
|
+
const getId = campaign => {
|
|
12
|
+
return campaign.campaignId;
|
|
13
|
+
};
|
|
14
|
+
const sortById = (a, b) => {
|
|
15
|
+
return getId(a) - getId(b);
|
|
10
16
|
};
|
|
11
17
|
export default class CampaignStore extends BaseStore {
|
|
12
18
|
async getAll() {
|
|
@@ -16,10 +22,10 @@ export default class CampaignStore extends BaseStore {
|
|
|
16
22
|
return this.table.get(slug);
|
|
17
23
|
}
|
|
18
24
|
async getProcessingCampaign() {
|
|
19
|
-
return (await this.table.toArray()).filter(filterProcessing);
|
|
25
|
+
return (await this.table.toArray()).filter(filterProcessing).sort(sortById);
|
|
20
26
|
}
|
|
21
27
|
subscribeProcessingCampaign() {
|
|
22
|
-
return liveQuery(() => this.table.filter(filterProcessing).toArray());
|
|
28
|
+
return liveQuery(async () => (await this.table.filter(filterProcessing).toArray()).sort(sortById));
|
|
23
29
|
}
|
|
24
30
|
upsertCampaign(campaign) {
|
|
25
31
|
return this.table.put(campaign);
|
|
@@ -3,6 +3,8 @@ import { YieldPositionInfo } from '@subwallet/extension-base/types';
|
|
|
3
3
|
export default class YieldPositionStore extends BaseStore<YieldPositionInfo> {
|
|
4
4
|
getAll(): Promise<YieldPositionInfo[]>;
|
|
5
5
|
getByAddress(addresses: string[]): Promise<YieldPositionInfo[]>;
|
|
6
|
+
removeByAddresses(addresses: string[]): import("dexie").PromiseExtended<number>;
|
|
7
|
+
removeByChains(chains: string[]): import("dexie").PromiseExtended<number>;
|
|
6
8
|
getByAddressAndChains(addresses: string[], chains: string[]): Promise<YieldPositionInfo[]>;
|
|
7
9
|
getByAddressAndSlug(address: string, slug: string): import("dexie").PromiseExtended<YieldPositionInfo | undefined>;
|
|
8
10
|
subscribeYieldPositions(addresses: string[]): import("dexie").Observable<YieldPositionInfo[]>;
|