Skip to content

Commit

Permalink
Add Metamask connection option (#788)
Browse files Browse the repository at this point in the history
Resolves #771

### What

Add Metamask to supported wallets 🦊 🥲

Metamask is visible only if you don't have Taho wallet installed.


![image](https://github.com/tahowallet/dapp/assets/20949277/f75f55a4-70ca-432f-a6a9-eeb7dad99ff3)

### Testing

1. Testing Taho **without** Metamask installed
- [x] make sure you are able to connect to Taho
- [x] make sure you are able to do transactions (stake, unstake) using
Taho
- [x] make sure you are able to disconnect and reconnect using Taho

2. Testing Taho **with** Metamask installed
- [x] make sure you are able to connect to Taho
- [x] make sure you are able to do transactions (stake, unstake) using
Taho
- [x] make sure you are able to disconnect and reconnect using Taho

3. Testing Metamask **without** Taho installed
- [x] make sure you are able to connect to Metamask
- [x] make sure you are able to do transactions (stake, unstake) using
Metamask
- [x] make sure you are able to disconnect and reconnect using Metamask
- [x] make sure selecting Taho as connection option fails gracefully
  • Loading branch information
xpaczka authored Dec 1, 2023
2 parents becb0fa + 5a8f2a6 commit 8186cf7
Show file tree
Hide file tree
Showing 6 changed files with 746 additions and 41 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"@rocicorp/rails": "^0.8.0",
"@rocicorp/reflect": "^0.38.202311200859",
"@web3-onboard/core": "^2.21.0",
"@web3-onboard/metamask": "^2.0.1",
"@web3-onboard/react": "^2.8.11",
"@web3-onboard/taho": "^2.0.5",
"@web3-onboard/trezor": "^2.4.2",
Expand Down
9 changes: 9 additions & 0 deletions src/shared/assets/favicon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
50 changes: 37 additions & 13 deletions src/shared/hooks/wallets.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useConnectWallet } from "@web3-onboard/react"
import { useConnectWallet, useSetChain } from "@web3-onboard/react"
import { useCallback, useEffect, useMemo, useState } from "react"
import { ethers, logger } from "ethers"
import {
Expand All @@ -23,6 +23,7 @@ import {
} from "shared/constants"
import { Network } from "@ethersproject/networks"
import { Logger, defineReadOnly } from "ethers/lib/utils"
import { usePostHog } from "posthog-js/react"
import { useAssistant } from "./assistant"
import { useInterval, useLocalStorageChange } from "./helpers"

Expand Down Expand Up @@ -171,33 +172,56 @@ export function useWalletOnboarding(): {
return { walletOnboarded: value, updateWalletOnboarding: updateStorage }
}

export function useConnect() {
const [{ wallet }, connect, disconnect] = useConnectWallet()
const { updateWalletOnboarding } = useWalletOnboarding()
export function useCorrectChain() {
const [{ wallet }] = useConnectWallet()
const [{ settingChain /* connectedChain */ }, setChain] = useSetChain()
const [chainSwitched, setChainSwitched] = useState(false)

useEffect(() => {
if (wallet?.provider !== undefined) {
const setCorrectChain = async () => {
const walletProvider = new ethers.providers.Web3Provider(
wallet.provider
)
await walletProvider.send("wallet_switchEthereumChain", [
{ chainId: ARBITRUM_SEPOLIA.id },
])
await setChain({
chainId: ARBITRUM_SEPOLIA.id,
})
setChainSwitched(true)
}

setCorrectChain()
// TODO: Metamask has a bug where it does not switch to the correct chain
// when the user adds new chain to the wallet. `connectedChain` is not updated
// until user reloads the page.
if (
!settingChain &&
!chainSwitched /* && connectedChain?.id !== ARBITRUM_SEPOLIA.id */
) {
setCorrectChain()
}
}
}, [wallet?.provider])
}, [wallet?.provider, setChain, settingChain, chainSwitched])
}

export function useConnect() {
const [{ wallet }, connect, disconnect] = useConnectWallet()
const { updateWalletOnboarding } = useWalletOnboarding()
const posthog = usePostHog()

const disconnectBound = useCallback(() => {
updateWalletOnboarding("")
return wallet && disconnect(wallet)
}, [wallet, disconnect, updateWalletOnboarding])

const connectBound = useCallback(async () => {
const [walletState] = await connect()

if (walletState) {
posthog?.capture("Wallet connected", {
wallet: walletState.label,
})
}
}, [connect, posthog])

return {
isConnected: process.env.IS_COMING_SOON !== "true" && !!wallet,
connect,
connect: connectBound,
disconnect: disconnectBound,
}
}
Expand Down
44 changes: 33 additions & 11 deletions src/shared/utils/web3Onboard.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,60 @@
import tahoWalletModule from "@web3-onboard/taho"
import trezorModule from "@web3-onboard/trezor"
import walletConnectModule from "@web3-onboard/walletconnect"
import metamaskSDK from "@web3-onboard/metamask"
import { init } from "@web3-onboard/react"
import { ARBITRUM_SEPOLIA } from "shared/constants"
import favicon from "shared/assets/favicon.svg"

const SUBSACAPE_NAME = "Subscape"
const SUBSACAPE_URL = "https://app.taho.xyz"
const SUBSACAPE_ICON = favicon
const chains = [ARBITRUM_SEPOLIA]

const appMetadata = {
name: SUBSACAPE_NAME,
description: "Subscape dapp",
icon: SUBSACAPE_ICON,
}

const walletsSetup = {
taho: tahoWalletModule(),
trezor: trezorModule({
// TODO: use proper email and url
email: "[email protected]",
appUrl: "https://taho.xyz",
appUrl: SUBSACAPE_URL,
}),
walletConnect: walletConnectModule({
projectId: process.env.WALLET_CONNECT_ID ?? "",
requiredChains: [parseInt(ARBITRUM_SEPOLIA.id, 16)],
}),
metamask: metamaskSDK({
options: {
extensionOnly: false,
dappMetadata: {
name: SUBSACAPE_NAME,
url: SUBSACAPE_URL,
},
},
}),
}

const wallets = [walletsSetup.taho]

const chains = [ARBITRUM_SEPOLIA]
// TODO: decide what metadata should look like
const appMetadata = {
name: "Taho Dapp",
description: "Taho Dapp",
icon: "https://raw.githubusercontent.com/tahowallet/taho.xyz/29a091abf919b5cfcf511fd10c41d73490ce4f23/src/shared/favicon.svg",
}
const hasTaho = "taho" in window
const wallets = hasTaho
? [walletsSetup.taho]
: [walletsSetup.taho, walletsSetup.metamask]

const web3Onboard = init({
wallets,
chains,
appMetadata,
connect: {
autoConnectLastWallet: true,
// TODO: web3onboard remembers last wallet that was used. If it was MM but MM becomes
// unavailable then web3onboard will try to auto connect to MM and will fail.
// So to avoid problem with attempting auto connection to the wallet
// that is not available on the wallet lists let's just disable autoConnect
// feature for Metamask for now.
autoConnectLastWallet: hasTaho,
iDontHaveAWalletLink:
"https://chrome.google.com/webstore/detail/taho/eajafomhmkipbjmfmhebemolkcicgfmd",
removeWhereIsMyWalletWarning: true,
Expand Down
4 changes: 3 additions & 1 deletion src/ui/DApps/DesktopDApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
reflectSingleton,
useBalanceFetch,
useConnect,
useCorrectChain,
useGameDataFetch,
useGameLoadDataFetch,
useInitializeReflect,
Expand All @@ -31,10 +32,11 @@ function DesktopDAppContent() {
usePopulationFetch()
useGameDataFetch()
useWalletChange()
useCorrectChain()

return (
<>
{!walletOnboarded && <Onboarding />}
{(!walletOnboarded || !isConnected) && <Onboarding />}
{walletOnboarded && isConnected && <IslandView />}
<PrivacyPolicy />
</>
Expand Down
Loading

0 comments on commit 8186cf7

Please sign in to comment.