From 9fdffaf895958931a27c12662763dc600d3e36e3 Mon Sep 17 00:00:00 2001 From: IsaccoSordo Date: Tue, 24 Sep 2024 16:28:54 +0200 Subject: [PATCH] fix: add locking mechanism --- .../beacon-core/src/utils/multi-tab-channel.ts | 15 ++++++++++----- .../beacon-dapp/src/dapp-client/DAppClient.ts | 4 ++-- .../src/transports/DappWalletConnectTransport.ts | 2 +- .../src/WalletConnectTransport.ts | 4 ++-- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/packages/beacon-core/src/utils/multi-tab-channel.ts b/packages/beacon-core/src/utils/multi-tab-channel.ts index af50eb9b3..c2fcfd37e 100644 --- a/packages/beacon-core/src/utils/multi-tab-channel.ts +++ b/packages/beacon-core/src/utils/multi-tab-channel.ts @@ -1,5 +1,6 @@ import { Logger } from '@airgap/beacon-core' import { BeaconMessageType } from '@airgap/beacon-types' +import { ExposedPromise } from '@airgap/beacon-utils' import { createLeaderElection, BroadcastChannel, LeaderElector } from 'broadcast-channel' type BCMessageType = @@ -35,6 +36,7 @@ export class MultiTabChannel { ] private onBCMessageHandler: Function private onElectedLeaderHandler: Function + private _isLeader: ExposedPromise = new ExposedPromise() // Auxiliary variable needed for handling beforeUnload. // Closing a tab causes the elector to be killed immediately private wasLeader: boolean = false @@ -58,8 +60,9 @@ export class MultiTabChannel { if (!hasLeader) { await this.elector.awaitLeadership() - this.wasLeader = this.isLeader() + this.wasLeader = this.elector.isLeader this.wasLeader && logger.log('The current tab is the leader.') + this._isLeader.resolve(this.wasLeader) } this.channel.onmessage = this.eventListeners[1] @@ -84,9 +87,11 @@ export class MultiTabChannel { if (message.type === 'LEADER_DEAD') { await this.elector.awaitLeadership() - this.wasLeader = this.isLeader() + this.wasLeader = this.elector.isLeader + this._isLeader = new ExposedPromise() + this._isLeader.resolve(this.wasLeader) - if (this.isLeader()) { + if (this.wasLeader) { this.onElectedLeaderHandler() logger.log('The current tab is the leader.') } @@ -96,8 +101,8 @@ export class MultiTabChannel { this.onBCMessageHandler(message) } - isLeader(): boolean { - return this.elector.isLeader + isLeader(): Promise { + return this._isLeader.promise } async getLeadership() { diff --git a/packages/beacon-dapp/src/dapp-client/DAppClient.ts b/packages/beacon-dapp/src/dapp-client/DAppClient.ts index fb58bf7c6..e4734525e 100644 --- a/packages/beacon-dapp/src/dapp-client/DAppClient.ts +++ b/packages/beacon-dapp/src/dapp-client/DAppClient.ts @@ -730,7 +730,7 @@ export class DAppClient extends Client { } private async getPairingRequestInfo(transport: DappWalletConnectTransport) { - if (this.multiTabChannel.isLeader()) { + if (await this.multiTabChannel.isLeader()) { return transport.getPairingRequestInfo() } @@ -960,7 +960,7 @@ export class DAppClient extends Client { this.debounceSetActiveAccount = true this._initPromise = undefined this.postMessageTransport = this.p2pTransport = this.walletConnectTransport = undefined - if (this.multiTabChannel.isLeader()) { + if (await this.multiTabChannel.isLeader()) { await transport.disconnect() this.openRequestsOtherTabs.clear() } else { diff --git a/packages/beacon-dapp/src/transports/DappWalletConnectTransport.ts b/packages/beacon-dapp/src/transports/DappWalletConnectTransport.ts index 5a794298d..f1a3f2e6e 100644 --- a/packages/beacon-dapp/src/transports/DappWalletConnectTransport.ts +++ b/packages/beacon-dapp/src/transports/DappWalletConnectTransport.ts @@ -25,7 +25,7 @@ export class DappWalletConnectTransport extends WalletConnectTransport< keyPair: KeyPair, storage: Storage, wcOptions: { network: NetworkType; opts: SignClientTypes.Options }, - isLeader: () => boolean + isLeader: () => Promise ) { super( name, diff --git a/packages/beacon-transport-walletconnect/src/WalletConnectTransport.ts b/packages/beacon-transport-walletconnect/src/WalletConnectTransport.ts index 48061b621..17f547f1c 100644 --- a/packages/beacon-transport-walletconnect/src/WalletConnectTransport.ts +++ b/packages/beacon-transport-walletconnect/src/WalletConnectTransport.ts @@ -35,7 +35,7 @@ export class WalletConnectTransport< storage: Storage, storageKey: K, private wcOptions: { network: NetworkType; opts: SignClientTypes.Options }, - private isLeader: () => boolean + private isLeader: () => Promise ) { super( name, @@ -62,7 +62,7 @@ export class WalletConnectTransport< this._isConnected = TransportStatus.CONNECTING - const isLeader = this.isLeader() + const isLeader = await this.isLeader() if (isLeader) { await this.client.init()