Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
166 changes: 100 additions & 66 deletions src/context/WalletProvider/WalletProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -674,32 +674,46 @@ export const WalletProvider = ({ children }: { children: React.ReactNode }): JSX
})
}

const localMetaMaskWallet = await metamaskAdapter?.pairDevice()
if (localMetaMaskWallet) {
const { name, icon } = SUPPORTED_WALLETS[KeyManager.MetaMask]
try {
try {
const localMetaMaskWallet = await metamaskAdapter?.pairDevice()
if (localMetaMaskWallet) {
const { name, icon } = SUPPORTED_WALLETS[KeyManager.MetaMask]
await localMetaMaskWallet.initialize()
const deviceId = await localMetaMaskWallet.getDeviceID()
dispatch({
type: WalletActions.SET_WALLET,
payload: {
wallet: localMetaMaskWallet,
name,
icon,
deviceId,
connectedType: KeyManager.MetaMask,
},
})
dispatch({ type: WalletActions.SET_IS_LOCKED, payload: false })
dispatch({
type: WalletActions.SET_IS_CONNECTED,
payload: true,
})
} catch (e) {

// Check if wallet is actually unlocked by verifying ethAddress is available
// If ethAddress is empty, the wallet is locked - don't claim it's connected
const ethAddress = (localMetaMaskWallet as MetaMaskMultiChainHDWallet).ethAddress

if (!ethAddress) {
// Wallet is locked - set locked state and disconnect
dispatch({ type: WalletActions.SET_IS_LOCKED, payload: true })
dispatch({ type: WalletActions.SET_IS_CONNECTED, payload: false })
} else {
dispatch({
type: WalletActions.SET_WALLET,
payload: {
wallet: localMetaMaskWallet,
name,
icon,
deviceId,
connectedType: KeyManager.MetaMask,
},
})
dispatch({ type: WalletActions.SET_IS_LOCKED, payload: false })
dispatch({
type: WalletActions.SET_IS_CONNECTED,
payload: true,
})
}
} else {
disconnect()
}
} else {
disconnect()
} catch (e) {
// pairDevice/initialize/getDeviceID failed - wallet is likely locked or disconnected
console.error('MetaMask: Failed to reconnect wallet on app load:', e)
dispatch({ type: WalletActions.SET_IS_LOCKED, payload: true })
dispatch({ type: WalletActions.SET_IS_CONNECTED, payload: false })
}
dispatch({ type: WalletActions.SET_LOCAL_WALLET_LOADING, payload: false })
break
Expand All @@ -717,32 +731,42 @@ export const WalletProvider = ({ children }: { children: React.ReactNode }): JSX
})
}

const localPhantomWallet = await phantomAdapter?.pairDevice()
if (localPhantomWallet) {
const { name, icon } = SUPPORTED_WALLETS[KeyManager.Phantom]
try {
try {
const localPhantomWallet = await phantomAdapter?.pairDevice()
if (localPhantomWallet) {
const { name, icon } = SUPPORTED_WALLETS[KeyManager.Phantom]
await localPhantomWallet.initialize()
const deviceId = await localPhantomWallet.getDeviceID()
dispatch({
type: WalletActions.SET_WALLET,
payload: {
wallet: localPhantomWallet,
name,
icon,
deviceId,
connectedType: KeyManager.Phantom,
},
})
dispatch({ type: WalletActions.SET_IS_LOCKED, payload: false })
dispatch({
type: WalletActions.SET_IS_CONNECTED,
payload: true,
})
} catch (e) {

if (!deviceId) {
// Wallet is locked - set locked state
dispatch({ type: WalletActions.SET_IS_LOCKED, payload: true })
dispatch({ type: WalletActions.SET_IS_CONNECTED, payload: false })
} else {
dispatch({
type: WalletActions.SET_WALLET,
payload: {
wallet: localPhantomWallet,
name,
icon,
deviceId,
connectedType: KeyManager.Phantom,
},
})
dispatch({ type: WalletActions.SET_IS_LOCKED, payload: false })
dispatch({
type: WalletActions.SET_IS_CONNECTED,
payload: true,
})
}
} else {
disconnect()
}
} else {
disconnect()
} catch (e) {
// pairDevice/initialize/getDeviceID failed - wallet is likely locked or disconnected
console.error('Phantom: Failed to reconnect wallet on app load:', e)
dispatch({ type: WalletActions.SET_IS_LOCKED, payload: true })
dispatch({ type: WalletActions.SET_IS_CONNECTED, payload: false })
}
dispatch({ type: WalletActions.SET_LOCAL_WALLET_LOADING, payload: false })
break
Expand All @@ -760,32 +784,42 @@ export const WalletProvider = ({ children }: { children: React.ReactNode }): JSX
})
}

