@subwallet/extension-base 1.0.2-3 → 1.0.3-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 (43) 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/index.js +14 -4
  10. package/cjs/services/history-service/index.js +84 -39
  11. package/cjs/services/migration-service/scripts/MigrateImportedToken.js +2 -1
  12. package/cjs/services/price-service/index.js +71 -23
  13. package/cjs/services/storage-service/DatabaseService.js +10 -0
  14. package/cjs/services/storage-service/db-stores/Transaction.js +6 -10
  15. package/cjs/services/transaction-service/index.js +78 -33
  16. package/cjs/services/transaction-service/utils.js +10 -8
  17. package/cjs/utils/promise.js +26 -0
  18. package/koni/background/handlers/Extension.d.ts +1 -0
  19. package/koni/background/handlers/Extension.js +9 -0
  20. package/koni/background/handlers/State.js +8 -1
  21. package/koni/background/subscription.d.ts +2 -0
  22. package/koni/background/subscription.js +23 -2
  23. package/package.json +17 -7
  24. package/packageInfo.js +1 -1
  25. package/services/base/types.d.ts +34 -0
  26. package/services/base/types.js +15 -0
  27. package/services/chain-service/index.d.ts +2 -0
  28. package/services/chain-service/index.js +15 -5
  29. package/services/history-service/index.d.ts +24 -5
  30. package/services/history-service/index.js +84 -39
  31. package/services/migration-service/scripts/MigrateImportedToken.js +2 -1
  32. package/services/price-service/index.d.ts +22 -1
  33. package/services/price-service/index.js +71 -23
  34. package/services/storage-service/DatabaseService.d.ts +1 -0
  35. package/services/storage-service/DatabaseService.js +10 -0
  36. package/services/storage-service/db-stores/Transaction.d.ts +2 -0
  37. package/services/storage-service/db-stores/Transaction.js +6 -10
  38. package/services/transaction-service/index.d.ts +2 -0
  39. package/services/transaction-service/index.js +60 -17
  40. package/services/transaction-service/types.d.ts +2 -0
  41. package/services/transaction-service/utils.js +10 -8
  42. package/utils/promise.d.ts +6 -0
  43. package/utils/promise.js +20 -0
@@ -342,14 +342,16 @@ export interface ExtrinsicDataTypeMap {
342
342
  [ExtrinsicType.STAKING_CANCEL_COMPOUNDING]: RequestTuringCancelStakeCompound;
343
343
  [ExtrinsicType.STAKING_CANCEL_UNSTAKE]: RequestStakeCancelWithdrawal;
344
344
  [ExtrinsicType.STAKING_POOL_WITHDRAW]: any;
345
- [ExtrinsicType.EVM_EXECUTE]: any;
345
+ [ExtrinsicType.EVM_EXECUTE]: TransactionConfig;
346
346
  [ExtrinsicType.UNKNOWN]: any;
347
347
  }
348
348
  export declare enum ExtrinsicStatus {
349
- PENDING = "pending",
349
+ QUEUED = "queued",
350
+ SUBMITTING = "submitting",
350
351
  PROCESSING = "processing",
351
352
  SUCCESS = "success",
352
353
  FAIL = "fail",
354
+ CANCELLED = "cancelled",
353
355
  UNKNOWN = "unknown"
354
356
  }
