@subwallet/extension-base 1.1.11-1 → 1.1.12-1

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 (41) hide show
  1. package/background/KoniTypes.d.ts +16 -6
  2. package/background/types.d.ts +4 -2
  3. package/cjs/koni/api/staking/bonding/utils.js +2 -1
  4. package/cjs/koni/api/tokens/evm/transfer.js +10 -4
  5. package/cjs/koni/background/handlers/Extension.js +33 -11
  6. package/cjs/koni/background/handlers/State.js +1 -1
  7. package/cjs/packageInfo.js +1 -1
  8. package/cjs/services/chain-service/constants.js +10 -2
  9. package/cjs/services/chain-service/handler/EvmApi.js +24 -12
  10. package/cjs/services/keyring-service/index.js +33 -1
  11. package/cjs/services/notification-service/NotificationService.js +2 -1
  12. package/cjs/services/request-service/constants.js +11 -2
  13. package/cjs/services/request-service/handler/AuthRequestHandler.js +20 -1
  14. package/cjs/services/request-service/handler/EvmRequestHandler.js +2 -1
  15. package/cjs/services/setting-service/SettingService.js +5 -1
  16. package/cjs/services/transaction-service/index.js +124 -55
  17. package/cjs/utils/lazy.js +20 -6
  18. package/koni/api/staking/bonding/utils.js +2 -1
  19. package/koni/api/tokens/evm/transfer.d.ts +1 -1
  20. package/koni/api/tokens/evm/transfer.js +11 -5
  21. package/koni/background/handlers/Extension.d.ts +2 -0
  22. package/koni/background/handlers/Extension.js +33 -11
  23. package/koni/background/handlers/State.js +1 -1
  24. package/package.json +10 -8
  25. package/packageInfo.js +1 -1
  26. package/page/SubWalleEvmProvider.d.ts +1 -1
  27. package/services/chain-service/constants.d.ts +6 -0
  28. package/services/chain-service/constants.js +6 -0
  29. package/services/chain-service/handler/EvmApi.js +24 -12
  30. package/services/keyring-service/index.d.ts +4 -1
  31. package/services/keyring-service/index.js +33 -1
  32. package/services/notification-service/NotificationService.js +2 -1
  33. package/services/request-service/constants.d.ts +1 -0
  34. package/services/request-service/constants.js +9 -1
  35. package/services/request-service/handler/AuthRequestHandler.js +21 -2
  36. package/services/request-service/handler/EvmRequestHandler.js +2 -1
  37. package/services/setting-service/SettingService.js +5 -1
  38. package/services/transaction-service/index.d.ts +1 -0
  39. package/services/transaction-service/index.js +116 -48
  40. package/utils/lazy.d.ts +1 -1
  41. package/utils/lazy.js +20 -7
