Skip to content

Commit

Permalink
Fix: re-connecting a locked wallet
Browse files Browse the repository at this point in the history
  • Loading branch information
katspaugh committed Aug 1, 2023
1 parent 9fd937a commit 063194c
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 13 deletions.
12 changes: 5 additions & 7 deletions src/hooks/wallets/useOnboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,17 +179,15 @@ export const useInitOnboard = () => {
}

// Connect to the last connected wallet
enableWallets().then(() => {
enableWallets().then(async () => {
if (onboard.state.get().wallets.length > 0) return

const label = lastWalletStorage.get()
if (!label) return
const isUnlocked = label && (await isWalletUnlocked(label))
if (!isUnlocked) return

isWalletUnlocked(label).then((isUnlocked) => {
isUnlocked &&
connectWallet(onboard, {
autoSelect: { label, disableModals: false },
})
connectWallet(onboard, {
autoSelect: { label, disableModals: true },
})
})
}, [chain, onboard])
Expand Down
53 changes: 53 additions & 0 deletions src/utils/__tests__/wallet.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { isWalletUnlocked, WalletNames } from '../wallets'

describe('utils/wallet', () => {
it('should check if MetaMask is unlocked and return false', async () => {
// mock window.ethereum
Object.defineProperty(window, 'ethereum', {
value: {
isMetaMask: true,
selectedAddress: '0x123',
isConnected: () => true,
_metamask: {
isUnlocked: () => Promise.resolve(false),
},
},
writable: true,
})
const result = await isWalletUnlocked(WalletNames.METAMASK)
expect(result).toBe(false)
})

it('should check if MetaMask is unlocked and return true', async () => {
// mock window.ethereum
Object.defineProperty(window, 'ethereum', {
value: {
isMetaMask: true,
selectedAddress: '0x123',
isConnected: () => true,
_metamask: {
isUnlocked: () => Promise.resolve(true),
},
},
writable: true,
})
const result = await isWalletUnlocked(WalletNames.METAMASK)
expect(result).toBe(true)
})

it('should check if WalletConnect is unlocked', async () => {
window.localStorage.setItem('walletconnect', 'true')

expect(await isWalletUnlocked(WalletNames.WALLET_CONNECT)).toBe(true)
expect(await isWalletUnlocked(WalletNames.WALLET_CONNECT_V2)).toBe(true)

window.localStorage.removeItem('walletconnect')

expect(await isWalletUnlocked(WalletNames.WALLET_CONNECT)).toBe(false)
expect(await isWalletUnlocked(WalletNames.WALLET_CONNECT_V2)).toBe(false)
})

it('should return false for unhandled wallets', async () => {
expect(await isWalletUnlocked('PINEAPPLE')).toBe(false)
})
})
8 changes: 2 additions & 6 deletions src/utils/wallets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,13 @@ export const WalletNames = {
export const isWalletUnlocked = async (walletName: string): Promise<boolean> => {
if (typeof window === 'undefined') return false

if (window.ethereum?.isConnected?.()) {
return true
}

// Only MetaMask exposes a method to check if the wallet is unlocked
if (walletName === WalletNames.METAMASK) {
return window.ethereum?._metamask?.isUnlocked?.() || false
return (await window.ethereum?._metamask?.isUnlocked?.()) || false
}

// Wallet connect creates a localStorage entry when connected and removes it when disconnected
if (walletName === WalletNames.WALLET_CONNECT) {
if (walletName === WalletNames.WALLET_CONNECT || walletName === WalletNames.WALLET_CONNECT_V2) {
return window.localStorage.getItem('walletconnect') !== null
}

Expand Down

0 comments on commit 063194c

Please sign in to comment.