@subwallet/extension-base 1.3.19-0 → 1.3.21-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 (92) hide show
  1. package/background/KoniTypes.d.ts +8 -1
  2. package/cjs/core/logic-validation/request.js +4 -1
  3. package/cjs/defaults.js +1 -1
  4. package/cjs/koni/background/handlers/Extension.js +519 -90
  5. package/cjs/packageInfo.js +1 -1
  6. package/cjs/services/chain-service/constants.js +1 -1
  7. package/cjs/services/chain-service/handler/EvmApi.js +1 -3
  8. package/cjs/services/chain-service/utils/patch.js +1 -1
  9. package/cjs/services/earning-service/handlers/liquid-staking/stella-swap.js +19 -8
  10. package/cjs/services/earning-service/handlers/special.js +16 -10
  11. package/cjs/services/history-service/helpers/recoverHistoryStatus.js +14 -5
  12. package/cjs/services/history-service/index.js +15 -3
  13. package/cjs/services/inapp-notification-service/index.js +78 -0
  14. package/cjs/services/inapp-notification-service/interfaces.js +2 -0
  15. package/cjs/services/keyring-service/context/state.js +2 -1
  16. package/cjs/services/request-service/handler/EvmRequestHandler.js +10 -0
  17. package/cjs/services/request-service/handler/SubstrateRequestHandler.js +4 -3
  18. package/cjs/services/request-service/index.js +2 -2
  19. package/cjs/services/setting-service/constants.js +5 -2
  20. package/cjs/services/storage-service/DatabaseService.js +98 -2
  21. package/cjs/services/storage-service/databases/index.js +3 -0
  22. package/cjs/services/storage-service/db-stores/ProcessTransaction.js +47 -0
  23. package/cjs/services/storage-service/db-stores/Transaction.js +2 -0
  24. package/cjs/services/storage-service/db-stores/index.js +8 -1
  25. package/cjs/services/swap-service/handler/asset-hub/handler.js +30 -11
  26. package/cjs/services/swap-service/handler/hydradx-handler.js +18 -10
  27. package/cjs/services/swap-service/index.js +3 -0
  28. package/cjs/services/swap-service/utils.js +1 -0
  29. package/cjs/services/transaction-service/index.js +218 -9
  30. package/cjs/types/index.js +11 -0
  31. package/cjs/types/setting.js +1 -0
  32. package/cjs/types/swap/index.js +4 -1
  33. package/cjs/types/transaction/index.js +11 -0
  34. package/cjs/types/transaction/process.js +28 -0
  35. package/cjs/types/yield/actions/join/submit.js +16 -1
  36. package/core/logic-validation/request.js +4 -1
  37. package/defaults.d.ts +1 -1
  38. package/defaults.js +1 -1
  39. package/koni/background/handlers/Extension.d.ts +5 -0
  40. package/koni/background/handlers/Extension.js +437 -12
  41. package/package.json +21 -6
  42. package/packageInfo.js +1 -1
  43. package/services/chain-service/constants.js +1 -1
  44. package/services/chain-service/handler/EvmApi.js +1 -3
  45. package/services/chain-service/utils/patch.js +1 -1
  46. package/services/earning-service/handlers/liquid-staking/stella-swap.js +19 -8
  47. package/services/earning-service/handlers/special.js +18 -12
  48. package/services/history-service/helpers/recoverHistoryStatus.js +14 -5
  49. package/services/history-service/index.d.ts +6 -5
  50. package/services/history-service/index.js +16 -5
  51. package/services/inapp-notification-service/index.d.ts +2 -0
  52. package/services/inapp-notification-service/index.js +79 -1
  53. package/services/inapp-notification-service/interfaces.d.ts +8 -1
  54. package/services/inapp-notification-service/interfaces.js +2 -0
  55. package/services/keyring-service/context/state.d.ts +1 -1
  56. package/services/keyring-service/context/state.js +3 -2
  57. package/services/request-service/handler/EvmRequestHandler.js +10 -0
  58. package/services/request-service/handler/SubstrateRequestHandler.d.ts +1 -1
  59. package/services/request-service/handler/SubstrateRequestHandler.js +4 -3
  60. package/services/request-service/index.d.ts +1 -1
  61. package/services/request-service/index.js +2 -2
  62. package/services/setting-service/constants.d.ts +1 -0
  63. package/services/setting-service/constants.js +3 -1
  64. package/services/storage-service/DatabaseService.d.ts +12 -3
  65. package/services/storage-service/DatabaseService.js +100 -4
  66. package/services/storage-service/databases/index.d.ts +2 -1
  67. package/services/storage-service/databases/index.js +3 -0
  68. package/services/storage-service/db-stores/ProcessTransaction.d.ts +14 -0
  69. package/services/storage-service/db-stores/ProcessTransaction.js +39 -0
  70. package/services/storage-service/db-stores/Transaction.js +2 -0
  71. package/services/storage-service/db-stores/index.d.ts +1 -0
  72. package/services/storage-service/db-stores/index.js +2 -1
  73. package/services/swap-service/handler/asset-hub/handler.js +30 -11
  74. package/services/swap-service/handler/hydradx-handler.js +18 -10
  75. package/services/swap-service/index.js +3 -0
  76. package/services/swap-service/utils.js +1 -0
  77. package/services/transaction-service/index.d.ts +19 -1
  78. package/services/transaction-service/index.js +220 -11
  79. package/services/transaction-service/types.d.ts +13 -4
  80. package/types/index.d.ts +1 -0
  81. package/types/index.js +1 -0
  82. package/types/setting.d.ts +3 -0
  83. package/types/setting.js +1 -0
  84. package/types/swap/index.d.ts +3 -2
  85. package/types/swap/index.js +4 -1
  86. package/types/transaction/index.d.ts +1 -0
  87. package/types/transaction/index.js +1 -0
  88. package/types/transaction/process.d.ts +84 -0
  89. package/types/transaction/process.js +20 -0
  90. package/types/transaction/request.d.ts +3 -1
  91. package/types/yield/actions/join/submit.d.ts +18 -3
  92. package/types/yield/actions/join/submit.js +11 -1
