@subwallet/extension-base 1.0.2-3 → 1.0.4-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 (49) hide show
  1. package/background/KoniTypes.d.ts +10 -2
  2. package/background/KoniTypes.js +3 -1
  3. package/cjs/background/KoniTypes.js +3 -1
  4. package/cjs/koni/background/handlers/Extension.js +9 -0
  5. package/cjs/koni/background/handlers/State.js +8 -1
  6. package/cjs/koni/background/subscription.js +24 -2
  7. package/cjs/packageInfo.js +1 -1
  8. package/cjs/services/base/types.js +20 -0
  9. package/cjs/services/chain-service/constants.js +17 -2
  10. package/cjs/services/chain-service/index.js +57 -18
  11. package/cjs/services/history-service/index.js +84 -39
  12. package/cjs/services/migration-service/scripts/MigrateImportedToken.js +2 -1
  13. package/cjs/services/price-service/index.js +71 -23
  14. package/cjs/services/storage-service/DatabaseService.js +10 -0
  15. package/cjs/services/storage-service/db-stores/Transaction.js +6 -10
  16. package/cjs/services/transaction-service/index.js +78 -33
  17. package/cjs/services/transaction-service/utils.js +10 -8
  18. package/cjs/utils/promise.js +26 -0
  19. package/koni/background/handlers/Extension.d.ts +1 -0
  20. package/koni/background/handlers/Extension.js +9 -0
  21. package/koni/background/handlers/State.js +8 -1
  22. package/koni/background/subscription.d.ts +2 -0
  23. package/koni/background/subscription.js +23 -2
  24. package/package.json +22 -12
  25. package/packageInfo.js +1 -1
  26. package/services/base/types.d.ts +34 -0
  27. package/services/base/types.js +15 -0
  28. package/services/chain-service/constants.d.ts +6 -0
  29. package/services/chain-service/constants.js +10 -1
  30. package/services/chain-service/index.d.ts +3 -0
  31. package/services/chain-service/index.js +59 -20
  32. package/services/history-service/index.d.ts +24 -5
  33. package/services/history-service/index.js +84 -39
  34. package/services/migration-service/scripts/MigrateImportedToken.js +2 -1
  35. package/services/price-service/index.d.ts +22 -1
  36. package/services/price-service/index.js +71 -23
  37. package/services/storage-service/DatabaseService.d.ts +1 -0
  38. package/services/storage-service/DatabaseService.js +10 -0
  39. package/services/storage-service/db-stores/Transaction.d.ts +2 -0
  40. package/services/storage-service/db-stores/Transaction.js +6 -10
  41. package/services/transaction-service/index.d.ts +2 -0
  42. package/services/transaction-service/index.js +60 -17
  43. package/services/transaction-service/types.d.ts +2 -0
  44. package/services/transaction-service/utils.js +10 -8
  45. package/utils/promise.d.ts +6 -0
  46. package/utils/promise.js +20 -0
  47. /package/cjs/services/chain-service/{heath-check → health-check}/index.js +0 -0
  48. /package/services/chain-service/{heath-check → health-check}/index.d.ts +0 -0
  49. /package/services/chain-service/{heath-check → health-check}/index.js +0 -0
@@ -5,7 +5,9 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.PriceService = void 0;
7
7
  var _constants = require("@subwallet/extension-base/constants");
8
+ var _types = require("@subwallet/extension-base/services/base/types");
8
9
  var _coingecko = require("@subwallet/extension-base/services/price-service/coingecko");
10
+ var _promise = require("@subwallet/extension-base/utils/promise");
9
11
  var _rxjs = require("rxjs");
10
12
  // Copyright 2019-2022 @subwallet/extension-koni authors & contributors
11
13
  // SPDX-License-Identifier: Apache-2.0
