1
0
mirror of https://github.com/oceanprotocol/market.git synced 2024-12-02 05:57:29 +01:00

wagmi + ethers + web3modal setup

This commit is contained in:
Matthias Kretschmann 2023-01-18 16:11:18 +00:00
parent f0889e5edc
commit 9a4de0cab9
Signed by: m
GPG Key ID: 606EEEF3C479A91F
6 changed files with 5121 additions and 1658 deletions

View File

@ -1,4 +1,5 @@
#NEXT_PUBLIC_INFURA_PROJECT_ID="xxx" #NEXT_PUBLIC_INFURA_PROJECT_ID="xxx"
#NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID="xxx"
#NEXT_PUBLIC_MARKET_FEE_ADDRESS="0xxx" #NEXT_PUBLIC_MARKET_FEE_ADDRESS="0xxx"
#NEXT_PUBLIC_PUBLISHER_MARKET_ORDER_FEE="1" #NEXT_PUBLIC_PUBLISHER_MARKET_ORDER_FEE="1"
#NEXT_PUBLIC_PUBLISHER_MARKET_FIXED_SWAP_FEE="1" #NEXT_PUBLIC_PUBLISHER_MARKET_FIXED_SWAP_FEE="1"

6474
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -31,13 +31,15 @@
"@oceanprotocol/use-dark-mode": "^2.4.3", "@oceanprotocol/use-dark-mode": "^2.4.3",
"@tippyjs/react": "^4.2.6", "@tippyjs/react": "^4.2.6",
"@urql/exchange-refocus": "^1.0.0", "@urql/exchange-refocus": "^1.0.0",
"@walletconnect/web3-provider": "^1.8.0", "@web3modal/ethereum": "^2.0.0-rc.3",
"@web3modal/react": "^2.0.0-rc.3",
"axios": "^1.2.0", "axios": "^1.2.0",
"classnames": "^2.3.2", "classnames": "^2.3.2",
"date-fns": "^2.29.3", "date-fns": "^2.29.3",
"decimal.js": "^10.4.2", "decimal.js": "^10.4.2",
"dom-confetti": "^0.2.2", "dom-confetti": "^0.2.2",
"dotenv": "^16.0.3", "dotenv": "^16.0.3",
"ethers": "^5.7.2",
"filesize": "^10.0.5", "filesize": "^10.0.5",
"formik": "^2.2.9", "formik": "^2.2.9",
"gray-matter": "^4.0.3", "gray-matter": "^4.0.3",
@ -66,8 +68,8 @@
"slugify": "^1.6.5", "slugify": "^1.6.5",
"swr": "^1.3.0", "swr": "^1.3.0",
"urql": "^3.0.3", "urql": "^3.0.3",
"wagmi": "^0.10.11",
"web3": "^1.8.1", "web3": "^1.8.1",
"web3modal": "^1.9.10",
"yup": "^0.32.11" "yup": "^0.32.11"
}, },
"devDependencies": { "devDependencies": {

View File

@ -8,11 +8,11 @@ import React, {
useCallback useCallback
} from 'react' } from 'react'
import Web3 from 'web3' import Web3 from 'web3'
import Web3Modal, { getProviderInfo, IProviderInfo } from 'web3modal' // import Web3Modal, { getProviderInfo, IProviderInfo } from 'web3modal'
import { infuraProjectId as infuraId } from '../../app.config' // import { infuraProjectId as infuraId } from '../../app.config'
import WalletConnectProvider from '@walletconnect/web3-provider' // import WalletConnectProvider from '@walletconnect/web3-provider'
import { LoggerInstance } from '@oceanprotocol/lib' import { LoggerInstance } from '@oceanprotocol/lib'
import { isBrowser } from '@utils/index' // import { isBrowser } from '@utils/index'
import { getEnsProfile } from '@utils/ens' import { getEnsProfile } from '@utils/ens'
import useNetworkMetadata, { import useNetworkMetadata, {
getNetworkDataById, getNetworkDataById,
@ -27,9 +27,9 @@ import { getOpcsApprovedTokens } from '@utils/subgraph'
interface Web3ProviderValue { interface Web3ProviderValue {
web3: Web3 web3: Web3
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
web3Provider: any // web3Provider: any
web3Modal: Web3Modal // web3Modal: Web3Modal
web3ProviderInfo: IProviderInfo // web3ProviderInfo: IProviderInfo
accountId: string accountId: string
accountEns: string accountEns: string
accountEnsAvatar: string accountEnsAvatar: string
@ -43,38 +43,38 @@ interface Web3ProviderValue {
web3Loading: boolean web3Loading: boolean
isSupportedOceanNetwork: boolean isSupportedOceanNetwork: boolean
approvedBaseTokens: TokenInfo[] approvedBaseTokens: TokenInfo[]
connect: () => Promise<void> // connect: () => Promise<void>
logout: () => Promise<void> // logout: () => Promise<void>
} }
const web3ModalTheme = { // const web3ModalTheme = {
background: 'var(--background-body)', // background: 'var(--background-body)',
main: 'var(--font-color-heading)', // main: 'var(--font-color-heading)',
secondary: 'var(--brand-grey-light)', // secondary: 'var(--brand-grey-light)',
border: 'var(--border-color)', // border: 'var(--border-color)',
hover: 'var(--background-highlight)' // hover: 'var(--background-highlight)'
} // }
const providerOptions = isBrowser // const providerOptions = isBrowser
? { // ? {
walletconnect: { // walletconnect: {
package: WalletConnectProvider, // package: WalletConnectProvider,
options: { // options: {
infuraId, // infuraId,
rpc: { // rpc: {
137: 'https://polygon-rpc.com', // 137: 'https://polygon-rpc.com',
80001: 'https://rpc-mumbai.matic.today' // 80001: 'https://rpc-mumbai.matic.today'
} // }
} // }
} // }
} // }
: {} // : {}
export const web3ModalOpts = { // export const web3ModalOpts = {
cacheProvider: true, // cacheProvider: true,
providerOptions, // providerOptions,
theme: web3ModalTheme // theme: web3ModalTheme
} // }
const refreshInterval = 20000 // 20 sec. const refreshInterval = 20000 // 20 sec.
@ -88,8 +88,8 @@ function Web3Provider({ children }: { children: ReactNode }): ReactElement {
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
const [web3Provider, setWeb3Provider] = useState<any>() const [web3Provider, setWeb3Provider] = useState<any>()
const [web3Modal, setWeb3Modal] = useState<Web3Modal>() // const [web3Modal, setWeb3Modal] = useState<Web3Modal>()
const [web3ProviderInfo, setWeb3ProviderInfo] = useState<IProviderInfo>() // const [web3ProviderInfo, setWeb3ProviderInfo] = useState<IProviderInfo>()
const [networkId, setNetworkId] = useState<number>() const [networkId, setNetworkId] = useState<number>()
const [chainId, setChainId] = useState<number>() const [chainId, setChainId] = useState<number>()
const [networkDisplayName, setNetworkDisplayName] = useState<string>() const [networkDisplayName, setNetworkDisplayName] = useState<string>()
@ -109,39 +109,39 @@ function Web3Provider({ children }: { children: ReactNode }): ReactElement {
// ----------------------------------- // -----------------------------------
// Helper: connect to web3 // Helper: connect to web3
// ----------------------------------- // -----------------------------------
const connect = useCallback(async () => { // const connect = useCallback(async () => {
if (!web3Modal) { // if (!web3Modal) {
setWeb3Loading(false) // setWeb3Loading(false)
return // return
} // }
try { // try {
setWeb3Loading(true) // setWeb3Loading(true)
LoggerInstance.log('[web3] Connecting Web3...') // LoggerInstance.log('[web3] Connecting Web3...')
const provider = await web3Modal?.connect() // const provider = await web3Modal?.connect()
setWeb3Provider(provider) // setWeb3Provider(provider)
const web3 = new Web3(provider) // const web3 = new Web3(provider)
setWeb3(web3) // setWeb3(web3)
LoggerInstance.log('[web3] Web3 created.', web3) // LoggerInstance.log('[web3] Web3 created.', web3)
const networkId = await web3.eth.net.getId() // const networkId = await web3.eth.net.getId()
setNetworkId(networkId) // setNetworkId(networkId)
LoggerInstance.log('[web3] network id ', networkId) // LoggerInstance.log('[web3] network id ', networkId)
const chainId = await web3.eth.getChainId() // const chainId = await web3.eth.getChainId()
setChainId(chainId) // setChainId(chainId)
LoggerInstance.log('[web3] chain id ', chainId) // LoggerInstance.log('[web3] chain id ', chainId)
const accountId = (await web3.eth.getAccounts())[0] // const accountId = (await web3.eth.getAccounts())[0]
setAccountId(accountId) // setAccountId(accountId)
LoggerInstance.log('[web3] account id', accountId) // LoggerInstance.log('[web3] account id', accountId)
} catch (error) { // } catch (error) {
LoggerInstance.error('[web3] Error: ', error.message) // LoggerInstance.error('[web3] Error: ', error.message)
} finally { // } finally {
setWeb3Loading(false) // setWeb3Loading(false)
} // }
}, [web3Modal]) // }, [web3Modal])
// ----------------------------------- // -----------------------------------
// Helper: Get approved base tokens list // Helper: Get approved base tokens list
@ -229,39 +229,39 @@ function Web3Provider({ children }: { children: ReactNode }): ReactElement {
// ----------------------------------- // -----------------------------------
// Create initial Web3Modal instance // Create initial Web3Modal instance
// ----------------------------------- // -----------------------------------
useEffect(() => { // useEffect(() => {
if (web3Modal) { // if (web3Modal) {
setWeb3Loading(false) // setWeb3Loading(false)
return // return
} // }
async function init() { // async function init() {
// note: needs artificial await here so the log message is reached and output // // note: needs artificial await here so the log message is reached and output
const web3ModalInstance = await new Web3Modal(web3ModalOpts) // const web3ModalInstance = await new Web3Modal(web3ModalOpts)
setWeb3Modal(web3ModalInstance) // setWeb3Modal(web3ModalInstance)
LoggerInstance.log( // LoggerInstance.log(
'[web3] Web3Modal instance created.', // '[web3] Web3Modal instance created.',
web3ModalInstance // web3ModalInstance
) // )
} // }
init() // init()
}, [connect, web3Modal]) // }, [connect, web3Modal])
// ----------------------------------- // -----------------------------------
// Reconnect automatically for returning users // Reconnect automatically for returning users
// ----------------------------------- // -----------------------------------
useEffect(() => { // useEffect(() => {
if (!web3Modal?.cachedProvider) return // if (!web3Modal?.cachedProvider) return
async function connectCached() { // async function connectCached() {
LoggerInstance.log( // LoggerInstance.log(
'[web3] Connecting to cached provider: ', // '[web3] Connecting to cached provider: ',
web3Modal.cachedProvider // web3Modal.cachedProvider
) // )
await connect() // await connect()
} // }
connectCached() // connectCached()
}, [connect, web3Modal]) // }, [connect, web3Modal])
// ----------------------------------- // -----------------------------------
// Get and set approved base tokens list // Get and set approved base tokens list
@ -336,25 +336,25 @@ function Web3Provider({ children }: { children: ReactNode }): ReactElement {
// ----------------------------------- // -----------------------------------
// Workaround cause getInjectedProviderName() always returns `MetaMask` // Workaround cause getInjectedProviderName() always returns `MetaMask`
// https://github.com/oceanprotocol/market/issues/332 // https://github.com/oceanprotocol/market/issues/332
useEffect(() => { // useEffect(() => {
if (!web3Provider) return // if (!web3Provider) return
const providerInfo = getProviderInfo(web3Provider) // const providerInfo = getProviderInfo(web3Provider)
setWeb3ProviderInfo(providerInfo) // setWeb3ProviderInfo(providerInfo)
}, [web3Provider]) // }, [web3Provider])
// ----------------------------------- // -----------------------------------
// Logout helper // Logout helper
// ----------------------------------- // -----------------------------------
async function logout() { // async function logout() {
/* eslint-disable @typescript-eslint/no-explicit-any */ // /* eslint-disable @typescript-eslint/no-explicit-any */
if ((web3?.currentProvider as any)?.close) { // if ((web3?.currentProvider as any)?.close) {
await (web3.currentProvider as any).close() // await (web3.currentProvider as any).close()
} // }
/* eslint-enable @typescript-eslint/no-explicit-any */ // /* eslint-enable @typescript-eslint/no-explicit-any */
await web3Modal.clearCachedProvider() // await web3Modal.clearCachedProvider()
} // }
// ----------------------------------- // -----------------------------------
// Get valid Networks and set isSupportedOceanNetwork // Get valid Networks and set isSupportedOceanNetwork
// ----------------------------------- // -----------------------------------
@ -408,9 +408,9 @@ function Web3Provider({ children }: { children: ReactNode }): ReactElement {
<Web3Context.Provider <Web3Context.Provider
value={{ value={{
web3, web3,
web3Provider, // web3Provider,
web3Modal, // web3Modal,
web3ProviderInfo, // web3ProviderInfo,
accountId, accountId,
accountEns, accountEns,
accountEnsAvatar, accountEnsAvatar,
@ -423,9 +423,9 @@ function Web3Provider({ children }: { children: ReactNode }): ReactElement {
isTestnet, isTestnet,
web3Loading, web3Loading,
isSupportedOceanNetwork, isSupportedOceanNetwork,
approvedBaseTokens, approvedBaseTokens
connect, // connect,
logout // logout
}} }}
> >
{children} {children}

View File

@ -4,6 +4,33 @@ import Web3 from 'web3'
import { getOceanConfig } from './ocean' import { getOceanConfig } from './ocean'
import { AbiItem } from 'web3-utils/types' import { AbiItem } from 'web3-utils/types'
import {
EthereumClient,
modalConnectors,
walletConnectProvider
} from '@web3modal/ethereum'
import { configureChains, createClient } from 'wagmi'
import { mainnet, polygon, bsc, goerli, polygonMumbai } from 'wagmi/chains'
export const chains = [mainnet, polygon, bsc, goerli, polygonMumbai]
// Wagmi client
export const { provider } = configureChains(chains, [
walletConnectProvider({
projectId: process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID
})
])
export const wagmiClient = createClient({
autoConnect: true,
connectors: modalConnectors({ appName: 'Ocean Market', chains }),
provider
})
// Web3Modal Ethereum Client
export const ethereumClient = new EthereumClient(wagmiClient, chains)
export function accountTruncate(account: string): string { export function accountTruncate(account: string): string {
if (!account || account === '') return if (!account || account === '') return
const middle = account.substring(6, 38) const middle = account.substring(6, 38)

View File

@ -1,23 +1,27 @@
// import App from "next/app"; // import App from "next/app";
import React, { ReactElement } from 'react' import React, { ReactElement } from 'react'
import type { AppProps /*, AppContext */ } from 'next/app' import type { AppProps /*, AppContext */ } from 'next/app'
import Web3Provider from '@context/Web3'
import { UserPreferencesProvider } from '@context/UserPreferences' import { UserPreferencesProvider } from '@context/UserPreferences'
import PricesProvider from '@context/Prices' import PricesProvider from '@context/Prices'
import UrqlProvider from '@context/UrqlProvider' import UrqlProvider from '@context/UrqlProvider'
import ConsentProvider from '@context/CookieConsent' import ConsentProvider from '@context/CookieConsent'
import App from '../../src/components/App' import App from '../../src/components/App'
import '@oceanprotocol/typographies/css/ocean-typo.css' import '@oceanprotocol/typographies/css/ocean-typo.css'
import '../stylesGlobal/styles.css' import '../stylesGlobal/styles.css'
import Decimal from 'decimal.js' import Decimal from 'decimal.js'
import MarketMetadataProvider from '@context/MarketMetadata' import MarketMetadataProvider from '@context/MarketMetadata'
import { WagmiConfig } from 'wagmi'
import { Web3Modal } from '@web3modal/react'
import { wagmiClient, ethereumClient } from '@utils/web3'
import Web3Provider from '@context/Web3'
function MyApp({ Component, pageProps }: AppProps): ReactElement { function MyApp({ Component, pageProps }: AppProps): ReactElement {
Decimal.set({ rounding: 1 }) Decimal.set({ rounding: 1 })
return ( return (
<>
<MarketMetadataProvider> <MarketMetadataProvider>
<Web3Provider> <Web3Provider>
<WagmiConfig client={wagmiClient}>
<UrqlProvider> <UrqlProvider>
<UserPreferencesProvider> <UserPreferencesProvider>
<PricesProvider> <PricesProvider>
@ -29,8 +33,15 @@ function MyApp({ Component, pageProps }: AppProps): ReactElement {
</PricesProvider> </PricesProvider>
</UserPreferencesProvider> </UserPreferencesProvider>
</UrqlProvider> </UrqlProvider>
</WagmiConfig>
</Web3Provider> </Web3Provider>
</MarketMetadataProvider> </MarketMetadataProvider>
<Web3Modal
projectId={process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID}
ethereumClient={ethereumClient}
/>
</>
) )
} }