355
357
  export interface TxHistoryItem {
@@ -398,6 +400,7 @@ export interface TransactionHistoryItem<ET extends ExtrinsicType = ExtrinsicType
398
400
  toName?: string;
399
401
  address: string;
400
402
  status: ExtrinsicStatus;
403
+ transactionId?: string;
401
404
  extrinsicHash: string;
402
405
  time: number;
403
406
  data?: string;
@@ -1357,6 +1360,10 @@ export declare type NotificationParams = Omit<Notification, 'id'>;
1357
1360
  export interface CronReloadRequest {
1358
1361
  data: 'nft' | 'staking';
1359
1362
  }
1363
+ export interface AllLogoMap {
1364
+ chainLogoMap: Record<string, string>;
1365
+ assetLogoMap: Record<string, string>;
1366
+ }
1360
1367
  export interface KoniRequestSignatures {
1361
1368
  'pri(staking.submitTuringCancelCompound)': [RequestTuringCancelStakeCompound, SWTransactionResponse];
1362
1369
  'pri(staking.submitTuringCompound)': [RequestTuringStakeCompound, SWTransactionResponse];
@@ -1450,6 +1457,7 @@ export interface KoniRequestSignatures {
1450
1457
  'pri(settings.saveTheme)': [ThemeNames, boolean, UiSettings];
1451
1458
  'pri(settings.saveBrowserConfirmationType)': [BrowserConfirmationType, boolean, UiSettings];
1452
1459
  'pri(settings.saveCamera)': [RequestCameraSettings, boolean];
1460
+ 'pri(settings.getLogoMaps)': [null, AllLogoMap];
1453
1461
  'pri(transaction.history.getSubscription)': [null, TransactionHistoryItem[], TransactionHistoryItem[]];
1454
1462
  'pri(transfer.checkReferenceCount)': [RequestTransferCheckReferenceCount, boolean];
1455
1463
  'pri(transfer.checkSupporting)': [RequestTransferCheckSupporting, SupportTransferResponse];
@@ -82,10 +82,12 @@ export let ExtrinsicType;
82
82
  })(ExtrinsicType || (ExtrinsicType = {}));
83
83
  export let ExtrinsicStatus;
84
84
  (function (ExtrinsicStatus) {
85
- ExtrinsicStatus["PENDING"] = "pending";
85
+ ExtrinsicStatus["QUEUED"] = "queued";
86
+ ExtrinsicStatus["SUBMITTING"] = "submitting";
86
87
  ExtrinsicStatus["PROCESSING"] = "processing";
87
88
  ExtrinsicStatus["SUCCESS"] = "success";
88
89
  ExtrinsicStatus["FAIL"] = "fail";
90
+ ExtrinsicStatus["CANCELLED"] = "cancelled";
89
91
  ExtrinsicStatus["UNKNOWN"] = "unknown";
90
92
  })(ExtrinsicStatus || (ExtrinsicStatus = {}));
91
93
  export let BasicTxErrorType;
@@ -86,10 +86,12 @@ exports.ExtrinsicType = ExtrinsicType;
86
86
  let ExtrinsicStatus;
87
87
  exports.ExtrinsicStatus = ExtrinsicStatus;
88
88
  (function (ExtrinsicStatus) {
89
- ExtrinsicStatus["PENDING"] = "pending";
89
+ ExtrinsicStatus["QUEUED"] = "queued";
90
+ ExtrinsicStatus["SUBMITTING"] = "submitting";
90
91
  ExtrinsicStatus["PROCESSING"] = "processing";
91
92
  ExtrinsicStatus["SUCCESS"] = "success";
92
93
  ExtrinsicStatus["FAIL"] = "fail";
94
+ ExtrinsicStatus["CANCELLED"] = "cancelled";
93
95
  ExtrinsicStatus["UNKNOWN"] = "unknown";
94
96
  })(ExtrinsicStatus || (exports.ExtrinsicStatus = ExtrinsicStatus = {}));
95
97
  let BasicTxErrorType;
@@ -2892,6 +2892,13 @@ class KoniExtension {
2892
2892
  }
2893
2893
  return Promise.resolve(false);
2894
2894
  }
