@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.
Files changed (84) hide show
  1. package/background/KoniTypes.d.ts +1 -0
  2. package/cjs/koni/api/staking/bonding/index.js +2 -0
  3. package/cjs/koni/api/staking/bonding/paraChain.js +6 -3
  4. package/cjs/koni/background/cron.js +0 -28
  5. package/cjs/koni/background/handlers/Extension.js +17 -11
  6. package/cjs/koni/background/handlers/State.js +4 -46
  7. package/cjs/koni/background/subscription.js +0 -155
  8. package/cjs/packageInfo.js +1 -1
  9. package/cjs/services/campaign-service/index.js +19 -0
  10. package/cjs/services/chain-service/constants.js +3 -2
  11. package/cjs/services/earning-service/constants/chains.js +1 -1
  12. package/cjs/services/earning-service/handlers/base.js +9 -6
  13. package/cjs/services/earning-service/handlers/lending/base.js +61 -0
  14. package/cjs/services/earning-service/handlers/lending/interlay.js +3 -2
  15. package/cjs/services/earning-service/handlers/liquid-staking/acala.js +3 -2
  16. package/cjs/services/earning-service/handlers/liquid-staking/base.js +54 -0
  17. package/cjs/services/earning-service/handlers/liquid-staking/bifrost.js +3 -2
  18. package/cjs/services/earning-service/handlers/liquid-staking/parallel.js +3 -2
  19. package/cjs/services/earning-service/handlers/liquid-staking/stella-swap.js +16 -7
  20. package/cjs/services/earning-service/handlers/native-staking/amplitude.js +7 -2
  21. package/cjs/services/earning-service/handlers/native-staking/astar.js +7 -2
  22. package/cjs/services/earning-service/handlers/native-staking/base.js +4 -2
  23. package/cjs/services/earning-service/handlers/native-staking/para-chain.js +7 -2
  24. package/cjs/services/earning-service/handlers/native-staking/relay-chain.js +12 -3
  25. package/cjs/services/earning-service/handlers/nomination-pool/index.js +9 -3
  26. package/cjs/services/earning-service/handlers/special.js +57 -67
  27. package/cjs/services/earning-service/service.js +370 -37
  28. package/cjs/services/event-service/index.js +1 -0
  29. package/cjs/services/migration-service/scripts/index.js +1 -2
  30. package/cjs/services/storage-service/DatabaseService.js +15 -0
  31. package/cjs/services/storage-service/db-stores/Campaign.js +9 -3
  32. package/cjs/services/storage-service/db-stores/YieldPositionStore.js +6 -0
  33. package/cjs/services/transaction-service/index.js +15 -1
  34. package/cjs/utils/number.js +3 -1
  35. package/koni/api/staking/bonding/index.d.ts +1 -0
  36. package/koni/api/staking/bonding/index.js +2 -0
  37. package/koni/api/staking/bonding/paraChain.js +6 -3
  38. package/koni/background/cron.d.ts +0 -5
  39. package/koni/background/cron.js +1 -29
  40. package/koni/background/handlers/Extension.js +17 -11
  41. package/koni/background/handlers/State.d.ts +1 -12
  42. package/koni/background/handlers/State.js +4 -46
  43. package/koni/background/subscription.d.ts +1 -11
  44. package/koni/background/subscription.js +2 -157
  45. package/package.json +6 -6
  46. package/packageInfo.js +1 -1
  47. package/services/campaign-service/index.js +19 -0
  48. package/services/chain-service/constants.js +3 -2
  49. package/services/earning-service/constants/chains.js +1 -1
  50. package/services/earning-service/handlers/base.d.ts +1 -0
  51. package/services/earning-service/handlers/base.js +9 -6
  52. package/services/earning-service/handlers/lending/base.d.ts +2 -0
  53. package/services/earning-service/handlers/lending/base.js +61 -0
  54. package/services/earning-service/handlers/lending/interlay.js +4 -3
  55. package/services/earning-service/handlers/liquid-staking/acala.js +4 -3
  56. package/services/earning-service/handlers/liquid-staking/base.d.ts +2 -0
  57. package/services/earning-service/handlers/liquid-staking/base.js +55 -1
  58. package/services/earning-service/handlers/liquid-staking/bifrost.js +4 -3
  59. package/services/earning-service/handlers/liquid-staking/parallel.js +4 -3
  60. package/services/earning-service/handlers/liquid-staking/stella-swap.js +16 -7
  61. package/services/earning-service/handlers/native-staking/amplitude.js +7 -2
  62. package/services/earning-service/handlers/native-staking/astar.js +7 -2
  63. package/services/earning-service/handlers/native-staking/base.js +5 -3
  64. package/services/earning-service/handlers/native-staking/para-chain.js +7 -2
  65. package/services/earning-service/handlers/native-staking/relay-chain.js +12 -3
  66. package/services/earning-service/handlers/nomination-pool/index.js +10 -4
  67. package/services/earning-service/handlers/special.d.ts +0 -1
  68. package/services/earning-service/handlers/special.js +58 -68
  69. package/services/earning-service/service.d.ts +49 -1
  70. package/services/earning-service/service.js +358 -28
  71. package/services/event-service/index.d.ts +1 -0
  72. package/services/event-service/index.js +1 -0
  73. package/services/event-service/types.d.ts +1 -0
  74. package/services/migration-service/scripts/index.js +1 -2
  75. package/services/storage-service/DatabaseService.d.ts +5 -0
  76. package/services/storage-service/DatabaseService.js +15 -0
  77. package/services/storage-service/db-stores/Campaign.js +9 -3
  78. package/services/storage-service/db-stores/YieldPositionStore.d.ts +2 -0
  79. package/services/storage-service/db-stores/YieldPositionStore.js +6 -0
  80. package/services/transaction-service/index.js +15 -1
  81. package/types/yield/actions/join/submit.d.ts +2 -1
  82. package/types/yield/info/account/reward.d.ts +2 -0
  83. package/utils/number.d.ts +1 -0
  84. 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.initHandlers().catch(console.error);
41
+ this.dbService = state.dbService;
42
+ this.eventService = state.eventService;
24
43
  }
25
44
  async initHandlers() {
26
- await this.state.eventService.waitChainReady;
27
- const chains = Object.keys(this.state.getChainInfoMap());
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
- /* Subscribe pools' info */
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.state.eventService.waitChainReady;
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
- /* Subscribe pools' info */
315
+ /* Pools' info methods */
119
316
 
120
- /* Subscribe pools' position */
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.state.eventService.waitChainReady;
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
- /* Subscribe pools' position */
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.state.eventService.waitChainReady;
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.state.eventService.waitChainReady;
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.blockTimestamp}`;
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.state.eventService.waitChainReady;
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.state.eventService.waitChainReady;
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.state.eventService.waitChainReady;
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.state.eventService.waitChainReady;
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.state.eventService.waitChainReady;
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.state.eventService.waitChainReady;
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.state.eventService.waitChainReady;
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.state.eventService.waitChainReady;
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.state.eventService.waitChainReady;
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.state.eventService.waitChainReady;
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[]>;