Skip to content
This repository has been archived by the owner on Jun 24, 2022. It is now read-only.

Use previously supported wallets #2166

Merged
merged 7 commits into from
Mar 1, 2022
Merged
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
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ REACT_APP_NETWORK_URL_100=https://rpc.xdaichain.com

# Wallets
REACT_APP_PORTIS_ID="c0e2bf01-4b08-4fd5-ac7b-8e26b58cd236"
REACT_APP_FORTMATIC_KEY="pk_live_F937DF033A1666BF"
REACT_APP_FORTMATIC_KEY="pk_live_6AED76CA755EFDC7"
REACT_APP_FORTMATIC_SITE_VERIFICATION="LzjrtdM7hqVJfvvA"

# Domain regex (to detect environment)
Expand Down
4 changes: 3 additions & 1 deletion .env.production
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ REACT_APP_NETWORK_URL_100=https://rpc.xdaichain.com

# Wallets
REACT_APP_PORTIS_ID="c0e2bf01-4b08-4fd5-ac7b-8e26b58cd236"
REACT_APP_FORTMATIC_KEY="pk_live_F937DF033A1666BF"
REACT_APP_FORTMATIC_KEY="pk_live_9E53F9A29112A9FC"
REACT_APP_FORTMATIC_KEY_BARN="pk_live_C0DA025E15EBF895"
REACT_APP_FORTMATIC_KEY_PROD="pk_live_7BD8004CBBF5CDD6"

