@subwallet/extension-base 1.1.9-0 → 1.1.11-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 (102) hide show
  1. package/background/KoniTypes.d.ts +13 -1
  2. package/background/KoniTypes.js +5 -0
  3. package/background/errors/BalanceError.js +7 -5
  4. package/background/errors/EvmProviderError.js +10 -8
  5. package/background/errors/ProviderError.js +5 -4
  6. package/background/errors/TransactionError.js +22 -17
  7. package/background/handlers/Extension.js +18 -18
  8. package/background/handlers/State.js +5 -5
  9. package/background/handlers/Tabs.js +1 -1
  10. package/background/warnings/TransactionWarning.js +4 -2
  11. package/cjs/background/KoniTypes.js +7 -1
  12. package/cjs/background/errors/BalanceError.js +7 -5
  13. package/cjs/background/errors/EvmProviderError.js +10 -8
  14. package/cjs/background/errors/ProviderError.js +5 -4
  15. package/cjs/background/errors/TransactionError.js +22 -17
  16. package/cjs/background/handlers/Extension.js +18 -18
  17. package/cjs/background/handlers/State.js +5 -5
  18. package/cjs/background/handlers/Tabs.js +1 -1
  19. package/cjs/background/warnings/TransactionWarning.js +4 -2
  20. package/cjs/constants/i18n.js +4 -1
  21. package/cjs/constants/index.js +12 -0
  22. package/cjs/constants/storage.js +11 -0
  23. package/cjs/defaults.js +3 -1
  24. package/cjs/koni/api/dotsama/parseTransaction.js +2 -1
  25. package/cjs/koni/api/nft/config.js +10 -12
  26. package/cjs/koni/api/staking/bonding/paraChain.js +10 -6
  27. package/cjs/koni/api/staking/bonding/relayChain.js +16 -7
  28. package/cjs/koni/api/staking/bonding/utils.js +80 -7
  29. package/cjs/koni/background/handlers/Extension.js +256 -183
  30. package/cjs/koni/background/handlers/State.js +19 -14
  31. package/cjs/koni/background/handlers/Tabs.js +15 -14
  32. package/cjs/packageInfo.js +1 -1
  33. package/cjs/services/balance-service/index.js +12 -3
  34. package/cjs/services/chain-service/constants.js +3 -2
  35. package/cjs/services/keyring-service/index.js +4 -0
  36. package/cjs/services/request-service/handler/AuthRequestHandler.js +4 -4
  37. package/cjs/services/request-service/handler/EvmRequestHandler.js +24 -11
  38. package/cjs/services/request-service/handler/SubstrateRequestHandler.js +10 -2
  39. package/cjs/services/request-service/index.js +1 -1
  40. package/cjs/services/setting-service/SettingService.js +29 -7
  41. package/cjs/services/setting-service/constants.js +5 -1
  42. package/cjs/services/setting-service/i18n/Backend.js +42 -0
  43. package/cjs/services/setting-service/i18n/cache.js +12 -0
  44. package/cjs/services/setting-service/i18n/extend.js +16 -0
  45. package/cjs/services/setting-service/i18n/i18n.js +29 -0
  46. package/cjs/services/transaction-service/index.js +25 -16
  47. package/cjs/services/wallet-connect-service/handler/PolkadotRequestHandler.js +0 -1
  48. package/cjs/utils/eth/parseTransaction/base.js +1 -1
  49. package/cjs/utils/eth/parseTransaction/index.js +2 -1
  50. package/cjs/utils/getId.js +1 -1
  51. package/cjs/utils/index.js +2 -1
  52. package/constants/i18n.js +4 -1
  53. package/constants/index.d.ts +1 -0
  54. package/constants/index.js +2 -1
  55. package/constants/storage.d.ts +1 -0
  56. package/constants/storage.js +4 -0
  57. package/defaults.d.ts +2 -1
  58. package/defaults.js +2 -1
  59. package/koni/api/dotsama/parseTransaction.js +2 -1
  60. package/koni/api/nft/config.d.ts +1 -1
  61. package/koni/api/nft/config.js +8 -10
  62. package/koni/api/staking/bonding/paraChain.js +11 -7
  63. package/koni/api/staking/bonding/relayChain.js +17 -8
  64. package/koni/api/staking/bonding/utils.d.ts +4 -0
  65. package/koni/api/staking/bonding/utils.js +70 -2
  66. package/koni/background/handlers/Extension.d.ts +1 -0
  67. package/koni/background/handlers/Extension.js +135 -63
  68. package/koni/background/handlers/State.js +19 -14
  69. package/koni/background/handlers/Tabs.js +15 -14
  70. package/package.json +31 -11
  71. package/packageInfo.js +1 -1
  72. package/services/balance-service/index.js +12 -3
  73. package/services/chain-service/constants.js +3 -2
  74. package/services/keyring-service/index.d.ts +1 -0
  75. package/services/keyring-service/index.js +4 -0
  76. package/services/request-service/handler/AuthRequestHandler.js +4 -4
  77. package/services/request-service/handler/EvmRequestHandler.js +24 -11
  78. package/services/request-service/handler/SubstrateRequestHandler.js +10 -2
  79. package/services/request-service/index.d.ts +1 -1
  80. package/services/request-service/index.js +1 -1
  81. package/services/setting-service/SettingService.d.ts +2 -0
  82. package/services/setting-service/SettingService.js +26 -5
  83. package/services/setting-service/constants.d.ts +2 -1
  84. package/services/setting-service/constants.js +4 -1
  85. package/services/setting-service/i18n/Backend.d.ts +9 -0
  86. package/services/setting-service/i18n/Backend.js +34 -0
  87. package/services/setting-service/i18n/cache.d.ts +2 -0
  88. package/services/setting-service/i18n/cache.js +5 -0
  89. package/services/setting-service/i18n/extend.d.ts +2 -0
  90. package/services/setting-service/i18n/extend.js +8 -0
  91. package/services/setting-service/i18n/i18n.d.ts +2 -0
  92. package/services/setting-service/i18n/i18n.js +21 -0
  93. package/services/transaction-service/index.d.ts +3 -3
  94. package/services/transaction-service/index.js +25 -16
  95. package/services/wallet-connect-service/handler/PolkadotRequestHandler.js +0 -1
  96. package/utils/eth/parseTransaction/base.js +1 -1
  97. package/utils/eth/parseTransaction/index.js +2 -1
  98. package/utils/getId.js +2 -2
  99. package/utils/index.js +2 -1
  100. package/cjs/utils/keyring.js +0 -57
  101. package/utils/keyring.d.ts +0 -4
  102. package/utils/keyring.js +0 -49
