@subwallet/extension-base 1.0.7-0 → 1.0.7-1

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 (55) hide show
  1. package/background/KoniTypes.d.ts +4 -5
  2. package/cjs/constants/index.js +1 -1
  3. package/cjs/koni/api/staking/bonding/amplitude.js +83 -0
  4. package/cjs/koni/api/staking/bonding/astar.js +104 -1
  5. package/cjs/koni/api/staking/bonding/index.js +35 -0
  6. package/cjs/koni/api/staking/bonding/paraChain.js +97 -0
  7. package/cjs/koni/api/staking/bonding/relayChain.js +191 -12
  8. package/cjs/koni/api/staking/index.js +11 -11
  9. package/cjs/koni/api/staking/paraChain.js +200 -130
  10. package/cjs/koni/api/staking/relayChain.js +66 -68
  11. package/cjs/koni/api/staking/subsquidStaking.js +6 -11
  12. package/cjs/koni/background/cron.js +0 -25
  13. package/cjs/koni/background/handlers/State.js +17 -19
  14. package/cjs/koni/background/subscription.js +57 -12
  15. package/cjs/packageInfo.js +1 -1
  16. package/cjs/services/chain-service/utils.js +6 -1
  17. package/cjs/services/storage-service/DatabaseService.js +7 -3
  18. package/cjs/services/storage-service/db-stores/ChainStakingMetadata.js +5 -0
  19. package/cjs/services/storage-service/db-stores/NominatorMetadata.js +4 -4
  20. package/cjs/services/transaction-service/index.js +6 -1
  21. package/constants/index.d.ts +1 -1
  22. package/constants/index.js +1 -1
  23. package/koni/api/staking/bonding/amplitude.d.ts +4 -0
  24. package/koni/api/staking/bonding/amplitude.js +81 -0
  25. package/koni/api/staking/bonding/astar.d.ts +4 -0
  26. package/koni/api/staking/bonding/astar.js +102 -1
  27. package/koni/api/staking/bonding/index.d.ts +1 -0
  28. package/koni/api/staking/bonding/index.js +38 -4
  29. package/koni/api/staking/bonding/paraChain.d.ts +4 -0
  30. package/koni/api/staking/bonding/paraChain.js +95 -0
  31. package/koni/api/staking/bonding/relayChain.d.ts +5 -0
  32. package/koni/api/staking/bonding/relayChain.js +185 -10
  33. package/koni/api/staking/index.d.ts +4 -4
  34. package/koni/api/staking/index.js +11 -11
  35. package/koni/api/staking/paraChain.d.ts +5 -5
  36. package/koni/api/staking/paraChain.js +201 -131
  37. package/koni/api/staking/relayChain.d.ts +4 -4
  38. package/koni/api/staking/relayChain.js +66 -67
  39. package/koni/api/staking/subsquidStaking.d.ts +1 -1
  40. package/koni/api/staking/subsquidStaking.js +6 -11
  41. package/koni/background/cron.js +1 -26
  42. package/koni/background/handlers/State.d.ts +2 -2
  43. package/koni/background/handlers/State.js +17 -19
  44. package/koni/background/subscription.d.ts +2 -1
  45. package/koni/background/subscription.js +58 -13
  46. package/package.json +5 -5
  47. package/packageInfo.js +1 -1
  48. package/services/chain-service/utils.js +6 -1
  49. package/services/storage-service/DatabaseService.d.ts +2 -2
  50. package/services/storage-service/DatabaseService.js +7 -3
  51. package/services/storage-service/db-stores/ChainStakingMetadata.d.ts +1 -0
  52. package/services/storage-service/db-stores/ChainStakingMetadata.js +3 -0
  53. package/services/storage-service/db-stores/NominatorMetadata.d.ts +2 -2
  54. package/services/storage-service/db-stores/NominatorMetadata.js +4 -4
  55. package/services/transaction-service/index.js +6 -1
@@ -39,9 +39,8 @@ const getSubsquidQuery = (account, chain) => {
39
39
  }