# Domain regex (to detect environment)
REACT_APP_DOMAIN_REGEX_LOCAL="^(:?localhost:\d{2,5}|(?:127|192)(?:\.[0-9]{1,3}){3})"
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
"@web3-react/injected-connector": "^6.0.7",
"@web3-react/portis-connector": "^6.1.9",
"@web3-react/walletconnect-connector": "6.2.4",
"@web3-react/walletlink-connector": "^6.2.5",
"@web3-react/walletlink-connector": "^6.2.12",
"ajv": "^6.12.3",
"array.prototype.flat": "^1.2.4",
"array.prototype.flatmap": "^1.2.4",
Expand Down Expand Up @@ -223,6 +223,7 @@
"bnc-sdk": "^3.5.0",
"fast-safe-stringify": "^2.0.8",
"firebase": "^9.1.3",
"fortmatic": "^2.2.1",
"ipfs-http-client": "^52.0.3",
"paraswap": "^5.0.1",
"react-appzi": "^1.0.4",
Expand Down
8 changes: 0 additions & 8 deletions src/constants/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,7 @@ export const SUPPORTED_WALLETS: { [key: string]: WalletInfo } = {
description: 'Use Coinbase Wallet app on mobile device',
href: null,
color: '#315CF5',
},
COINBASE_LINK: {
name: 'Open in Coinbase Wallet',
iconURL: COINBASE_ICON_URL,
description: 'Open in Coinbase Wallet app.',
href: 'https://go.cb-w.com/mtUDhEZPy1',
color: '#315CF5',
mobile: true,
mobileOnly: true,
},
FORTMATIC: {
connector: fortmatic,
Expand Down
14 changes: 7 additions & 7 deletions src/custom/components/WalletModal/WalletModalMod.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import styled from 'styled-components/macro'

import MetamaskIcon from 'assets/images/metamask.png'
import { ReactComponent as Close } from 'assets/images/x.svg'
import { fortmatic, injected, portis } from 'connectors'
import { OVERLAY_READY } from 'connectors/Fortmatic'
import { injected, portis } from 'connectors'
// import { OVERLAY_READY } from 'connectors/Fortmatic'
import { SUPPORTED_WALLETS } from 'constants/index'
import usePrevious from 'hooks/usePrevious'
import { useModalOpen, useWalletModalToggle } from 'state/application/hooks'
Expand Down Expand Up @@ -229,11 +229,11 @@ export default function WalletModal({
}

// close wallet modal if fortmatic modal is active
useEffect(() => {
fortmatic.on(OVERLAY_READY, () => {
toggleWalletModal()
})
}, [toggleWalletModal])
// useEffect(() => {
// fortmatic.on(OVERLAY_READY, () => {
// toggleWalletModal()
// })
// }, [toggleWalletModal])

// get wallets user can switch too, depending on device/browser
function getOptions() {
Expand Down
40 changes: 32 additions & 8 deletions src/custom/components/Web3Status/Web3StatusMod.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,19 +88,30 @@ const Web3StatusConnect = styled(Web3StatusGeneric)<{ faded?: boolean }>`
`}
`

export const Web3StatusConnected = styled(Web3StatusGeneric)<{ pending?: boolean }>`
export const Web3StatusConnected = styled(Web3StatusGeneric)<{ pending?: boolean; clickDisabled?: boolean }>`
background-color: ${({ pending, theme }) => (pending ? theme.primary1 : theme.bg2)};
border: 1px solid ${({ pending, theme }) => (pending ? theme.primary1 : theme.bg3)};
color: ${({ pending, theme }) => (pending ? theme.white : theme.text1)};
font-weight: 500;
:hover,
:focus {
background-color: ${({ pending, theme }) => (pending ? darken(0.05, theme.primary1) : lighten(0.05, theme.bg2))};

:focus {
border: 1px solid ${({ pending, theme }) => (pending ? darken(0.1, theme.primary1) : darken(0.1, theme.bg3))};
}
}
${({ clickDisabled }) =>
clickDisabled &&
css`
cursor: not-allowed;
`}

${({ clickDisabled, pending }) =>
!clickDisabled &&
css`
:hover,
:focus {
background-color: ${({ theme }) => (pending ? darken(0.05, theme.primary1) : lighten(0.05, theme.bg2))};

:focus {
border: 1px solid ${({ theme }) => (pending ? darken(0.1, theme.primary1) : darken(0.1, theme.bg3))};
}
}
`}
`

export const Text = styled.p`
Expand Down Expand Up @@ -172,10 +183,12 @@ export function Web3StatusInner({
pendingCount,
StatusIconComponent,
openOrdersPanel, // mod
thereWasAProvider, //mod
}: {
pendingCount?: number
StatusIconComponent: (props: { connector: AbstractConnector }) => JSX.Element | null
openOrdersPanel: () => void // mod
thereWasAProvider: boolean //mod
}) {
const { account, connector, error } = useWeb3React()

Expand Down Expand Up @@ -230,6 +243,17 @@ export function Web3StatusInner({
<Text>{error instanceof UnsupportedChainIdError ? <Trans>Wrong Network</Trans> : <Trans>Error</Trans>}</Text>
</Web3StatusError>
)
} else if (thereWasAProvider) {
return (
<Web3StatusConnected pending clickDisabled={true}>
<RowBetween>
<Text>
<Trans>Connecting</Trans>...
</Text>{' '}
<Loader stroke="white" />
</RowBetween>
</Web3StatusConnected>
)
} else {
return (
<Web3StatusConnect id="connect-wallet" onClick={toggleWalletModal} faded={!account}>
Expand Down
6 changes: 4 additions & 2 deletions src/custom/components/Web3Status/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import useRecentActivity, { TransactionAndOrder } from 'hooks/useRecentActivity'
import { useWalletInfo } from 'hooks/useWalletInfo'
import { ButtonSecondary } from 'components/Button'
import { OrderStatus } from '@src/custom/state/orders/actions'
import { STORAGE_KEY_LAST_PROVIDER } from 'constants/index'

export const Wrapper = styled.div`
color: ${({ theme }) => theme.wallet?.color};
Expand Down Expand Up @@ -72,7 +73,7 @@ interface Web3StatusProps {

export default function Web3Status({ openOrdersPanel }: Web3StatusProps) {
const walletInfo = useWalletInfo()

const latestProvider = localStorage.getItem(STORAGE_KEY_LAST_PROVIDER)
// Returns all RECENT (last day) transaction and orders in 2 arrays: pending and confirmed
const allRecentActivity = useRecentActivity()

Expand All @@ -88,7 +89,7 @@ export default function Web3Status({ openOrdersPanel }: Web3StatusProps) {
}, [allRecentActivity])

const { active, activeNetwork, ensName } = walletInfo
if (!activeNetwork && !active) {
if (!activeNetwork && !active && !latestProvider) {
return null
}

Expand All @@ -98,6 +99,7 @@ export default function Web3Status({ openOrdersPanel }: Web3StatusProps) {
pendingCount={pendingActivity.length}
StatusIconComponent={StatusIcon}
openOrdersPanel={openOrdersPanel}
thereWasAProvider={!!latestProvider}
/>
<WalletModal ENSName={ensName} pendingTransactions={pendingActivity} confirmedTransactions={confirmedActivity} />
</Wrapper>
Expand Down
56 changes: 56 additions & 0 deletions src/custom/connectors/Fortmatic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { FortmaticConnector as FortmaticConnectorCore } from '@web3-react/fortmatic-connector'
import { isProd, isBarn } from 'utils/environments'
import { SupportedChainId } from 'constants/chains'

export const OVERLAY_READY = 'OVERLAY_READY'

type FormaticSupportedChains = SupportedChainId.MAINNET | SupportedChainId.RINKEBY

const CHAIN_ID_NETWORK_ARGUMENT: Partial<Record<SupportedChainId, string | undefined>> = {
[SupportedChainId.MAINNET]: undefined,
[SupportedChainId.RINKEBY]: 'rinkeby',
}

export class FortmaticConnector extends FortmaticConnectorCore {
async activate() {
if (!this.fortmatic) {
const { default: Fortmatic } = await import('fortmatic')

const { apiKey, chainId } = this as any
if (chainId in CHAIN_ID_NETWORK_ARGUMENT) {
this.fortmatic = new Fortmatic(apiKey, CHAIN_ID_NETWORK_ARGUMENT[chainId as FormaticSupportedChains])
} else {
throw new Error(`Unsupported network ID: ${chainId}`)
}
}

const provider = this.fortmatic.getProvider()

// It is no longer necessary
// const pollForOverlayReady = new Promise<void>((resolve) => {
// const interval = setInterval(() => {
// if (provider.overlay.overlayReady) {
// clearInterval(interval)
// this.emit(OVERLAY_READY)
// resolve()
// }
// }, 200)
// })

const account = await provider.enable().then((accounts: string[]) => accounts[0])

return { provider: this.fortmatic.getProvider(), chainId: (this as any).chainId, account }
}
}

// Allows to select fortmatic envvar according to prod, barn or test environment
export function getFortmaticApiKey(): string | undefined {
let apiKey = process.env.REACT_APP_FORTMATIC_KEY
if (isProd) {
apiKey = process.env.REACT_APP_FORTMATIC_KEY_PROD
} else if (isBarn) {
apiKey = process.env.REACT_APP_FORTMATIC_KEY_BARN
}

return apiKey
}
5 changes: 3 additions & 2 deletions src/custom/connectors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { WalletConnectConnector } from '@web3-react/walletconnect-connector'
import { WalletLinkConnector } from '@web3-react/walletlink-connector'
import { PortisConnector } from '@web3-react/portis-connector'

import { FortmaticConnector } from 'connectors/Fortmatic'
import { FortmaticConnector, getFortmaticApiKey } from 'connectors/Fortmatic'
import { NetworkConnector } from 'connectors/NetworkConnector'
import { AbstractConnector } from '@web3-react/abstract-connector'

Expand Down Expand Up @@ -91,7 +91,7 @@ export const walletconnect = new WalletConnectConnector({

// mainnet only
export const fortmatic = new FortmaticConnector({
apiKey: process.env.REACT_APP_FORTMATIC_KEY ?? '',
apiKey: getFortmaticApiKey() ?? '',
chainId: NETWORK_CHAIN_ID,
})

Expand All @@ -108,6 +108,7 @@ export const walletlink = new WalletLinkConnector({
url: rpcNetworks[NETWORK_CHAIN_ID],
appName: 'CowSwap',
appLogoUrl: 'https://raw.githubusercontent.com/gnosis/gp-swap-ui/develop/public/favicon.png',
supportedChainIds: getSupportedChainIds(),
})

export enum WalletProvider {
Expand Down
2 changes: 1 addition & 1 deletion src/custom/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const APP_DATA_HASH = getAppDataHash()
export const PRODUCTION_URL = 'cowswap.exchange'
export const BARN_URL = `barn.${PRODUCTION_URL}`

const DISABLED_WALLETS = /^(?:WALLET_LINK|COINBASE_LINK|FORTMATIC|Portis)$/i
const DISABLED_WALLETS = /^(?:Portis)$/i

// Re-export only the supported wallets
export const SUPPORTED_WALLETS = Object.keys(SUPPORTED_WALLETS_UNISWAP).reduce((acc, key) => {
Expand Down
85 changes: 64 additions & 21 deletions src/custom/hooks/web3.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import { useWeb3React as useWeb3ReactCore } from '@web3-react/core'
import { AbstractConnector } from '@web3-react/abstract-connector'
import { useEffect, useState, useCallback } from 'react'
import { isMobile } from 'react-device-detect'
import { injected, walletconnect, getProviderType, WalletProvider } from 'connectors'
import { injected, walletconnect, getProviderType, WalletProvider, fortmatic, walletlink } from 'connectors'
import { STORAGE_KEY_LAST_PROVIDER } from 'constants/index'

// exports from the original file
export { useActiveWeb3React, useInactiveListener } from '@src/hooks/web3'

enum DefaultProvidersInjected {
METAMASK = WalletProvider.INJECTED,
COINBASE_WALLET = WalletProvider.WALLET_LINK,
}

export function useEagerConnect() {
const { activate, active, connector } = useWeb3ReactCore()
const [tried, setTried] = useState(false)
Expand All @@ -22,30 +28,38 @@ export function useEagerConnect() {
}
}, [connector, active])

const connectInjected = useCallback(() => {
// check if the our application is authorized/connected with Metamask
injected.isAuthorized().then((isAuthorized) => {
if (isAuthorized) {
activate(injected, undefined, true).catch(() => {
setTried(true)
})
} else {
if (isMobile && window.ethereum) {
const connectInjected = useCallback(
(providerName = DefaultProvidersInjected.METAMASK) => {
// check if the our application is authorized/connected with Metamask
injected.isAuthorized().then((isAuthorized) => {
if (isAuthorized) {
setDefaultInjected(providerName)
activate(injected, undefined, true).catch(() => {
setTried(true)
})
} else {
setTried(true)
if (isMobile && window.ethereum) {
setDefaultInjected(providerName)
activate(injected, undefined, true).catch(() => {
setTried(true)
})
} else {
setTried(true)
}
}
}
})
}, [activate, setTried])
})
},
[activate, setTried]
)

const connectWalletConnect = useCallback(() => {
activate(walletconnect, undefined, true).catch(() => {
setTried(true)
})
}, [activate, setTried])
const reconnectUninjectedProvider = useCallback(
(provider: AbstractConnector): void => {
activate(provider, undefined, true).catch(() => {
setTried(true)
})
},
[activate, setTried]
)

useEffect(() => {
if (!active) {
Expand All @@ -60,10 +74,14 @@ export function useEagerConnect() {
connectInjected()
} else if (latestProvider === WalletProvider.WALLET_CONNECT) {
// WC is last provider
connectWalletConnect()
reconnectUninjectedProvider(walletconnect)
} else if (latestProvider === WalletProvider.WALLET_LINK) {
reconnectUninjectedProvider(walletlink)
} else if (latestProvider === WalletProvider.FORMATIC) {
reconnectUninjectedProvider(fortmatic)
}
}
}, [connectInjected, connectWalletConnect, active]) // intentionally only running on mount (make sure it's only mounted once :))
}, [connectInjected, active, reconnectUninjectedProvider]) // intentionally only running on mount (make sure it's only mounted once :))

// if the connection worked, wait until we get confirmation of that to flip the flag
useEffect(() => {
Expand All @@ -84,3 +102,28 @@ export function useEagerConnect() {

return tried
}

/**
* Allows to select the default injected ethereum provider.
*
* It is assumed that metamask is the default injected Provider, however coinbaseWallet overrides this.
*/
export function setDefaultInjected(providerName: DefaultProvidersInjected) {
const { ethereum } = window

if (!ethereum?.providers) return

let provider
switch (providerName) {
case DefaultProvidersInjected.COINBASE_WALLET:
provider = ethereum.providers.find(({ isCoinbaseWallet }) => isCoinbaseWallet)
break
case DefaultProvidersInjected.METAMASK:
provider = ethereum.providers.find(({ isMetaMask }) => isMetaMask)
break
}

if (provider) {
ethereum.setSelectedProvider(provider)
}
}
Loading