diff --git a/.gitignore b/.gitignore
index f0f1b52a0..0024f7f36 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@ node_modules/
 packages/*/dist/
 example/.next/
 .env.local
+.idea/
diff --git a/example/components/Card.tsx b/example/components/Card.tsx
index 64582b5c6..2c5a56993 100644
--- a/example/components/Card.tsx
+++ b/example/components/Card.tsx
@@ -1,6 +1,7 @@
 import type { CoinbaseWallet } from '@web3-react/coinbase-wallet'
 import type { Web3ReactHooks } from '@web3-react/core'
 import type { GnosisSafe } from '@web3-react/gnosis-safe'
+import type { ClvWallet } from '@web3-react/clvWallet'
 import type { MetaMask } from '@web3-react/metamask'
 import type { Network } from '@web3-react/network'
 import type { WalletConnect } from '@web3-react/walletconnect'
@@ -13,7 +14,7 @@ import { ConnectWithSelect } from './ConnectWithSelect'
 import { Status } from './Status'
 
 interface Props {
-  connector: MetaMask | WalletConnect | WalletConnectV2 | CoinbaseWallet | Network | GnosisSafe
+  connector: ClvWallet | MetaMask | WalletConnect | WalletConnectV2 | CoinbaseWallet | Network | GnosisSafe
   activeChainId: ReturnType<Web3ReactHooks['useChainId']>
   chainIds?: ReturnType<Web3ReactHooks['useChainId']>[]
   isActivating: ReturnType<Web3ReactHooks['useIsActivating']>
diff --git a/example/components/ConnectWithSelect.tsx b/example/components/ConnectWithSelect.tsx
index 3568c6574..b4c38345b 100644
--- a/example/components/ConnectWithSelect.tsx
+++ b/example/components/ConnectWithSelect.tsx
@@ -1,6 +1,7 @@
 import type { CoinbaseWallet } from '@web3-react/coinbase-wallet'
 import type { Web3ReactHooks } from '@web3-react/core'
 import { GnosisSafe } from '@web3-react/gnosis-safe'
+import { ClvWallet } from '@web3-react/clvWallet'
 import type { MetaMask } from '@web3-react/metamask'
 import { Network } from '@web3-react/network'
 import { WalletConnect } from '@web3-react/walletconnect'
@@ -48,7 +49,7 @@ export function ConnectWithSelect({
   error,
   setError,
 }: {
-  connector: MetaMask | WalletConnect | WalletConnectV2 | CoinbaseWallet | Network | GnosisSafe
+  connector: ClvWallet | MetaMask | WalletConnect | WalletConnectV2 | CoinbaseWallet | Network | GnosisSafe
   activeChainId: ReturnType<Web3ReactHooks['useChainId']>
   chainIds?: ReturnType<Web3ReactHooks['useChainId']>[]
   isActivating: ReturnType<Web3ReactHooks['useIsActivating']>
diff --git a/example/components/ProviderExample.tsx b/example/components/ProviderExample.tsx
index 8721d3318..bee863360 100644
--- a/example/components/ProviderExample.tsx
+++ b/example/components/ProviderExample.tsx
@@ -1,18 +1,21 @@
 import type { CoinbaseWallet } from '@web3-react/coinbase-wallet'
 import { useWeb3React, Web3ReactHooks, Web3ReactProvider } from '@web3-react/core'
+import type { ClvWallet } from '@web3-react/clvWallet'
 import type { MetaMask } from '@web3-react/metamask'
 import type { Network } from '@web3-react/network'
 import type { WalletConnect } from '@web3-react/walletconnect'
 import type { WalletConnect as WalletConnectV2 } from '@web3-react/walletconnect-v2'
 
 import { coinbaseWallet, hooks as coinbaseWalletHooks } from '../connectors/coinbaseWallet'
+import { hooks as clvWalletHooks, clvWallet } from '../connectors/clvWallet'
 import { hooks as metaMaskHooks, metaMask } from '../connectors/metaMask'
 import { hooks as networkHooks, network } from '../connectors/network'
 import { hooks as walletConnectHooks, walletConnect } from '../connectors/walletConnect'
 import { hooks as walletConnectV2Hooks, walletConnectV2 } from '../connectors/walletConnectV2'
 import { getName } from '../utils'
 
-const connectors: [MetaMask | WalletConnect | WalletConnectV2 | CoinbaseWallet | Network, Web3ReactHooks][] = [
+const connectors: [ClvWallet | MetaMask | WalletConnect | WalletConnectV2 | CoinbaseWallet | Network, Web3ReactHooks][] = [
+  [clvWallet, clvWalletHooks],
   [metaMask, metaMaskHooks],
   [walletConnect, walletConnectHooks],
   [walletConnectV2, walletConnectV2Hooks],
diff --git a/example/components/connectorCards/ClvWalletCard.tsx b/example/components/connectorCards/ClvWalletCard.tsx
new file mode 100644
index 000000000..7497db735
--- /dev/null
+++ b/example/components/connectorCards/ClvWalletCard.tsx
@@ -0,0 +1,40 @@
+import { useEffect, useState } from 'react'
+import { hooks, clvWallet } from '../../connectors/clvWallet'
+import { Card } from '../Card'
+
+
+const { useChainId, useAccounts, useIsActivating, useIsActive, useProvider, useENSNames } = hooks
+
+export default function ClvWalletCard() {
+  const chainId = useChainId()
+  const accounts = useAccounts()
+  const isActivating = useIsActivating()
+
+  const isActive = useIsActive()
+
+  const provider = useProvider()
+  const ENSNames = useENSNames(provider)
+
+  const [error, setError] = useState(undefined)
+
+  // attempt to connect eagerly on mount
+  useEffect(() => {
+    clvWallet.connectEagerly().catch((error) => {
+      console.debug('Failed to connect eagerly to clvWallet', error)
+    })
+  }, [])
+
+  return (
+    <Card
+      connector={clvWallet}
+      activeChainId={chainId}
+      isActivating={isActivating}
+      isActive={isActive}
+      error={error}
+      setError={setError}
+      accounts={accounts}
+      provider={provider}
+      ENSNames={ENSNames}
+    />
+  )
+}
diff --git a/example/connectors/clvWallet.ts b/example/connectors/clvWallet.ts
new file mode 100644
index 000000000..8ca4d4414
--- /dev/null
+++ b/example/connectors/clvWallet.ts
@@ -0,0 +1,4 @@
+import { initializeConnector } from '@web3-react/core'
+import { ClvWallet } from '@web3-react/clvWallet'
+
+export const [clvWallet, hooks] = initializeConnector<ClvWallet>((actions) => new ClvWallet({ actions }))
diff --git a/example/pages/index.tsx b/example/pages/index.tsx
index baefa90fd..0f304f3c2 100644
--- a/example/pages/index.tsx
+++ b/example/pages/index.tsx
@@ -1,6 +1,7 @@
 import CoinbaseWalletCard from '../components/connectorCards/CoinbaseWalletCard'
 import GnosisSafeCard from '../components/connectorCards/GnosisSafeCard'
 import MetaMaskCard from '../components/connectorCards/MetaMaskCard'
+import ClvWalletCard from '../components/connectorCards/ClvWalletCard'
 import NetworkCard from '../components/connectorCards/NetworkCard'
 import WalletConnectV2Card from '../components/connectorCards/WalletConnectV2Card'
 import ProviderExample from '../components/ProviderExample'
@@ -10,6 +11,7 @@ export default function Home() {
     <>
       <ProviderExample />
       <div style={{ display: 'flex', flexFlow: 'wrap', fontFamily: 'sans-serif' }}>
+        <ClvWalletCard />
         <MetaMaskCard />
         <WalletConnectV2Card />
         <CoinbaseWalletCard />
diff --git a/example/utils.ts b/example/utils.ts
index 68e79460a..e275effbc 100644
--- a/example/utils.ts
+++ b/example/utils.ts
@@ -1,5 +1,6 @@
 import { CoinbaseWallet } from '@web3-react/coinbase-wallet'
 import { GnosisSafe } from '@web3-react/gnosis-safe'
+import { ClvWallet } from '@web3-react/clvWallet'
 import { MetaMask } from '@web3-react/metamask'
 import { Network } from '@web3-react/network'
 import type { Connector } from '@web3-react/types'
@@ -7,6 +8,7 @@ import { WalletConnect as WalletConnect } from '@web3-react/walletconnect'
 import { WalletConnect as WalletConnectV2 } from '@web3-react/walletconnect-v2'
 
 export function getName(connector: Connector) {
+  if (connector instanceof ClvWallet) return 'ClvWallet'
   if (connector instanceof MetaMask) return 'MetaMask'
   if (connector instanceof WalletConnectV2) return 'WalletConnect V2'
   if (connector instanceof WalletConnect) return 'WalletConnect'
diff --git a/packages/clvWallet/README.md b/packages/clvWallet/README.md
new file mode 100644
index 000000000..76ac99adc
--- /dev/null
+++ b/packages/clvWallet/README.md
@@ -0,0 +1 @@
+# @web3-react/clvWallet
diff --git a/packages/clvWallet/package.json b/packages/clvWallet/package.json
new file mode 100644
index 000000000..771eb766b
--- /dev/null
+++ b/packages/clvWallet/package.json
@@ -0,0 +1,32 @@
+{
+  "name": "@web3-react/clvWallet",
+  "keywords": [
+    "web3-react",
+    "clvWallet"
+  ],
+  "author": "Noah Zinsmeister <noahwz@gmail.com>",
+  "license": "GPL-3.0-or-later",
+  "repository": "github:Uniswap/web3-react",
+  "publishConfig": {
+    "access": "public"
+  },
+  "version": "8.2.3",
+  "files": [
+    "dist/*"
+  ],
+  "type": "commonjs",
+  "types": "./dist/index.d.ts",
+  "main": "./dist/index.js",
+  "exports": "./dist/index.js",
+  "scripts": {
+    "prebuild": "rm -rf dist",
+    "build": "tsc",
+    "start": "tsc --watch"
+  },
+  "dependencies": {
+    "@web3-react/types": "^8.2.2"
+  },
+  "devDependencies": {
+    "@web3-react/store": "^8.2.2"
+  }
+}
diff --git a/packages/clvWallet/src/index.spec.ts b/packages/clvWallet/src/index.spec.ts
new file mode 100644
index 000000000..c2d982200
--- /dev/null
+++ b/packages/clvWallet/src/index.spec.ts
@@ -0,0 +1,66 @@
+import { createWeb3ReactStoreAndActions } from '@web3-react/store'
+import type { Actions, Web3ReactStore } from '@web3-react/types'
+import {ClvWallet} from '.'
+import { MockEIP1193Provider } from '@web3-react/core'
+
+const chainId = '0x1'
+const accounts: string[] = ['0x0000000000000000000000000000000000000000']
+
+describe('ClvWallet', () => {
+  let mockProvider: MockEIP1193Provider
+
+  beforeEach(() => {
+    mockProvider = new MockEIP1193Provider()
+  })
+
+  beforeEach(() => {
+    ;(window as any).ethereum = mockProvider
+  })
+
+  let store: Web3ReactStore
+  let connector: ClvWallet
+
+  beforeEach(() => {
+    let actions: Actions
+    ;[store, actions] = createWeb3ReactStoreAndActions()
+    connector = new ClvWallet({ actions })
+  })
+
+  test('#connectEagerly', async () => {
+    mockProvider.chainId = chainId
+    mockProvider.accounts = accounts
+
+    await connector.connectEagerly()
+
+    expect(mockProvider.eth_requestAccounts).not.toHaveBeenCalled()
+    expect(mockProvider.eth_accounts).toHaveBeenCalled()
+    expect(mockProvider.eth_chainId).toHaveBeenCalled()
+    expect(mockProvider.eth_chainId.mock.invocationCallOrder[0])
+      .toBeGreaterThan(mockProvider.eth_accounts.mock.invocationCallOrder[0])
+
+    expect(store.getState()).toEqual({
+      chainId: Number.parseInt(chainId, 16),
+      accounts,
+      activating: false,
+    })
+  })
+
+  test('#activate', async () => {
+    mockProvider.chainId = chainId
+    mockProvider.accounts = accounts
+
+    await connector.activate()
+
+    expect(mockProvider.eth_requestAccounts).toHaveBeenCalled()
+    expect(mockProvider.eth_accounts).not.toHaveBeenCalled()
+    expect(mockProvider.eth_chainId).toHaveBeenCalled()
+    expect(mockProvider.eth_chainId.mock.invocationCallOrder[0])
+      .toBeGreaterThan(mockProvider.eth_requestAccounts.mock.invocationCallOrder[0])
+
+    expect(store.getState()).toEqual({
+      chainId: Number.parseInt(chainId, 16),
+      accounts,
+      activating: false,
+    })
+  })
+})
diff --git a/packages/clvWallet/src/index.ts b/packages/clvWallet/src/index.ts
new file mode 100644
index 000000000..0a8c86e95
--- /dev/null
+++ b/packages/clvWallet/src/index.ts
@@ -0,0 +1,202 @@
+import type {
+  Actions,
+  AddEthereumChainParameter,
+  Provider,
+  ProviderConnectInfo,
+  ProviderRpcError,
+  WatchAssetParameters,
+} from '@web3-react/types'
+import { Connector } from '@web3-react/types'
+
+type ClvWalletProvider = Provider & {
+  isClover?: boolean
+  isConnected?: () => boolean
+  providers?: ClvWalletProvider[]
+}
+
+export class NoClvWalletError extends Error {
+  public constructor() {
+    super('ClvWallet not installed')
+    this.name = NoClvWalletError.name
+    Object.setPrototypeOf(this, NoClvWalletError.prototype)
+  }
+}
+
+function parseChainId(chainId: string) {
+  return Number.parseInt(chainId, 16)
+}
+
+/**
+ * @param options - Options to pass to `@clvWallet/detect-provider`
+ * @param onError - Handler to report errors thrown from eventListeners.
+ */
+export interface ClvWalletConstructorArgs {
+  actions: Actions
+  options?: Parameters<any>[0]
+  onError?: (error: Error) => void
+}
+
+export class ClvWallet extends Connector {
+  /** {@inheritdoc Connector.provider} */
+  public provider?: ClvWalletProvider
+
+  private readonly options?: Parameters<any>[0]
+  private eagerConnection?: Promise<void>
+
+  constructor({ actions, options, onError }: ClvWalletConstructorArgs) {
+    super(actions, onError)
+    this.options = options
+  }
+
+  private async isomorphicInitialize(): Promise<void> {
+    if (this.eagerConnection) return
+
+    const windowObj: any = window
+    const provider = windowObj.clover as any
+    if (provider) {
+      this.provider = provider as ClvWalletProvider
+
+      // handle the case when e.g. clvWallet and coinbase wallet are both installed
+      if (this.provider.providers?.length) {
+        this.provider = this.provider.providers.find((p) => p.isClover) ?? this.provider.providers[0]
+      }
+
+      this.provider.on('connect', ({ chainId }: ProviderConnectInfo): void => {
+        this.actions.update({ chainId: parseChainId(chainId) })
+      })
+
+      this.provider.on('disconnect', (error: ProviderRpcError): void => {
+        // 1013 indicates that ClvWallet is attempting to reestablish the connection
+        // https://github.com/ClvWallet/providers/releases/tag/v8.0.0
+        if (error.code === 1013) {
+          console.debug('ClvWallet logged connection error 1013: "Try again later"')
+          return
+        }
+        this.actions.resetState()
+        this.onError?.(error)
+      })
+
+      this.provider.on('chainChanged', (chainId: string): void => {
+        this.actions.update({ chainId: parseChainId(chainId) })
+      })
+
+      this.provider.on('accountsChanged', (accounts: string[]): void => {
+        if (accounts.length === 0) {
+          // handle this edge case by disconnecting
+          this.actions.resetState()
+        } else {
+          this.actions.update({ accounts })
+        }
+      })
+    }
+  }
+
+  /** {@inheritdoc Connector.connectEagerly} */
+  public async connectEagerly(): Promise<void> {
+    const cancelActivation = this.actions.startActivation()
+
+    try {
+      await this.isomorphicInitialize()
+      if (!this.provider) return cancelActivation()
+
+      // Wallets may resolve eth_chainId and hang on eth_accounts pending user interaction, which may include changing
+      // chains; they should be requested serially, with accounts first, so that the chainId can settle.
+      const accounts = (await this.provider.request({ method: 'eth_accounts' })) as string[]
+      if (!accounts.length) throw new Error('No accounts returned')
+      const chainId = (await this.provider.request({ method: 'eth_chainId' })) as string
+      this.actions.update({ chainId: parseChainId(chainId), accounts })
+    } catch (error) {
+      console.debug('Could not connect eagerly', error)
+      // we should be able to use `cancelActivation` here, but on mobile, clvWallet emits a 'connect'
+      // event, meaning that chainId is updated, and cancelActivation doesn't work because an intermediary
+      // update has occurred, so we reset state instead
+      this.actions.resetState()
+    }
+  }
+
+  /**
+   * Initiates a connection.
+   *
+   * @param desiredChainIdOrChainParameters - If defined, indicates the desired chain to connect to. If the user is
+   * already connected to this chain, no additional steps will be taken. Otherwise, the user will be prompted to switch
+   * to the chain, if one of two conditions is met: either they already have it added in their extension, or the
+   * argument is of type AddEthereumChainParameter, in which case the user will be prompted to add the chain with the
+   * specified parameters first, before being prompted to switch.
+   */
+  public async activate(desiredChainIdOrChainParameters?: number | AddEthereumChainParameter): Promise<void> {
+    let cancelActivation: () => void
+    if (!this.provider?.isConnected?.()) cancelActivation = this.actions.startActivation()
+
+    return this.isomorphicInitialize()
+      .then(async () => {
+        if (!this.provider) throw new NoClvWalletError()
+
+        // Wallets may resolve eth_chainId and hang on eth_accounts pending user interaction, which may include changing
+        // chains; they should be requested serially, with accounts first, so that the chainId can settle.
+        const accounts = (await this.provider.request({ method: 'eth_requestAccounts' })) as string[]
+        const chainId = (await this.provider.request({ method: 'eth_chainId' })) as string
+        const receivedChainId = parseChainId(chainId)
+        const desiredChainId =
+          typeof desiredChainIdOrChainParameters === 'number'
+            ? desiredChainIdOrChainParameters
+            : desiredChainIdOrChainParameters?.chainId
+
+        // if there's no desired chain, or it's equal to the received, update
+        if (!desiredChainId || receivedChainId === desiredChainId)
+          return this.actions.update({ chainId: receivedChainId, accounts })
+
+        const desiredChainIdHex = `0x${desiredChainId.toString(16)}`
+
+        // if we're here, we can try to switch networks
+        return this.provider
+          .request({
+            method: 'wallet_switchEthereumChain',
+            params: [{ chainId: desiredChainIdHex }],
+          })
+          .catch((error: ProviderRpcError) => {
+            // https://github.com/ClvWallet/clvWallet-mobile/issues/3312#issuecomment-1065923294
+            const errorCode = (error.data as any)?.originalError?.code || error.code
+
+            // 4902 indicates that the chain has not been added to ClvWallet and wallet_addEthereumChain needs to be called
+            // https://docs.clvWallet.io/guide/rpc-api.html#wallet-switchethereumchain
+            if (errorCode === 4902 && typeof desiredChainIdOrChainParameters !== 'number') {
+              if (!this.provider) throw new Error('No provider')
+              // if we're here, we can try to add a new network
+              return this.provider.request({
+                method: 'wallet_addEthereumChain',
+                params: [{ ...desiredChainIdOrChainParameters, chainId: desiredChainIdHex }],
+              })
+            }
+
+            throw error
+          })
+          .then(() => this.activate(desiredChainId))
+      })
+      .catch((error) => {
+        cancelActivation?.()
+        throw error
+      })
+  }
+
+  public async watchAsset({ address, symbol, decimals, image }: WatchAssetParameters): Promise<true> {
+    if (!this.provider) throw new Error('No provider')
+
+    return this.provider
+      .request({
+        method: 'wallet_watchAsset',
+        params: {
+          type: 'ERC20', // Initially only supports ERC20, but eventually more!
+          options: {
+            address, // The address that the token is at.
+            symbol, // A ticker symbol or shorthand, up to 5 chars.
+            decimals, // The number of decimals in the token
+            image, // A string url of the token logo
+          },
+        },
+      })
+      .then((success) => {
+        if (!success) throw new Error('Rejected')
+        return true
+      })
+  }
+}
diff --git a/packages/clvWallet/tsconfig.json b/packages/clvWallet/tsconfig.json
new file mode 100644
index 000000000..67531bbb0
--- /dev/null
+++ b/packages/clvWallet/tsconfig.json
@@ -0,0 +1,7 @@
+{
+  "extends": "../../tsconfig.json",
+  "include": ["./src"],
+  "compilerOptions": {
+    "outDir": "./dist"
+  }
+}