2895
+ async getLogoMap() {
2896
+ const [chainLogoMap, assetLogoMap] = await Promise.all([this.#koniState.chainService.getChainLogoMap(), this.#koniState.chainService.getAssetLogoMap()]);
2897
+ return {
2898
+ chainLogoMap,
2899
+ assetLogoMap
2900
+ };
2901
+ }
2895
2902
 
2896
2903
  // --------------------------------------------------------------
2897
2904
  // eslint-disable-next-line @typescript-eslint/require-await
@@ -3251,6 +3258,8 @@ class KoniExtension {
3251
3258
  return this.subscribeNotifications(id, port);
3252
3259
  case 'pri(cron.reload)':
3253
3260
  return await this.reloadCron(request);
3261
+ case 'pri(settings.getLogoMaps)':
3262
+ return await this.getLogoMap();
3254
3263
 
3255
3264
  // Default
3256
3265
  default:
@@ -221,6 +221,8 @@ class KoniState {
221
221
  onReady() {
222
222
  this.subscription.start();
223
223
  this.cron.start();
224
+ this.historyService.start().catch(console.error);
225
+ this.priceService.start().catch(console.error);
224
226
  this.ready = true;
225
227
  this.logger.log('State is ready');
226
228
  }
@@ -572,7 +574,8 @@ class KoniState {
572
574
  assetType: tokenInfo.type,
573
575
  metadata: (0, _utils._parseMetadataForSmartContractAsset)(tokenInfo.contractAddress),
574
576
  multiChainAsset: null,
575
- hasValue: (0, _utils._isChainTestNet)(this.chainService.getChainInfoByKey(tokenInfo.originChain))
577
+ hasValue: (0, _utils._isChainTestNet)(this.chainService.getChainInfoByKey(tokenInfo.originChain)),
578
+ icon: ''
576
579
  });
577
580
  return isApproved;
578
581
  } else {
@@ -1348,11 +1351,15 @@ class KoniState {
1348
1351
  this.cron.stop();
1349
1352
  this.subscription.stop();
1350
1353
  await this.pauseAllNetworks(undefined, 'IDLE mode');
1354
+ await this.historyService.stop();
1355
+ await this.priceService.stop();
1351
1356
  }
1352
1357
  async wakeup() {
1353
1358
  await this.resumeAllNetworks();
1354
1359
  this.cron.start();
1355
1360
  this.subscription.start();
1361
+ await this.historyService.start();
1362
+ await this.priceService.start();
1356
1363
  }
1357
1364
  cancelSubscription(id) {
1358
1365
  if ((0, _subscriptions.isSubscriptionRunning)(id)) {
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
3
4
  Object.defineProperty(exports, "__esModule", {
4
5
  value: true
5
6
  });
@@ -15,6 +16,7 @@ var _handlers = require("@subwallet/extension-base/koni/background/handlers");
15
16
  var _constants2 = require("@subwallet/extension-base/services/chain-service/constants");
16
17
  var _utils = require("@subwallet/extension-base/services/chain-service/utils");
17
18
  var _types = require("@subwallet/extension-base/services/event-service/types");
19
+ var _axios = _interopRequireDefault(require("axios"));
18
20
  var _util = require("@polkadot/util");
19
21
  var _utilCrypto = require("@polkadot/util-crypto");
20
22
  // Copyright 2019-2022 @subwallet/extension-koni authors & contributors
@@ -238,6 +240,17 @@ class KoniSubscription {
238
240
  const result = [...poolingStakingRewards, ...amplitudeUnclaimedStakingRewards];
239
241
  this.state.updateStakingReward(result, 'fastInterval');
240
242
  }
243
+ async fetchingStakingFromApi() {
244
+ try {
245
+ const response = await _axios.default.get('https://staking-data.subwallet.app/api/staking/get');
246
+ if (response.status === 200) {
247
+ return response.data;
248
+ }
249
+ } catch (e) {
250
+ this.logger.error(e);
251
+ }
252
+ return {};
253
+ }
241
254
  async fetchChainStakingMetadata(chainInfoMap, chainStateMap, substrateApiMap) {
242
255
  const filteredChainInfoMap = {};
243
256
  Object.values(chainInfoMap).forEach(chainInfo => {
@@ -249,9 +262,18 @@ class KoniSubscription {
249
262
  if (Object.values(filteredChainInfoMap).length === 0) {
250
263
  return;
251
264
  }
265
+
266
+ // Fetch data from helper API
267
+ const dataFromApi = await this.fetchingStakingFromApi();
252
268
  await Promise.all(Object.values(filteredChainInfoMap).map(async chainInfo => {
253
- const chainStakingMetadata = await (0, _bonding.getChainStakingMetadata)(chainInfo, substrateApiMap[chainInfo.slug]);
254
- this.state.updateChainStakingMetadata(chainStakingMetadata);
269
+ // Use fetch API data if available
270
+ if (dataFromApi[chainInfo.slug]) {
271
+ this.state.updateChainStakingMetadata(dataFromApi[chainInfo.slug]);
272
+ } else {
273
+ console.warn('Not found staking data from api', chainInfo.slug);
274
+ const chainStakingMetadata = await (0, _bonding.getChainStakingMetadata)(chainInfo, substrateApiMap[chainInfo.slug]);
275
+ this.state.updateChainStakingMetadata(chainStakingMetadata);
276
+ }
255
277
  }));
256
278
  }
257
279
  async fetchNominatorMetadata(currentAddress, chainInfoMap, chainStateMap, substrateApiMap) {
@@ -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.2-3'
16
+ version: '1.0.3-0'
17
17
  };
18
18
  exports.packageInfo = packageInfo;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.ServiceStatus = void 0;
7
+ // Copyright 2019-2022 @subwallet/extension-base
8
+ // SPDX-License-Identifier: Apache-2.0
9
+ // 'init' | 'started' | 'starting' | 'stopped' | 'stopping'
10
+ let ServiceStatus;
11
+ exports.ServiceStatus = ServiceStatus;
12
+ (function (ServiceStatus) {
13
+ ServiceStatus["NOT_INITIALIZED"] = "not_initialized";
14
+ ServiceStatus["INITIALIZING"] = "initializing";
15
+ ServiceStatus["INITIALIZED"] = "initialized";
16
+ ServiceStatus["STARTED"] = "started";
17
+ ServiceStatus["STARTING"] = "starting";
18
+ ServiceStatus["STOPPED"] = "stopped";
19
+ ServiceStatus["STOPPING"] = "stopping";
20
+ })(ServiceStatus || (exports.ServiceStatus = ServiceStatus = {}));
@@ -157,7 +157,8 @@ class ChainService {
157
157
  priceId: '',
158
158
  slug: '',
159
159
  symbol: '',
160
- hasValue: true
160
+ hasValue: true,
161
+ icon: ''
161
162
  };
162
163
  for (const assetInfo of Object.values(this.getAssetRegistry())) {
163
164
  if (assetInfo.assetType === _types._AssetType.NATIVE && assetInfo.originChain === chainSlug) {
@@ -558,7 +559,8 @@ class ChainService {
558
559
  evmInfo: storedChainInfo.evmInfo,
559
560
  substrateInfo: storedChainInfo.substrateInfo,
560
561
  isTestnet: storedChainInfo.isTestnet,
561
- chainStatus: storedChainInfo.chainStatus
562
+ chainStatus: storedChainInfo.chainStatus,
563
+ icon: storedChainInfo.icon
562
564
  };
563
565
  this.dataMap.chainStateMap[storedSlug] = {
564
566
  currentProvider: storedChainInfo.currentProvider,
@@ -730,7 +732,8 @@ class ChainService {
730
732
  substrateInfo,
731
733
  evmInfo,
732
734
  isTestnet: false,
733
- chainStatus: _types._ChainStatus.ACTIVE
735
+ chainStatus: _types._ChainStatus.ACTIVE,
736
+ icon: '' // Todo: Allow update with custom chain
734
737
  };
735
738
 
736
739
  // insert new chainInfo
@@ -758,7 +761,8 @@ class ChainService {
758
761
  priceId: params.chainEditInfo.priceId || null,
759
762
  slug: '',
760
763
  symbol: params.chainEditInfo.symbol,
761
- hasValue: true
764
+ hasValue: true,
765
+ icon: ''
762
766
  });
763
767
 
764
768
  // update subscription
@@ -1198,5 +1202,11 @@ class ChainService {
1198
1202
  subscribeAssetSettings() {
1199
1203
  return this.assetSettingSubject;
1200
1204
  }
1205
+ async getChainLogoMap() {
1206
+ return Promise.resolve(_chainList.ChainLogoMap);
1207
+ }
1208
+ async getAssetLogoMap() {
1209
+ return Promise.resolve(_chainList.AssetLogoMap);
1210
+ }
1201
1211
  }
1202
1212
  exports.ChainService = ChainService;
@@ -5,6 +5,8 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.HistoryService = void 0;
7
7
  var _constants = require("@subwallet/extension-base/constants");
8
+ var _types = require("@subwallet/extension-base/services/base/types");
9
+ var _promise = require("@subwallet/extension-base/utils/promise");
8
10
  var _uiKeyring = require("@subwallet/ui-keyring");
9
11
  var _rxjs = require("rxjs");
10
12
  var _subsquidMultiChainHistory = require("./subsquid-multi-chain-history");
@@ -18,24 +20,10 @@ class HistoryService {
18
20
  this.chainService = chainService;
19
21
  this.eventService = eventService;
20
22
  this.keyringService = keyringService;
21
- // Load history from database
22
- this.dbService.getHistories().then(histories => {
23
- this.historySubject.next(histories);
24
- }).catch(console.error);
25
-
26
- // Wait for keyring and chain ready and start
27
- Promise.all([this.eventService.waitKeyringReady, this.eventService.waitChainReady]).then(() => {
28
- this.getHistories().catch(console.log);
29
- this.eventService.on('account.add', () => {
30
- this.refreshHistoryInterval();
31
- });
32
- this.eventService.on('account.remove', address => {
33
- this.removeHistoryByAddress(address).catch(console.error);
34
- });
35
- }).catch(console.error);
23
+ this.init().catch(console.error);
36
24
  }
37
25
  fetchPromise = null;
38
- nextFetch = undefined;
26
+ interval = undefined;
39
27
  async fetchAndLoadHistories(addresses) {
40
28
  if (!addresses || addresses.length === 0) {
41
29
  return [];
@@ -59,32 +47,16 @@ class HistoryService {
59
47
  await this.addHistoryItems(historyRecords);
60
48
  return historyRecords;
61
49
  }
62
- async fetchHistories(addresses) {
63
- if (!this.fetchPromise) {
64
- // Fetch another histories data data indexer and merge it with stored in database
65
- this.fetchPromise = this.fetchAndLoadHistories(addresses);
66
- }
67
- return this.fetchPromise;
68
- }
69
- invalidCache() {
70
- this.fetchPromise = null;
71
- }
72
- refreshHistoryInterval() {
73
- clearTimeout(this.nextFetch);
74
- this.invalidCache();
75
- this.getHistories().catch(console.error);
76
- this.nextFetch = setTimeout(() => {
77
- this.refreshHistoryInterval();
78
- }, _constants.CRON_REFRESH_HISTORY_INTERVAL);
79
- }
80
50
  async getHistories() {
81
51
  const addressList = _uiKeyring.keyring.getAccounts().map(a => a.address);
82
- const currentHistories = this.historySubject.value;
83
- if (!this.fetchPromise || currentHistories.length === 0) {
84
- await this.fetchHistories(addressList);
85
- this.historySubject.next(await this.dbService.getHistories());
52
+ if (!this.fetchPromise) {
53
+ this.fetchPromise = (async () => {
54
+ await this.fetchAndLoadHistories(addressList);
55
+ const histories = await this.dbService.getHistories();
56
+ this.historySubject.next(histories);
57
+ })();
86
58
  }
87
- return this.historySubject.getValue();
59
+ return Promise.resolve(this.historySubject.getValue());
88
60
  }
89
61
  async getHistorySubject() {
90
62
  await this.getHistories();
@@ -103,6 +75,10 @@ class HistoryService {
103
75
  });
104
76
  await this.addHistoryItems(updatedRecords);
105
77
  }
78
+ async updateHistoryByExtrinsicHash(extrinsicHash, updateData) {
79
+ await this.dbService.updateHistoryByNewExtrinsicHash(extrinsicHash, updateData);
80
+ this.historySubject.next(await this.dbService.getHistories());
81
+ }
106
82
 
107
83
  // Insert history without check override origin 'app'
108
84
  async insertHistories(historyItems) {
@@ -131,5 +107,74 @@ class HistoryService {
131
107
  await this.dbService.stores.transaction.removeAllByAddress(address);
132
108
  this.historySubject.next(await this.dbService.getHistories());
133
109
  }
110
+ status = _types.ServiceStatus.NOT_INITIALIZED;
111
+ async loadData() {
112
+ const histories = await this.dbService.getHistories();
113
+ this.historySubject.next(histories);
114
+ }
115
+ async persistData() {
116
+ await this.dbService.upsertHistory(this.historySubject.value);
117
+ }
118
+ async startCron() {
119
+ await this.getHistories();
120
+ this.interval = setInterval(() => {
121
+ this.getHistories().catch(console.error);
122
+ }, _constants.CRON_REFRESH_HISTORY_INTERVAL);
123
+ }
124
+ stopCron() {
125
+ clearTimeout(this.interval);
126
+ this.fetchPromise = null;
127
+ return Promise.resolve();
128
+ }
129
+ startPromiseHandler = (0, _promise.createPromiseHandler)();
130
+ async init() {
131
+ this.status = _types.ServiceStatus.INITIALIZING;
132
+ await this.loadData();
133
+ Promise.all([this.eventService.waitKeyringReady, this.eventService.waitChainReady]).then(() => {
134
+ this.getHistories().catch(console.log);
135
+ this.eventService.on('account.add', () => {
136
+ (async () => {
137
+ await this.stopCron();
138
+ await this.startCron();
139
+ })().catch(console.error);
140
+ });
141
+ this.eventService.on('account.remove', address => {
142
+ this.removeHistoryByAddress(address).catch(console.error);
143
+ });
144
+ }).catch(console.error);
145
+ this.status = _types.ServiceStatus.INITIALIZED;
146
+ }
147
+ async start() {
148
+ try {
149
+ console.debug('Start history service');
150
+ this.startPromiseHandler = (0, _promise.createPromiseHandler)();
151
+ this.status = _types.ServiceStatus.STARTING;
152
+ await this.startCron();
153
+ this.status = _types.ServiceStatus.STARTED;
154
+ this.startPromiseHandler.resolve();
155
+ } catch (e) {
156
+ this.startPromiseHandler.reject(e);
157
+ }
158
+ }
159
+ waitForStarted() {
160
+ return this.startPromiseHandler.promise;
161
+ }
162
+ stopPromiseHandler = (0, _promise.createPromiseHandler)();
163
+ async stop() {
164
+ console.debug('Stop history service');
165
+ try {
166
+ this.stopPromiseHandler = (0, _promise.createPromiseHandler)();
167
+ this.status = _types.ServiceStatus.STOPPING;
168
+ await this.persistData();
169
+ await this.stopCron();
170
+ this.stopPromiseHandler.resolve();
171
+ this.status = _types.ServiceStatus.STOPPED;
172
+ } catch (e) {
173
+ this.stopPromiseHandler.reject(e);
174
+ }
175
+ }
176
+ waitForStopped() {
177
+ return this.stopPromiseHandler.promise;
178
+ }
134
179
  }
135
180
  exports.HistoryService = HistoryService;
@@ -33,7 +33,8 @@ class MigrateImportedToken extends _Base.default {
33
33
  originChain: item.chain,
34
34
  priceId: null,
35
35
  slug: '',
36
- symbol: item.symbol || ''
36
+ symbol: item.symbol || '',
37
+ icon: ''
37
38
  });
38
39
  } catch (e) {
39
40
  console.log(e);
@@ -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
  }