@@ -20,34 +22,14 @@ class PriceService {
20
22
  priceSubject = new _rxjs.BehaviorSubject(DEFAULT_PRICE_SUBJECT);
21
23
  priceIds = new Set();
22
24
  constructor(dbService, eventService, chainService) {
25
+ this.status = _types.ServiceStatus.NOT_INITIALIZED;
23
26
  this.dbService = dbService;
24
27
  this.eventService = eventService;
25
28
  this.chainService = chainService;
26
-
27
- // Fetch data from storage
28
- this.getPrice().catch(console.error);
29
- const eventHandler = () => {
30
- const newPriceIds = this.getPriceIds();
31
-
32
- // Compare two set newPriceIds and this.priceIds
33
- if (newPriceIds.size !== this.priceIds.size || !Array.from(newPriceIds).every(v => this.priceIds.has(v))) {
34
- this.priceIds = newPriceIds;
35
- this.refreshPriceData(this.priceIds);
36
- }
37
- };
38
- this.eventService.waitAssetReady.then(() => {
39
- this.refreshPriceData();
40
- this.eventService.on('asset.updateState', eventHandler);
41
- this.eventService.on('asset.updateState', eventHandler);
42
- }).catch(console.error);
29
+ this.init().catch(console.error);
43
30
  }
44
31
  async getPrice() {
45
- const isReady = this.priceSubject.value.ready;
46
- if (!isReady) {
47
- const data = await this.dbService.getPriceStore();
48
- this.priceSubject.next(data || DEFAULT_PRICE_SUBJECT);
49
- }
50
- return this.priceSubject.value;
32
+ return Promise.resolve(this.priceSubject.value);
51
33
  }
52
34
  getPriceSubject() {
53
35
  return this.priceSubject;
@@ -71,5 +53,71 @@ class PriceService {
71
53
  }).catch(console.error);
72
54
  this.refreshTimeout = setTimeout(this.refreshPriceData.bind(this), _constants.CRON_REFRESH_PRICE_INTERVAL);
73
55
  }
56
+ async init() {
57
+ this.status = _types.ServiceStatus.INITIALIZING;
58
+ // Fetch data from storage
59
+ await this.loadData();
60
+ const eventHandler = () => {
61
+ const newPriceIds = this.getPriceIds();
62
+
63
+ // Compare two set newPriceIds and this.priceIds
64
+ if (newPriceIds.size !== this.priceIds.size || !Array.from(newPriceIds).every(v => this.priceIds.has(v))) {
65
+ this.priceIds = newPriceIds;
66
+ this.refreshPriceData(this.priceIds);
67
+ }
68
+ };
69
+ await this.eventService.waitAssetReady;
70
+ this.status = _types.ServiceStatus.INITIALIZED;
71
+ this.eventService.on('asset.updateState', eventHandler);
72
+ this.eventService.on('asset.updateState', eventHandler);
73
+ }
74
+ async loadData() {
75
+ const data = await this.dbService.getPriceStore();
76
+ this.priceSubject.next(data || DEFAULT_PRICE_SUBJECT);
77
+ }
78
+ async persistData() {
79
+ await this.dbService.updatePriceStore(this.priceSubject.value).catch(console.error);
80
+ }
81
+ startPromiseHandler = (0, _promise.createPromiseHandler)();
82
+ async start() {
83
+ console.debug('Start price service');
84
+ try {
85
+ this.startPromiseHandler = (0, _promise.createPromiseHandler)();
86
+ this.status = _types.ServiceStatus.STARTING;
87
+ await this.startCron();
88
+ this.status = _types.ServiceStatus.STARTED;
89
+ this.startPromiseHandler.resolve();
90
+ } catch (e) {
91
+ this.startPromiseHandler.reject(e);
92
+ }
93
+ }
94
+ async startCron() {
95
+ this.refreshPriceData();
96
+ return Promise.resolve();
97
+ }
98
+ stopPromiseHandler = (0, _promise.createPromiseHandler)();
99
+ async stop() {
100
+ console.debug('Stop price service');
101
+ try {
102
+ this.status = _types.ServiceStatus.STOPPING;
103
+ this.stopPromiseHandler = (0, _promise.createPromiseHandler)();
104
+ await this.stopCron();
105
+ await this.persistData();
106
+ this.status = _types.ServiceStatus.STOPPED;
107
+ this.stopPromiseHandler.resolve();
108
+ } catch (e) {
109
+ this.stopPromiseHandler.reject(e);
110
+ }
111
+ }
112
+ stopCron() {
113
+ clearTimeout(this.refreshTimeout);
114
+ return Promise.resolve(undefined);
115
+ }
116
+ waitForStarted() {
117
+ return this.startPromiseHandler.promise;
118
+ }
119
+ waitForStopped() {
120
+ return this.stopPromiseHandler.promise;
121
+ }
74
122
  }