40
40
  }`;
41
41
  };
42
- const getSubsquidStaking = async (accounts, chain, chainInfoMap) => {
42
+ const getSubsquidStaking = async (accounts, chain, chainInfoMap, callback) => {
43
43
  try {
44
- const result = [];
45
44
  await Promise.all(accounts.map(async account => {
46
45
  if ((0, _utils._isChainEvmCompatible)(chainInfoMap[chain]) && (0, _utilCrypto.isEthereumAddress)(account) || !(0, _utils._isChainEvmCompatible)(chainInfoMap[chain]) && !(0, _utilCrypto.isEthereumAddress)(account)) {
47
46
  const parsedAccount = (0, _utils2.reformatAddress)(account, (0, _utils._getChainSubstrateAddressPrefix)(chainInfoMap[chain]));
@@ -77,17 +76,15 @@ const getSubsquidStaking = async (accounts, chain, chainInfoMap) => {
77
76
  }
78
77
  }
79
78
  if (stakingRewardItem.totalReward && parseFloat(stakingRewardItem.totalReward) > 0) {
80
- result.push(stakingRewardItem);
79
+ callback(stakingRewardItem);
81
80
  }
82
81
  }
83
82
  }));
84
- return result;
85
83
  } catch (e) {
86
- return [];
84
+ console.debug(e);
87
85
  }
88
86
  };
89
- const getAllSubsquidStaking = async (accounts, chainInfoMap) => {
90
- let rewardList = [];
87
+ const getAllSubsquidStaking = async (accounts, chainInfoMap, callback) => {
91
88
  const filteredNetworks = [];
92
89
  Object.values(chainInfoMap).forEach(network => {
93
90
  if (_config.INDEXER_SUPPORTED_STAKING_CHAINS.includes(network.slug)) {
@@ -96,12 +93,10 @@ const getAllSubsquidStaking = async (accounts, chainInfoMap) => {
96
93
  });
97
94
  try {
98
95
  await Promise.all(filteredNetworks.map(async network => {
99
- const rewardItems = await getSubsquidStaking(accounts, network, chainInfoMap);
100
- rewardList = rewardList.concat(rewardItems);
96
+ await getSubsquidStaking(accounts, network, chainInfoMap, callback);
101
97
  }));
102
98
  } catch (e) {
103
- return rewardList;
99
+ console.debug(e);
104
100
  }
105
- return rewardList;
106
101
  };
107
102
  exports.getAllSubsquidStaking = getAllSubsquidStaking;
@@ -60,26 +60,6 @@ class KoniCron {
60
60
  delete this.cronMap[key];
61
61
  });
62
62
  };
63
-
64
- // init = () => {
65
- // const currentAccountInfo = this.state.keyringService.currentAccount;
66
- //
67
- // if (!currentAccountInfo?.address) {
68
- // return;
69
- // }
70
- //
71
- // if (Object.keys(this.state.getSubstrateApiMap()).length !== 0 || Object.keys(this.state.getEvmApiMap()).length !== 0) {
72
- // this.refreshNft(currentAccountInfo.address, this.state.getApiMap(), this.state.getSmartContractNfts(), this.state.getActiveChainInfoMap());
73
- // this.updateApiMapStatus();
74
- // this.refreshStakingReward(currentAccountInfo.address);
75
- // this.refreshStakingRewardFastInterval(currentAccountInfo.address);
76
- // // this.updateChainStakingMetadata(this.state.getChainInfoMap(), this.state.getChainStateMap(), this.state.getSubstrateApiMap());
77
- // this.updateNominatorMetadata(currentAccountInfo.address, this.state.getChainInfoMap(), this.state.getChainStateMap(), this.state.getSubstrateApiMap());
78
- // } else {
79
- // this.setStakingRewardReady();
80
- // }
81
- // };
82
-
83
63
  start = () => {
84
64
  if (this.status === 'running') {
85
65
  return;
@@ -120,7 +100,6 @@ class KoniCron {
120
100
  (commonReload || needUpdateStaking || stakingSubmitted) && this.resetStakingReward();
121
101
  (commonReload || needUpdateStaking || stakingSubmitted) && this.removeCron('refreshStakingReward');
122
102
  (commonReload || needUpdateStaking || stakingSubmitted) && this.removeCron('refreshPoolingStakingReward');
123
- (commonReload || needUpdateStaking || stakingSubmitted) && this.removeCron('updateNominatorMetadata');
124
103
  needUpdateStaking && this.removeCron('updateChainStakingMetadata');
125
104
 
126
105
  // Chains
@@ -133,7 +112,6 @@ class KoniCron {
133
112
  chainUpdated && this.addCron('recoverApiMap', this.recoverApiMap, _constants.CRON_AUTO_RECOVER_DOTSAMA_INTERVAL, false);
134
113
  (commonReload || needUpdateStaking || stakingSubmitted) && this.addCron('refreshStakingReward', this.refreshStakingReward(address), _constants.CRON_REFRESH_STAKING_REWARD_INTERVAL);
135
114
  (commonReload || needUpdateStaking || stakingSubmitted) && this.addCron('refreshPoolingStakingReward', this.refreshStakingRewardFastInterval(address), _constants.CRON_REFRESH_STAKING_REWARD_FAST_INTERVAL);
136
- (commonReload || needUpdateStaking || stakingSubmitted) && this.addCron('updateNominatorMetadata', this.updateNominatorMetadata(address, serviceInfo.chainInfoMap, serviceInfo.chainStateMap, serviceInfo.chainApiMap.substrate), _constants.CRON_REFRESH_CHAIN_NOMINATOR_METADATA);
137
115
  needUpdateStaking && this.addCron('updateChainStakingMetadata', this.updateChainStakingMetadata(serviceInfo.chainInfoMap, serviceInfo.chainStateMap, serviceInfo.chainApiMap.substrate), _constants.CRON_REFRESH_CHAIN_STAKING_METADATA);
138
116
  } else {
139
117
  this.setStakingRewardReady();
@@ -151,7 +129,6 @@ class KoniCron {
151
129
  this.addCron('refreshStakingReward', this.refreshStakingReward(currentAccountInfo.address), _constants.CRON_REFRESH_STAKING_REWARD_INTERVAL);
152
130
  this.addCron('refreshPoolingStakingReward', this.refreshStakingRewardFastInterval(currentAccountInfo.address), _constants.CRON_REFRESH_STAKING_REWARD_FAST_INTERVAL);
153
131
  this.addCron('updateChainStakingMetadata', this.updateChainStakingMetadata(this.state.getChainInfoMap(), this.state.getChainStateMap(), this.state.getSubstrateApiMap()), _constants.CRON_REFRESH_CHAIN_STAKING_METADATA);
154
- this.addCron('updateNominatorMetadata', this.updateNominatorMetadata(currentAccountInfo.address, this.state.getChainInfoMap(), this.state.getChainStateMap(), this.state.getSubstrateApiMap()), _constants.CRON_REFRESH_CHAIN_NOMINATOR_METADATA);
155
132
  } else {
156
133
  this.setStakingRewardReady();
157
134
  }
@@ -246,10 +223,8 @@ class KoniCron {
246
223
  this.resetStakingReward();
247
224
  this.removeCron('refreshStakingReward');
248
225
  this.removeCron('refreshPoolingStakingReward');
249
- this.removeCron('updateNominatorMetadata');
250
226
  this.addCron('refreshStakingReward', this.refreshStakingReward(address), _constants.CRON_REFRESH_STAKING_REWARD_INTERVAL);
251
227
  this.addCron('refreshPoolingStakingReward', this.refreshStakingRewardFastInterval(address), _constants.CRON_REFRESH_STAKING_REWARD_FAST_INTERVAL);
252
- this.addCron('updateNominatorMetadata', this.updateNominatorMetadata(address, this.state.getChainInfoMap(), this.state.getChainStateMap(), this.state.getSubstrateApiMap()), _constants.CRON_REFRESH_CHAIN_NOMINATOR_METADATA);
253
228
  await (0, _utils2.waitTimeout)(1800);
254
229
  return true;
255
230
  }
@@ -77,8 +77,7 @@ class KoniState {
77
77
  stakingRewardSubject = new _rxjs.Subject();
78
78
  stakingRewardState = {
79
79
  ready: false,
80
- slowInterval: [],
81
- fastInterval: []
80
+ data: {}
82
81
  };
83
82
  lazyMap = {};
84
83
  ready = false;
@@ -203,18 +202,24 @@ class KoniState {
203
202
  async init() {
204
203
  await this.chainService.init();
205
204
  await this.migrationService.run();
206
- this.startSubscription();
207
205
  this.eventService.emit('chain.ready', true);
208
206
  this.onReady();
209
207
  this.onAccountAdd();
210
208
  this.onAccountRemove();
209
+ await this.startSubscription();
211
210
  }
212
- startSubscription() {
211
+ async startSubscription() {
212
+ await this.eventService.waitKeyringReady;
213
213
  this.dbService.subscribeChainStakingMetadata([], data => {
214
214
  this.chainStakingMetadataSubject.next(data);
215
215
  });
216
- this.dbService.subscribeNominatorMetadata(data => {
217
- this.stakingNominatorMetadataSubject.next(data);
216
+ let unsub;
217
+ this.keyringService.accountSubject.subscribe(accounts => {
218
+ // TODO: improve this
219
+ unsub && unsub.unsubscribe();
220
+ unsub = this.dbService.subscribeNominatorMetadata(Object.keys(accounts), data => {
221
+ this.stakingNominatorMetadataSubject.next(data);
222
+ });
218
223
  });
219
224
  }
220
225
  onReady() {
@@ -309,14 +314,6 @@ class KoniState {
309
314
  async getPooledStakingRecordsByAddress(addresses) {
310
315
  return this.dbService.getPooledStakings(addresses, this.activeChainSlugs);
311
316
  }
312
-
313
- // TODO: delete later
314
- // public async getStoredStaking (address: string) {
315
- // const items = await this.dbService.stores.staking.getDataByAddressAsObject(address);
316
- //
317
- // return items || {};
318
- // }
319
-
320
317
  subscribeStaking() {
321
318
  return this.stakingSubject;
322
319
  }
@@ -332,8 +329,8 @@ class KoniState {
332
329
  setStakingItem(networkKey, item) {
333
330
  this.dbService.updateStaking(networkKey, item.address, item).catch(e => this.logger.warn(e));
334
331
  }
335
- updateChainStakingMetadata(item) {
336
- this.dbService.updateChainStakingMetadata(item).catch(e => this.logger.warn(e));
332
+ updateChainStakingMetadata(item, changes) {
333
+ this.dbService.updateChainStakingMetadata(item, changes).catch(e => this.logger.warn(e));
337
334
  }
338
335
  updateStakingNominatorMetadata(item) {
339
336
  this.dbService.updateNominatorMetadata(item).catch(e => this.logger.warn(e));
@@ -386,12 +383,13 @@ class KoniState {
386
383
  return this.nftSubject;
387
384
  }
388
385
  resetStakingReward() {
389
- this.stakingRewardState.slowInterval = [];
386
+ this.stakingRewardState.data = {};
390
387
  this.stakingRewardSubject.next(this.stakingRewardState);
391
388
  }
392
- updateStakingReward(stakingRewardData, type, callback) {
389
+ updateStakingReward(stakingRewardData, callback) {
393
390
  this.stakingRewardState.ready = true;
394
- this.stakingRewardState[type] = stakingRewardData;
391
+ const key = `${stakingRewardData.chain}___${stakingRewardData.address}___${stakingRewardData.type}`;
392
+ this.stakingRewardState.data[key] = stakingRewardData;
395
393
  if (callback) {
396
394
  callback(this.stakingRewardState);
397
395
  }
@@ -26,7 +26,8 @@ class KoniSubscription {
26
26
  subscriptionMap = {
27
27
  crowdloan: undefined,
28
28
  balance: undefined,
29
- stakingOnChain: undefined
29
+ stakingOnChain: undefined,
30
+ essentialChainStakingMetadata: undefined
30
31
  };
31
32
  constructor(state, dbService) {
32
33
  this.dbService = dbService;
@@ -105,11 +106,38 @@ class KoniSubscription {
105
106
  return;
106
107
  }
107
108
  this.updateSubscription('stakingOnChain', this.initStakingOnChainSubscription(addresses, substrateApiMap, onlyRunOnFirstTime));
109
+ this.updateSubscription('essentialChainStakingMetadata', this.initEssentialChainStakingMetadataSubscription(substrateApiMap, onlyRunOnFirstTime)); // TODO: might not need to re-subscribe on changing account
108
110
  }
111
+
109
112
  initStakingOnChainSubscription(addresses, substrateApiMap, onlyRunOnFirstTime) {
110
- const unsub = (0, _staking.stakingOnChainApi)(addresses, substrateApiMap, (networkKey, rs) => {
113
+ const stakingCallback = (networkKey, rs) => {
111
114
  this.state.setStakingItem(networkKey, rs);
112
- }, this.state.getActiveChainInfoMap());
115
+ };
116
+ const nominatorStateCallback = nominatorMetadata => {
117
+ this.state.updateStakingNominatorMetadata(nominatorMetadata);
118
+ };
119
+ const unsub = (0, _staking.stakingOnChainApi)(addresses, substrateApiMap, this.state.getActiveChainInfoMap(), stakingCallback, nominatorStateCallback);
120
+ if (onlyRunOnFirstTime) {
121
+ unsub && unsub();
122
+ return;
123
+ }
124
+ return () => {
125
+ unsub && unsub();
126
+ };
127
+ }
128
+ initEssentialChainStakingMetadataSubscription(substrateApiMap, onlyRunOnFirstTime) {
129
+ const unsub = (0, _bonding.subscribeEssentialChainStakingMetadata)(substrateApiMap, this.state.getActiveChainInfoMap(), (networkKey, rs) => {
130
+ this.state.updateChainStakingMetadata(rs, {
131
+ era: rs.era,
132
+ minStake: rs.minStake,
133
+ maxValidatorPerNominator: rs.maxValidatorPerNominator,
134
+ // temporary fix for Astar, there's no limit for now
135
+ maxWithdrawalRequestPerValidator: rs.maxWithdrawalRequestPerValidator,
136
+ // by default
137
+ allowCancelUnstaking: rs.allowCancelUnstaking,
138
+ unstakingPeriod: rs.unstakingPeriod
139
+ });
140
+ });
113
141
  if (onlyRunOnFirstTime) {
114
142
  unsub && unsub();
115
143
  return;
@@ -183,8 +211,9 @@ class KoniSubscription {
183
211
  targetNetworkMap[key] = network;
184
212
  }
185
213
  });
186
- const result = await (0, _staking.getNominationStakingRewardData)(addresses, targetNetworkMap);
187
- this.state.updateStakingReward(result, 'slowInterval');
214
+ await (0, _staking.getNominationStakingRewardData)(addresses, targetNetworkMap, rewardItem => {
215
+ this.state.updateStakingReward(rewardItem);
216
+ });
188
217
  }
189
218
  async subscribeStakingRewardFastInterval(address) {
190
219
  const addresses = this.state.getDecodedAddresses(address);
@@ -211,9 +240,10 @@ class KoniSubscription {
211
240
  Object.keys(targetChainMap).forEach(key => {
212
241
  activeNetworks.push(key);
213
242
  });
214
- const [poolingStakingRewards, amplitudeUnclaimedStakingRewards] = await Promise.all([(0, _staking.getPoolingStakingRewardData)(pooledAddresses, targetChainMap, this.state.getSubstrateApiMap()), (0, _paraChain.getAmplitudeUnclaimedStakingReward)(this.state.getSubstrateApiMap(), addresses, chainInfoMap, activeNetworks)]);
215
- const result = [...poolingStakingRewards, ...amplitudeUnclaimedStakingRewards];
216
- this.state.updateStakingReward(result, 'fastInterval');
243
+ const updateState = result => {
244
+ this.state.updateStakingReward(result);
245
+ };
246
+ await Promise.all([(0, _staking.getPoolingStakingRewardData)(pooledAddresses, targetChainMap, this.state.getSubstrateApiMap(), updateState), (0, _paraChain.getAmplitudeUnclaimedStakingReward)(this.state.getSubstrateApiMap(), addresses, chainInfoMap, activeNetworks, updateState)]);
217
247
  }
218
248
  async fetchingStakingFromApi() {
219
249
  try {
@@ -237,16 +267,31 @@ class KoniSubscription {
237
267
  if (Object.values(filteredChainInfoMap).length === 0) {
238
268
  return;
239
269
  }
270
+ const timeout = new Promise(resolve => {
271
+ const id = setTimeout(() => {
272
+ clearTimeout(id);
273
+ resolve(null);
274
+ }, 3000);
275
+ });
240
276
 
241
277
  // Fetch data from helper API
242
- const dataFromApi = await this.fetchingStakingFromApi();
278
+ const _dataFromApi = await Promise.race([this.fetchingStakingFromApi(), timeout]);
279
+ const dataFromApi = _dataFromApi;
243
280
  await Promise.all(Object.values(filteredChainInfoMap).map(async chainInfo => {
244
281
  // Use fetch API data if available
245
- if (dataFromApi[chainInfo.slug]) {
246
- this.state.updateChainStakingMetadata(dataFromApi[chainInfo.slug]);
282
+ if (dataFromApi && dataFromApi[chainInfo.slug]) {
283
+ this.state.updateChainStakingMetadata(dataFromApi[chainInfo.slug], {
284
+ expectedReturn: dataFromApi[chainInfo.slug].expectedReturn,
285
+ inflation: dataFromApi[chainInfo.slug].inflation,
286
+ nominatorCount: dataFromApi[chainInfo.slug].nominatorCount
287
+ });
247
288
  } else {
248
289
  const chainStakingMetadata = await (0, _bonding.getChainStakingMetadata)(chainInfo, substrateApiMap[chainInfo.slug]);
249
- this.state.updateChainStakingMetadata(chainStakingMetadata);
290
+ this.state.updateChainStakingMetadata(chainStakingMetadata, {
291
+ expectedReturn: chainStakingMetadata.expectedReturn,
292
+ inflation: chainStakingMetadata.inflation,
293
+ nominatorCount: chainStakingMetadata.nominatorCount
294
+ });
250
295
  }
251
296
  }));
252
297
  }
@@ -13,6 +13,6 @@ const packageInfo = {
13
13
  name: '@subwallet/extension-base',
14
14
  path: typeof __dirname === 'string' ? __dirname : 'auto',
15
15
  type: 'cjs',
16
- version: '1.0.7-0'
16
+ version: '1.0.7-1'
17
17
  };
18
18
  exports.packageInfo = packageInfo;
@@ -121,7 +121,12 @@ function _isPureSubstrateChain(chainInfo) {
121
121
  }
122
122
  function _getOriginChainOfAsset(assetSlug) {
123
123
  if (assetSlug.startsWith(_types2._CUSTOM_PREFIX)) {
124
- return assetSlug.split('-')[1];
124
+ const arr = assetSlug.split('-').slice(1);
125
+ if (arr[0] === 'custom') {
126
+ const end = arr.findIndex(str => Object.values(_types._AssetType).includes(str));
127
+ return arr.slice(0, end).join('-');
128
+ }
129
+ return arr[0];
125
130
  }
126
131
  return assetSlug.split('-')[0];
127
132
  }
@@ -106,8 +106,8 @@ class DatabaseService {
106
106
  next: data => callback && callback(data)
107
107
  });
108
108
  }
109
- subscribeNominatorMetadata(callback) {
110
- this.stores.nominatorMetadata.subscribeAll().subscribe({
109
+ subscribeNominatorMetadata(addresses, callback) {
110
+ return this.stores.nominatorMetadata.subscribeByAddresses(addresses).subscribe({
111
111
  next: data => callback && callback(data)
112
112
  });
113
113
  }
@@ -198,7 +198,11 @@ class DatabaseService {
198
198
  }
199
199
 
200
200
  // Staking
201
- async updateChainStakingMetadata(item) {
201
+ async updateChainStakingMetadata(item, changes) {
202
+ const existingRecord = await this.stores.chainStakingMetadata.getByChainAndType(item.chain, item.type);
203
+ if (existingRecord && changes) {
204
+ return this.stores.chainStakingMetadata.updateByChainAndType(item.chain, item.type, changes);
205
+ }
202
206
  return this.stores.chainStakingMetadata.upsert(item);
203
207
  }
204
208
  async getChainStakingMetadata() {
@@ -34,5 +34,10 @@ class ChainStakingMetadataStore extends _BaseStoreWithChain.default {
34
34
  async removeByChains(chains) {
35
35
  return this.table.where('chain').anyOfIgnoreCase(chains).delete();
36
36
  }
37
+ updateByChainAndType(chain) {
38
+ let type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _KoniTypes.StakingType.NOMINATED;
39
+ let changes = arguments.length > 2 ? arguments[2] : undefined;
40
+ return this.table.update([chain, type], changes);
41
+ }
37
42
  }
38
43
  exports.default = ChainStakingMetadataStore;
@@ -14,14 +14,14 @@ class NominatorMetadataStore extends _BaseStoreWithAddressAndChain.default {
14
14
  async getAll() {
15
15
  return this.table.toArray();
16
16
  }
17
- subscribeByAddress(address) {
18
- return (0, _dexie.liveQuery)(() => this.getByAddress(address));
17
+ subscribeByAddresses(addresses) {
18
+ return (0, _dexie.liveQuery)(() => this.getByAddress(addresses));
19
19
  }
20
20
  subscribeAll() {
21
21
  return (0, _dexie.liveQuery)(() => this.getAll());
22
22
  }
23
- getByAddress(address) {
24
- return this.table.where('address').anyOfIgnoreCase(address).toArray();
23
+ getByAddress(addresses) {
24
+ return this.table.where('address').anyOfIgnoreCase(addresses).toArray();
25
25
  }
26
26
  async removeByAddress(address) {
27
27
  return this.table.where('address').anyOfIgnoreCase(address).delete();
@@ -644,7 +644,12 @@ class TransactionService {
644
644
  if (!payload.parseData) {
645
645
  const isToContract = await (0, _parseTransaction.isContractAddress)(payload.to || '', evmApi);
646
646
  payload.isToContract = isToContract;
647
- payload.parseData = isToContract ? payload.data ? (await (0, _parseTransaction.parseContractInput)(payload.data || '', payload.to || '', chainInfo)).result : '' : payload.data || '';
647
+ try {
648
+ payload.parseData = isToContract ? payload.data ? (await (0, _parseTransaction.parseContractInput)(payload.data || '', payload.to || '', chainInfo)).result : '' : payload.data || '';
649
+ } catch (e) {
650
+ console.warn('Unable to parse contract input data');
651
+ payload.parseData = payload.data;
652
+ }
648
653
  }
649
654
  if ('data' in payload && payload.data === undefined) {
650
655
  delete payload.data;
@@ -6,7 +6,7 @@ export declare const ASTAR_REFRESH_BALANCE_INTERVAL = 60000;
6
6
  export declare const SUB_TOKEN_REFRESH_BALANCE_INTERVAL = 60000;
7
7
  export declare const CRON_REFRESH_NFT_INTERVAL = 7200000;
8
8
  export declare const CRON_REFRESH_STAKING_REWARD_INTERVAL = 900000;
9
- export declare const CRON_REFRESH_STAKING_REWARD_FAST_INTERVAL = 45000;
9
+ export declare const CRON_REFRESH_STAKING_REWARD_FAST_INTERVAL = 300000;
10
10
  export declare const CRON_REFRESH_HISTORY_INTERVAL = 900000;
11
11
  export declare const CRON_GET_API_MAP_STATUS = 10000;
12
12
  export declare const CRON_REFRESH_CHAIN_STAKING_METADATA = 900000;
@@ -9,7 +9,7 @@ export const ASTAR_REFRESH_BALANCE_INTERVAL = 60000;
9
9
  export const SUB_TOKEN_REFRESH_BALANCE_INTERVAL = 60000;
10
10
  export const CRON_REFRESH_NFT_INTERVAL = 7200000;
11
11
  export const CRON_REFRESH_STAKING_REWARD_INTERVAL = 900000;
12
- export const CRON_REFRESH_STAKING_REWARD_FAST_INTERVAL = 45000;
12
+ export const CRON_REFRESH_STAKING_REWARD_FAST_INTERVAL = 300000;
13
13
  export const CRON_REFRESH_HISTORY_INTERVAL = 900000;
14
14
  export const CRON_GET_API_MAP_STATUS = 10000;
15
15
  export const CRON_REFRESH_CHAIN_STAKING_METADATA = 900000;
@@ -1,7 +1,11 @@
1
1
  import { _ChainInfo } from '@subwallet/chain-list/types';
2
2
  import { ChainStakingMetadata, NominatorMetadata, ValidatorInfo } from '@subwallet/extension-base/background/KoniTypes';
3
+ import { ParachainStakingStakeOption } from '@subwallet/extension-base/koni/api/staking/bonding/utils';
3
4
  import { _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
5
+ import { Codec } from '@polkadot/types/types';
6
+ export declare function subscribeAmplitudeStakingMetadata(chain: string, substrateApi: _SubstrateApi, callback: (chain: string, rs: ChainStakingMetadata) => void): Promise<Codec>;
4
7
  export declare function getAmplitudeStakingMetadata(chain: string, substrateApi: _SubstrateApi): Promise<ChainStakingMetadata>;
8
+ export declare function subscribeAmplitudeNominatorMetadata(chainInfo: _ChainInfo, address: string, substrateApi: _SubstrateApi, delegatorState: ParachainStakingStakeOption, unstakingInfo: Record<string, number>): Promise<NominatorMetadata>;
5
9
  export declare function getAmplitudeNominatorMetadata(chainInfo: _ChainInfo, address: string, substrateApi: _SubstrateApi): Promise<NominatorMetadata | undefined>;
6
10
  export declare function getAmplitudeCollatorsInfo(chain: string, substrateApi: _SubstrateApi): Promise<ValidatorInfo[]>;
7
11
  export declare function getAmplitudeBondingExtrinsic(substrateApi: _SubstrateApi, amount: string, selectedValidatorInfo: ValidatorInfo, nominatorMetadata?: NominatorMetadata): Promise<import("@polkadot/api-base/types").SubmittableExtrinsic<"promise", import("@polkadot/types/types").ISubmittableResult>>;
@@ -7,6 +7,30 @@ import { _STAKING_ERA_LENGTH_MAP } from '@subwallet/extension-base/services/chai
7
7
  import { parseRawNumber, reformatAddress } from '@subwallet/extension-base/utils';
8
8
  import { BN, BN_ZERO } from '@polkadot/util';
9
9
  import { isEthereumAddress } from '@polkadot/util-crypto';
10
+ export function subscribeAmplitudeStakingMetadata(chain, substrateApi, callback) {
11
+ return substrateApi.api.query.parachainStaking.round(_round => {
12
+ const roundObj = _round.toHuman();
13
+ const round = parseRawNumber(roundObj.current);
14
+ const maxDelegations = substrateApi.api.consts.parachainStaking.maxDelegationsPerRound.toString();
15
+ const minDelegatorStake = substrateApi.api.consts.parachainStaking.minDelegatorStake.toString();
16
+ const unstakingDelay = substrateApi.api.consts.parachainStaking.stakeDuration.toString();
17
+ const _blockPerRound = substrateApi.api.consts.parachainStaking.defaultBlocksPerRound.toString();
18
+ const blockPerRound = parseFloat(_blockPerRound);
19
+ const blockDuration = (_STAKING_ERA_LENGTH_MAP[chain] || _STAKING_ERA_LENGTH_MAP.default) / blockPerRound; // in hours
20
+ const unstakingPeriod = blockDuration * parseInt(unstakingDelay);
21
+ callback(chain, {
22
+ chain,
23
+ type: StakingType.NOMINATED,
24
+ era: round,
25
+ minStake: minDelegatorStake,
26
+ maxValidatorPerNominator: parseInt(maxDelegations),
27
+ maxWithdrawalRequestPerValidator: 1,
28
+ // by default
29
+ allowCancelUnstaking: true,
30
+ unstakingPeriod
31
+ });
32
+ });
33
+ }
10
34
  export async function getAmplitudeStakingMetadata(chain, substrateApi) {
11
35
  const chainApi = await substrateApi.isReady;
12
36
  const _round = (await chainApi.api.query.parachainStaking.round()).toHuman();
@@ -30,6 +54,63 @@ export async function getAmplitudeStakingMetadata(chain, substrateApi) {
30
54
  unstakingPeriod
31
55
  };
32
56
  }
57
+ export async function subscribeAmplitudeNominatorMetadata(chainInfo, address, substrateApi, delegatorState, unstakingInfo) {
58
+ const nominationList = [];
59
+ const unstakingList = [];
60
+ const minDelegatorStake = substrateApi.api.consts.parachainStaking.minDelegatorStake.toString();
61
+ let activeStake = '0';
62
+ if (delegatorState) {
63
+ // delegatorState can be null while unstaking all
64
+ const identityInfo = substrateApi.api.query.identity ? (await substrateApi.api.query.identity.identityOf(delegatorState.owner)).toPrimitive() : undefined;
65
+ const identity = identityInfo ? parseIdentity(identityInfo) : undefined;
66
+ activeStake = delegatorState.amount.toString();
67
+ const bnActiveStake = new BN(activeStake);
68
+ let delegationStatus = StakingStatus.NOT_EARNING;
69
+ if (bnActiveStake.gt(BN_ZERO) && bnActiveStake.gte(new BN(minDelegatorStake))) {
70
+ delegationStatus = StakingStatus.EARNING_REWARD;
71
+ }
72
+ nominationList.push({
73
+ status: delegationStatus,
74
+ chain: chainInfo.slug,
75
+ validatorAddress: delegatorState.owner,
76
+ activeStake: delegatorState.amount.toString(),
77
+ validatorMinStake: '0',
78
+ hasUnstaking: !!unstakingInfo && Object.values(unstakingInfo).length > 0,
79
+ validatorIdentity: identity
80
+ });
81
+ }
82
+ if (unstakingInfo && Object.values(unstakingInfo).length > 0) {
83
+ const _currentBlockInfo = await substrateApi.api.rpc.chain.getHeader();
84
+ const currentBlockInfo = _currentBlockInfo.toPrimitive();
85
+ const currentBlockNumber = currentBlockInfo.number;
86
+ const _blockPerRound = substrateApi.api.consts.parachainStaking.defaultBlocksPerRound.toString();
87
+ const blockPerRound = parseFloat(_blockPerRound);
88
+ const nearestUnstakingBlock = Object.keys(unstakingInfo)[0];
89
+ const nearestUnstakingAmount = Object.values(unstakingInfo)[0];
90
+ const blockDuration = (_STAKING_ERA_LENGTH_MAP[chainInfo.slug] || _STAKING_ERA_LENGTH_MAP.default) / blockPerRound; // in hours
91
+
92
+ const isClaimable = parseInt(nearestUnstakingBlock) - currentBlockNumber <= 0;
93
+ const remainingBlock = parseInt(nearestUnstakingBlock) - (currentBlockNumber + 1);
94
+ const waitingTime = remainingBlock * blockDuration;
95
+ unstakingList.push({
96
+ chain: chainInfo.slug,
97
+ status: isClaimable ? UnstakingStatus.CLAIMABLE : UnstakingStatus.UNLOCKING,
98
+ claimable: nearestUnstakingAmount.toString(),
99
+ waitingTime: waitingTime > 0 ? waitingTime : 0,
100
+ validatorAddress: (delegatorState === null || delegatorState === void 0 ? void 0 : delegatorState.owner) || undefined
101
+ });
102
+ }
103
+ const stakingStatus = getStakingStatusByNominations(new BN(activeStake), nominationList);
104
+ return {
105
+ chain: chainInfo.slug,
106
+ type: StakingType.NOMINATED,
107
+ status: stakingStatus,
108
+ address: address,
109
+ activeStake: activeStake,
110
+ nominations: nominationList,
111
+ unstakings: unstakingList
112
+ };
113
+ }
33
114
  export async function getAmplitudeNominatorMetadata(chainInfo, address, substrateApi) {
34
115
  if (isEthereumAddress(address)) {
35
116
  return;
@@ -1,7 +1,11 @@
1
1
  import { _ChainInfo } from '@subwallet/chain-list/types';
2
2
  import { ChainStakingMetadata, NominatorMetadata, UnstakingInfo, ValidatorInfo } from '@subwallet/extension-base/background/KoniTypes';
3
+ import { PalletDappsStakingAccountLedger } from '@subwallet/extension-base/koni/api/staking/bonding/utils';
3
4
  import { _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
5
+ import { Codec } from '@polkadot/types/types';
6
+ export declare function subscribeAstarStakingMetadata(chain: string, substrateApi: _SubstrateApi, callback: (chain: string, rs: ChainStakingMetadata) => void): Promise<Codec>;
4
7
  export declare function getAstarStakingMetadata(chain: string, substrateApi: _SubstrateApi): Promise<ChainStakingMetadata>;
8
+ export declare function subscribeAstarNominatorMetadata(chainInfo: _ChainInfo, address: string, substrateApi: _SubstrateApi, ledger: PalletDappsStakingAccountLedger): Promise<NominatorMetadata>;
5
9
  export declare function getAstarNominatorMetadata(chainInfo: _ChainInfo, address: string, substrateApi: _SubstrateApi): Promise<NominatorMetadata | undefined>;
6
10
  export declare function getAstarDappsInfo(networkKey: string, substrateApi: _SubstrateApi): Promise<ValidatorInfo[]>;
7
11
  export declare function getAstarBondingExtrinsic(substrateApi: _SubstrateApi, amount: string, dappInfo: ValidatorInfo): Promise<import("@polkadot/api-base/types").SubmittableExtrinsic<"promise", import("@polkadot/types/types").ISubmittableResult>>;