diff --git a/packages/beacon-dapp/src/dapp-client/DAppClient.ts b/packages/beacon-dapp/src/dapp-client/DAppClient.ts index 40a5e8baa..85db8c667 100644 --- a/packages/beacon-dapp/src/dapp-client/DAppClient.ts +++ b/packages/beacon-dapp/src/dapp-client/DAppClient.ts @@ -144,6 +144,7 @@ export class DAppClient extends Client { protected wcProjectId?: string protected wcRelayUrl?: string + private isGetActiveAccountHandled: boolean = false /** * A map of requests that are currently "open", meaning we have sent them to a wallet and are still awaiting a response. */ @@ -577,12 +578,28 @@ export class DAppClient extends Client { return this._activeAccount.promise } + private async isInvalidState(account: AccountInfo) { + const activeAccount = await this._activeAccount.promise + return !activeAccount + ? false + : activeAccount?.address !== account.address && !this.isGetActiveAccountHandled + } + /** * Sets the active account * * @param account The account that will be set as the active account */ public async setActiveAccount(account?: AccountInfo): Promise { + if (account && (await this.isInvalidState(account))) { + setTimeout(() => this.events.emit(BeaconEvent.HIDE_UI), 1000) + this.destroy() + this.setActiveAccount(undefined) + setTimeout(() => this.events.emit(BeaconEvent.INVALID_ACTIVE_ACCOUNT_STATE), 1000) + + return + } + if (this._activeAccount.isSettled()) { // If the promise has already been resolved we need to create a new one. this._activeAccount = ExposedPromise.resolve(account) @@ -742,6 +759,10 @@ export class DAppClient extends Client { internalEvent: K, eventCallback: BeaconEventHandlerFunction ): Promise { + if (internalEvent === BeaconEvent.ACTIVE_ACCOUNT_SET) { + this.isGetActiveAccountHandled = true + } + await this.events.on(internalEvent, eventCallback) } diff --git a/packages/beacon-dapp/src/events.ts b/packages/beacon-dapp/src/events.ts index aae6a6dc4..95fddb6dd 100644 --- a/packages/beacon-dapp/src/events.ts +++ b/packages/beacon-dapp/src/events.ts @@ -87,7 +87,7 @@ export enum BeaconEvent { SHOW_PREPARE = 'SHOW_PREPARE', HIDE_UI = 'HIDE_UI', - + INVALID_ACTIVE_ACCOUNT_STATE = 'INVALID_ACTIVE_ACCOUNT_STATE', PAIR_INIT = 'PAIR_INIT', PAIR_SUCCESS = 'PAIR_SUCCESS', CHANNEL_CLOSED = 'CHANNEL_CLOSED', @@ -164,6 +164,7 @@ export interface BeaconEventType { [BeaconEvent.NO_PERMISSIONS]: undefined [BeaconEvent.ACTIVE_ACCOUNT_SET]: AccountInfo [BeaconEvent.ACTIVE_TRANSPORT_SET]: Transport + [BeaconEvent.INVALID_ACTIVE_ACCOUNT_STATE]: undefined [BeaconEvent.SHOW_PREPARE]: { walletInfo?: WalletInfo } [BeaconEvent.HIDE_UI]: ('alert' | 'toast')[] | undefined [BeaconEvent.PAIR_INIT]: { @@ -287,6 +288,17 @@ const showNoPermissionAlert = async (): Promise => { }) } +/** + * Show a + */ +const showInvalidActiveAccountState = async (): Promise => { + await openAlert({ + title: 'Invalid state', + body: `A new active account has been received but no handler found + (INVALID STATE: no handler found for BeaconEvent.ACTIVE_ACCOUNT_SET)` + }) +} + /** * Show an error toast * @@ -645,6 +657,7 @@ export const defaultEventCallbacks: { [BeaconEvent.NO_PERMISSIONS]: showNoPermissionAlert, [BeaconEvent.ACTIVE_ACCOUNT_SET]: emptyHandler(), [BeaconEvent.ACTIVE_TRANSPORT_SET]: emptyHandler(), + [BeaconEvent.INVALID_ACTIVE_ACCOUNT_STATE]: showInvalidActiveAccountState, [BeaconEvent.SHOW_PREPARE]: showPrepare, [BeaconEvent.HIDE_UI]: hideUI, [BeaconEvent.PAIR_INIT]: showPairAlert, @@ -684,6 +697,7 @@ export class BeaconEventHandler { [BeaconEvent.NO_PERMISSIONS]: [defaultEventCallbacks.NO_PERMISSIONS], [BeaconEvent.ACTIVE_ACCOUNT_SET]: [defaultEventCallbacks.ACTIVE_ACCOUNT_SET], [BeaconEvent.ACTIVE_TRANSPORT_SET]: [defaultEventCallbacks.ACTIVE_TRANSPORT_SET], + [BeaconEvent.INVALID_ACTIVE_ACCOUNT_STATE]: [defaultEventCallbacks.INVALID_ACTIVE_ACCOUNT_STATE], [BeaconEvent.SHOW_PREPARE]: [defaultEventCallbacks.SHOW_PREPARE], [BeaconEvent.HIDE_UI]: [defaultEventCallbacks.HIDE_UI], [BeaconEvent.PAIR_INIT]: [defaultEventCallbacks.PAIR_INIT],