75
123
  exports.PriceService = PriceService;
@@ -133,6 +133,16 @@ class DatabaseService {
133
133
  const cleanedHistory = histories.filter(x => x && x.address && x.chain && x.extrinsicHash);
134
134
  return this.stores.transaction.bulkUpsert(cleanedHistory);
135
135
  }
136
+ async updateHistoryByNewExtrinsicHash(extrinsicHash, updateData) {
137
+ // this.logger.log('Updating transaction histories');
138
+ const canUpdate = updateData && extrinsicHash;
139
+ if (!canUpdate) {
140
+ return;
141
+ }
142
+ return this.stores.transaction.updateWithQuery({
143
+ extrinsicHash
144
+ }, updateData);
145
+ }
136
146
 
137
147
  // NFT Collection
138
148
  async addNftCollection(collection) {
@@ -36,16 +36,12 @@ class TransactionStore extends _BaseStoreWithAddressAndChain.default {
36
36
  }
37
37
  async bulkUpsert(records) {
38
38
  await this.table.bulkPut(records);
39
-
40
- // await Promise.all(records.map((record) => {
41
- // return this.table.where({
42
- // chain: record.chain,
43
- // address: record.address,
44
- // extrinsicHash: record.extrinsicHash
45
- // }).filter((item) => (item.origin === 'app' && record.origin !== 'app'))
46
- // .delete();
47
- // }));
48
-
39
+ return true;
40
+ }
41
+ async updateWithQuery(query, update) {
42
+ await this.table.where(query).modify(record => {
43
+ return Object.assign(record, update);
44
+ });
49
45
  return true;
50
46
  }
51
47
  }
@@ -44,7 +44,7 @@ class TransactionService {
44
44
  return Object.values(this.transactions);
45
45
  }
46
46
  get processingTransactions() {
47
- return this.allTransactions.filter(t => t.status === _KoniTypes.ExtrinsicStatus.PENDING || t.status === _KoniTypes.ExtrinsicStatus.PROCESSING);
47
+ return this.allTransactions.filter(t => t.status === _KoniTypes.ExtrinsicStatus.QUEUED || t.status === _KoniTypes.ExtrinsicStatus.PROCESSING);
48
48
  }