@@ -32,6 +32,7 @@ import { createPromiseHandler } from '@subwallet/extension-base/utils/promise';
32
32
  import { decodePair } from '@subwallet/keyring/pair/decode';
33
33
  import { keyring } from '@subwallet/ui-keyring';
34
34
  import SimpleKeyring from 'eth-simple-keyring';
35
+ import { t } from 'i18next';
35
36
  import { Subject } from 'rxjs';
36
37
  import { assert, BN, hexStripPrefix, hexToU8a, isHex, logger as createLogger, u8aToHex } from '@polkadot/util';
37
38
  import { base64Decode, isEthereumAddress, keyExtractSuri } from '@polkadot/util-crypto';
@@ -138,7 +139,7 @@ export default class KoniState {
138
139
 
139
140
  // Start a provider, return its meta
140
141
  rpcStartProvider(key, port) {
141
- assert(Object.keys(this.providers).includes(key), `Provider ${key} is not exposed by extension`);
142
+ assert(Object.keys(this.providers).includes(key), 'Provider cannot be found.');
142
143
  if (this.injectedProviders.get(port)) {
143
144
  return Promise.resolve(this.providers[key].meta);
144
145
  }
@@ -488,7 +489,7 @@ export default class KoniState {
488
489
  setAccountTie(address, genesisHash) {
489
490
  if (address !== ALL_ACCOUNT_KEY) {
490
491
  const pair = keyring.getPair(address);
491
- assert(pair, 'Unable to find pair');
492
+ assert(pair, t('Unable to find account'));
492
493
  keyring.saveAccountMeta(pair, {
493
494
  ...pair.meta,
494
495
  genesisHash
@@ -512,7 +513,11 @@ export default class KoniState {
512
513
  authUrls[shortenUrl].currentEvmNetworkKey = networkKey;
513
514
  this.setAuthorize(authUrls);
514
515
  } else {
515
- throw new EvmProviderError(EvmProviderErrorType.INTERNAL_ERROR, `Not found ${shortenUrl} in auth list`);
516
+ throw new EvmProviderError(EvmProviderErrorType.INTERNAL_ERROR, t('Not found {{shortenUrl}} in auth list', {
517
+ replace: {
518
+ shortenUrl
519
+ }
520
+ }));
516
521
  }
517
522
  }
518
523
  async switchNetworkAccount(id, url, networkKey, changeAddress) {
@@ -537,7 +542,7 @@ export default class KoniState {
537
542
  }
538
543
  if (useAddress !== ALL_ACCOUNT_KEY) {
539
544
  const pair = keyring.getPair(useAddress);
540
- assert(pair, 'Unable to find pair');
545
+ assert(pair, t('Unable to find account'));
541
546
  keyring.saveAccountMeta(pair, {
542
547
  ...pair.meta,
543
548
  genesisHash: _getSubstrateGenesisHash(chainInfo)
@@ -1114,10 +1119,10 @@ export default class KoniState {
1114
1119
  payload = p1;
1115
1120
  }
1116
1121
  if (address === '' || !payload) {
1117
- throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, 'Not found address or payload to sign');
1122
+ throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, t('Not found address or payload to sign'));
1118
1123
  }
1119
1124
  if (['eth_sign', 'personal_sign', 'eth_signTypedData', 'eth_signTypedData_v1', 'eth_signTypedData_v3', 'eth_signTypedData_v4'].indexOf(method) < 0) {
1120
- throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, 'Not found sign method');
1125
+ throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, t('Unsupported action'));
1121
1126
  }
1122
1127
  if (['eth_signTypedData_v3', 'eth_signTypedData_v4'].indexOf(method) > -1) {
1123
1128
  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument,@typescript-eslint/no-unsafe-assignment
@@ -1126,11 +1131,11 @@ export default class KoniState {
1126
1131
 
1127
1132
  // Check sign abiblity
1128
1133
  if (!allowedAccounts.find(acc => acc.toLowerCase() === address.toLowerCase())) {
1129
- throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, 'Account ' + address + ' not in allowed list');
1134
+ throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, t('You have rescinded allowance for this account in wallet'));
1130
1135
  }
1131
1136
  const pair = keyring.getPair(address);
1132
1137
  if (!pair) {
1133
- throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, 'Cannot find pair with address: ' + address);
1138
+ throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, t('Unable to find account'));
1134
1139
  }
1135
1140
  const account = {
1136
1141
  address: pair.address,
@@ -1153,7 +1158,7 @@ export default class KoniState {
1153
1158
  }
1154
1159
  break;
1155
1160
  default:
1156
- throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, 'Not found sign method');
1161
+ throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, t('Unsupported action'));
1157
1162
  }
1158
1163
  const signPayload = {
1159
1164
  account: account,
@@ -1174,7 +1179,7 @@ export default class KoniState {
1174
1179
  if (payload) {
1175
1180
  return payload;
1176
1181
  } else {
1177
- throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, 'Not found signature');
1182
+ throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, t('Not found signature'));
1178
1183
  }
1179
1184
  } else {
1180
1185
  throw new EvmProviderError(EvmProviderErrorType.USER_REJECTED_REQUEST);
@@ -1194,7 +1199,7 @@ export default class KoniState {
1194
1199
  return val;
1195
1200
  };
1196
1201
  if (transactionParams.from === transactionParams.to) {
1197
- throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, 'From address and to address must not be the same');
1202
+ throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, t('Receiving address must be different from sending address'));
1198
1203
  }
