@subwallet/extension-base 1.1.9-0 → 1.1.10-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.
- package/background/KoniTypes.d.ts +13 -1
- package/background/KoniTypes.js +5 -0
- package/background/errors/BalanceError.js +7 -5
- package/background/errors/EvmProviderError.js +10 -8
- package/background/errors/ProviderError.js +5 -4
- package/background/errors/TransactionError.js +22 -17
- package/background/handlers/Extension.js +18 -18
- package/background/handlers/State.js +5 -5
- package/background/handlers/Tabs.js +1 -1
- package/background/warnings/TransactionWarning.js +4 -2
- package/cjs/background/KoniTypes.js +7 -1
- package/cjs/background/errors/BalanceError.js +7 -5
- package/cjs/background/errors/EvmProviderError.js +10 -8
- package/cjs/background/errors/ProviderError.js +5 -4
- package/cjs/background/errors/TransactionError.js +22 -17
- package/cjs/background/handlers/Extension.js +18 -18
- package/cjs/background/handlers/State.js +5 -5
- package/cjs/background/handlers/Tabs.js +1 -1
- package/cjs/background/warnings/TransactionWarning.js +4 -2
- package/cjs/constants/i18n.js +4 -1
- package/cjs/constants/index.js +12 -0
- package/cjs/constants/storage.js +11 -0
- package/cjs/koni/api/dotsama/parseTransaction.js +2 -1
- package/cjs/koni/api/staking/bonding/paraChain.js +10 -6
- package/cjs/koni/api/staking/bonding/relayChain.js +16 -7
- package/cjs/koni/api/staking/bonding/utils.js +80 -7
- package/cjs/koni/background/handlers/Extension.js +206 -170
- package/cjs/koni/background/handlers/State.js +19 -14
- package/cjs/koni/background/handlers/Tabs.js +15 -14
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/balance-service/index.js +12 -3
- package/cjs/services/request-service/handler/AuthRequestHandler.js +4 -4
- package/cjs/services/request-service/handler/EvmRequestHandler.js +11 -10
- package/cjs/services/setting-service/SettingService.js +20 -7
- package/cjs/services/setting-service/constants.js +5 -1
- package/cjs/services/setting-service/i18n/Backend.js +42 -0
- package/cjs/services/setting-service/i18n/cache.js +12 -0
- package/cjs/services/setting-service/i18n/extend.js +16 -0
- package/cjs/services/setting-service/i18n/i18n.js +29 -0
- package/cjs/services/transaction-service/index.js +25 -16
- package/cjs/services/wallet-connect-service/handler/PolkadotRequestHandler.js +0 -1
- package/cjs/utils/eth/parseTransaction/base.js +1 -1
- package/cjs/utils/eth/parseTransaction/index.js +2 -1
- package/cjs/utils/index.js +2 -1
- package/constants/i18n.js +4 -1
- package/constants/index.d.ts +1 -0
- package/constants/index.js +2 -1
- package/constants/storage.d.ts +1 -0
- package/constants/storage.js +4 -0
- package/koni/api/dotsama/parseTransaction.js +2 -1
- package/koni/api/staking/bonding/paraChain.js +11 -7
- package/koni/api/staking/bonding/relayChain.js +17 -8
- package/koni/api/staking/bonding/utils.d.ts +4 -0
- package/koni/api/staking/bonding/utils.js +70 -2
- package/koni/background/handlers/Extension.d.ts +1 -0
- package/koni/background/handlers/Extension.js +85 -50
- package/koni/background/handlers/State.js +19 -14
- package/koni/background/handlers/Tabs.js +15 -14
- package/package.json +31 -11
- package/packageInfo.js +1 -1
- package/services/balance-service/index.js +12 -3
- package/services/request-service/handler/AuthRequestHandler.js +4 -4
- package/services/request-service/handler/EvmRequestHandler.js +11 -10
- package/services/setting-service/SettingService.d.ts +1 -0
- package/services/setting-service/SettingService.js +17 -5
- package/services/setting-service/constants.d.ts +2 -1
- package/services/setting-service/constants.js +4 -1
- package/services/setting-service/i18n/Backend.d.ts +9 -0
- package/services/setting-service/i18n/Backend.js +34 -0
- package/services/setting-service/i18n/cache.d.ts +2 -0
- package/services/setting-service/i18n/cache.js +5 -0
- package/services/setting-service/i18n/extend.d.ts +2 -0
- package/services/setting-service/i18n/extend.js +8 -0
- package/services/setting-service/i18n/i18n.d.ts +2 -0
- package/services/setting-service/i18n/i18n.js +21 -0
- package/services/transaction-service/index.js +25 -16
- package/services/wallet-connect-service/handler/PolkadotRequestHandler.js +0 -1
- package/utils/eth/parseTransaction/base.js +1 -1
- package/utils/eth/parseTransaction/index.js +2 -1
- package/utils/index.js +2 -1
- package/cjs/utils/keyring.js +0 -57
- package/utils/keyring.d.ts +0 -4
- package/utils/keyring.js +0 -49
|
@@ -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
|
|
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(
|
|
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(
|
|
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,
|
|
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,
|
|
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, '
|
|
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, '
|
|
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, '
|
|
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('
|
|
761
|
+
throw new Error(t('You have rescinded allowance for this account in wallet'));
|
|
761
762
|
}
|
|
762
763
|
if (!networkKey) {
|
|
763
|
-
throw new Error('
|
|
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,
|
|
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, '
|
|
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, '
|
|
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.
|
|
20
|
+
"version": "1.1.10-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.
|
|
1205
|
-
"@subwallet/extension-base": "^1.1.
|
|
1206
|
-
"@subwallet/extension-chains": "^1.1.
|
|
1207
|
-
"@subwallet/extension-dapp": "^1.1.
|
|
1208
|
-
"@subwallet/extension-inject": "^1.1.
|
|
1224
|
+
"@subwallet/chain-list": "0.2.12",
|
|
1225
|
+
"@subwallet/extension-base": "^1.1.10-0",
|
|
1226
|
+
"@subwallet/extension-chains": "^1.1.10-0",
|
|
1227
|
+
"@subwallet/extension-dapp": "^1.1.10-0",
|
|
1228
|
+
"@subwallet/extension-inject": "^1.1.10-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.
|
|
10
|
+
version: '1.1.10-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,
|
|
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,
|
|
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('
|
|
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
|
});
|
|
@@ -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,
|
|
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(
|
|
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(
|
|
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(
|
|
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 {
|
|
@@ -46,7 +47,7 @@ export default class EvmRequestHandler {
|
|
|
46
47
|
// Check duplicate request
|
|
47
48
|
const duplicated = Object.values(confirmationType).find(c => c.url === url && c.payloadJson === payloadJson);
|
|
48
49
|
if (duplicated) {
|
|
49
|
-
throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, 'Duplicate request
|
|
50
|
+
throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, t('Duplicate request'));
|
|
50
51
|
}
|
|
51
52
|
confirmationType[id] = {
|
|
52
53
|
id,
|
|
@@ -79,7 +80,7 @@ export default class EvmRequestHandler {
|
|
|
79
80
|
// Check duplicate request
|
|
80
81
|
const exists = confirmationType[id];
|
|
81
82
|
if (!exists) {
|
|
82
|
-
throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, 'Request does not exist');
|
|
83
|
+
throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, t('Request does not exist'));
|
|
83
84
|
}
|
|
84
85
|
const payloadJson = JSON.stringify(payload);
|
|
85
86
|
confirmationType[id] = {
|
|
@@ -113,7 +114,7 @@ export default class EvmRequestHandler {
|
|
|
113
114
|
case 'eth_signTypedData_v4':
|
|
114
115
|
return await pair.evmSigner.signMessage(payload, type);
|
|
115
116
|
default:
|
|
116
|
-
throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, '
|
|
117
|
+
throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, t('Unsupported action'));
|
|
117
118
|
}
|
|
118
119
|
}
|
|
119
120
|
configToTransaction(config) {
|
|
@@ -186,8 +187,8 @@ export default class EvmRequestHandler {
|
|
|
186
187
|
async completeConfirmation(request) {
|
|
187
188
|
const confirmations = this.confirmationsQueueSubject.getValue();
|
|
188
189
|
for (const ct in request) {
|
|
189
|
-
const
|
|
190
|
-
const result = request[
|
|
190
|
+
const type = ct;
|
|
191
|
+
const result = request[type];
|
|
191
192
|
const {
|
|
192
193
|
id
|
|
193
194
|
} = result;
|
|
@@ -195,14 +196,14 @@ export default class EvmRequestHandler {
|
|
|
195
196
|
resolver,
|
|
196
197
|
validator
|
|
197
198
|
} = this.confirmationsPromiseMap[id];
|
|
198
|
-
const confirmation = confirmations[
|
|
199
|
+
const confirmation = confirmations[type][id];
|
|
199
200
|
if (!resolver || !confirmation) {
|
|
200
|
-
this.#logger.error('
|
|
201
|
-
throw new Error('
|
|
201
|
+
this.#logger.error(t('Unable to proceed. Please try again'), type, id);
|
|
202
|
+
throw new Error(t('Unable to proceed. Please try again'));
|
|
202
203
|
}
|
|
203
204
|
|
|
204
205
|
// Fill signature for some special type
|
|
205
|
-
await this.decorateResult(
|
|
206
|
+
await this.decorateResult(type, confirmation, result);
|
|
206
207
|
|
|
207
208
|
// Validate response from confirmation popup some info like password, response format....
|
|
208
209
|
const error = validator && validator(result);
|
|
@@ -212,7 +213,7 @@ export default class EvmRequestHandler {
|
|
|
212
213
|
|
|
213
214
|
// Delete confirmations from queue
|
|
214
215
|
delete this.confirmationsPromiseMap[id];
|
|
215
|
-
delete confirmations[
|
|
216
|
+
delete confirmations[type][id];
|
|
216
217
|
this.confirmationsQueueSubject.next(confirmations);
|
|
217
218
|
|
|
218
219
|
// Update icon, and close queue
|
|
@@ -3,6 +3,7 @@ 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;
|
|
@@ -1,22 +1,34 @@
|
|
|
1
1
|
// Copyright 2019-2022 @subwallet/extension-base authors & contributors
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
+
import { LANGUAGE } from '@subwallet/extension-base/constants';
|
|
4
5
|
import PassPhishingStore from '@subwallet/extension-base/stores/PassPhishingStore';
|
|
5
6
|
import SettingsStore from '@subwallet/extension-base/stores/Settings';
|
|
7
|
+
import i18n from "./i18n/i18n.js";
|
|
6
8
|
import { DEFAULT_SETTING } from "./constants.js";
|
|
7
9
|
export default class SettingService {
|
|
8
10
|
settingsStore = new SettingsStore();
|
|
9
11
|
passPhishingStore = new PassPhishingStore();
|
|
12
|
+
constructor() {
|
|
13
|
+
let old = localStorage.getItem(LANGUAGE) || 'en';
|
|
14
|
+
this.settingsStore.getSubject().subscribe(({
|
|
15
|
+
language
|
|
16
|
+
}) => {
|
|
17
|
+
if (language !== old) {
|
|
18
|
+
old = language;
|
|
19
|
+
i18n.changeLanguage(language).catch(console.error);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
10
23
|
getSubject() {
|
|
11
24
|
return this.settingsStore.getSubject();
|
|
12
25
|
}
|
|
13
26
|
getSettings(update) {
|
|
14
27
|
this.settingsStore.get('Settings', value => {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
28
|
+
update({
|
|
29
|
+
...DEFAULT_SETTING,
|
|
30
|
+
...(value || {})
|
|
31
|
+
});
|
|
20
32
|
});
|
|
21
33
|
}
|
|
22
34
|
setSettings(data, callback) {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { BrowserConfirmationType, LanguageType, ThemeNames, UiSettings } from '@subwallet/extension-base/background/KoniTypes';
|
|
1
|
+
import { BrowserConfirmationType, LanguageType, ThemeNames, UiSettings, WalletUnlockType } from '@subwallet/extension-base/background/KoniTypes';
|
|
2
2
|
export declare const DEFAULT_THEME: ThemeNames;
|
|
3
3
|
export declare const DEFAULT_NOTIFICATION_TYPE: BrowserConfirmationType;
|
|
4
4
|
export declare const DEFAULT_AUTO_LOCK_TIME = 15;
|
|
5
|
+
export declare const DEFAULT_UNLOCK_TYPE: WalletUnlockType;
|
|
5
6
|
export declare const DEFAULT_CHAIN_PATROL_ENABLE = false;
|
|
6
7
|
export declare const DEFAULT_LANGUAGE: LanguageType;
|
|
7
8
|
export declare const DEFAULT_SHOW_ZERO_BALANCE = true;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
// Copyright 2019-2022 @subwallet/extension-koni authors & contributors
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
-
import { ThemeNames } from '@subwallet/extension-base/background/KoniTypes';
|
|
4
|
+
import { ThemeNames, WalletUnlockType } from '@subwallet/extension-base/background/KoniTypes';
|
|
5
|
+
import { TARGET_ENV } from '@subwallet/extension-base/utils';
|
|
5
6
|
export const DEFAULT_THEME = ThemeNames.DARK;
|
|
6
7
|
export const DEFAULT_NOTIFICATION_TYPE = 'popup';
|
|
7
8
|
export const DEFAULT_AUTO_LOCK_TIME = 15;
|
|
9
|
+
export const DEFAULT_UNLOCK_TYPE = TARGET_ENV === 'extension' ? WalletUnlockType.ALWAYS_REQUIRED : WalletUnlockType.WHEN_NEEDED;
|
|
8
10
|
export const DEFAULT_CHAIN_PATROL_ENABLE = false;
|
|
9
11
|
export const DEFAULT_LANGUAGE = 'en';
|
|
10
12
|
export const DEFAULT_SHOW_ZERO_BALANCE = true;
|
|
@@ -18,6 +20,7 @@ export const DEFAULT_SETTING = {
|
|
|
18
20
|
isShowBalance: DEFAULT_SHOW_BALANCE,
|
|
19
21
|
accountAllLogo: DEFAULT_ALL_LOGO,
|
|
20
22
|
theme: DEFAULT_THEME,
|
|
23
|
+
unlockType: DEFAULT_UNLOCK_TYPE,
|
|
21
24
|
camera: DEFAULT_CAMERA_ENABLE,
|
|
22
25
|
timeAutoLock: DEFAULT_AUTO_LOCK_TIME,
|
|
23
26
|
enableChainPatrol: DEFAULT_CHAIN_PATROL_ENABLE,
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
declare type Callback = (error: string | null, data: unknown) => void;
|
|
2
|
+
declare type LoadResult = [string | null, Record<string, string> | boolean];
|
|
3
|
+
export default class Backend {
|
|
4
|
+
type: string;
|
|
5
|
+
static type: 'backend';
|
|
6
|
+
read(lng: string, _namespace: string, responder: Callback): Promise<void>;
|
|
7
|
+
createLoader(lng: string): Promise<LoadResult>;
|
|
8
|
+
}
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// Copyright 2017-2022 @polkadot/react-components authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import languageCache from "./cache.js";
|
|
5
|
+
const loaders = {};
|
|
6
|
+
export default class Backend {
|
|
7
|
+
type = 'backend';
|
|
8
|
+
static type = 'backend';
|
|
9
|
+
async read(lng, _namespace, responder) {
|
|
10
|
+
if (languageCache[lng]) {
|
|
11
|
+
return responder(null, languageCache[lng]);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
15
|
+
if (!loaders[lng]) {
|
|
16
|
+
loaders[lng] = this.createLoader(lng);
|
|
17
|
+
}
|
|
18
|
+
const [error, data] = await loaders[lng];
|
|
19
|
+
return responder(error, data);
|
|
20
|
+
}
|
|
21
|
+
async createLoader(lng) {
|
|
22
|
+
try {
|
|
23
|
+
const response = await fetch(`locales/${lng}/translation.json`, {});
|
|
24
|
+
if (!response.ok) {
|
|
25
|
+
return [`i18n: failed loading ${lng}`, response.status >= 500 && response.status < 600];
|
|
26
|
+
} else {
|
|
27
|
+
languageCache[lng] = await response.json();
|
|
28
|
+
return [null, languageCache[lng]];
|
|
29
|
+
}
|
|
30
|
+
} catch (error) {
|
|
31
|
+
return [error.message, false];
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// Copyright 2017-2022 @subwallet/extension-base authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { detectTranslate } from '@subwallet/extension-base/utils';
|
|
5
|
+
export const ExternalTranslation = [
|
|
6
|
+
// Case change password
|
|
7
|
+
detectTranslate('Invalid master password')];
|
|
8
|
+
export const InternalTranslation = [];
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Copyright 2019-2022 @polkadot/extension-ui authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { LANGUAGE } from '@subwallet/extension-base/constants';
|
|
5
|
+
import i18next from 'i18next';
|
|
6
|
+
import Backend from "./Backend.js";
|
|
7
|
+
i18next.use(Backend).init({
|
|
8
|
+
backend: {},
|
|
9
|
+
debug: false,
|
|
10
|
+
fallbackLng: 'en',
|
|
11
|
+
interpolation: {
|
|
12
|
+
escapeValue: false
|
|
13
|
+
},
|
|
14
|
+
keySeparator: false,
|
|
15
|
+
lng: localStorage.getItem(LANGUAGE) || 'en',
|
|
16
|
+
load: 'languageOnly',
|
|
17
|
+
nsSeparator: false,
|
|
18
|
+
returnEmptyString: false,
|
|
19
|
+
returnNull: false
|
|
20
|
+
}).catch(error => console.log('i18n: failure', error));
|
|
21
|
+
export default i18next;
|
|
@@ -22,6 +22,7 @@ import BigN from 'bignumber.js';
|
|
|
22
22
|
import { addHexPrefix } from 'ethereumjs-util';
|
|
23
23
|
import { ethers } from 'ethers';
|
|
24
24
|
import EventEmitter from 'eventemitter3';
|
|
25
|
+
import { t } from 'i18next';
|
|
25
26
|
import { BehaviorSubject } from 'rxjs';
|
|
26
27
|
import { isHex } from '@polkadot/util';
|
|
27
28
|
export default class TransactionService {
|
|
@@ -90,7 +91,7 @@ export default class TransactionService {
|
|
|
90
91
|
};
|
|
91
92
|
const chainInfo = this.chainService.getChainInfoByKey(chain);
|
|
92
93
|
if (!chainInfo) {
|
|
93
|
-
validationResponse.errors.push(new TransactionError(BasicTxErrorType.INTERNAL_ERROR,
|
|
94
|
+
validationResponse.errors.push(new TransactionError(BasicTxErrorType.INTERNAL_ERROR, t('Cannot find network')));
|
|
94
95
|
} else {
|
|
95
96
|
const {
|
|
96
97
|
decimals,
|
|
@@ -105,7 +106,7 @@ export default class TransactionService {
|
|
|
105
106
|
} else {
|
|
106
107
|
const web3 = this.chainService.getEvmApi(chain);
|
|
107
108
|
if (!web3) {
|
|
108
|
-
validationResponse.errors.push(new TransactionError(BasicTxErrorType.CHAIN_DISCONNECTED));
|
|
109
|
+
validationResponse.errors.push(new TransactionError(BasicTxErrorType.CHAIN_DISCONNECTED, undefined));
|
|
109
110
|
} else {
|
|
110
111
|
const gasPrice = await web3.api.eth.getGasPrice();
|
|
111
112
|
const gasLimit = await web3.api.eth.estimateGas(transaction);
|
|
@@ -126,11 +127,11 @@ export default class TransactionService {
|
|
|
126
127
|
// Read-only account
|
|
127
128
|
const pair = keyring.getPair(address);
|
|
128
129
|
if (!pair) {
|
|
129
|
-
validationResponse.errors.push(new TransactionError(BasicTxErrorType.INTERNAL_ERROR, '
|
|
130
|
+
validationResponse.errors.push(new TransactionError(BasicTxErrorType.INTERNAL_ERROR, t('Unable to find account')));
|
|
130
131
|
} else {
|
|
131
132
|
var _pair$meta;
|
|
132
133
|
if ((_pair$meta = pair.meta) !== null && _pair$meta !== void 0 && _pair$meta.isReadOnly) {
|
|
133
|
-
validationResponse.errors.push(new TransactionError(BasicTxErrorType.INTERNAL_ERROR, 'This is watch-only
|
|
134
|
+
validationResponse.errors.push(new TransactionError(BasicTxErrorType.INTERNAL_ERROR, t('This account is watch-only')));
|
|
134
135
|
}
|
|
135
136
|
}
|
|
136
137
|
|
|
@@ -159,9 +160,9 @@ export default class TransactionService {
|
|
|
159
160
|
if (!isTransferAll) {
|
|
160
161
|
if (balanceNum - (transferNativeNum + feeNum) < edNum) {
|
|
161
162
|
if (edAsWarning) {
|
|
162
|
-
validationResponse.warnings.push(new TransactionWarning(BasicTxWarningCode.NOT_ENOUGH_EXISTENTIAL_DEPOSIT
|
|
163
|
+
validationResponse.warnings.push(new TransactionWarning(BasicTxWarningCode.NOT_ENOUGH_EXISTENTIAL_DEPOSIT));
|
|
163
164
|
} else {
|
|
164
|
-
validationResponse.errors.push(new TransactionError(BasicTxErrorType.NOT_ENOUGH_EXISTENTIAL_DEPOSIT
|
|
165
|
+
validationResponse.errors.push(new TransactionError(BasicTxErrorType.NOT_ENOUGH_EXISTENTIAL_DEPOSIT));
|
|
165
166
|
}
|
|
166
167
|
}
|
|
167
168
|
}
|
|
@@ -582,8 +583,12 @@ export default class TransactionService {
|
|
|
582
583
|
const info = isHex(extrinsicHash) ? extrinsicHash : getBaseTransactionInfo(transaction, this.chainService.getChainInfoMap());
|
|
583
584
|
this.notificationService.notify({
|
|
584
585
|
type: NotificationType.SUCCESS,
|
|
585
|
-
title: 'Transaction completed',
|
|
586
|
-
message:
|
|
586
|
+
title: t('Transaction completed'),
|
|
587
|
+
message: t('Transaction {{info}} completed', {
|
|
588
|
+
replace: {
|
|
589
|
+
info
|
|
590
|
+
}
|
|
591
|
+
}),
|
|
587
592
|
action: {
|
|
588
593
|
url: this.getTransactionLink(id)
|
|
589
594
|
},
|
|
@@ -617,8 +622,12 @@ export default class TransactionService {
|
|
|
617
622
|
const info = isHex(transaction === null || transaction === void 0 ? void 0 : transaction.extrinsicHash) ? transaction === null || transaction === void 0 ? void 0 : transaction.extrinsicHash : getBaseTransactionInfo(transaction, this.chainService.getChainInfoMap());
|
|
618
623
|
this.notificationService.notify({
|
|
619
624
|
type: NotificationType.ERROR,
|
|
620
|
-
title: 'Transaction failed',
|
|
621
|
-
message:
|
|
625
|
+
title: t('Transaction failed'),
|
|
626
|
+
message: t('Transaction {{info}} failed', {
|
|
627
|
+
replace: {
|
|
628
|
+
info
|
|
629
|
+
}
|
|
630
|
+
}),
|
|
622
631
|
action: {
|
|
623
632
|
url: this.getTransactionLink(id)
|
|
624
633
|
},
|
|
@@ -721,7 +730,7 @@ export default class TransactionService {
|
|
|
721
730
|
if (isApproved) {
|
|
722
731
|
let signedTransaction;
|
|
723
732
|
if (!payload) {
|
|
724
|
-
throw new EvmProviderError(EvmProviderErrorType.UNAUTHORIZED, '
|
|
733
|
+
throw new EvmProviderError(EvmProviderErrorType.UNAUTHORIZED, t('Failed to sign'));
|
|
725
734
|
}
|
|
726
735
|
const web3Api = this.chainService.getEvmApi(chain).api;
|
|
727
736
|
if (!isExternal) {
|
|
@@ -730,7 +739,7 @@ export default class TransactionService {
|
|
|
730
739
|
const signed = mergeTransactionAndSignature(txObject, payload);
|
|
731
740
|
const recover = web3Api.eth.accounts.recoverTransaction(signed);
|
|
732
741
|
if (recover.toLowerCase() !== account.address.toLowerCase()) {
|
|
733
|
-
throw new EvmProviderError(EvmProviderErrorType.UNAUTHORIZED, '
|
|
742
|
+
throw new EvmProviderError(EvmProviderErrorType.UNAUTHORIZED, t('Wrong signature. Please sign with the account you use in dApp'));
|
|
734
743
|
}
|
|
735
744
|
signedTransaction = signed;
|
|
736
745
|
}
|
|
@@ -754,10 +763,10 @@ export default class TransactionService {
|
|
|
754
763
|
eventData.blockNumber = rs.blockNumber;
|
|
755
764
|
emitter.emit('success', eventData);
|
|
756
765
|
}).once('error', e => {
|
|
757
|
-
eventData.errors.push(new TransactionError(BasicTxErrorType.SEND_TRANSACTION_FAILED, e.message));
|
|
766
|
+
eventData.errors.push(new TransactionError(BasicTxErrorType.SEND_TRANSACTION_FAILED, t(e.message)));
|
|
758
767
|
emitter.emit('error', eventData);
|
|
759
768
|
}).catch(e => {
|
|
760
|
-
eventData.errors.push(new TransactionError(BasicTxErrorType.UNABLE_TO_SEND, e.message));
|
|
769
|
+
eventData.errors.push(new TransactionError(BasicTxErrorType.UNABLE_TO_SEND, t(e.message)));
|
|
761
770
|
emitter.emit('error', eventData);
|
|
762
771
|
});
|
|
763
772
|
} else {
|
|
@@ -767,7 +776,7 @@ export default class TransactionService {
|
|
|
767
776
|
}
|
|
768
777
|
}).catch(e => {
|
|
769
778
|
this.removeTransaction(id);
|
|
770
|
-
eventData.errors.push(new TransactionError(BasicTxErrorType.UNABLE_TO_SIGN, e.message));
|
|
779
|
+
eventData.errors.push(new TransactionError(BasicTxErrorType.UNABLE_TO_SIGN, t(e.message)));
|
|
771
780
|
emitter.emit('error', eventData);
|
|
772
781
|
});
|
|
773
782
|
return emitter;
|
|
@@ -857,7 +866,7 @@ export default class TransactionService {
|
|
|
857
866
|
const timeout = setTimeout(() => {
|
|
858
867
|
const transaction = this.getTransaction(eventData.id);
|
|
859
868
|
if (transaction.status !== ExtrinsicStatus.SUCCESS && transaction.status !== ExtrinsicStatus.FAIL) {
|
|
860
|
-
eventData.errors.push(new TransactionError(BasicTxErrorType.TIMEOUT, 'Transaction timeout'));
|
|
869
|
+
eventData.errors.push(new TransactionError(BasicTxErrorType.TIMEOUT, t('Transaction timeout')));
|
|
861
870
|
emitter.emit('error', eventData);
|
|
862
871
|
clearTimeout(timeout);
|
|
863
872
|
}
|