@@ -26,7 +26,8 @@ export default class NotificationService {
26
26
 
27
27
  // Create a new chrome notification with link
28
28
  static createBrowserNotification(title, message, link) {
29
- chrome.notifications.create({
29
+ var _chrome, _chrome$notifications;
30
+ (_chrome = chrome) === null || _chrome === void 0 ? void 0 : (_chrome$notifications = _chrome.notifications) === null || _chrome$notifications === void 0 ? void 0 : _chrome$notifications.create({
30
31
  type: 'basic',
31
32
  title,
32
33
  message,
@@ -1,2 +1,3 @@
1
1
  export declare const EXTENSION_REQUEST_URL = "extension";
2
2
  export declare const PREDEFINED_CHAIN_DAPP_CHAIN_MAP: Record<string, string[]>;
3
+ export declare const WEB_APP_URL: string[];
@@ -6,4 +6,12 @@ export const PREDEFINED_CHAIN_DAPP_CHAIN_MAP = {
6
6
  'portal.astar.network': ['astar', 'astarEvm'],
7
7
  'apps.moonbeam.network': ['moonbeam', 'moonriver'],
8
8
  'app.stellaswap.com': ['moonbeam']
9
- };
9
+ };
10
+ export const WEB_APP_URL = [
11
+ /// Web app
12
+ 'localhost:9000',
13
+ // Local
14
+ 'subwallet-webapp.pages.dev',
15
+ // Pull request build
16
+ 'web.subwallet.app' // Production
17
+ ];
@@ -2,7 +2,7 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import { _isChainEvmCompatible } from '@subwallet/extension-base/services/chain-service/utils';
5
- import { PREDEFINED_CHAIN_DAPP_CHAIN_MAP } from '@subwallet/extension-base/services/request-service/constants';
5
+ import { PREDEFINED_CHAIN_DAPP_CHAIN_MAP, WEB_APP_URL } from '@subwallet/extension-base/services/request-service/constants';
6
6
  import AuthorizeStore from '@subwallet/extension-base/stores/Authorize';
7
7
  import { getDomainFromUrl, stripUrl } from '@subwallet/extension-base/utils';
8
8
  import { getId } from '@subwallet/extension-base/utils/getId';
@@ -209,7 +209,7 @@ export default class AuthRequestHandler {
209
209
  }
210
210
  const idStr = stripUrl(url);
211
211
  // Do not enqueue duplicate authorization requests.
212
- const isDuplicate = Object.values(this.#authRequestsV2).some(request => request.idStr === idStr);
212
+ const isDuplicate = Object.values(this.#authRequestsV2).some(_request => _request.idStr === idStr && _request.accountAuthType === request.accountAuthType);
213
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;
@@ -235,6 +235,25 @@ export default class AuthRequestHandler {
235
235
  // Prevent appear confirmation popup
236
236
  return false;
237
237
  }
238
+ } else {
239
+ // Auto auth for web app
240
+
241
+ // Ignore white list
242
+ const isWhiteList = WEB_APP_URL.some(url => idStr.includes(url)) && false;
243
+ if (isWhiteList) {
244
+ const isAllowedMap = this.getAddressList(true);
245
+ authList[stripUrl(url)] = {
246
+ count: 0,
247
+ id: idStr,
248
+ isAllowed: true,
249
+ isAllowedMap,
250
+ origin,
251
+ url,
252
+ accountAuthType: 'both'
253
+ };
254
+ this.setAuthorize(authList);
255
+ return true;
256
+ }
238
257
  }
239
258
  return new Promise((resolve, reject) => {
240
259
  const id = getId();
@@ -21,7 +21,8 @@ export default class EvmRequestHandler {
21
21
  addTokenRequest: {},
22
22
  switchNetworkRequest: {},
23
23
  evmSignatureRequest: {},
24
- evmSendTransactionRequest: {}
24
+ evmSendTransactionRequest: {},
25
+ evmWatchTransactionRequest: {}
25
26
  });
26
27
  confirmationsPromiseMap = {};
27
28
  constructor(requestService) {
@@ -11,13 +11,17 @@ export default class SettingService {
11
11
  passPhishingStore = new PassPhishingStore();
12
12
  constructor() {
13
13
  let old = localStorage.getItem(LANGUAGE) || 'en';
14
- this.settingsStore.getSubject().subscribe(({
14
+ const updateLanguage = ({
15
15
  language
16
16
  }) => {
17
17
  if (language !== old) {
18
18
  old = language;
19
19
  i18n.changeLanguage(language).catch(console.error);
20
20
  }
21
+ };
22
+ this.getSettings(updateLanguage);
23
+ this.settingsStore.getSubject().subscribe({
24
+ next: updateLanguage
21
25
  });
22
26
  }
23
27
  getSubject() {
@@ -19,6 +19,7 @@ export default class TransactionService {
19
19
  private readonly notificationService;
20
20
  private readonly requestService;
21
21
  private readonly transactionSubject;
22
+ private readonly watchTransactionSubscribes;
22
23
  private get transactions();
23
24
  constructor(chainService: ChainService, eventService: EventService, requestService: RequestService, balanceService: BalanceService, historyService: HistoryService, notificationService: NotificationService, databaseService: DatabaseService);
24
25
  private get allTransactions();
@@ -27,6 +27,7 @@ import { BehaviorSubject } from 'rxjs';
27
27
  import { isHex } from '@polkadot/util';
28
28
  export default class TransactionService {
29
29
  transactionSubject = new BehaviorSubject({});
30
+ watchTransactionSubscribes = {};
30
31
  get transactions() {
31
32
  return this.transactionSubject.getValue();
32
33
  }
@@ -703,6 +704,7 @@ export default class TransactionService {
703
704
  payload.from = address;
704
705
  }
705
706
  const isExternal = !!account.isExternal;
707
+ const isInjected = !!account.isInjected;
706
708
 
707
709
  // generate hashPayload for EVM transaction
708
710
  payload.hashPayload = this.generateHashPayload(chain, payload);
@@ -723,62 +725,128 @@ export default class TransactionService {
723
725
  warnings: [],
724
726
  extrinsicHash: id
725
727
  };
726
- this.requestService.addConfirmation(id, url || EXTENSION_REQUEST_URL, 'evmSendTransactionRequest', payload, {}).then(async ({
727
- isApproved,
728
- payload
729
- }) => {
730
- if (isApproved) {
731
- let signedTransaction;
732
- if (!payload) {
733
- throw new EvmProviderError(EvmProviderErrorType.UNAUTHORIZED, t('Failed to sign'));
734
- }
735
- const web3Api = this.chainService.getEvmApi(chain).api;
736
- if (!isExternal) {
737
- signedTransaction = payload;
738
- } else {
739
- const signed = mergeTransactionAndSignature(txObject, payload);
740
- const recover = web3Api.eth.accounts.recoverTransaction(signed);
741
- if (recover.toLowerCase() !== account.address.toLowerCase()) {
742
- throw new EvmProviderError(EvmProviderErrorType.UNAUTHORIZED, t('Wrong signature. Please sign with the account you use in dApp'));
728
+ if (isInjected) {
729
+ this.requestService.addConfirmation(id, url || EXTENSION_REQUEST_URL, 'evmWatchTransactionRequest', payload, {}).then(async ({
730
+ isApproved,
731
+ payload
732
+ }) => {
733
+ if (isApproved) {
734
+ if (!payload) {
735
+ throw new EvmProviderError(EvmProviderErrorType.UNAUTHORIZED, 'Bad signature');
743
736
  }
744
- signedTransaction = signed;
745
- }
746
-
747
- // Emit signed event
748
- emitter.emit('signed', eventData);
737
+ const web3Api = this.chainService.getEvmApi(chain).api;
749
738
 
750
- // Send transaction
751
- this.handleTransactionTimeout(emitter, eventData);
739
+ // Emit signed event
740
+ emitter.emit('signed', eventData);
741
+ eventData.nonce = txObject.nonce;
742
+ eventData.startBlock = (await web3Api.eth.getBlockNumber()) - 3;
743
+ // Add start info
744
+ emitter.emit('send', eventData); // This event is needed after sending transaction with queue
752
745
 
753
- // Add start info
754
- eventData.nonce = txObject.nonce;
755
- eventData.startBlock = await web3Api.eth.getBlockNumber();
756
- emitter.emit('send', eventData); // This event is needed after sending transaction with queue
757
- signedTransaction && web3Api.eth.sendSignedTransaction(signedTransaction).once('transactionHash', hash => {
758
- eventData.extrinsicHash = hash;
746
+ const txHash = payload;
747
+ eventData.extrinsicHash = txHash;
759
748
  emitter.emit('extrinsicHash', eventData);
760
- }).once('receipt', rs => {
761
- eventData.extrinsicHash = rs.transactionHash;
762
- eventData.blockHash = rs.blockHash;
763
- eventData.blockNumber = rs.blockNumber;
764
- emitter.emit('success', eventData);
765
- }).once('error', e => {
766
- eventData.errors.push(new TransactionError(BasicTxErrorType.SEND_TRANSACTION_FAILED, t(e.message)));
749
+ this.watchTransactionSubscribes[id] = new Promise((resolve, reject) => {
750
+ // eslint-disable-next-line prefer-const
751
+ let subscribe;
752
+ const onComplete = () => {
753
+ var _subscribe, _subscribe$unsubscrib, _subscribe$unsubscrib2;
754
+ (_subscribe = subscribe) === null || _subscribe === void 0 ? void 0 : (_subscribe$unsubscrib = _subscribe.unsubscribe) === null || _subscribe$unsubscrib === void 0 ? void 0 : (_subscribe$unsubscrib2 = _subscribe$unsubscrib.call(_subscribe)) === null || _subscribe$unsubscrib2 === void 0 ? void 0 : _subscribe$unsubscrib2.then(console.debug).catch(console.debug);
755
+ delete this.watchTransactionSubscribes[id];
756
+ };
757
+ const onSuccess = rs => {
758
+ if (rs) {
759
+ eventData.extrinsicHash = rs.transactionHash;
760
+ eventData.blockHash = rs.blockHash;
761
+ eventData.blockNumber = rs.blockNumber;
762
+ emitter.emit('success', eventData);
763
+ onComplete();
764
+ resolve();
765
+ }
766
+ };
767
+ const onError = error => {
768
+ if (error) {
769
+ // TODO: Change type and message
770
+ eventData.errors.push(new TransactionError(BasicTxErrorType.UNABLE_TO_SEND, error.message));
771
+ emitter.emit('error', eventData);
772
+ onComplete();
773
+ reject(error);
774
+ }
775
+ };
776
+ const onCheck = () => {
777
+ web3Api.eth.getTransactionReceipt(txHash).then(onSuccess).catch(onError);
778
+ };
779
+ subscribe = web3Api.eth.subscribe('newBlockHeaders', onCheck);
780
+ });
781
+ } else {
782
+ this.removeTransaction(id);
783
+ eventData.errors.push(new TransactionError(BasicTxErrorType.USER_REJECT_REQUEST));
767
784
  emitter.emit('error', eventData);
768
- }).catch(e => {
769
- eventData.errors.push(new TransactionError(BasicTxErrorType.UNABLE_TO_SEND, t(e.message)));
785
+ }
786
+ }).catch(e => {
787
+ this.removeTransaction(id);
788
+ // TODO: Change type
789
+ eventData.errors.push(new TransactionError(BasicTxErrorType.UNABLE_TO_SIGN, e.message));
790
+ emitter.emit('error', eventData);
791
+ });
792
+ } else {
793
+ this.requestService.addConfirmation(id, url || EXTENSION_REQUEST_URL, 'evmSendTransactionRequest', payload, {}).then(async ({
794
+ isApproved,
795
+ payload
796
+ }) => {
797
+ if (isApproved) {
798
+ let signedTransaction;
799
+ if (!payload) {
800
+ throw new EvmProviderError(EvmProviderErrorType.UNAUTHORIZED, t('Failed to sign'));
801
+ }
802
+ const web3Api = this.chainService.getEvmApi(chain).api;
803
+ if (!isExternal) {
804
+ signedTransaction = payload;
805
+ } else {
806
+ const signed = mergeTransactionAndSignature(txObject, payload);
807
+ const recover = web3Api.eth.accounts.recoverTransaction(signed);
808
+ if (recover.toLowerCase() !== account.address.toLowerCase()) {
809
+ throw new EvmProviderError(EvmProviderErrorType.UNAUTHORIZED, t('Wrong signature. Please sign with the account you use in dApp'));
810
+ }
811
+ signedTransaction = signed;
812
+ }
813
+
814
+ // Emit signed event
815
+ emitter.emit('signed', eventData);
816
+
817
+ // Send transaction
818
+ this.handleTransactionTimeout(emitter, eventData);
819
+
820
+ // Add start info
821
+ eventData.nonce = txObject.nonce;
822
+ eventData.startBlock = await web3Api.eth.getBlockNumber();
823
+ emitter.emit('send', eventData); // This event is needed after sending transaction with queue
824
+ signedTransaction && web3Api.eth.sendSignedTransaction(signedTransaction).once('transactionHash', hash => {
825
+ eventData.extrinsicHash = hash;
826
+ emitter.emit('extrinsicHash', eventData);
827
+ }).once('receipt', rs => {
828
+ eventData.extrinsicHash = rs.transactionHash;
829
+ eventData.blockHash = rs.blockHash;
830
+ eventData.blockNumber = rs.blockNumber;
831
+ emitter.emit('success', eventData);
832
+ }).once('error', e => {
833
+ eventData.errors.push(new TransactionError(BasicTxErrorType.SEND_TRANSACTION_FAILED, t(e.message)));
834
+ emitter.emit('error', eventData);
835
+ }).catch(e => {
836
+ eventData.errors.push(new TransactionError(BasicTxErrorType.UNABLE_TO_SEND, t(e.message)));
837
+ emitter.emit('error', eventData);
838
+ });
839
+ } else {
840
+ this.removeTransaction(id);
841
+ eventData.errors.push(new TransactionError(BasicTxErrorType.USER_REJECT_REQUEST));
770
842
  emitter.emit('error', eventData);
771
- });
772
- } else {
843
+ }
844
+ }).catch(e => {
773
845
  this.removeTransaction(id);
774
- eventData.errors.push(new TransactionError(BasicTxErrorType.USER_REJECT_REQUEST));
846
+ eventData.errors.push(new TransactionError(BasicTxErrorType.UNABLE_TO_SIGN, t(e.message)));
775
847
  emitter.emit('error', eventData);
776
- }
777
- }).catch(e => {
778
- this.removeTransaction(id);
779
- eventData.errors.push(new TransactionError(BasicTxErrorType.UNABLE_TO_SIGN, t(e.message)));
780
- emitter.emit('error', eventData);
781
- });
848
+ });
849
+ }
782
850
  return emitter;
783
851
  }
784
852
  signAndSendSubstrateTransaction({
package/utils/lazy.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  export declare function removeLazy(key: string): void;
2
- export declare function addLazy(key: string, callback: () => void, lazyTime?: number, maxLazyTime?: number): void;
2
+ export declare function addLazy(key: string, callback: () => void, lazyTime?: number, maxLazyTime?: number, fireOnFirst?: boolean): void;
package/utils/lazy.js CHANGED
@@ -10,7 +10,7 @@ export function removeLazy(key) {
10
10
  }
11
11
 
12
12
  // Add or update new lazy thread
13
- export function addLazy(key, callback, lazyTime = 300, maxLazyTime = 3000) {
13
+ export function addLazy(key, callback, lazyTime = 300, maxLazyTime = 3000, fireOnFirst = true) {
14
14
  const existed = lazyMap[key];
15
15
  const now = new Date().getTime();
16
16
  if (existed) {
@@ -33,11 +33,24 @@ export function addLazy(key, callback, lazyTime = 300, maxLazyTime = 3000) {
33
33
  }, lazyTime);
34
34
  }
35
35
  } else {
36
- // Fire callback immediately in the first time
37
- callback();
38
- lazyMap[key] = {
39
- callback,
40
- lastFire: now
41
- };
36
+ if (fireOnFirst) {
37
+ // Fire callback immediately in the first time
38
+ callback();
39
+ lazyMap[key] = {
40
+ callback,
41
+ lastFire: now
42
+ };
43
+ } else {
44
+ lazyMap[key] = {
45
+ callback,
46
+ lastFire: now
47
+ };
48
+ lazyMap[key].timeout = setTimeout(() => {
49
+ // This will be fire in the last call of lazy thread
50
+ callback();
51
+ lazyMap[key].lastFire = new Date().getTime();
52
+ removeLazy(key);
53
+ }, lazyTime);
54
+ }
42
55
  }
43
56
  }