1199
1204
  const transaction = {
1200
1205
  from: transactionParams.from,
@@ -1223,11 +1228,11 @@ export default class KoniState {
1223
1228
  // Address is validated in before step
1224
1229
  const fromAddress = allowedAccounts.find(account => account.toLowerCase() === transaction.from.toLowerCase());
1225
1230
  if (!fromAddress) {
1226
- throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, 'From address is not in available for ' + url);
1231
+ throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, t('You have rescinded allowance for this account in wallet'));
1227
1232
  }
1228
1233
  const pair = keyring.getPair(fromAddress);
1229
1234
  if (!pair) {
1230
- throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, 'Cannot find pair with address: ' + fromAddress);
1235
+ throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, t('Unable to find account'));
1231
1236
  }
1232
1237
  const account = {
1233
1238
  address: pair.address,
@@ -1237,7 +1242,7 @@ export default class KoniState {
1237
1242
  // Validate balance
1238
1243
  const balance = new BN((await web3.eth.getBalance(fromAddress)) || 0);
1239
1244
  if (balance.lt(new BN(gasPrice.toString()).mul(new BN(transaction.gas)).add(new BN(autoFormatNumber(transactionParams.value) || '0')))) {
1240
- throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, 'Balance can be not enough to send transaction');
1245
+ throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, t('Insufficient balance'));
1241
1246
  }
1242
1247
  transaction.nonce = await web3.eth.getTransactionCount(fromAddress);
1243
1248
  const hashPayload = this.transactionService.generateHashPayload(networkKey, transaction);
@@ -15,6 +15,7 @@ import { _generateCustomProviderKey } from '@subwallet/extension-base/services/c
15
15
  import { DEFAULT_CHAIN_PATROL_ENABLE } from '@subwallet/extension-base/services/setting-service/constants';
16
16
  import { canDerive, stripUrl } from '@subwallet/extension-base/utils';
17
17
  import keyring from '@subwallet/ui-keyring';
18
+ import { t } from 'i18next';
18
19
  import Web3 from 'web3';
19
20
  import { checkIfDenied } from '@polkadot/phishing';
20
21
  import { assert, isNumber } from '@polkadot/util';