const localCoinbaseWallet = await coinbaseAdapter?.pairDevice()
if (localCoinbaseWallet) {
const { name, icon } = SUPPORTED_WALLETS[KeyManager.Coinbase]
try {
try {
const localCoinbaseWallet = await coinbaseAdapter?.pairDevice()
if (localCoinbaseWallet) {
const { name, icon } = SUPPORTED_WALLETS[KeyManager.Coinbase]
await localCoinbaseWallet.initialize()
const deviceId = await localCoinbaseWallet.getDeviceID()
dispatch({
type: WalletActions.SET_WALLET,
payload: {
wallet: localCoinbaseWallet,
name,
icon,
deviceId,
connectedType: KeyManager.Coinbase,
},
})
dispatch({ type: WalletActions.SET_IS_LOCKED, payload: false })
dispatch({
type: WalletActions.SET_IS_CONNECTED,
payload: true,
})
} catch (e) {

if (!deviceId) {
// Wallet is locked - set locked state
dispatch({ type: WalletActions.SET_IS_LOCKED, payload: true })
dispatch({ type: WalletActions.SET_IS_CONNECTED, payload: false })
} else {
dispatch({
type: WalletActions.SET_WALLET,
payload: {
wallet: localCoinbaseWallet,
name,
icon,
deviceId,
connectedType: KeyManager.Coinbase,
},
})
dispatch({ type: WalletActions.SET_IS_LOCKED, payload: false })
dispatch({
type: WalletActions.SET_IS_CONNECTED,
payload: true,
})
}
} else {
disconnect()
}
} else {
disconnect()
} catch (e) {
// pairDevice/initialize/getDeviceID failed - wallet is likely locked or disconnected
console.error('Coinbase: Failed to reconnect wallet on app load:', e)
dispatch({ type: WalletActions.SET_IS_LOCKED, payload: true })
dispatch({ type: WalletActions.SET_IS_CONNECTED, payload: false })
}
dispatch({ type: WalletActions.SET_LOCAL_WALLET_LOADING, payload: false })
break
Expand Down
60 changes: 36 additions & 24 deletions src/context/WalletProvider/useEip1993EventHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,38 +63,50 @@ export const useEip1993EventHandler = ({
const _isLocked = Array.isArray(accountsOrChains) && accountsOrChains.length === 0

if (_isLocked) {
// Wallet is locked - set both locked state AND disconnected state
// This prevents the wallet drawer overlay from blocking interaction
dispatch({ type: WalletActions.SET_IS_LOCKED, payload: true })
} else {
// Either a chain change or a wallet unlock - ensure we set isLocked to false before continuing to avoid bad states
dispatch({ type: WalletActions.SET_IS_LOCKED, payload: false })
dispatch({ type: WalletActions.SET_IS_CONNECTED, payload: false })
// Return early - don't try to re-pair when wallet is locked
return
}

// Either a chain change or a wallet unlock - ensure we set isLocked to false before continuing to avoid bad states
dispatch({ type: WalletActions.SET_IS_LOCKED, payload: false })

const adapter = (await getAdapter(localWalletType)) as MetaMaskAdapter | PhantomAdapter | null

// Re-pair - which in case of accounts changed means the user will be prompted to connect their current account if they didn't do so
// Note, this isn't guaranteed to work, not all wallets are the same, some (i.e MM) have this weird flow where connecting to an unconnected account
// from a connected account can only be done from the wallet itself and not programmatically
const localWallet = await adapter?.pairDevice()

if (!localWallet) return

await localWallet.initialize()
const deviceId = await localWallet?.getDeviceID()

if (!deviceId) return

const { icon, name } = SUPPORTED_WALLETS[localWalletType]

dispatch({
type: WalletActions.SET_WALLET,
payload: {
wallet: localWallet,
name,
icon,
deviceId,
connectedType: localWalletType,
},
})
try {
const localWallet = await adapter?.pairDevice()

if (!localWallet) return

await localWallet.initialize()
const deviceId = await localWallet?.getDeviceID()

if (!deviceId) return

const { icon, name } = SUPPORTED_WALLETS[localWalletType]

dispatch({
type: WalletActions.SET_WALLET,
payload: {
wallet: localWallet,
name,
icon,
deviceId,
connectedType: localWalletType,
},
})
} catch (e) {
// If pairDevice/initialize/getDeviceID fails, wallet is likely locked or disconnected
console.error('Failed to re-pair wallet after account/chain change:', e)
dispatch({ type: WalletActions.SET_IS_LOCKED, payload: true })
dispatch({ type: WalletActions.SET_IS_CONNECTED, payload: false })
}
},
[dispatch, getAdapter, localWalletType, state.adapters],
)
Expand Down
Loading