@subwallet/extension-base 0.8.1-wr2x → 0.8.1-wr3
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 +31 -1
- package/background/KoniTypes.js +15 -1
- package/background/errors/BalanceError.d.ts +6 -0
- package/background/errors/BalanceError.js +33 -0
- package/background/handlers/State.js +2 -1
- package/cjs/background/KoniTypes.js +18 -2
- package/cjs/background/errors/BalanceError.js +39 -0
- package/cjs/background/handlers/State.js +2 -1
- package/cjs/koni/api/dotsama/balance.js +1 -0
- package/cjs/koni/background/handlers/Extension.js +140 -94
- package/cjs/koni/background/handlers/State.js +15 -11
- package/cjs/services/balance-service/index.js +95 -2
- package/cjs/services/chain-service/utils.js +13 -3
- package/cjs/services/notification-service/NotificationService.js +23 -1
- package/cjs/services/request-service/handler/PopupHandler.js +10 -16
- package/cjs/services/request-service/index.js +2 -6
- package/cjs/services/setting-service/SettingService.js +2 -1
- package/cjs/services/storage-service/DatabaseService.js +3 -2
- package/cjs/services/storage-service/db-stores/Balance.js +0 -25
- package/cjs/services/transaction-service/index.js +22 -6
- package/koni/api/dotsama/balance.d.ts +1 -0
- package/koni/api/dotsama/balance.js +1 -1
- package/koni/background/handlers/Extension.d.ts +4 -0
- package/koni/background/handlers/Extension.js +58 -14
- package/koni/background/handlers/State.d.ts +3 -1
- package/koni/background/handlers/State.js +15 -11
- package/package.json +8 -3
- package/services/balance-service/index.d.ts +7 -5
- package/services/balance-service/index.js +95 -2
- package/services/chain-service/utils.d.ts +1 -1
- package/services/chain-service/utils.js +13 -3
- package/services/notification-service/NotificationService.d.ts +6 -1
- package/services/notification-service/NotificationService.js +23 -1
- package/services/request-service/handler/PopupHandler.d.ts +0 -1
- package/services/request-service/handler/PopupHandler.js +10 -15
- package/services/request-service/index.d.ts +3 -2
- package/services/request-service/index.js +2 -6
- package/services/setting-service/SettingService.js +2 -1
- package/services/storage-service/DatabaseService.d.ts +2 -1
- package/services/storage-service/DatabaseService.js +3 -2
- package/services/storage-service/db-stores/Balance.js +0 -25
- package/services/transaction-service/index.d.ts +3 -1
- package/services/transaction-service/index.js +23 -7
- package/cjs/background/errors/EvmRpcError.js +0 -21
- package/cjs/background/errors/SubWalletProviderError.js +0 -17
- package/cjs/constants/ethereum.js +0 -19
- package/cjs/utils/eth/parseTransactionData.js +0 -284
|
@@ -9,7 +9,6 @@ import { createSubscription } from '@subwallet/extension-base/background/handler
|
|
|
9
9
|
import { AccountExternalErrorCode, BasicTxErrorType, ChainType, ExternalRequestPromiseStatus, ExtrinsicType, TransferTxErrorType } from '@subwallet/extension-base/background/KoniTypes';
|
|
10
10
|
import { ALL_ACCOUNT_KEY, ALL_GENESIS_HASH } from '@subwallet/extension-base/constants';
|
|
11
11
|
import { ALLOWED_PATH } from '@subwallet/extension-base/defaults';
|
|
12
|
-
import { getFreeBalance, subscribeFreeBalance } from '@subwallet/extension-base/koni/api/dotsama/balance';
|
|
13
12
|
import { parseSubstrateTransaction } from '@subwallet/extension-base/koni/api/dotsama/parseTransaction';
|
|
14
13
|
import { checkReferenceCount, checkSupportTransfer, createTransferExtrinsic } from '@subwallet/extension-base/koni/api/dotsama/transfer';
|
|
15
14
|
import { getNftTransferExtrinsic, isRecipientSelf } from '@subwallet/extension-base/koni/api/nft/transfer';
|
|
@@ -574,6 +573,14 @@ export default class KoniExtension {
|
|
|
574
573
|
const transformedAccounts = transformAccounts(storedAccounts);
|
|
575
574
|
return transformedAccounts.filter(a => !a.isReadOnly).map(a => a.address);
|
|
576
575
|
}
|
|
576
|
+
isAddressValidWithAuthType(address, accountAuthType) {
|
|
577
|
+
if (accountAuthType === 'substrate') {
|
|
578
|
+
return !isEthereumAddress(address);
|
|
579
|
+
} else if (accountAuthType === 'evm') {
|
|
580
|
+
return isEthereumAddress(address);
|
|
581
|
+
}
|
|
582
|
+
return true;
|
|
583
|
+
}
|
|
577
584
|
filterAccountsByAccountAuthType(accounts, accountAuthType) {
|
|
578
585
|
if (accountAuthType === 'substrate') {
|
|
579
586
|
return accounts.filter(address => !isEthereumAddress(address));
|
|
@@ -647,11 +654,15 @@ export default class KoniExtension {
|
|
|
647
654
|
_changeAuthorizationPerAcc(address, connectValue, url, callBack) {
|
|
648
655
|
this.#koniState.getAuthorize(value => {
|
|
649
656
|
assert(value, 'The source is not known');
|
|
650
|
-
value[url].
|
|
651
|
-
|
|
652
|
-
|
|
657
|
+
if (this.isAddressValidWithAuthType(address, value[url].accountAuthType)) {
|
|
658
|
+
value[url].isAllowedMap[address] = connectValue;
|
|
659
|
+
console.log('Devbu: ', value);
|
|
660
|
+
this.#koniState.setAuthorize(value, () => {
|
|
661
|
+
callBack && callBack(value);
|
|
662
|
+
});
|
|
663
|
+
} else {
|
|
653
664
|
callBack && callBack(value);
|
|
654
|
-
}
|
|
665
|
+
}
|
|
655
666
|
});
|
|
656
667
|
}
|
|
657
668
|
_changeAuthorizationBlock(connectValue, id) {
|
|
@@ -737,6 +748,12 @@ export default class KoniExtension {
|
|
|
737
748
|
});
|
|
738
749
|
return true;
|
|
739
750
|
}
|
|
751
|
+
setCamera({
|
|
752
|
+
camera
|
|
753
|
+
}) {
|
|
754
|
+
this.#koniState.setCamera(camera);
|
|
755
|
+
return true;
|
|
756
|
+
}
|
|
740
757
|
saveBrowserConfirmationType(data, id, port) {
|
|
741
758
|
const cb = createSubscription(id, port);
|
|
742
759
|
this.#koniState.setBrowserConfirmationType(data, cb);
|
|
@@ -914,7 +931,9 @@ export default class KoniExtension {
|
|
|
914
931
|
this.#koniState.getAuthorize(value => {
|
|
915
932
|
if (value && Object.keys(value).length) {
|
|
916
933
|
Object.keys(value).forEach(url => {
|
|
917
|
-
value[url].
|
|
934
|
+
if (this.isAddressValidWithAuthType(address, value[url].accountAuthType)) {
|
|
935
|
+
value[url].isAllowedMap[address] = isAllowed;
|
|
936
|
+
}
|
|
918
937
|
});
|
|
919
938
|
this.#koniState.setAuthorize(value);
|
|
920
939
|
}
|
|
@@ -1327,7 +1346,6 @@ export default class KoniExtension {
|
|
|
1327
1346
|
} = inputData;
|
|
1328
1347
|
const [errors,,, tokenInfo] = this.validateTransfer(tokenSlug, from, to, value, transferAll);
|
|
1329
1348
|
const warnings = [];
|
|
1330
|
-
const substrateApiMap = this.#koniState.getSubstrateApiMap();
|
|
1331
1349
|
const evmApiMap = this.#koniState.getEvmApiMap();
|
|
1332
1350
|
const chainInfo = this.#koniState.getChainInfo(networkKey);
|
|
1333
1351
|
const nativeTokenInfo = this.#koniState.getNativeTokenInfo(networkKey);
|
|
@@ -1345,10 +1363,10 @@ export default class KoniExtension {
|
|
|
1345
1363
|
let transaction;
|
|
1346
1364
|
|
|
1347
1365
|
// Get native token amount
|
|
1348
|
-
const freeBalance = await
|
|
1366
|
+
const freeBalance = await this.#koniState.balanceService.getTokenFreeBalance(from, networkKey, tokenSlug);
|
|
1349
1367
|
if (isEthereumAddress(from) && isEthereumAddress(to)) {
|
|
1350
1368
|
chainType = ChainType.EVM;
|
|
1351
|
-
const txVal = transferAll ? freeBalance : value || '0';
|
|
1369
|
+
const txVal = transferAll ? freeBalance.value : value || '0';
|
|
1352
1370
|
|
|
1353
1371
|
// Estimate with EVM API
|
|
1354
1372
|
if (_isTokenEvmSmartContract(tokenInfo)) {
|
|
@@ -1371,7 +1389,7 @@ export default class KoniExtension {
|
|
|
1371
1389
|
|
|
1372
1390
|
// Additional validator
|
|
1373
1391
|
const additionalValidator = swTran => {
|
|
1374
|
-
if (new BN(freeBalance).lt(new BN(transferAmount.value))) {
|
|
1392
|
+
if (new BN(freeBalance.value).lt(new BN(transferAmount.value))) {
|
|
1375
1393
|
var _swTran$errors;
|
|
1376
1394
|
(_swTran$errors = swTran.errors) === null || _swTran$errors === void 0 ? void 0 : _swTran$errors.push(new TransactionError(BasicTxErrorType.NOT_ENOUGH_BALANCE));
|
|
1377
1395
|
}
|
|
@@ -1518,17 +1536,25 @@ export default class KoniExtension {
|
|
|
1518
1536
|
async validateCustomAsset(data) {
|
|
1519
1537
|
return await this.#koniState.validateCustomAsset(data);
|
|
1520
1538
|
}
|
|
1539
|
+
async getAddressFreeBalance({
|
|
1540
|
+
address,
|
|
1541
|
+
networkKey,
|
|
1542
|
+
token
|
|
1543
|
+
}) {
|
|
1544
|
+
return await this.#koniState.balanceService.getTokenFreeBalance(address, networkKey, token);
|
|
1545
|
+
}
|
|
1521
1546
|
async subscribeAddressFreeBalance({
|
|
1522
1547
|
address,
|
|
1523
1548
|
networkKey,
|
|
1524
1549
|
token
|
|
1525
1550
|
}, id, port) {
|
|
1526
1551
|
const cb = createSubscription(id, port);
|
|
1527
|
-
|
|
1552
|
+
const [unsub, currentFreeBalance] = await this.#koniState.balanceService.subscribeTokenFreeBalance(address, networkKey, token, cb);
|
|
1553
|
+
this.createUnsubscriptionHandle(id, unsub);
|
|
1528
1554
|
port.onDisconnect.addListener(() => {
|
|
1529
1555
|
this.cancelSubscription(id);
|
|
1530
1556
|
});
|
|
1531
|
-
return
|
|
1557
|
+
return currentFreeBalance;
|
|
1532
1558
|
}
|
|
1533
1559
|
async transferCheckReferenceCount({
|
|
1534
1560
|
address,
|
|
@@ -2695,6 +2721,18 @@ export default class KoniExtension {
|
|
|
2695
2721
|
});
|
|
2696
2722
|
return convertRs(transactionsSubject.getValue());
|
|
2697
2723
|
}
|
|
2724
|
+
subscribeNotifications(id, port) {
|
|
2725
|
+
const cb = createSubscription(id, port);
|
|
2726
|
+
const notificationSubject = this.#koniState.notificationService.getNotificationSubject();
|
|
2727
|
+
const notificationSubscription = notificationSubject.subscribe(rs => {
|
|
2728
|
+
cb(rs);
|
|
2729
|
+
});
|
|
2730
|
+
port.onDisconnect.addListener(() => {
|
|
2731
|
+
notificationSubscription.unsubscribe();
|
|
2732
|
+
this.cancelSubscription(id);
|
|
2733
|
+
});
|
|
2734
|
+
return notificationSubject.value;
|
|
2735
|
+
}
|
|
2698
2736
|
|
|
2699
2737
|
// --------------------------------------------------------------
|
|
2700
2738
|
// eslint-disable-next-line @typescript-eslint/require-await
|
|
@@ -2743,8 +2781,6 @@ export default class KoniExtension {
|
|
|
2743
2781
|
return this.seedCreate(request);
|
|
2744
2782
|
case 'pri(seed.validate)':
|
|
2745
2783
|
return this.seedValidate(request);
|
|
2746
|
-
case 'pri(settings.notification)':
|
|
2747
|
-
return this.#koniState.setNotification(request);
|
|
2748
2784
|
case 'pri(signing.approve.signature)':
|
|
2749
2785
|
return this.signingApproveSignature(request);
|
|
2750
2786
|
case 'pri(signing.cancel)':
|
|
@@ -2821,6 +2857,8 @@ export default class KoniExtension {
|
|
|
2821
2857
|
return await this.subscribeSettings(id, port);
|
|
2822
2858
|
case 'pri(settings.saveAccountAllLogo)':
|
|
2823
2859
|
return this.saveAccountAllLogo(request, id, port);
|
|
2860
|
+
case 'pri(settings.saveCamera)':
|
|
2861
|
+
return this.setCamera(request);
|
|
2824
2862
|
case 'pri(settings.saveTheme)':
|
|
2825
2863
|
return this.saveTheme(request, id, port);
|
|
2826
2864
|
case 'pri(settings.saveBrowserConfirmationType)':
|
|
@@ -2903,6 +2941,8 @@ export default class KoniExtension {
|
|
|
2903
2941
|
return await this.transferCheckSupporting(request);
|
|
2904
2942
|
case 'pri(transfer.getExistentialDeposit)':
|
|
2905
2943
|
return this.transferGetExistentialDeposit(request);
|
|
2944
|
+
case 'pri(freeBalance.get)':
|
|
2945
|
+
return this.getAddressFreeBalance(request);
|
|
2906
2946
|
case 'pri(freeBalance.subscribe)':
|
|
2907
2947
|
return this.subscribeAddressFreeBalance(request, id, port);
|
|
2908
2948
|
case 'pri(subscription.cancel)':
|
|
@@ -3030,6 +3070,10 @@ export default class KoniExtension {
|
|
|
3030
3070
|
case 'pri(transactions.subscribe)':
|
|
3031
3071
|
return this.subscribeTransactions(id, port);
|
|
3032
3072
|
|
|
3073
|
+
// Notification
|
|
3074
|
+
case 'pri(notifications.subscribe)':
|
|
3075
|
+
return this.subscribeNotifications(id, port);
|
|
3076
|
+
|
|
3033
3077
|
// Default
|
|
3034
3078
|
default:
|
|
3035
3079
|
throw new Error(`Unable to handle message of type ${type}`);
|
|
@@ -5,6 +5,7 @@ import { AccountJson, RequestAuthorizeTab, RequestRpcSend, RequestRpcSubscribe,
|
|
|
5
5
|
import { BalanceService } from '@subwallet/extension-base/services/balance-service';
|
|
6
6
|
import { _ChainConnectionStatus, _ChainState, _NetworkUpsertParams, _ValidateCustomAssetRequest } from '@subwallet/extension-base/services/chain-service/types';
|
|
7
7
|
import { HistoryService } from '@subwallet/extension-base/services/history-service';
|
|
8
|
+
import NotificationService from '@subwallet/extension-base/services/notification-service/NotificationService';
|
|
8
9
|
import { PriceService } from '@subwallet/extension-base/services/price-service';
|
|
9
10
|
import { AuthUrls, MetaRequest, SignRequest } from '@subwallet/extension-base/services/request-service/types';
|
|
10
11
|
import DatabaseService from '@subwallet/extension-base/services/storage-service/DatabaseService';
|
|
@@ -41,6 +42,7 @@ export default class KoniState {
|
|
|
41
42
|
private stakingRewardSubject;
|
|
42
43
|
private stakingRewardState;
|
|
43
44
|
private lazyMap;
|
|
45
|
+
readonly notificationService: NotificationService;
|
|
44
46
|
private chainService;
|
|
45
47
|
dbService: DatabaseService;
|
|
46
48
|
private cron;
|
|
@@ -65,7 +67,6 @@ export default class KoniState {
|
|
|
65
67
|
rpcSubscribeConnected(_request: null, cb: ProviderInterfaceCallback, port: chrome.runtime.Port): void;
|
|
66
68
|
rpcUnsubscribe(request: RequestRpcUnsubscribe, port: chrome.runtime.Port): Promise<boolean>;
|
|
67
69
|
saveMetadata(meta: MetadataDef): void;
|
|
68
|
-
setNotification(notification: string): boolean;
|
|
69
70
|
sign(url: string, request: RequestSign, account: AccountJson): Promise<ResponseSigning>;
|
|
70
71
|
get authSubjectV2(): BehaviorSubject<import("@subwallet/extension-base/background/types").AuthorizeRequest[]>;
|
|
71
72
|
generateDefaultBalanceMap(): Record<string, BalanceItem>;
|
|
@@ -137,6 +138,7 @@ export default class KoniState {
|
|
|
137
138
|
setSettings(settings: UiSettings, callback?: () => void): void;
|
|
138
139
|
setTheme(theme: ThemeNames, callback?: (settingData: UiSettings) => void): void;
|
|
139
140
|
setBrowserConfirmationType(browserConfirmationType: BrowserConfirmationType, callback?: (settingData: UiSettings) => void): void;
|
|
141
|
+
setCamera(value: boolean): void;
|
|
140
142
|
subscribeSettingsSubject(): Subject<RequestSettingsType>;
|
|
141
143
|
subscribeCurrentAccount(): Subject<CurrentAccountInfo>;
|
|
142
144
|
getAccountAddress(): Promise<string | null | undefined>;
|
|
@@ -7,12 +7,12 @@ import { withErrorLog } from '@subwallet/extension-base/background/handlers/help
|
|
|
7
7
|
import { isSubscriptionRunning, unsubscribe } from '@subwallet/extension-base/background/handlers/subscriptions';
|
|
8
8
|
import { APIItemState, BasicTxErrorType, ChainType, EvmProviderErrorType, ExternalRequestPromiseStatus, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
|
|
9
9
|
import { ALL_ACCOUNT_KEY, ALL_GENESIS_HASH } from '@subwallet/extension-base/constants';
|
|
10
|
-
import { getFreeBalance } from '@subwallet/extension-base/koni/api/dotsama/balance';
|
|
11
10
|
import { BalanceService } from '@subwallet/extension-base/services/balance-service';
|
|
12
11
|
import { ChainService } from '@subwallet/extension-base/services/chain-service';
|
|
13
12
|
import { _PREDEFINED_SINGLE_MODES } from '@subwallet/extension-base/services/chain-service/constants';
|
|
14
13
|
import { _getEvmChainId, _getSubstrateGenesisHash, _isAssetFungibleToken, _isChainEnabled, _isChainTestNet, _isSubstrateParachain, _parseMetadataForSmartContractAsset } from '@subwallet/extension-base/services/chain-service/utils';
|
|
15
14
|
import { HistoryService } from '@subwallet/extension-base/services/history-service';
|
|
15
|
+
import NotificationService from '@subwallet/extension-base/services/notification-service/NotificationService';
|
|
16
16
|
import { PriceService } from '@subwallet/extension-base/services/price-service';
|
|
17
17
|
import RequestService from '@subwallet/extension-base/services/request-service';
|
|
18
18
|
import SettingService from '@subwallet/extension-base/services/setting-service/SettingService';
|
|
@@ -86,21 +86,19 @@ export default class KoniState {
|
|
|
86
86
|
fastInterval: []
|
|
87
87
|
};
|
|
88
88
|
lazyMap = {};
|
|
89
|
-
|
|
90
|
-
// TODO: consider making chainService public (or getter) and call function directly
|
|
91
|
-
|
|
92
89
|
ready = false;
|
|
93
90
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
94
91
|
constructor(providers = {}) {
|
|
95
92
|
this.providers = providers;
|
|
96
93
|
this.dbService = new DatabaseService();
|
|
94
|
+
this.notificationService = new NotificationService();
|
|
97
95
|
this.chainService = new ChainService(this.dbService);
|
|
98
96
|
this.settingService = new SettingService();
|
|
99
|
-
this.requestService = new RequestService(this.chainService);
|
|
97
|
+
this.requestService = new RequestService(this.chainService, this.settingService);
|
|
100
98
|
this.priceService = new PriceService(this.dbService, this.chainService);
|
|
101
|
-
this.balanceService = new BalanceService(
|
|
99
|
+
this.balanceService = new BalanceService(this.chainService);
|
|
102
100
|
this.historyService = new HistoryService(this.dbService, this.chainService);
|
|
103
|
-
this.transactionService = new TransactionService(this.chainService, this.requestService, this.balanceService, this.historyService);
|
|
101
|
+
this.transactionService = new TransactionService(this.chainService, this.requestService, this.balanceService, this.historyService, this.notificationService);
|
|
104
102
|
this.subscription = new KoniSubscription(this, this.dbService);
|
|
105
103
|
this.cron = new KoniCron(this, this.subscription, this.dbService);
|
|
106
104
|
this.logger = createLogger('State');
|
|
@@ -178,10 +176,6 @@ export default class KoniState {
|
|
|
178
176
|
saveMetadata(meta) {
|
|
179
177
|
this.requestService.saveMetadata(meta);
|
|
180
178
|
}
|
|
181
|
-
setNotification(notification) {
|
|
182
|
-
this.requestService.setNotification(notification);
|
|
183
|
-
return true;
|
|
184
|
-
}
|
|
185
179
|
sign(url, request, account) {
|
|
186
180
|
return this.requestService.sign(url, request, account);
|
|
187
181
|
}
|
|
@@ -667,6 +661,16 @@ export default class KoniState {
|
|
|
667
661
|
});
|
|
668
662
|
});
|
|
669
663
|
}
|
|
664
|
+
setCamera(value) {
|
|
665
|
+
this.settingService.getSettings(settings => {
|
|
666
|
+
const newSettings = {
|
|
667
|
+
...settings,
|
|
668
|
+
camera: value
|
|
669
|
+
};
|
|
670
|
+
console.log(newSettings, value);
|
|
671
|
+
this.settingService.setSettings(newSettings);
|
|
672
|
+
});
|
|
673
|
+
}
|
|
670
674
|
subscribeSettingsSubject() {
|
|
671
675
|
return this.settingService.getSubject();
|
|
672
676
|
}
|
package/package.json
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"./cjs/detectPackage.js"
|
|
18
18
|
],
|
|
19
19
|
"type": "module",
|
|
20
|
-
"version": "0.8.1-
|
|
20
|
+
"version": "0.8.1-wr3",
|
|
21
21
|
"main": "./cjs/index.js",
|
|
22
22
|
"module": "./index.js",
|
|
23
23
|
"types": "./index.d.ts",
|
|
@@ -29,6 +29,11 @@
|
|
|
29
29
|
"require": "./cjs/index.js",
|
|
30
30
|
"default": "./index.js"
|
|
31
31
|
},
|
|
32
|
+
"./background/errors/BalanceError": {
|
|
33
|
+
"types": "./background/errors/BalanceError.d.ts",
|
|
34
|
+
"require": "./cjs/background/errors/BalanceError.js",
|
|
35
|
+
"default": "./background/errors/BalanceError.js"
|
|
36
|
+
},
|
|
32
37
|
"./background/errors/EvmProviderError": {
|
|
33
38
|
"types": "./background/errors/EvmProviderError.d.ts",
|
|
34
39
|
"require": "./cjs/background/errors/EvmProviderError.js",
|
|
@@ -1589,7 +1594,7 @@
|
|
|
1589
1594
|
"@polkadot/hw-ledger": "^10.1.9",
|
|
1590
1595
|
"@polkadot/keyring": "^10.2.1",
|
|
1591
1596
|
"@polkadot/networks": "^10.2.1",
|
|
1592
|
-
"@polkadot/phishing": "^0.
|
|
1597
|
+
"@polkadot/phishing": "^0.20.3",
|
|
1593
1598
|
"@polkadot/react-identicon": "^2.9.14",
|
|
1594
1599
|
"@polkadot/react-qr": "^2.9.14",
|
|
1595
1600
|
"@polkadot/rpc-provider": "^9.10.3",
|
|
@@ -1606,7 +1611,7 @@
|
|
|
1606
1611
|
"@sora-substrate/type-definitions": "^1.12.4",
|
|
1607
1612
|
"@subsocial/types": "^0.6.8",
|
|
1608
1613
|
"@substrate/connect": "^0.7.18",
|
|
1609
|
-
"@subwallet/chain-list": "^0.0.
|
|
1614
|
+
"@subwallet/chain-list": "^0.0.16",
|
|
1610
1615
|
"@subwallet/extension-base": "^0.8.1",
|
|
1611
1616
|
"@subwallet/extension-chains": "^0.8.1",
|
|
1612
1617
|
"@subwallet/extension-dapp": "^0.8.1",
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { AmountData, BalanceItem } from '@subwallet/extension-base/background/KoniTypes';
|
|
2
|
+
import { ChainService } from '@subwallet/extension-base/services/chain-service';
|
|
3
3
|
export declare class BalanceService {
|
|
4
|
-
|
|
5
|
-
constructor(
|
|
4
|
+
private chainService;
|
|
5
|
+
constructor(chainService: ChainService);
|
|
6
|
+
subscribeTokenFreeBalance(address: string, chain: string, tokenSlug: string | undefined, callback?: (rs: AmountData) => void): Promise<[() => void, AmountData]>;
|
|
7
|
+
getTokenFreeBalance(address: string, chain: string, tokenSlug?: string): Promise<AmountData>;
|
|
8
|
+
subscribeBalance(addresses: string[], chains: string[] | null, callback: (rs: BalanceItem) => void): () => void;
|
|
6
9
|
}
|
|
7
|
-
export {};
|
|
@@ -1,8 +1,101 @@
|
|
|
1
1
|
// Copyright 2019-2022 @subwallet/extension-base authors & contributors
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
+
import { BalanceError } from '@subwallet/extension-base/background/errors/BalanceError';
|
|
5
|
+
import { BalanceErrorType } from '@subwallet/extension-base/background/KoniTypes';
|
|
6
|
+
import { subscribeEVMBalance, subscribeSubstrateBalance } from '@subwallet/extension-base/koni/api/dotsama/balance';
|
|
7
|
+
import { state } from '@subwallet/extension-base/koni/background/handlers';
|
|
8
|
+
import { _PURE_EVM_CHAINS } from '@subwallet/extension-base/services/chain-service/constants';
|
|
9
|
+
import { _getChainNativeTokenSlug, _isChainEvmCompatible, _isPureEvmChain } from '@subwallet/extension-base/services/chain-service/utils';
|
|
10
|
+
import { categoryAddresses } from '@subwallet/extension-base/utils';
|
|
4
11
|
export class BalanceService {
|
|
5
|
-
constructor(
|
|
6
|
-
this.
|
|
12
|
+
constructor(chainService) {
|
|
13
|
+
this.chainService = chainService;
|
|
14
|
+
|
|
15
|
+
// Todo: Load data from db to balanceSubject
|
|
16
|
+
// Todo: Start subscribe balance and data
|
|
17
|
+
// Todo: Listen change and apply to balanceSubject
|
|
18
|
+
// Todo: Active/Chain
|
|
19
|
+
// Todo: Add/remove account
|
|
20
|
+
// Todo: Add new account
|
|
21
|
+
// Todo: Optimize get balance for single account and chain with cache
|
|
22
|
+
// Todo: Move everything of fetching balance to this service
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async subscribeTokenFreeBalance(address, chain, tokenSlug, callback) {
|
|
26
|
+
const chainInfo = this.chainService.getChainInfoByKey(chain);
|
|
27
|
+
const chainState = this.chainService.getChainStateByKey(chain);
|
|
28
|
+
if (!chainInfo || !chainState || !chainState.active) {
|
|
29
|
+
return Promise.reject(new BalanceError(BalanceErrorType.NETWORK_ERROR, `Chain ${chain} is not active`));
|
|
30
|
+
}
|
|
31
|
+
const tSlug = tokenSlug || _getChainNativeTokenSlug(chainInfo);
|
|
32
|
+
const tokenInfo = this.chainService.getAssetBySlug(tSlug);
|
|
33
|
+
if (!tokenInfo) {
|
|
34
|
+
return Promise.reject(new BalanceError(BalanceErrorType.TOKEN_ERROR, `Token ${tSlug} is not supported`));
|
|
35
|
+
}
|
|
36
|
+
return new Promise((resolve, reject) => {
|
|
37
|
+
let hasError = true;
|
|
38
|
+
const unsub = this.subscribeBalance([address], [chain], rs => {
|
|
39
|
+
if (rs.tokenSlug === tSlug) {
|
|
40
|
+
hasError = false;
|
|
41
|
+
const balance = {
|
|
42
|
+
value: rs.free,
|
|
43
|
+
decimals: tokenInfo.decimals || 0,
|
|
44
|
+
symbol: tokenInfo.symbol
|
|
45
|
+
};
|
|
46
|
+
if (callback) {
|
|
47
|
+
callback(balance);
|
|
48
|
+
} else {
|
|
49
|
+
// Auto unsubscribe if no callback
|
|
50
|
+
unsub();
|
|
51
|
+
}
|
|
52
|
+
resolve([unsub, balance]);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
setTimeout(() => {
|
|
56
|
+
if (hasError) {
|
|
57
|
+
unsub();
|
|
58
|
+
reject(new Error('Get Balance Timeout'));
|
|
59
|
+
}
|
|
60
|
+
}, 9999);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
async getTokenFreeBalance(address, chain, tokenSlug) {
|
|
64
|
+
const [, balance] = await this.subscribeTokenFreeBalance(address, chain, tokenSlug);
|
|
65
|
+
return balance;
|
|
66
|
+
}
|
|
67
|
+
subscribeBalance(addresses, chains, callback) {
|
|
68
|
+
const [substrateAddresses, evmAddresses] = categoryAddresses(addresses);
|
|
69
|
+
const chainInfoMap = this.chainService.getChainInfoMap();
|
|
70
|
+
const chainStateMap = this.chainService.getChainStateMap();
|
|
71
|
+
const substrateApiMap = this.chainService.getSubstrateApiMap();
|
|
72
|
+
const evmApiMap = this.chainService.getEvmApiMap();
|
|
73
|
+
|
|
74
|
+
// Get data from chain or all chains
|
|
75
|
+
const chainList = chains || Object.keys(chainInfoMap);
|
|
76
|
+
// Filter active chain only
|
|
77
|
+
const useChainInfos = chainList.filter(c => chainStateMap[c] && chainStateMap[c].active).map(c => chainInfoMap[c]);
|
|
78
|
+
|
|
79
|
+
// Looping over each chain
|
|
80
|
+
const unsubList = useChainInfos.map(async chainInfo => {
|
|
81
|
+
const chainSlug = chainInfo.slug;
|
|
82
|
+
const useAddresses = _isChainEvmCompatible(chainInfo) ? evmAddresses : substrateAddresses;
|
|
83
|
+
if (_isPureEvmChain(chainInfo)) {
|
|
84
|
+
const nativeTokenInfo = state.getNativeTokenInfo(chainSlug);
|
|
85
|
+
return subscribeEVMBalance(chainSlug, useAddresses, evmApiMap, callback, nativeTokenInfo);
|
|
86
|
+
}
|
|
87
|
+
if (!useAddresses || useAddresses.length === 0 || _PURE_EVM_CHAINS.indexOf(chainSlug) > -1) {
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
const networkAPI = await substrateApiMap[chainSlug].isReady;
|
|
91
|
+
return subscribeSubstrateBalance(useAddresses, chainInfo, chainSlug, networkAPI, evmApiMap, callback);
|
|
92
|
+
});
|
|
93
|
+
return () => {
|
|
94
|
+
unsubList.forEach(subProm => {
|
|
95
|
+
subProm.then(unsub => {
|
|
96
|
+
unsub && unsub();
|
|
97
|
+
}).catch(console.error);
|
|
98
|
+
});
|
|
99
|
+
};
|
|
7
100
|
}
|
|
8
101
|
}
|
|
@@ -57,7 +57,7 @@ export declare function _getMultiChainAssetSymbol(multiChainAsset: _MultiChainAs
|
|
|
57
57
|
export declare function _getAssetOriginChain(assetInfo: _ChainAsset): string;
|
|
58
58
|
export declare function _getChainName(chainInfo: _ChainInfo): string;
|
|
59
59
|
export declare function _getAssetDecimals(assetInfo: _ChainAsset): number;
|
|
60
|
-
export declare function _getBlockExplorerFromChain(chainInfo: _ChainInfo): string;
|
|
60
|
+
export declare function _getBlockExplorerFromChain(chainInfo: _ChainInfo): string | undefined;
|
|
61
61
|
export declare function _parseMetadataForSmartContractAsset(contractAddress: string): Record<string, string>;
|
|
62
62
|
export declare function _isChainTestNet(chainInfo: _ChainInfo): boolean;
|
|
63
63
|
export declare function _isAssetFungibleToken(chainAsset: _ChainAsset): boolean;
|
|
@@ -273,12 +273,22 @@ export function _getAssetDecimals(assetInfo) {
|
|
|
273
273
|
return assetInfo.decimals || 0;
|
|
274
274
|
}
|
|
275
275
|
export function _getBlockExplorerFromChain(chainInfo) {
|
|
276
|
-
|
|
276
|
+
let blockExplorer;
|
|
277
277
|
if (_isPureEvmChain(chainInfo)) {
|
|
278
278
|
var _chainInfo$evmInfo4;
|
|
279
|
-
|
|
279
|
+
blockExplorer = chainInfo === null || chainInfo === void 0 ? void 0 : (_chainInfo$evmInfo4 = chainInfo.evmInfo) === null || _chainInfo$evmInfo4 === void 0 ? void 0 : _chainInfo$evmInfo4.blockExplorer;
|
|
280
|
+
} else {
|
|
281
|
+
var _chainInfo$substrateI12;
|
|
282
|
+
blockExplorer = chainInfo === null || chainInfo === void 0 ? void 0 : (_chainInfo$substrateI12 = chainInfo.substrateInfo) === null || _chainInfo$substrateI12 === void 0 ? void 0 : _chainInfo$substrateI12.blockExplorer;
|
|
283
|
+
}
|
|
284
|
+
if (!blockExplorer) {
|
|
285
|
+
return undefined;
|
|
286
|
+
}
|
|
287
|
+
if (blockExplorer !== '' && !blockExplorer.endsWith('/')) {
|
|
288
|
+
return `${blockExplorer}/`;
|
|
289
|
+
} else {
|
|
290
|
+
return blockExplorer;
|
|
280
291
|
}
|
|
281
|
-
return (chainInfo === null || chainInfo === void 0 ? void 0 : (_chainInfo$substrateI12 = chainInfo.substrateInfo) === null || _chainInfo$substrateI12 === void 0 ? void 0 : _chainInfo$substrateI12.blockExplorer) || '';
|
|
282
292
|
}
|
|
283
293
|
export function _parseMetadataForSmartContractAsset(contractAddress) {
|
|
284
294
|
return {
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import { Notification, NotificationParams } from '@subwallet/extension-base/background/KoniTypes';
|
|
2
|
+
import { BehaviorSubject } from 'rxjs';
|
|
1
3
|
export default class NotificationService {
|
|
2
|
-
|
|
4
|
+
private notificationSubject;
|
|
5
|
+
getNotificationSubject(): BehaviorSubject<Notification[]>;
|
|
6
|
+
notify(notification: NotificationParams): void;
|
|
7
|
+
static createBrowserNotification(title: string, message: string, link?: string): void;
|
|
3
8
|
}
|
|
@@ -1,9 +1,31 @@
|
|
|
1
1
|
// Copyright 2019-2022 @subwallet/extension-base authors & contributors
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
+
import { BehaviorSubject } from 'rxjs';
|
|
4
5
|
export default class NotificationService {
|
|
6
|
+
notificationSubject = new BehaviorSubject([]);
|
|
7
|
+
getNotificationSubject() {
|
|
8
|
+
return this.notificationSubject;
|
|
9
|
+
}
|
|
10
|
+
notify(notification) {
|
|
11
|
+
const now = new Date().getTime();
|
|
12
|
+
// Get values in last 30 seconds only
|
|
13
|
+
const notifications = this.notificationSubject.value.filter(n => n.id < now - 30000);
|
|
14
|
+
|
|
15
|
+
// Push notification
|
|
16
|
+
notifications.push({
|
|
17
|
+
...notification,
|
|
18
|
+
id: now
|
|
19
|
+
});
|
|
20
|
+
this.notificationSubject.next(notifications);
|
|
21
|
+
if (notification.notifyViaBrowser) {
|
|
22
|
+
var _notification$action;
|
|
23
|
+
NotificationService.createBrowserNotification(notification.title, notification.message, notification === null || notification === void 0 ? void 0 : (_notification$action = notification.action) === null || _notification$action === void 0 ? void 0 : _notification$action.url);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
5
27
|
// Create a new chrome notification with link
|
|
6
|
-
static
|
|
28
|
+
static createBrowserNotification(title, message, link) {
|
|
7
29
|
chrome.notifications.create({
|
|
8
30
|
type: 'basic',
|
|
9
31
|
title,
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import { withErrorLog } from '@subwallet/extension-base/background/handlers/helpers';
|
|
5
|
-
import settings from '@polkadot/ui-settings';
|
|
6
5
|
const NOTIFICATION_URL = chrome.extension.getURL('notification.html');
|
|
7
6
|
const POPUP_WINDOW_OPTS = {
|
|
8
7
|
focused: true,
|
|
@@ -20,10 +19,17 @@ const NORMAL_WINDOW_OPTS = {
|
|
|
20
19
|
};
|
|
21
20
|
export default class PopupHandler {
|
|
22
21
|
#requestService;
|
|
23
|
-
#notification =
|
|
22
|
+
#notification = 'popup';
|
|
24
23
|
#windows = [];
|
|
25
24
|
constructor(requestService) {
|
|
26
25
|
this.#requestService = requestService;
|
|
26
|
+
const updateNotification = rs => {
|
|
27
|
+
this.#notification = rs.browserConfirmationType;
|
|
28
|
+
};
|
|
29
|
+
requestService.settingService.getSettings(updateNotification);
|
|
30
|
+
requestService.settingService.getSubject().subscribe({
|
|
31
|
+
next: updateNotification
|
|
32
|
+
});
|
|
27
33
|
}
|
|
28
34
|
updateIconV2(shouldClose) {
|
|
29
35
|
const numRequests = this.#requestService.numRequests;
|
|
@@ -38,10 +44,6 @@ export default class PopupHandler {
|
|
|
38
44
|
this.popupClose();
|
|
39
45
|
}
|
|
40
46
|
}
|
|
41
|
-
setNotification(notification) {
|
|
42
|
-
this.#notification = notification;
|
|
43
|
-
return true;
|
|
44
|
-
}
|
|
45
47
|
get popup() {
|
|
46
48
|
return this.#windows;
|
|
47
49
|
}
|
|
@@ -51,19 +53,12 @@ export default class PopupHandler {
|
|
|
51
53
|
}
|
|
52
54
|
popupOpen() {
|
|
53
55
|
if (this.#notification !== 'extension') {
|
|
54
|
-
if (this.#notification === 'window') {
|
|
55
|
-
chrome.windows.create(NORMAL_WINDOW_OPTS, window => {
|
|
56
|
-
if (window) {
|
|
57
|
-
this.#windows.push(window.id || 0);
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
56
|
chrome.windows.getCurrent(win => {
|
|
62
57
|
const popupOptions = {
|
|
63
|
-
...POPUP_WINDOW_OPTS
|
|
58
|
+
...(this.#notification === 'window' ? NORMAL_WINDOW_OPTS : POPUP_WINDOW_OPTS)
|
|
64
59
|
};
|
|
65
60
|
if (win) {
|
|
66
|
-
popupOptions.left = (win.left || 0) + (win.width || 0) - (
|
|
61
|
+
popupOptions.left = (win.left || 0) + (win.width || 0) - (popupOptions.width || 0) - 20;
|
|
67
62
|
popupOptions.top = (win.top || 0) + 80;
|
|
68
63
|
}
|
|
69
64
|
chrome.windows.create(popupOptions, window => {
|
|
@@ -2,16 +2,17 @@ import { AuthRequestV2, ConfirmationDefinitions, ConfirmationsQueue, Confirmatio
|
|
|
2
2
|
import { AccountJson, AuthorizeRequest, MetadataRequest, RequestAuthorizeTab, RequestSign, ResponseSigning, SigningRequest } from '@subwallet/extension-base/background/types';
|
|
3
3
|
import { ChainService } from '@subwallet/extension-base/services/chain-service';
|
|
4
4
|
import { AuthUrls, MetaRequest } from '@subwallet/extension-base/services/request-service/types';
|
|
5
|
+
import SettingService from '@subwallet/extension-base/services/setting-service/SettingService';
|
|
5
6
|
import { MetadataDef } from '@subwallet/extension-inject/types';
|
|
6
7
|
import { BehaviorSubject, Subject } from 'rxjs';
|
|
7
8
|
import { SignerPayloadJSON } from '@polkadot/types/types/extrinsic';
|
|
8
9
|
export default class RequestService {
|
|
9
10
|
#private;
|
|
10
|
-
|
|
11
|
+
readonly settingService: SettingService;
|
|
12
|
+
constructor(chainService: ChainService, settingService: SettingService);
|
|
11
13
|
get numAllRequests(): number;
|
|
12
14
|
updateIconV2(shouldClose?: boolean): void;
|
|
13
15
|
getAddressList(value?: boolean): Record<string, boolean>;
|
|
14
|
-
setNotification(notification: string): boolean;
|
|
15
16
|
get popup(): number[];
|
|
16
17
|
popupClose(): void;
|
|
17
18
|
popupOpen(): void;
|
|
@@ -17,8 +17,9 @@ export default class RequestService {
|
|
|
17
17
|
#evmRequestHandler;
|
|
18
18
|
|
|
19
19
|
// Common
|
|
20
|
-
constructor(chainService) {
|
|
20
|
+
constructor(chainService, settingService) {
|
|
21
21
|
this.#chainService = chainService;
|
|
22
|
+
this.settingService = settingService;
|
|
22
23
|
this.#popupHandler = new PopupHandler(this);
|
|
23
24
|
this.#metadataRequestHandler = new MetadataRequestHandler(this);
|
|
24
25
|
this.#authRequestHandler = new AuthRequestHandler(this, this.#chainService);
|
|
@@ -43,11 +44,6 @@ export default class RequestService {
|
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
// Popup
|
|
46
|
-
|
|
47
|
-
setNotification(notification) {
|
|
48
|
-
this.#popupHandler.setNotification(notification);
|
|
49
|
-
return true;
|
|
50
|
-
}
|
|
51
47
|
get popup() {
|
|
52
48
|
return this.#popupHandler.popup;
|
|
53
49
|
}
|