@@ -103,7 +104,7 @@ export default class KoniTabs {
103
104
  /// Clone from Polkadot.js
104
105
  getSigningPair(address) {
105
106
  const pair = keyring.getPair(address);
106
- assert(pair, 'Unable to find keypair');
107
+ assert(pair, t('Unable to find account'));
107
108
  return pair;
108
109
  }
109
110
  async bytesSign(url, request) {
@@ -327,13 +328,13 @@ export default class KoniTabs {
327
328
  const web3 = evmApi === null || evmApi === void 0 ? void 0 : evmApi.api;
328
329
  if ((web3 === null || web3 === void 0 ? void 0 : web3.currentProvider) instanceof Web3.providers.WebsocketProvider) {
329
330
  if (!web3.currentProvider.connected) {
330
- console.log(`[Web3] ${slug} is disconnected, trying to connect...`);
331
+ console.log(`${slug} is disconnected, trying to connect...`);
331
332
  this.#koniState.refreshWeb3Api(slug);
332
333
  let checkingNum = 0;
333
334
  const poll = resolve => {
334
335
  checkingNum += 1;
335
336
  if (web3.currentProvider.connected) {
336
- console.log(`Network [${slug}] is connected.`);
337
+ console.log(`${slug} is connected.`);
337
338
  resolve(true);
338
339
  } else {
339
340
  console.log(`Connecting to network [${slug}]`);
@@ -383,7 +384,7 @@ export default class KoniTabs {
383
384
  if (networkKey) {
384
385
  await this.#koniState.switchEvmNetworkByUrl(stripUrl(url), networkKey);
385
386
  } else {
386
- throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, `Not found chainId ${chainId} in wallet`);
387
+ throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, 'This network is currently not supported');
387
388
  }
388
389
  return null;
389
390
  }
@@ -394,15 +395,15 @@ export default class KoniTabs {
394
395
  const input = params;
395
396
  const _tokenType = (input === null || input === void 0 ? void 0 : (_input$type = input.type) === null || _input$type === void 0 ? void 0 : _input$type.toLowerCase()) || '';
396
397
  if (_tokenType !== 'erc20' && _tokenType !== 'erc721') {
397
- throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, `Assets type ${_tokenType} is not supported`);
398
+ throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, 'Assets type {{tokenType}} is not supported'.replace('{{tokenType}}', _tokenType));
398
399
  }
399
400
  if (!(input !== null && input !== void 0 && (_input$options = input.options) !== null && _input$options !== void 0 && _input$options.address) || !(input !== null && input !== void 0 && (_input$options2 = input.options) !== null && _input$options2 !== void 0 && _input$options2.symbol)) {
400
- throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, 'Assets params require address and symbol');
401
+ throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, 'Unable to get contract address and token symbol');
401
402
  }
402
403
  const evmState = await this.getEvmState(url);
403
404
  const chain = evmState.networkKey;
404
405
  if (!chain) {
405
- throw new EvmProviderError(EvmProviderErrorType.INTERNAL_ERROR, 'Current chain is not available');
406
+ throw new EvmProviderError(EvmProviderErrorType.INTERNAL_ERROR, 'The network on dApp is not supported in wallet. Please manually add the network to wallet');
406
407
  }
407
408
  const tokenType = _tokenType === 'erc20' ? _AssetType.ERC20 : _AssetType.ERC721;
408
409
  const tokenInfo = {
@@ -503,7 +504,7 @@ export default class KoniTabs {
503
504
  return url.protocol === 'http:' || url.protocol === 'https:';
504
505
  });
505
506
  if (!filteredUrls.length) {
506
- throw new EvmProviderError(EvmProviderErrorType.INTERNAL_ERROR, 'Currently HTTP provider for EVM network');
507
+ throw new EvmProviderError(EvmProviderErrorType.INTERNAL_ERROR, 'Currently support WSS provider for Substrate networks and HTTP provider for EVM network');
507
508
  }
508
509
  const provider = filteredUrls[0];
509
510
  const chainInfo = {
@@ -746,7 +747,7 @@ export default class KoniTabs {
746
747
  if (signResult) {
747
748
  return signResult;
748
749
  } else {
749
- throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, 'Have something wrong to sign message');
750
+ throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, 'Failed to sign message');
750
751
  }
751
752
  }
752
753
  async evmSendTransaction(id, url, {
@@ -757,10 +758,10 @@ export default class KoniTabs {
757
758
  const evmState = await this.getEvmState(url);
758
759
  const networkKey = evmState.networkKey;
759
760
  if (!canUseAccount) {
760
- throw new Error('Account ' + transactionParams.from + ' not in allowed list');
761
+ throw new Error(t('You have rescinded allowance for this account in wallet'));
761
762
  }
762
763
  if (!networkKey) {
763
- throw new Error('Empty current network key');
764
+ throw new Error('Network unavailable. Please switch network or manually add network to wallet');
764
765
  }
765
766
  const allowedAccounts = await this.getEvmCurrentAccount(url, true);
766
767
  const transactionHash = await this.#koniState.evmSendTransaction(id, url, networkKey, allowedAccounts, transactionParams);
@@ -851,14 +852,14 @@ export default class KoniTabs {
851
852
  }) {
852
853
  const _tokenType = input.type;
853
854
  if (_tokenType !== 'psp22' && _tokenType !== 'psp34') {
854
- throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, `Assets type ${_tokenType} is not supported`);
855
+ throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, 'Assets type {{tokenType}} is not supported'.replace('{{tokenType}}', _tokenType));
855
856
  }
856
857
  if (!input.address || !input.symbol) {
857
- throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, 'Assets params require address and symbol');
858
+ throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, 'Unable to get contract address and token symbol');
858
859
  }