@@ -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.3.19-0'
16
+ version: '1.3.21-0'
17
17
  };
18
18
  exports.packageInfo = packageInfo;
@@ -272,7 +272,7 @@ const _TRANSFER_CHAIN_GROUP = {
272
272
  avail: ['kate', 'goldberg_testnet'],
273
273
  pendulum: ['pendulum', 'amplitude', 'amplitude_test', 'hydradx_main', 'bifrost', 'bifrost_dot'],
274
274
  centrifuge: ['centrifuge'],
275
- disable_transfer: ['invarch', 'crab', 'pangolin']
275
+ disable_transfer: ['crab', 'pangolin']
276
276
  };
277
277
  exports._TRANSFER_CHAIN_GROUP = _TRANSFER_CHAIN_GROUP;
278
278
  const _BALANCE_PARSING_CHAIN_GROUP = {
@@ -126,12 +126,10 @@ class EvmApi {
126
126
  return this.disconnect();
127
127
  }
128
128
  onConnect() {
129
+ this.isReadyHandler.resolve(this);
129
130
  if (!this.isApiConnected) {
130
131
  console.log(`Connected to ${this.chainSlug} at ${this.apiUrl}`);
131
132
  this.isApiReady = true;
132
- if (this.isApiReadyOnce) {
133
- this.isReadyHandler.resolve(this);
134
- }
135
133
  }
136
134
  this.updateConnectionStatus(_types._ChainConnectionStatus.CONNECTED);
137
135
  }
@@ -11,7 +11,7 @@ const PRODUCTION_BRANCHES = ['master', 'webapp', 'webapp-dev'];
11
11
  const branchName = process.env.BRANCH_NAME || 'subwallet-dev';
12
12
  const fetchDomain = PRODUCTION_BRANCHES.indexOf(branchName) > -1 ? 'https://chain-list-assets.subwallet.app' : 'https://dev.sw-chain-list-assets.pages.dev';
13
13
  const fetchFile = PRODUCTION_BRANCHES.indexOf(branchName) > -1 ? 'list.json' : 'preview.json';
14
- const ChainListVersion = '0.2.98'; // update this when build chainlist
14
+ const ChainListVersion = '0.2.99'; // update this when build chainlist
15
15
 
16
16
  // todo: move this interface to chainlist
17
17
 
@@ -27,6 +27,7 @@ const getStellaswapLiquidStakingContract = function (networkKey, assetAddress, e
27
27
  exports.getStellaswapLiquidStakingContract = getStellaswapLiquidStakingContract;
28
28
  const APR_STATS_URL = 'https://apr-api.stellaswap.com/api/v1/stdot';
29
29
  const SUBWALLET_REFERRAL = '0x7e6815f45E624768548d085231f2d453f16FD7DD';
30
+ const TOP_HOLDER = '0x4300e09284e3bB4d9044DdAB31EfAF5f3301DABa';
30
31
  class StellaSwapLiquidStakingPoolHandler extends _base.default {
31
32
  inputAsset = 'moonbeam-LOCAL-xcDOT';
32
33
  altInputAsset = '';
@@ -207,9 +208,15 @@ class StellaSwapLiquidStakingPoolHandler extends _base.default {
207
208
  // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
208
209
  await allowanceCall.call(), evmApi.api.eth.getGasPrice()]);
209
210
  if (!allowance || parseInt(allowance) <= 0) {
211
+ const metadata = {
212
+ tokenApprove: inputTokenSlug,
213
+ contractAddress: (0, _utils._getContractAddressOfToken)(inputTokenInfo),
214
+ spenderAddress: (0, _utils._getContractAddressOfToken)(derivativeTokenInfo)
215
+ };
210
216
  const step = {
211
217
  name: 'Authorize token approval',
212
- type: _types.YieldStepType.TOKEN_APPROVAL
218
+ type: _types.YieldStepType.TOKEN_APPROVAL,
219
+ metadata: metadata
213
220
  };
214
221
 
215
222
  // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
@@ -232,13 +239,17 @@ class StellaSwapLiquidStakingPoolHandler extends _base.default {
232
239
  // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
233
240
  const depositCall = stakingContract.methods.deposit(params.amount);
234
241
  let estimatedDepositGas = 0;
235
- try {
236
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
237
- estimatedDepositGas = await depositCall.estimateGas({
238
- from: params.address
239
- });
240
- } catch (e) {
241
- console.error(e);
242
+ const addressToTests = [params.address, TOP_HOLDER];
243
+ for (const address of addressToTests) {
244
+ try {
245
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
246
+ estimatedDepositGas = await depositCall.estimateGas({
247
+ from: address
248
+ });
249
+ break;
250
+ } catch (e) {
251
+ console.error(e);
252
+ }
242
253
  }
243
254
  const gasPrice = await evmApi.api.eth.getGasPrice();
244
255
  return {
@@ -223,15 +223,6 @@ class BaseSpecialStakingPoolHandler extends _base.default {
223
223
  const altChainInfo = this.state.getChainInfo(altInputTokenInfo.originChain);
224
224
  const symbol = altInputTokenInfo.symbol;
225
225
  const networkName = altChainInfo.name;
226
- const step = {
227
- metadata: {
228
- sendingValue: bnAmount.toString(),
229
- originTokenInfo: altInputTokenInfo,
230
- destinationTokenInfo: inputTokenInfo
231
- },
232
- name: `Transfer ${symbol} from ${networkName}`,
233
- type: _types.YieldStepType.XCM
234
- };
235
226
  const xcmOriginSubstrateApi = await this.state.getSubstrateApi(altInputTokenInfo.originChain).isReady;
236
227
  const id = (0, _getId.getId)();
237
228
  const feeInfo = await this.state.feeService.subscribeChainFee(id, altChainInfo.slug, 'substrate');
@@ -252,9 +243,24 @@ class BaseSpecialStakingPoolHandler extends _base.default {
252
243
 
253
244
  const fee = {
254
245
  slug: altInputTokenSlug,
255
- amount: Math.round(xcmFeeInfo.partialFee * 1.2).toString() // TODO
246
+ amount: Math.round(xcmFeeInfo.partialFee * _constants.XCM_MIN_AMOUNT_RATIO).toString() // TODO
256
247
  };
257
248
 
249
+ let bnTransferAmount = bnAmount.sub(bnInputTokenBalance);
250
+ if ((0, _utils2._isNativeToken)(altInputTokenInfo)) {
251
+ const bnXcmFee = new _util.BN(fee.amount || 0); // xcm fee is paid in native token but swap token is not always native token
252
+
253
+ bnTransferAmount = bnTransferAmount.add(bnXcmFee);
254
+ }
255
+ const step = {
256
+ metadata: {
257
+ sendingValue: bnTransferAmount.toString(),
258
+ originTokenInfo: altInputTokenInfo,
259
+ destinationTokenInfo: inputTokenInfo
260
+ },
261
+ name: `Transfer ${symbol} from ${networkName}`,
262
+ type: _types.YieldStepType.XCM
263
+ };
258
264
  return [step, fee];
259
265
  }
260
266
  }
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.historyRecover = exports.HistoryRecoverStatus = void 0;
7
7
  var _utils = require("@subwallet/extension-base/utils");
8
+ var _util = require("@polkadot/util");
8
9
  // Copyright 2019-2022 @subwallet/extension-koni authors & contributors
9
10
  // SPDX-License-Identifier: Apache-2.0
10
11
  let HistoryRecoverStatus;
@@ -37,7 +38,7 @@ const substrateRecover = async (history, chainService) => {
37
38
  const _api = await substrateApi.isReady;
38
39
  const api = _api.api;
39
40
  if (!blockHash) {
40
- if (!nonce || !startBlock) {
41
+ if (nonce === undefined || startBlock === undefined) {
41
42
  console.log(`Fail to find extrinsic for ${address} on ${chain}: With nonce ${nonce || 'undefined'} from block ${startBlock || 'undefined'}`);
42
43
  return {
43
44
  status: HistoryRecoverStatus.LACK_INFO
@@ -47,7 +48,7 @@ const substrateRecover = async (history, chainService) => {
47
48
  for (let i = 1, found = false; i < BLOCK_LIMIT && !found && startBlock + i <= currentBlock; i++) {
48
49
  const blockHash = (await api.rpc.chain.getBlockHash(startBlock + i)).toHex();
49
50
  const block = await api.rpc.chain.getBlock(blockHash);
50
- const extrinsics = block.block.extrinsics;
51
+ const extrinsics = block.block.extrinsics.toArray();
51
52
  let index;
52
53
  for (const [idx, extrinsic] of Object.entries(extrinsics)) {
53
54
  if (extrinsic.signer && (0, _utils.isSameAddress)(from, extrinsic.signer.toString()) && nonce === extrinsic.nonce.toNumber()) {
@@ -154,16 +155,24 @@ const evmRecover = async (history, chainService) => {
154
155
  try {
155
156
  const evmApi = chainService.getEvmApi(chain);
156
157
  if (evmApi) {
157
- const _api = await evmApi.isReady;
158
+ const _api = await Promise.race([evmApi.isReady, new Promise((resolve, reject) => {
159
+ const createTimeout = callback => {
160
+ setTimeout(callback, 10000);
161
+ };
162
+ createTimeout(() => {
163
+ const api = chainService.getEvmApi(chain);
164
+ Promise.race([api.isReady, new Promise((resolve, reject) => createTimeout(() => reject(new Error('Timeout'))))]).then(resolve).catch(reject);
165
+ });
166
+ })]);
158
167
  const api = _api.api;
159
- if (extrinsicHash) {
168
+ if (extrinsicHash && (0, _util.isHex)(extrinsicHash)) {
160
169
  const transactionReceipt = await api.eth.getTransactionReceipt(extrinsicHash);
161
170
  return {
162
171
  ...result,
163
172
  status: transactionReceipt.status ? HistoryRecoverStatus.SUCCESS : HistoryRecoverStatus.FAILED
164
173
  };
165
174
  } else {
166
- if (!nonce || !startBlock) {
175
+ if (nonce === undefined || startBlock === undefined) {
167
176
  console.log(`Fail to find extrinsic for ${address} on ${chain}: With nonce ${nonce || 'undefined'} from block ${startBlock || 'undefined'}`);
168
177
  return {
169
178
  ...result,
@@ -185,7 +185,8 @@ class HistoryService {
185
185
  await this.addHistoryItems(updatedRecords);
186
186
  }
187
187
  async updateHistoryByExtrinsicHash(extrinsicHash, updateData) {
188
- await this.dbService.updateHistoryByExtrinsicHash(extrinsicHash, updateData);
188
+ let isRecover = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
189
+ await this.dbService.updateHistoryByExtrinsicHash(extrinsicHash, updateData, isRecover);
189
190
  this.historySubject.next(await this.dbService.getHistories());
190
191
  }
191
192
 
@@ -260,11 +261,11 @@ class HistoryService {
260
261
  case _recoverHistoryStatus.HistoryRecoverStatus.FAILED:
261
262
  case _recoverHistoryStatus.HistoryRecoverStatus.SUCCESS:
262
263
  updateData.status = recoverResult.status === _recoverHistoryStatus.HistoryRecoverStatus.SUCCESS ? _KoniTypes.ExtrinsicStatus.SUCCESS : _KoniTypes.ExtrinsicStatus.FAIL;
263
- this.updateHistoryByExtrinsicHash(currentExtrinsicHash, updateData).catch(console.error);
264
+ this.updateHistoryByExtrinsicHash(currentExtrinsicHash, updateData, true).catch(console.error);
264
265
  delete this.#needRecoveryHistories[currentExtrinsicHash];
265
266
  break;
266
267
  default:
267
- this.updateHistoryByExtrinsicHash(currentExtrinsicHash, updateData).catch(console.error);
268
+ this.updateHistoryByExtrinsicHash(currentExtrinsicHash, updateData, true).catch(console.error);
268
269
  delete this.#needRecoveryHistories[currentExtrinsicHash];
269
270
  }
270
271
  });
@@ -276,6 +277,7 @@ class HistoryService {
276
277
  async init() {
277
278
  this.status = _types.ServiceStatus.INITIALIZING;
278
279
  await this.eventService.waitCryptoReady;
280
+ this.restoreProcessTransaction().catch(console.error);
279
281
  await this.loadData();
280
282
  Promise.all([this.eventService.waitKeyringReady, this.eventService.waitChainReady]).then(() => {
281
283
  this.getHistories().catch(console.log);
@@ -286,11 +288,21 @@ class HistoryService {
286
288
  }).catch(console.error);
287
289
  this.status = _types.ServiceStatus.INITIALIZED;
288
290
  }
291
+ async restoreProcessTransaction() {
292
+ await this.dbService.restoreProcessTransaction();
293
+ }
289
294
  async recoverProcessingHistory() {
290
295
  const histories = await this.dbService.getHistories();
291
296
  this.#needRecoveryHistories = {};
292
297
  histories.filter(history => {
293
298
  return [_KoniTypes.ExtrinsicStatus.PROCESSING, _KoniTypes.ExtrinsicStatus.SUBMITTING].includes(history.status);
299
+ }).filter(history => {
300
+ if (history.type === _KoniTypes.ExtrinsicType.TRANSFER_XCM) {
301
+ const data = history.additionalInfo;
302
+ return data.originalChain === history.chain;
303
+ } else {
304
+ return true;
305
+ }
294
306
  }).forEach(history => {
295
307
  this.#needRecoveryHistories[history.extrinsicHash] = history;
296
308
  });
@@ -9,9 +9,11 @@ var _KoniTypes = require("@subwallet/extension-base/background/KoniTypes");
9
9
  var _constants = require("@subwallet/extension-base/constants");
10
10
  var _remindNotificationTime = require("@subwallet/extension-base/constants/remind-notification-time");
11
11
  var _types = require("@subwallet/extension-base/services/base/types");
12
+ var _constants2 = require("@subwallet/extension-base/services/earning-service/constants");
12
13
  var _consts = require("@subwallet/extension-base/services/inapp-notification-service/consts");
13
14
  var _interfaces = require("@subwallet/extension-base/services/inapp-notification-service/interfaces");
14
15
  var _utils = require("@subwallet/extension-base/services/inapp-notification-service/utils");
16
+ var _types2 = require("@subwallet/extension-base/types");
15
17
  var _utils2 = require("@subwallet/extension-base/utils");
16
18
  var _keyring = require("@subwallet/keyring");
17
19
  // Copyright 2019-2022 @subwallet/extension-base authors & contributors
@@ -133,6 +135,17 @@ class InappNotificationService {
133
135
  }
134
136
  }
135
137
  }
138
+ if ([_interfaces.NotificationActionType.SWAP, _interfaces.NotificationActionType.EARNING].includes(candidateNotification.actionType)) {
139
+ const candidateMetadata = candidateNotification.metadata;
140
+ const processId = candidateMetadata.processId;
141
+ for (const notification of comparedNotifications) {
142
+ const comparedMetadata = notification.metadata;
143
+ const _processId = comparedMetadata.processId;
144
+ if (processId === _processId) {
145
+ return false;
146
+ }
147
+ }
148
+ }
136
149
  return true;
137
150
  }
138
151
  async validateAndWriteNotificationsToDB(notifications, address) {
@@ -326,6 +339,71 @@ class InappNotificationService {
326
339
  });
327
340
  await this.validateAndWriteNotificationsToDB(notifications, address);
328
341
  }
342
+ async createProcessNotification(process) {
343
+ const timestamp = Date.now();
344
+ const _id = process.id;
345
+ const address = process.address;
346
+ let actionType;
347
+ let extrinsicType;
348
+ let title = '';
349
+ let description = '';
350
+ if (process.type === _types2.ProcessType.SWAP) {
351
+ actionType = _interfaces.NotificationActionType.SWAP;
352
+ extrinsicType = _KoniTypes.ExtrinsicType.SWAP;
353
+ const combineInfo = process.combineInfo;
354
+ const fromAsset = this.chainService.getAssetBySlug(combineInfo.quote.pair.from);
355
+ const toAsset = this.chainService.getAssetBySlug(combineInfo.quote.pair.to);
356
+ const fromChain = this.chainService.getChainInfoByKey(fromAsset.originChain);
357
+ const toChain = this.chainService.getChainInfoByKey(toAsset.originChain);
358
+ title = '[{{accountName}}] SWAPPED {{fromAsset}}'.replace('{{fromAsset}}', fromAsset.symbol);
359
+ description = '{{fromAmount}} {{fromAsset}} on {{fromChain}} swapped for {{toAmount}} {{toAsset}} on {{toChain}}. Click to view details'.replace('{{fromAmount}}', (0, _utils2.formatNumber)(combineInfo.quote.fromAmount, fromAsset.decimals || 0)).replace('{{fromAsset}}', fromAsset.symbol).replace('{{fromChain}}', fromChain.name).replace('{{toAmount}}', (0, _utils2.formatNumber)(combineInfo.quote.toAmount, toAsset.decimals || 0)).replace('{{toAsset}}', toAsset.symbol).replace('{{toChain}}', toChain.name);
360
+ } else {
361
+ actionType = _interfaces.NotificationActionType.EARNING;
362
+ extrinsicType = _KoniTypes.ExtrinsicType.JOIN_YIELD_POOL; // Not used
363
+
364
+ const combineInfo = process.combineInfo;
365
+ const asset = this.chainService.getAssetBySlug(combineInfo.brief.token);
366
+ const chain = this.chainService.getChainInfoByKey(combineInfo.brief.chain);
367
+ const amount = combineInfo.brief.amount;
368
+ let method;
369
+ switch (combineInfo.brief.method) {
370
+ case _types2.YieldPoolType.LIQUID_STAKING:
371
+ method = 'Liquid staking';
372
+ break;
373
+ case _types2.YieldPoolType.LENDING:
374
+ method = 'Lending';
375
+ break;
376
+ case _types2.YieldPoolType.SINGLE_FARMING:
377
+ method = 'Single farming';
378
+ break;
379
+ case _types2.YieldPoolType.NOMINATION_POOL:
380
+ method = 'Nomination pool';
381
+ break;
382
+ case _types2.YieldPoolType.PARACHAIN_STAKING:
383
+ method = 'Parachain staking';
384
+ break;
385
+ case _types2.YieldPoolType.NATIVE_STAKING:
386
+ method = _constants2._STAKING_CHAIN_GROUP.astar.includes(chain.slug) ? 'dApp staking' : 'Direct nomination';
387
+ break;
388
+ }
389
+ title = '[{{accountName}}] STAKED {{asset}}'.replace('{{asset}}', asset.symbol);
390
+ description = '{{amount}} {{asset}} on {{chain}} staked via {{method}}. Click to view details'.replace('{{amount}}', (0, _utils2.formatNumber)(amount, asset.decimals || 0)).replace('{{asset}}', asset.symbol).replace('{{chain}}', chain.name).replace('{{method}}', method);
391
+ }
392
+ const notification = {
393
+ id: `${actionType}___${_id}___${timestamp}`,
394
+ address: (0, _utils2.reformatAddress)(address),
395
+ title,
396
+ actionType,
397
+ metadata: {
398
+ processId: process.id
399
+ },
400
+ time: timestamp,
401
+ description,
402
+ isRead: false,
403
+ extrinsicType
404
+ };
405
+ await this.validateAndWriteNotificationsToDB([notification], process.address);
406
+ }
329
407
 
330
408
  // Polygon Claimable Handle
331
409
 
@@ -30,6 +30,8 @@ exports.NotificationActionType = NotificationActionType;
30
30
  NotificationActionType["CLAIM_AVAIL_BRIDGE_ON_AVAIL"] = "CLAIM_AVAIL_BRIDGE_ON_AVAIL";
31
31
  NotificationActionType["CLAIM_AVAIL_BRIDGE_ON_ETHEREUM"] = "CLAIM_AVAIL_BRIDGE_ON_ETHEREUM";
32
32
  NotificationActionType["CLAIM_POLYGON_BRIDGE"] = "CLAIM_POLYGON_BRIDGE";
33
+ NotificationActionType["SWAP"] = "SWAP";
34
+ NotificationActionType["EARNING"] = "EARNING";
33
35
  })(NotificationActionType || (exports.NotificationActionType = NotificationActionType = {}));
34
36
  let NotificationTab;
35
37
  exports.NotificationTab = NotificationTab;
@@ -393,10 +393,11 @@ class AccountState {
393
393
  const accountProxies = this.accounts;
394
394
  return Object.values(accountProxies).some(value => value.accountType === _types.AccountProxyType.UNIFIED && value.id === proxyId);
395
395
  }
396
- belongUnifiedAccount(address) {
396
+ belongUnifiedAccount(_address) {
397
397
  var _modifyPairs$address;
398
398
  const modifyPairs = this.modifyPairs;
399
399
  const accountProxies = this.accountProxies;
400
+ const address = (0, _utils.reformatAddress)(_address);
400
401
  const proxyId = (_modifyPairs$address = modifyPairs[address]) === null || _modifyPairs$address === void 0 ? void 0 : _modifyPairs$address.accountProxyId;
401
402
  if (proxyId) {
402
403
  var _accountProxies$proxy;
@@ -86,6 +86,16 @@ class EvmRequestHandler {
86
86
  if (!isInternal) {
87
87
  this.#requestService.popupOpen();
88
88
  }
89
+ if (options.isPassConfirmation) {
90
+ await this.completeConfirmation({
91
+ evmSendTransactionRequest: {
92
+ id,
93
+ url,
94
+ isApproved: true,
95
+ payload: ''
96
+ }
97
+ });
98
+ }
89
99
  this.#requestService.updateIconV2();
90
100
  return promise;
91
101
  }
@@ -84,9 +84,9 @@ class SubstrateRequestHandler {
84
84
  this.#requestService.popupOpen();
85
85
  });
86
86
  }
87
- async signTransaction(id, address, url, payload) {
87
+ async signTransaction(id, address, url, payload, onSign) {
88
88
  const isAlwaysRequired = await this.#requestService.settingService.isAlwaysRequired;
89
- if (isAlwaysRequired) {
89
+ if (isAlwaysRequired && !onSign) {
90
90
  this.#requestService.keyringService.lock();
91
91
  }
92
92
  return new Promise((resolve, reject) => {
@@ -98,9 +98,10 @@ class SubstrateRequestHandler {
98
98
  url: url
99
99
  };
100
100
  this.updateIconSign();
101
- if (!(0, _request.isInternalRequest)(url)) {
101
+ if (!(0, _request.isInternalRequest)(url) && !onSign) {
102
102
  this.#requestService.popupOpen();
103
103
  }
104
+ onSign === null || onSign === void 0 ? void 0 : onSign(id);
104
105
  });
105
106
  }
106
107
  resetWallet() {
@@ -159,8 +159,8 @@ class RequestService {
159
159
  getSignRequest(id) {
160
160
  return this.#substrateRequestHandler.getSignRequest(id);
161
161
  }
162
- async signInternalTransaction(id, address, url, payload) {
163
- return this.#substrateRequestHandler.signTransaction(id, address, url, payload);
162
+ async signInternalTransaction(id, address, url, payload, onSign) {
163
+ return this.#substrateRequestHandler.signTransaction(id, address, url, payload, onSign);
164
164
  }
165
165
  addConfirmation(id, url, type, payload) {
166
166
  let options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.DEFAULT_UNLOCK_TYPE = exports.DEFAULT_THEME = exports.DEFAULT_SHOW_ZERO_BALANCE = exports.DEFAULT_SHOW_BALANCE = exports.DEFAULT_SETTING = exports.DEFAULT_NOTIFICATION_TYPE = exports.DEFAULT_NOTIFICATION_SETUP = exports.DEFAULT_LANGUAGE = exports.DEFAULT_CURRENCY = exports.DEFAULT_CHAIN_PATROL_ENABLE = exports.DEFAULT_CAMERA_ENABLE = exports.DEFAULT_AUTO_LOCK_TIME = exports.DEFAULT_ALL_LOGO = void 0;
6
+ exports.DEFAULT_UNLOCK_TYPE = exports.DEFAULT_THEME = exports.DEFAULT_SHOW_ZERO_BALANCE = exports.DEFAULT_SHOW_BALANCE = exports.DEFAULT_SETTING = exports.DEFAULT_NOTIFICATION_TYPE = exports.DEFAULT_NOTIFICATION_SETUP = exports.DEFAULT_LANGUAGE = exports.DEFAULT_CURRENCY = exports.DEFAULT_CHAIN_PATROL_ENABLE = exports.DEFAULT_CAMERA_ENABLE = exports.DEFAULT_AUTO_LOCK_TIME = exports.DEFAULT_ALL_LOGO = exports.DEFAULT_ALLOW_ONE_SIGN = void 0;
7
7
  var _KoniTypes = require("@subwallet/extension-base/background/KoniTypes");
8
8
  var _utils = require("@subwallet/extension-base/utils");
9
9
  // Copyright 2019-2022 @subwallet/extension-koni authors & contributors
@@ -31,6 +31,8 @@ const DEFAULT_ALL_LOGO = '';
31
31
  exports.DEFAULT_ALL_LOGO = DEFAULT_ALL_LOGO;
32
32
  const DEFAULT_CAMERA_ENABLE = false;
33
33
  exports.DEFAULT_CAMERA_ENABLE = DEFAULT_CAMERA_ENABLE;
34
+ const DEFAULT_ALLOW_ONE_SIGN = true;
35
+ exports.DEFAULT_ALLOW_ONE_SIGN = DEFAULT_ALLOW_ONE_SIGN;
34
36
  const DEFAULT_NOTIFICATION_SETUP = {
35
37
  isEnabled: true,
36
38
  showNotice: {
@@ -59,6 +61,7 @@ const DEFAULT_SETTING = {
59
61
  timeAutoLock: DEFAULT_AUTO_LOCK_TIME,
60
62
  enableChainPatrol: DEFAULT_CHAIN_PATROL_ENABLE,
61
63
  notificationSetup: DEFAULT_NOTIFICATION_SETUP,
62
- walletReference: ''
64
+ walletReference: '',
65
+ allowOneSign: DEFAULT_ALLOW_ONE_SIGN
63
66
  };
64
67
  exports.DEFAULT_SETTING = DEFAULT_SETTING;
@@ -15,6 +15,7 @@ var _MantaPay = _interopRequireDefault(require("@subwallet/extension-base/servic
15
15
  var _NominatorMetadata = _interopRequireDefault(require("@subwallet/extension-base/services/storage-service/db-stores/NominatorMetadata"));
16
16
  var _YieldPoolStore = _interopRequireDefault(require("@subwallet/extension-base/services/storage-service/db-stores/YieldPoolStore"));
17
17
  var _YieldPositionStore = _interopRequireDefault(require("@subwallet/extension-base/services/storage-service/db-stores/YieldPositionStore"));
18
+ var _types = require("@subwallet/extension-base/types");
18
19
  var _utils = require("@subwallet/extension-base/utils");
19
20
  var _uiKeyring = _interopRequireDefault(require("@subwallet/ui-keyring"));
20
21
  var _bignumber = _interopRequireDefault(require("bignumber.js"));
@@ -59,7 +60,9 @@ class DatabaseService {
59
60
  // assetRef: new AssetRefStore(this._db.assetRef)
60
61
 
61
62
  // inapp notification
62
- inappNotification: new _InappNotification.default(this._db.inappNotification)
63
+ inappNotification: new _InappNotification.default(this._db.inappNotification),
64
+ // process transaction
65
+ processTransactions: new _dbStores.ProcessTransactionStore(this._db.processTransactions)
63
66
  };
64
67
  }
65
68
  async updatePriceStore(priceData) {
@@ -271,15 +274,90 @@ class DatabaseService {
271
274
  const cleanedHistory = histories.filter(x => x && x.address && x.chain && x.extrinsicHash);
272
275
  return this.stores.transaction.bulkUpsert(cleanedHistory);
273
276
  }
274
- async updateHistoryByExtrinsicHash(extrinsicHash, updateData) {
277
+ async updateHistoryByExtrinsicHash(extrinsicHash, updateData, isRecover) {
275
278
  const canUpdate = updateData && extrinsicHash;
276
279
  if (!canUpdate) {
277
280
  return;
278
281
  }
282
+ if (isRecover) {
283
+ await this.recoverProcessTransaction(extrinsicHash, updateData);
284
+ }
279
285
  return this.stores.transaction.updateWithQuery({
280
286
  extrinsicHash
281
287
  }, updateData);
282
288
  }
289
+ async restoreProcessTransaction() {
290
+ const processes = await this.stores.processTransactions.getSubmittingProcess();
291
+ const queuedProcesses = processes.filter(process => process.status === _types.StepStatus.QUEUED);
292
+ const processingProcesses = processes.filter(process => process.status === _types.StepStatus.PROCESSING);
293
+ await this.stores.processTransactions.bulkDelete(queuedProcesses.map(process => process.id));
294
+ for (const process of processingProcesses) {
295
+ const currentStepId = process.currentStepId;
296
+ const currentStep = process.steps.find(step => step.id === currentStepId);
297
+ if (currentStep) {
298
+ const currentStepStatus = currentStep.status;
299
+ if ([_types.StepStatus.QUEUED, _types.StepStatus.PREPARE].includes(currentStepStatus)) {
300
+ currentStep.status = _types.StepStatus.CANCELLED;
301
+ process.status = _types.StepStatus.CANCELLED;
302
+ } else if (currentStepStatus === _types.StepStatus.TIMEOUT) {
303
+ currentStep.status = _types.StepStatus.CANCELLED;
304
+ }
305
+ const nextSteps = process.steps.filter(step => step.id > currentStepId);
306
+ for (const step of nextSteps) {
307
+ step.status = _types.StepStatus.CANCELLED;
308
+ }
309
+ }
310
+ }
311
+ await this.stores.processTransactions.bulkUpsert(processingProcesses);
312
+ }
313
+ async recoverProcessTransaction(extrinsicHash, updateData) {
314
+ const txs = await this.stores.transaction.queryHistory({
315
+ extrinsicHash
316
+ });
317
+ const map = new Map(txs.filter(x => !!x.processId && x.extrinsicHash === extrinsicHash).map(tx => [tx.processId || '', tx.transactionId || '']));
318
+ if (map.size && updateData.status) {
319
+ const processes = await this.stores.processTransactions.getByIds(Array.from(map.keys()));
320
+ for (const [processId, process] of Object.entries(processes)) {
321
+ const txId = map.get(processId);
322
+ if (txId) {
323
+ const currentStep = process.steps.find(tx => tx.transactionId === txId);
324
+ if (currentStep) {
325
+ const differentHash = txId !== extrinsicHash && currentStep.extrinsicHash !== extrinsicHash;
326
+ if (currentStep.status === _types.StepStatus.PROCESSING || currentStep.status === _types.StepStatus.SUBMITTING) {
327
+ switch (updateData.status) {
328
+ case _KoniTypes.ExtrinsicStatus.SUCCESS:
329
+ currentStep.status = _types.StepStatus.COMPLETE;
330
+ if (differentHash) {
331
+ currentStep.extrinsicHash = extrinsicHash;
332
+ }
333
+ break;
334
+ case _KoniTypes.ExtrinsicStatus.FAIL:
335
+ currentStep.status = _types.StepStatus.FAILED;
336
+ if (differentHash) {
337
+ currentStep.extrinsicHash = extrinsicHash;
338
+ }
339
+ break;
340
+ case _KoniTypes.ExtrinsicStatus.UNKNOWN:
341
+ currentStep.status = _types.StepStatus.TIMEOUT;
342
+ break;
343
+ }
344
+ }
345
+ const isLastStep = process.steps[process.steps.length - 1].id === currentStep.id;
346
+ if (isLastStep) {
347
+ process.status = currentStep.status;
348
+ } else {
349
+ if (currentStep.status === _types.StepStatus.TIMEOUT) {
350
+ process.status = _types.StepStatus.TIMEOUT;
351
+ } else {
352
+ process.status = _types.StepStatus.CANCELLED;
353
+ }
354
+ }
355
+ await this.stores.processTransactions.upsert(process);
356
+ }
357
+ }
358
+ }
359
+ }
360
+ }
283
361
 
284
362
  // NFT Collection
285
363
  async addNftCollection(collection) {
@@ -555,6 +633,24 @@ class DatabaseService {
555
633
  async getExportJson() {
556
634
  return JSON.parse(await this.exportDB());
557
635
  }
636
+ upsertProcessTransaction(processTransaction) {
637
+ return this.stores.processTransactions.upsert(processTransaction);
638
+ }
639
+ observableProcessTransactions() {
640
+ return this.stores.processTransactions.observableAll();
641
+ }
642
+ getProcessTransactions() {
643
+ return this.stores.processTransactions.getAll();
644
+ }
645
+ getProcessTransactionById(processId) {
646
+ return this.stores.processTransactions.getOne(processId);
647
+ }
648
+ observableProcessTransactionById(processId) {
649
+ return this.stores.processTransactions.observableOne(processId);
650
+ }
651
+ deleteProcessTransactionById(processId) {
652
+ return this.stores.processTransactions.delete(processId);
653
+ }
558
654
 
559
655
  // public setAssetRef (assetRef: Record<string, _AssetRef>) {
560
656
  // const assetRefList = Object.entries(assetRef).map(([slug, item]) => {
@@ -56,6 +56,9 @@ class KoniDatabase extends _dexie.default {
56
56
  this.conditionalVersion(8, {
57
57
  metadataV15: 'genesisHash, chain'
58
58
  });
59
+ this.conditionalVersion(9, {
60
+ processTransactions: 'id, address'
61
+ });
59
62
  }
60
63
  conditionalVersion(version, schema, upgrade) {
61
64
  if (this.schemaVersion != null && this.schemaVersion < version) {
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = void 0;
8
+ var _types = require("@subwallet/extension-base/types");
9
+ var _dexie = require("dexie");
10
+ var _BaseStoreWithAddress = _interopRequireDefault(require("./BaseStoreWithAddress"));
11
+ // Copyright 2019-2022 @subwallet/extension-base authors & contributors
12
+ // SPDX-License-Identifier: Apache-2.0
13
+
14
+ class ProcessTransaction extends _BaseStoreWithAddress.default {
15
+ async getAll() {
16
+ const all = await this.table.toArray();
17
+ return Object.fromEntries(all.map(item => [item.id, item]));
18
+ }
19
+ observableAll() {
20
+ return (0, _dexie.liveQuery)(async () => {
21
+ const all = await this.table.toArray();
22
+ return Object.fromEntries(all.map(item => [item.id, item]));
23
+ });
24
+ }
25
+ async getOne(id) {
26
+ return this.table.get(id);
27
+ }
28
+ observableOne(id) {
29
+ return (0, _dexie.liveQuery)(async () => {
30
+ return this.table.get(id);
31
+ });
32
+ }
33
+ async getByIds(ids) {
34
+ const rs = await this.table.where('id').anyOf(ids).toArray();
35
+ return Object.fromEntries(rs.map(item => [item.id, item]));
36
+ }
37
+ delete(key) {
38
+ return this.table.delete(key);
39
+ }
40
+ getSubmittingProcess() {
41
+ return this.table.filter(item => [_types.StepStatus.PROCESSING, _types.StepStatus.QUEUED].includes(item.status)).toArray();
42
+ }
43
+ bulkDelete(keys) {
44
+ return this.table.bulkDelete(keys);
45
+ }
46
+ }
47
+ exports.default = ProcessTransaction;
@@ -17,6 +17,8 @@ class TransactionStore extends _BaseStoreWithAddressAndChain.default {
17
17
  }
18
18
  return this.table.where('address').equals(address).toArray();
19
19
  }
20
+
21
+ // TODO: This query is not exactly correct. It makes a lot of wrong assumptions, need to be fixed.
20
22
  async queryHistory(query) {
21
23
  if (!(query !== null && query !== void 0 && query.address) && !(query !== null && query !== void 0 && query.chain)) {
22
24
  return this.table.toArray();