49
49
  getTransaction(id) {
50
50
  return this.transactions[id];
@@ -164,6 +164,7 @@ class TransactionService {
164
164
  }
165
165
  fillTransactionDefaultInfo(transaction) {
166
166
  const isInternal = !transaction.url;
167
+ const transactionId = (0, _helpers.getTransactionId)(transaction.chainType, transaction.chain, isInternal);
167
168
  return {
168
169
  ...transaction,
169
170
  createdAt: new Date(),
@@ -171,10 +172,10 @@ class TransactionService {
171
172
  errors: transaction.errors || [],
172
173
  warnings: transaction.warnings || [],
173
174
  url: transaction.url || _constants2.EXTENSION_REQUEST_URL,
174
- status: _KoniTypes.ExtrinsicStatus.PENDING,
175
+ status: _KoniTypes.ExtrinsicStatus.QUEUED,
175
176
  isInternal,
176
- id: (0, _helpers.getTransactionId)(transaction.chainType, transaction.chain, isInternal),
177
- extrinsicHash: ''
177
+ id: transactionId,
178
+ extrinsicHash: transactionId
178
179
  };
179
180
  }
180
181
  async addTransaction(inputTransaction) {
@@ -187,8 +188,6 @@ class TransactionService {
187
188
  this.transactionSubject.next({
188
189
  ...transactions
189
190
  });
190
-
191
- // Send transaction
192
191
  return await this.sendTransaction(transaction);
193
192
  }
194
193
  generateBeforeHandleResponseErrors(errors) {
@@ -215,7 +214,8 @@ class TransactionService {
215
214
  validatedTransaction.warnings = [];
216
215
  const emitter = await this.addTransaction(validatedTransaction);
217
216
  await new Promise(resolve => {
218
- emitter.on('extrinsicHash', data => {
217
+ emitter.on('signed', data => {
218
+ validatedTransaction.id = data.id;
219
219
  validatedTransaction.extrinsicHash = data.extrinsicHash;
220
220
  resolve();
221
221
  });
@@ -231,6 +231,12 @@ class TransactionService {
231
231
  async sendTransaction(transaction) {
232
232
  // Send Transaction
233
233
  const emitter = transaction.chainType === 'substrate' ? this.signAndSendSubstrateTransaction(transaction) : await this.signAndSendEvmTransaction(transaction);
234
+ emitter.on('signed', data => {
235
+ this.onSigned(data);
236
+ });
237
+ emitter.on('send', data => {
238
+ this.onSend(data);
239
+ });
234
240
  emitter.on('extrinsicHash', data => {
235
241
  this.onHasTransactionHash(data);
236
242
  });
@@ -283,7 +289,8 @@ class TransactionService {
283
289
  to: '',
284
290
  chainType: transaction.chainType,
285
291
  address: transaction.address,
286
- status: _KoniTypes.ExtrinsicStatus.PROCESSING,
292
+ status: transaction.status,
293
+ transactionId: transaction.id,
287
294
  extrinsicHash: transaction.extrinsicHash,
288
295
  time: transaction.createdAt.getTime(),
289
296
  fee: transaction.estimateFee,
@@ -426,8 +433,14 @@ class TransactionService {
426
433
  break;
427
434
  }
428
435
  case _KoniTypes.ExtrinsicType.EVM_EXECUTE:
429
- // Todo: Update historyItem.to
430
- break;
436
+ {
437
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
438
+ const data = (0, _utils2.parseTransactionData)(transaction.data);
439
+
440
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access
441
+ historyItem.to = (data === null || data === void 0 ? void 0 : data.to) || '';
442
+ break;
443
+ }
431
444
  case _KoniTypes.ExtrinsicType.UNKNOWN:
432
445
  break;
433
446
  }
@@ -446,18 +459,39 @@ class TransactionService {
446
459
  }
447
460
  return [historyItem];
448
461
  }
449
- onHasTransactionHash(_ref) {
462
+ onSigned(_ref) {
450
463
  let {
451
- eventLogs,
452
- extrinsicHash,
453
464
  id
454
465
  } = _ref;
455
- // Write processing transaction history
466
+ console.log(`Transaction "${id}" is signed`);
467
+ }
468
+ onSend(_ref2) {
469
+ let {
470
+ id
471
+ } = _ref2;
472
+ // Update transaction status
456
473
  this.updateTransaction(id, {
474
+ status: _KoniTypes.ExtrinsicStatus.SUBMITTING
475
+ });
476
+
477
+ // Create Input History Transaction History
478
+ this.historyService.insertHistories(this.transactionToHistories(id)).catch(console.error);
479
+ console.log(`Transaction "${id}" is sent`);
480
+ }
481
+ onHasTransactionHash(_ref3) {
482
+ let {
483
+ extrinsicHash,
484
+ id
485
+ } = _ref3;
486
+ // Write processing transaction history
487
+ const updateData = {
457
488
  extrinsicHash,
458
489
  status: _KoniTypes.ExtrinsicStatus.PROCESSING
459
- });
460
- this.historyService.insertHistories(this.transactionToHistories(id, eventLogs)).catch(console.error);
490
+ };
491
+ this.updateTransaction(id, updateData);
492
+
493
+ // In this case transaction id is the same as extrinsic hash and will change after below update
494
+ this.historyService.updateHistoryByExtrinsicHash(id, updateData).catch(console.error);
461
495
  console.log(`Transaction "${id}" is submitted with hash ${extrinsicHash || ''}`);
462
496
  }
463
497
  handlePostProcessing(id) {
@@ -486,12 +520,12 @@ class TransactionService {
486
520
  this.eventService.emit('transaction.submitStaking', transaction.chain);
487
521
  }
488
522
  }
489
- onSuccess(_ref2) {
523
+ onSuccess(_ref4) {
490
524
  let {
491
525
  blockHash,
492
526
  blockNumber,
493
527
  id
494
- } = _ref2;
528
+ } = _ref4;
495
529
  const transaction = this.getTransaction(id);
496
530
  this.updateTransaction(id, {
497
531
  status: _KoniTypes.ExtrinsicStatus.SUCCESS
@@ -515,24 +549,25 @@ class TransactionService {
515
549
  });
516
550
  this.eventService.emit('transaction.done', transaction);
517
551
  }
518
- onFailed(_ref3) {
552
+ onFailed(_ref5) {
519
553
  let {
520
554
  blockHash,
521
555
  blockNumber,
522
556
  errors,
523
557
  id
524
- } = _ref3;
558
+ } = _ref5;
525
559
  const transaction = this.getTransaction(id);
560
+ const nextStatus = _KoniTypes.ExtrinsicStatus.FAIL;
526
561
  if (transaction) {
527
562
  this.updateTransaction(id, {
528
- status: _KoniTypes.ExtrinsicStatus.FAIL,
563
+ status: nextStatus,
529
564
  errors
530
565
  });
531
566
  console.log('Transaction failed', id, transaction.extrinsicHash);
532
567
 
533
568
  // Write failed transaction history
534
569
  this.historyService.updateHistories(transaction.chain, transaction.extrinsicHash, {
535
- status: _KoniTypes.ExtrinsicStatus.FAIL,
570
+ status: nextStatus,
536
571
  blockNumber: blockNumber || 0,
537
572
  blockHash: blockHash || ''
538
573
  }).catch(console.error);
@@ -566,14 +601,14 @@ class TransactionService {
566
601
  const encoded = _rlp.default.encode(data);
567
602
  return (0, _util.u8aToHex)(encoded);
568
603
  }
569
- async signAndSendEvmTransaction(_ref4) {
604
+ async signAndSendEvmTransaction(_ref6) {
570
605
  let {
571
606
  address,
572
607
  chain,
573
608
  id,
574
609
  transaction,
575
610
  url
576
- } = _ref4;
611
+ } = _ref6;
577
612
  const payload = transaction;
578
613
  const evmApi = this.chainService.getEvmApi(chain);
579
614
  const chainInfo = this.chainService.getChainInfoByKey(chain);
@@ -633,11 +668,11 @@ class TransactionService {
633
668
  errors: [],
634
669
  warnings: []
635
670
  };
636
- this.requestService.addConfirmation(id, url || _constants2.EXTENSION_REQUEST_URL, 'evmSendTransactionRequest', payload, {}).then(_ref5 => {
671
+ this.requestService.addConfirmation(id, url || _constants2.EXTENSION_REQUEST_URL, 'evmSendTransactionRequest', payload, {}).then(_ref7 => {
637
672
  let {
638
673
  isApproved,
639
674
  payload
640
- } = _ref5;
675
+ } = _ref7;
641
676
  if (isApproved) {
642
677
  let signedTransaction;
643
678
  if (!payload) {
@@ -654,6 +689,12 @@ class TransactionService {
654
689
  }
655
690
  signedTransaction = signed;
656
691
  }
692
+
693
+ // Emit signed event
694
+ emitter.emit('signed', eventData);
695
+
696
+ // Send transaction
697
+ emitter.emit('send', eventData); // This event is needed after sending transaction with queue
657
698
  signedTransaction && web3Api.eth.sendSignedTransaction(signedTransaction).once('transactionHash', hash => {
658
699
  eventData.extrinsicHash = hash;
659
700
  emitter.emit('extrinsicHash', eventData);
@@ -680,20 +721,19 @@ class TransactionService {
680
721
  });
681
722
  return emitter;
682
723
  }
683
- signAndSendSubstrateTransaction(_ref6) {
724
+ signAndSendSubstrateTransaction(_ref8) {
684
725
  let {
685
726
  address,
686
727
  id,
687
728
  transaction,
688
729
  url
689
- } = _ref6;
730
+ } = _ref8;
690
731
  const emitter = new _eventemitter.default();
691
732
  const eventData = {
692
733
  id,
693
734
  errors: [],
694
735
  warnings: []
695
736
  };
696
- console.debug(address, transaction);
697
737
  transaction.signAsync(address, {
698
738
  signer: {
699
739
  signPayload: async payload => {
@@ -705,6 +745,11 @@ class TransactionService {
705
745
  }
706
746
  }
707
747
  }).then(rs => {
748
+ // Emit signed event
749
+ emitter.emit('signed', eventData);
750
+
751
+ // Send transaction
752
+ emitter.emit('send', eventData); // This event is needed after sending transaction with queue
708
753
  rs.send(txState => {
709
754
  // handle events, logs, history
710
755
  if (!txState || !txState.status) {
@@ -720,20 +765,20 @@ class TransactionService {
720
765
  if (txState.status.isFinalized) {
721
766
  eventData.eventLogs = txState.events;
722
767
  // TODO: push block hash and block number into eventData
723
- txState.events.filter(_ref7 => {
768
+ txState.events.filter(_ref9 => {
724
769
  let {
725
770
  event: {
726
771
  section
727
772
  }
728
- } = _ref7;
773
+ } = _ref9;
729
774
  return section === 'system';
730
- }).forEach(_ref8 => {
775
+ }).forEach(_ref10 => {
731
776
  let {
732
777
  event: {
733
778
  method,
734
779
  data: [error]
735
780
  }
736
- } = _ref8;
781
+ } = _ref10;
737
782
  if (method === 'ExtrinsicFailed') {
738
783
  eventData.errors.push(new _TransactionError.TransactionError(_KoniTypes.BasicTxErrorType.SEND_TRANSACTION_FAILED, error.toString()));
739
784
  emitter.emit('error', eventData);
@@ -15,15 +15,17 @@ function parseTransactionData(data) {
15
15
  return data;
16
16
  }
17
17
  function getTransactionLink(chainInfo, extrinsicHash) {
18
- const explorerLink = (0, _utils._getBlockExplorerFromChain)(chainInfo);
19
- if ((0, _utils._isPureEvmChain)(chainInfo)) {
20
- if (explorerLink) {
21
- return `${explorerLink}${explorerLink.endsWith('/') ? '' : '/'}tx/${extrinsicHash}`;
22
- }
23
- } else {
18
+ if (extrinsicHash.startsWith('0x')) {
24
19
  const explorerLink = (0, _utils._getBlockExplorerFromChain)(chainInfo);
25
- if (explorerLink) {
26
- return `${explorerLink}${explorerLink.endsWith('/') ? '' : '/'}extrinsic/${extrinsicHash}`;
20
+ if ((0, _utils._isPureEvmChain)(chainInfo)) {
21
+ if (explorerLink) {
22
+ return `${explorerLink}${explorerLink.endsWith('/') ? '' : '/'}tx/${extrinsicHash}`;
23
+ }
24
+ } else {
25
+ const explorerLink = (0, _utils._getBlockExplorerFromChain)(chainInfo);
26
+ if (explorerLink) {
27
+ return `${explorerLink}${explorerLink.endsWith('/') ? '' : '/'}extrinsic/${extrinsicHash}`;
28
+ }
27
29
  }
28
30
  }
29
31
  return undefined;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createPromiseHandler = createPromiseHandler;
7
+ // Copyright 2019-2022 @subwallet/extension-base
8
+ // SPDX-License-Identifier: Apache-2.0
9
+
10
+ function createPromiseHandler() {
11
+ let _resolve = () => {
12
+ console.warn('This promise handler is not implemented');
13
+ };
14
+ let _reject = () => {
15
+ console.warn('This promise handler is not implemented');
16
+ };
17
+ const promise = new Promise((resolve, reject) => {
18
+ _resolve = resolve;
19
+ _reject = reject;
20
+ });
21
+ return {
22
+ resolve: _resolve,
23
+ reject: _reject,
24
+ promise
25
+ };
26
+ }
@@ -184,5 +184,6 @@ export default class KoniExtension {
184
184
  private subscribeTransactions;
185
185
  private subscribeNotifications;
186
186
  private reloadCron;
187
+ private getLogoMap;
187
188
  handle<TMessageType extends MessageTypes>(id: string, type: TMessageType, request: RequestTypes[TMessageType], port: chrome.runtime.Port): Promise<ResponseType<TMessageType>>;
188
189
  }
@@ -2814,6 +2814,13 @@ export default class KoniExtension {
2814
2814
  }
2815
2815
  return Promise.resolve(false);
2816
2816
  }
2817
+ async getLogoMap() {
2818
+ const [chainLogoMap, assetLogoMap] = await Promise.all([this.#koniState.chainService.getChainLogoMap(), this.#koniState.chainService.getAssetLogoMap()]);
2819
+ return {
2820
+ chainLogoMap,
2821
+ assetLogoMap
2822
+ };
2823
+ }
2817
2824
 
2818
2825
  // --------------------------------------------------------------
2819
2826
  // eslint-disable-next-line @typescript-eslint/require-await
@@ -3173,6 +3180,8 @@ export default class KoniExtension {
3173
3180
  return this.subscribeNotifications(id, port);
3174
3181
  case 'pri(cron.reload)':
3175
3182
  return await this.reloadCron(request);
3183
+ case 'pri(settings.getLogoMaps)':
3184
+ return await this.getLogoMap();
3176
3185
 
3177
3186
  // Default
3178
3187
  default:
@@ -211,6 +211,8 @@ export default class KoniState {
211
211
  onReady() {
212
212
  this.subscription.start();
213
213
  this.cron.start();
214
+ this.historyService.start().catch(console.error);
215
+ this.priceService.start().catch(console.error);
214
216
  this.ready = true;
215
217
  this.logger.log('State is ready');
216
218
  }
@@ -556,7 +558,8 @@ export default class KoniState {
556
558
  assetType: tokenInfo.type,
557
559
  metadata: _parseMetadataForSmartContractAsset(tokenInfo.contractAddress),
558
560
  multiChainAsset: null,
559
- hasValue: _isChainTestNet(this.chainService.getChainInfoByKey(tokenInfo.originChain))
561
+ hasValue: _isChainTestNet(this.chainService.getChainInfoByKey(tokenInfo.originChain)),
562
+ icon: ''
560
563
  });
561
564
  return isApproved;
562
565
  } else {
@@ -1321,11 +1324,15 @@ export default class KoniState {
1321
1324
  this.cron.stop();
1322
1325
  this.subscription.stop();
1323
1326
  await this.pauseAllNetworks(undefined, 'IDLE mode');
1327
+ await this.historyService.stop();
1328
+ await this.priceService.stop();
1324
1329
  }
1325
1330
  async wakeup() {
1326
1331
  await this.resumeAllNetworks();
1327
1332
  this.cron.start();
1328
1333
  this.subscription.start();
1334
+ await this.historyService.start();
1335
+ await this.priceService.start();
1329
1336
  }
1330
1337
  cancelSubscription(id) {
1331
1338
  if (isSubscriptionRunning(id)) {
@@ -1,4 +1,5 @@
1
1
  import { _ChainAsset, _ChainInfo } from '@subwallet/chain-list/types';
2
+ import { ChainStakingMetadata } from '@subwallet/extension-base/background/KoniTypes';
2
3
  import { _ChainState, _EvmApi, _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
3
4
  import DatabaseService from '@subwallet/extension-base/services/storage-service/DatabaseService';
4
5
  import KoniState from './handlers/State';
@@ -26,6 +27,7 @@ export declare class KoniSubscription {
26
27
  initNftSubscription(addresses: string[], substrateApiMap: Record<string, _SubstrateApi>, evmApiMap: Record<string, _EvmApi>, smartContractNfts: _ChainAsset[], chainInfoMap: Record<string, _ChainInfo>): void;
27
28
  subscribeStakingReward(address: string): Promise<void>;
28
29
  subscribeStakingRewardFastInterval(address: string): Promise<void>;
30
+ fetchingStakingFromApi(): Promise<Record<string, ChainStakingMetadata>>;
29
31
  fetchChainStakingMetadata(chainInfoMap: Record<string, _ChainInfo>, chainStateMap: Record<string, _ChainState>, substrateApiMap: Record<string, _SubstrateApi>): Promise<void>;
30
32
  fetchNominatorMetadata(currentAddress: string, chainInfoMap: Record<string, _ChainInfo>, chainStateMap: Record<string, _ChainState>, substrateApiMap: Record<string, _SubstrateApi>): Promise<void>;
31
33
  }
@@ -12,6 +12,7 @@ import { nftHandler } from '@subwallet/extension-base/koni/background/handlers';
12
12
  import { _STAKING_CHAIN_GROUP } from '@subwallet/extension-base/services/chain-service/constants';
13
13
  import { _isChainEnabled, _isChainEvmCompatible, _isChainSupportSubstrateStaking, _isSubstrateRelayChain } from '@subwallet/extension-base/services/chain-service/utils';
14
14
  import { COMMON_RELOAD_EVENTS } from '@subwallet/extension-base/services/event-service/types';
15
+ import axios from 'axios';
15
16
  import { logger as createLogger } from '@polkadot/util';
16
17
  import { isEthereumAddress } from '@polkadot/util-crypto';
17
18
  export class KoniSubscription {
@@ -223,6 +224,17 @@ export class KoniSubscription {
223
224
  const result = [...poolingStakingRewards, ...amplitudeUnclaimedStakingRewards];
224
225
  this.state.updateStakingReward(result, 'fastInterval');
225
226
  }
227
+ async fetchingStakingFromApi() {
228
+ try {
229
+ const response = await axios.get('https://staking-data.subwallet.app/api/staking/get');
230
+ if (response.status === 200) {
231
+ return response.data;
232
+ }
233
+ } catch (e) {
234
+ this.logger.error(e);
235
+ }
236
+ return {};
237
+ }
226
238
  async fetchChainStakingMetadata(chainInfoMap, chainStateMap, substrateApiMap) {
227
239
  const filteredChainInfoMap = {};
228
240
  Object.values(chainInfoMap).forEach(chainInfo => {
@@ -234,9 +246,18 @@ export class KoniSubscription {
234
246
  if (Object.values(filteredChainInfoMap).length === 0) {
235
247
  return;
236
248
  }
249
+
250
+ // Fetch data from helper API
251
+ const dataFromApi = await this.fetchingStakingFromApi();
237
252
  await Promise.all(Object.values(filteredChainInfoMap).map(async chainInfo => {
238
- const chainStakingMetadata = await getChainStakingMetadata(chainInfo, substrateApiMap[chainInfo.slug]);
239
- this.state.updateChainStakingMetadata(chainStakingMetadata);
253
+ // Use fetch API data if available
254
+ if (dataFromApi[chainInfo.slug]) {
255
+ this.state.updateChainStakingMetadata(dataFromApi[chainInfo.slug]);
256
+ } else {
257
+ console.warn('Not found staking data from api', chainInfo.slug);
258
+ const chainStakingMetadata = await getChainStakingMetadata(chainInfo, substrateApiMap[chainInfo.slug]);
259
+ this.state.updateChainStakingMetadata(chainStakingMetadata);
260
+ }
240
261
  }));
241
262
  }
242
263
  async fetchNominatorMetadata(currentAddress, chainInfoMap, chainStateMap, substrateApiMap) {