859
860
  const [chain] = this.#koniState.findNetworkKeyByGenesisHash(genesisHash);
860
861
  if (!chain) {
861
- throw new EvmProviderError(EvmProviderErrorType.INTERNAL_ERROR, 'Current chain is not available');
862
+ throw new EvmProviderError(EvmProviderErrorType.INTERNAL_ERROR, 'The network on dApp is not supported in wallet. Please manually add the network to wallet');
862
863
  }
863
864
  const state = this.#koniState.getChainStateByKey(chain);
864
865
  if (!state.active) {
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "./cjs/detectPackage.js"
18
18
  ],
19
19
  "type": "module",
20
- "version": "1.1.9-0",
20
+ "version": "1.1.11-0",
21
21
  "main": "./cjs/index.js",
22
22
  "module": "./index.js",
23
23
  "types": "./index.d.ts",
@@ -134,6 +134,11 @@
134
134
  "require": "./cjs/constants/staking.js",
135
135
  "default": "./constants/staking.js"
136
136
  },
137
+ "./constants/storage": {
138
+ "types": "./constants/storage.d.ts",
139
+ "require": "./cjs/constants/storage.js",
140
+ "default": "./constants/storage.js"
141
+ },
137
142
  "./defaults": {
138
143
  "types": "./defaults.d.ts",
139
144
  "require": "./cjs/defaults.js",
@@ -792,6 +797,26 @@
792
797
  "require": "./cjs/services/setting-service/constants.js",
793
798
  "default": "./services/setting-service/constants.js"
794
799
  },
800
+ "./services/setting-service/i18n/Backend": {
801
+ "types": "./services/setting-service/i18n/Backend.d.ts",
802
+ "require": "./cjs/services/setting-service/i18n/Backend.js",
803
+ "default": "./services/setting-service/i18n/Backend.js"
804
+ },
805
+ "./services/setting-service/i18n/cache": {
806
+ "types": "./services/setting-service/i18n/cache.d.ts",
807
+ "require": "./cjs/services/setting-service/i18n/cache.js",
808
+ "default": "./services/setting-service/i18n/cache.js"
809
+ },
810
+ "./services/setting-service/i18n/extend": {
811
+ "types": "./services/setting-service/i18n/extend.d.ts",
812
+ "require": "./cjs/services/setting-service/i18n/extend.js",
813
+ "default": "./services/setting-service/i18n/extend.js"
814
+ },
815
+ "./services/setting-service/i18n/i18n": {
816
+ "types": "./services/setting-service/i18n/i18n.d.ts",
817
+ "require": "./cjs/services/setting-service/i18n/i18n.js",
818
+ "default": "./services/setting-service/i18n/i18n.js"
819
+ },
795
820
  "./services/setting-service/SettingService": {
796
821
  "types": "./services/setting-service/SettingService.d.ts",
797
822
  "require": "./cjs/services/setting-service/SettingService.js",
@@ -1137,11 +1162,6 @@
1137
1162
  "require": "./cjs/utils/getId.js",
1138
1163
  "default": "./utils/getId.js"
1139
1164
  },
1140
- "./utils/keyring": {
1141
- "types": "./utils/keyring.d.ts",
1142
- "require": "./cjs/utils/keyring.js",
1143
- "default": "./utils/keyring.js"
1144
- },
1145
1165
  "./utils/lazy": {
1146
1166
  "types": "./utils/lazy.d.ts",
1147
1167
  "require": "./cjs/utils/lazy.js",
@@ -1201,11 +1221,11 @@
1201
1221
  "@reduxjs/toolkit": "^1.9.1",
1202
1222
  "@sora-substrate/type-definitions": "^1.17.7",
1203
1223
  "@substrate/connect": "^0.7.26",
1204
- "@subwallet/chain-list": "0.2.11-beta.0",
1205
- "@subwallet/extension-base": "^1.1.9-0",
1206
- "@subwallet/extension-chains": "^1.1.9-0",
1207
- "@subwallet/extension-dapp": "^1.1.9-0",
1208
- "@subwallet/extension-inject": "^1.1.9-0",
1224
+ "@subwallet/chain-list": "0.2.13",
1225
+ "@subwallet/extension-base": "^1.1.11-0",
1226
+ "@subwallet/extension-chains": "^1.1.11-0",
1227
+ "@subwallet/extension-dapp": "^1.1.11-0",
1228
+ "@subwallet/extension-inject": "^1.1.11-0",
1209
1229
  "@subwallet/keyring": "^0.0.10",
1210
1230
  "@subwallet/ui-keyring": "^0.0.10",
1211
1231
  "@walletconnect/sign-client": "^2.8.4",
package/packageInfo.js CHANGED
@@ -7,5 +7,5 @@ export const packageInfo = {
7
7
  name: '@subwallet/extension-base',
8
8
  path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto',
9
9
  type: 'esm',
10
- version: '1.1.9-0'
10
+ version: '1.1.11-0'
11
11
  };
@@ -8,6 +8,7 @@ import { state } from '@subwallet/extension-base/koni/background/handlers';
8
8
  import { _PURE_EVM_CHAINS } from '@subwallet/extension-base/services/chain-service/constants';
9
9
  import { _getChainNativeTokenSlug, _isChainEvmCompatible, _isPureEvmChain } from '@subwallet/extension-base/services/chain-service/utils';
10
10
  import { categoryAddresses } from '@subwallet/extension-base/utils';
11
+ import { t } from 'i18next';
11
12
  export class BalanceService {
12
13
  constructor(chainService) {
13
14
  this.chainService = chainService;
@@ -26,12 +27,20 @@ export class BalanceService {
26
27
  const chainInfo = this.chainService.getChainInfoByKey(chain);
27
28
  const chainState = this.chainService.getChainStateByKey(chain);
28
29
  if (!chainInfo || !chainState || !chainState.active) {
29
- return Promise.reject(new BalanceError(BalanceErrorType.NETWORK_ERROR, `Chain ${chain} is not active`));
30
+ return Promise.reject(new BalanceError(BalanceErrorType.NETWORK_ERROR, t('{{chain}} is inactive. Please enable network', {
31
+ replace: {
32
+ chain
33
+ }
34
+ })));
30
35
  }
31
36
  const tSlug = tokenSlug || _getChainNativeTokenSlug(chainInfo);
32
37
  const tokenInfo = this.chainService.getAssetBySlug(tSlug);
33
38
  if (!tokenInfo) {
34
- return Promise.reject(new BalanceError(BalanceErrorType.TOKEN_ERROR, `Token ${tSlug} is not supported`));
39
+ return Promise.reject(new BalanceError(BalanceErrorType.TOKEN_ERROR, t('Transfer is currently not available for this token: {{tSlug}}', {
40
+ replace: {
41
+ slug: tSlug
42
+ }
43
+ })));
35
44
  }
36
45
  return new Promise((resolve, reject) => {
37
46
  let hasError = true;
@@ -55,7 +64,7 @@ export class BalanceService {
55
64
  setTimeout(() => {
56
65
  if (hasError) {
57
66
  unsub();
58
- reject(new Error('Get Balance Timeout'));
67
+ reject(new Error(t('Failed to get balance. Please check your internet connection or change your network endpoint')));
59
68
  }
60
69
  }, 9999);
61
70
  });
@@ -49,7 +49,7 @@ export const _NFT_CHAIN_GROUP = {
49
49
  // Staking--------------------------------------------------------------------------------------------------------------
50
50
 
51
51
  export const _STAKING_CHAIN_GROUP = {
52
- relay: ['polkadot', 'kusama', 'aleph', 'polkadex', 'ternoa', 'ternoa_alphanet', 'alephTest', 'polkadexTest', 'westend', 'kate', 'edgeware'],
52
+ relay: ['polkadot', 'kusama', 'aleph', 'polkadex', 'ternoa', 'ternoa_alphanet', 'alephTest', 'polkadexTest', 'westend', 'kate', 'edgeware', 'creditcoin'],
53
53
  para: ['moonbeam', 'moonriver', 'moonbase', 'turing', 'turingStaging', 'bifrost', 'bifrost_testnet', 'calamari_test', 'calamari'],
54
54
  astar: ['astar', 'shiden', 'shibuya'],
55
55
  amplitude: ['amplitude', 'amplitude_test', 'kilt', 'kilt_peregrine', 'pendulum'],
@@ -89,7 +89,8 @@ export const _STAKING_ERA_LENGTH_MAP = {
89
89
  kilt: 2,
90
90
  kilt_peregrine: 2,
91
91
  edgeware: 6,
92
- kate: 6
92
+ kate: 6,
93
+ creditcoin: 24
93
94
  };
94
95
  export const _PARACHAIN_INFLATION_DISTRIBUTION = {
95
96
  moonbeam: {
@@ -18,5 +18,6 @@ export declare class KeyringService {
18
18
  get addresses(): SubjectInfo;
19
19
  get currentAccount(): CurrentAccountInfo;
20
20
  setCurrentAccount(currentAccountData: CurrentAccountInfo): void;
21
+ lock(): void;
21
22
  resetWallet(resetAll: boolean): void;
22
23
  }
@@ -87,6 +87,10 @@ export class KeyringService {
87
87
  this.eventService.emit('account.updateCurrent', currentAccountData);
88
88
  this.currentAccountStore.set('CurrentAccountInfo', currentAccountData);
89
89
  }
90
+ lock() {
91
+ keyring.lockAll();
92
+ this.updateKeyringState();
93
+ }
90
94
  resetWallet(resetAll) {
91
95
  keyring.resetWallet(resetAll);
92
96
  this.updateKeyringState();
@@ -210,7 +210,7 @@ export default class AuthRequestHandler {
210
210
  const idStr = stripUrl(url);
211
211
  // Do not enqueue duplicate authorization requests.
212
212
  const isDuplicate = Object.values(this.#authRequestsV2).some(request => request.idStr === idStr);
213
- assert(!isDuplicate, `The source ${url} has a pending authorization request`);
213
+ assert(!isDuplicate, 'The source {{url}} has a pending authorization request'.replace('{{url}}', url));
214
214
  const existedAuth = authList[idStr];
215
215
  const existedAccountAuthType = existedAuth === null || existedAuth === void 0 ? void 0 : existedAuth.accountAuthType;
216
216
  const confirmAnotherType = existedAccountAuthType !== 'both' && existedAccountAuthType !== request.accountAuthType;
@@ -222,7 +222,7 @@ export default class AuthRequestHandler {
222
222
  if (existedAuth) {
223
223
  const inBlackList = existedAuth && !existedAuth.isAllowed;
224
224
  if (inBlackList) {
225
- throw new Error(`The source ${url} is not allowed to interact with this extension`);
225
+ throw new Error('The source {{url}} is not allowed to interact with this extension'.replace('{{url}}', url));
226
226
  }
227
227
  request.allowedAccounts = Object.entries(existedAuth.isAllowedMap).map(([address, allowed]) => allowed ? address : '').filter(item => item !== '');
228
228
  let allowedListByRequestType = [...request.allowedAccounts];
@@ -270,11 +270,11 @@ export default class AuthRequestHandler {
270
270
  }
271
271
  const entry = Object.keys(value).includes(idStr);
272
272
  if (!entry) {
273
- reject(new Error(`The source ${url} has not been enabled yet`));
273
+ reject(new Error('The source {{url}} has not been authorized yet'.replace('{{url}}', url)));
274
274
  }
275
275
  const isConnected = value[idStr] && Object.keys(value[idStr].isAllowedMap).some(address => value[idStr].isAllowedMap[address]);
276
276
  if (!isConnected) {
277
- reject(new Error(`The source ${url} is not allowed to interact with this extension`));
277
+ reject(new Error('The source {{url}} is not allowed to interact with this extension'.replace('{{url}}', url)));
278
278
  }
279
279
  resolve(true);
280
280
  });
@@ -10,6 +10,7 @@ import keyring from '@subwallet/ui-keyring';
10
10
  import BN from 'bn.js';
11
11
  import { Transaction } from 'ethereumjs-tx';
12
12
  import { toBuffer } from 'ethereumjs-util';
13
+ import { t } from 'i18next';
13
14
  import { BehaviorSubject } from 'rxjs';
14
15
  import { logger as createLogger } from '@polkadot/util';
15
16
  export default class EvmRequestHandler {
@@ -37,16 +38,22 @@ export default class EvmRequestHandler {
37
38
  getConfirmationsQueueSubject() {
38
39
  return this.confirmationsQueueSubject;
39
40
  }
40
- addConfirmation(id, url, type, payload, options = {}, validator) {
41
+ async addConfirmation(id, url, type, payload, options = {}, validator) {
41
42
  const confirmations = this.confirmationsQueueSubject.getValue();
42
43
  const confirmationType = confirmations[type];
43
44
  const payloadJson = JSON.stringify(payload);
44
45
  const isInternal = isInternalRequest(url);
46
+ if (['evmSignatureRequest', 'evmSendTransactionRequest'].includes(type)) {
47
+ const isAlwaysRequired = await this.#requestService.settingService.isAlwaysRequired;
48
+ if (isAlwaysRequired) {
49
+ this.#requestService.keyringService.lock();
50
+ }
51
+ }
45
52
 
46
53
  // Check duplicate request
47
54
  const duplicated = Object.values(confirmationType).find(c => c.url === url && c.payloadJson === payloadJson);
48
55
  if (duplicated) {
49
- throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, 'Duplicate request information');
56
+ throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, t('Duplicate request'));
50
57
  }
51
58
  confirmationType[id] = {
52
59
  id,
@@ -79,7 +86,7 @@ export default class EvmRequestHandler {
79
86
  // Check duplicate request
80
87
  const exists = confirmationType[id];
81
88
  if (!exists) {
82
- throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, 'Request does not exist');
89
+ throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, t('Request does not exist'));
83
90
  }
84
91
  const payloadJson = JSON.stringify(payload);
85
92
  confirmationType[id] = {
@@ -113,7 +120,7 @@ export default class EvmRequestHandler {
113
120
  case 'eth_signTypedData_v4':
114
121
  return await pair.evmSigner.signMessage(payload, type);
115
122
  default:
116
- throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, 'Not found sign method');
123
+ throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, t('Unsupported action'));
117
124
  }
118
125
  }
119
126
  configToTransaction(config) {
@@ -181,13 +188,19 @@ export default class EvmRequestHandler {
181
188
  } else if (t === 'evmSendTransactionRequest') {
182
189
  result.payload = await this.signTransaction(request);
183
190
  }
191
+ if (t === 'evmSignatureRequest' || t === 'evmSendTransactionRequest') {
192
+ const isAlwaysRequired = await this.#requestService.settingService.isAlwaysRequired;
193
+ if (isAlwaysRequired) {
194
+ this.#requestService.keyringService.lock();
195
+ }
196
+ }
184
197
  }
185
198
  }
186
199
  async completeConfirmation(request) {
187
200
  const confirmations = this.confirmationsQueueSubject.getValue();
188
201
  for (const ct in request) {
189
- const t = ct;
190
- const result = request[t];
202
+ const type = ct;
203
+ const result = request[type];
191
204
  const {
192
205
  id
193
206
  } = result;
@@ -195,14 +208,14 @@ export default class EvmRequestHandler {
195
208
  resolver,
196
209
  validator
197
210
  } = this.confirmationsPromiseMap[id];
198
- const confirmation = confirmations[t][id];
211
+ const confirmation = confirmations[type][id];
199
212
  if (!resolver || !confirmation) {
200
- this.#logger.error('Not found confirmation', t, id);
201
- throw new Error('Not found promise for confirmation');
213
+ this.#logger.error(t('Unable to proceed. Please try again'), type, id);
214
+ throw new Error(t('Unable to proceed. Please try again'));
202
215
  }
203
216
 
204
217
  // Fill signature for some special type
205
- await this.decorateResult(t, confirmation, result);
218
+ await this.decorateResult(type, confirmation, result);
206
219
 
207
220
  // Validate response from confirmation popup some info like password, response format....
208
221
  const error = validator && validator(result);
@@ -212,7 +225,7 @@ export default class EvmRequestHandler {
212
225
 
213
226
  // Delete confirmations from queue
214
227
  delete this.confirmationsPromiseMap[id];
215
- delete confirmations[t][id];
228
+ delete confirmations[type][id];
216
229
  this.confirmationsQueueSubject.next(confirmations);
217
230
 
218
231
  // Update icon, and close queue
@@ -57,8 +57,12 @@ export default class SubstrateRequestHandler {
57
57
  get numSubstrateRequests() {
58
58
  return Object.keys(this.#substrateRequests).length;
59
59
  }
60
- sign(url, request, account, _id) {
60
+ async sign(url, request, account, _id) {
61
61
  const id = _id || getId();
62
+ const isAlwaysRequired = await this.#requestService.settingService.isAlwaysRequired;
63
+ if (isAlwaysRequired) {
64
+ this.#requestService.keyringService.lock();
65
+ }
62
66
  return new Promise((resolve, reject) => {
63
67
  this.#substrateRequests[id] = {
64
68
  ...this.signComplete(id, resolve, reject),
@@ -71,7 +75,11 @@ export default class SubstrateRequestHandler {
71
75
  this.#requestService.popupOpen();
72
76
  });
73
77
  }
74
- signTransaction(id, address, url, payload) {
78
+ async signTransaction(id, address, url, payload) {
79
+ const isAlwaysRequired = await this.#requestService.settingService.isAlwaysRequired;
80
+ if (isAlwaysRequired) {
81
+ this.#requestService.keyringService.lock();
82
+ }
75
83
  return new Promise((resolve, reject) => {
76
84
  const pair = keyring.getPair(address);
77
85
  const account = {
@@ -10,8 +10,8 @@ import { SignerPayloadJSON } from '@polkadot/types/types/extrinsic';
10
10
  import { AuthUrls, MetaRequest } from './types';
11
11
  export default class RequestService {
12
12
  #private;
13
- private keyringService;
14
13
  readonly settingService: SettingService;
14
+ readonly keyringService: KeyringService;
15
15
  constructor(chainService: ChainService, settingService: SettingService, keyringService: KeyringService);
16
16
  get numAllRequests(): number;
17
17
  updateIconV2(shouldClose?: boolean): void;
@@ -15,9 +15,9 @@ export default class RequestService {
15
15
 
16
16
  // Common
17
17
  constructor(chainService, settingService, keyringService) {
18
- this.keyringService = keyringService;
19
18
  this.#chainService = chainService;
20
19
  this.settingService = settingService;
20
+ this.keyringService = keyringService;
21
21
  this.#popupHandler = new PopupHandler(this);
22
22
  this.#metadataRequestHandler = new MetadataRequestHandler(this);
23
23
  this.#authRequestHandler = new AuthRequestHandler(this, this.#chainService, this.keyringService);
@@ -3,11 +3,13 @@ import { Subject } from 'rxjs';
3
3
  export default class SettingService {
4
4
  private readonly settingsStore;
5
5
  private readonly passPhishingStore;
6
+ constructor();
6
7
  getSubject(): Subject<RequestSettingsType>;
7
8
  getSettings(update: (value: RequestSettingsType) => void): void;
8
9
  setSettings(data: RequestSettingsType, callback?: () => void): void;
9
10
  passPhishingSubject(): Subject<Record<string, PassPhishing>>;
10
11
  getPassPhishingList(update: (value: Record<string, PassPhishing>) => void): void;
11
12
  setPassPhishing(data: Record<string, PassPhishing>, callback?: () => void): void;
13
+ get isAlwaysRequired(): Promise<boolean>;
12
14
  resetWallet(): void;
13
15
  }