mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
Add custom network (#450)
* add custom network * created announcement banner * add custom network from banner * show ADD CUSTOM NETWORK on MetaMask provider * show add ocean to wallet action * removed warningPolygon from alert * removed customNetwork component * remove Add custom network on asset details page * Details use function from web3 to add token * changed available on Polygon link, refactoring * show Switch to Polygon when no wallet connected * banner content for no provider and Polygon network * change message when not provider and eth network * changed warning and added announcement in site.json * moved network logic inside Announcement, moved Announcement component * added switch to ETH button, refactoring * removed add mOcean action button * moved location verification to App.tsx * styling & copy updates Co-authored-by: Matthias Kretschmann <m@kretschmann.io>
This commit is contained in:
parent
6190737f08
commit
96296008c9
@ -16,8 +16,13 @@
|
||||
"link": "/history"
|
||||
}
|
||||
],
|
||||
"warning": "We are in beta. Please familiarize yourself with [the market](https://oceanprotocol.com/technology/marketplaces), [the risks](https://blog.oceanprotocol.com/on-staking-on-data-in-ocean-market-3d8e09eb0a13), and the [Terms of Use](/terms).",
|
||||
"warningPolygon": "Polygon/Matic EVM support is in early stages. Use the Matic bridge to [get mOCEAN](https://docs.oceanprotocol.com/tutorials/polygon-bridge/).",
|
||||
"warningPolygonPublish": "Only republish data sets with a pool from ETH Mainnet into Polygon/Matic if the liquidity is **less than or equal to 1000 OCEAN in the original pool**. Doing otherwise will lead to [purgatory](https://github.com/oceanprotocol/list-purgatory) for the data set in Polygon/Matic."
|
||||
"warning": {
|
||||
"main": "We are in beta. Please familiarize yourself with [the market](https://oceanprotocol.com/technology/marketplaces), [the risks](https://blog.oceanprotocol.com/on-staking-on-data-in-ocean-market-3d8e09eb0a13), and the [Terms of Use](/terms).",
|
||||
"polygonPublish": "Only republish data sets with a pool from ETH Mainnet into Polygon/Matic if the liquidity is **less than or equal to 1000 OCEAN in the original pool**. Doing otherwise will lead to [purgatory](https://github.com/oceanprotocol/list-purgatory) for the data set in Polygon/Matic."
|
||||
},
|
||||
"announcement": {
|
||||
"main": "Ocean Market is [available on Polygon](https://blog.oceanprotocol.com/ocean-on-polygon-network-8abad19cbf47).",
|
||||
"polygon": "Polygon/Matic EVM support is in early stages. [Use the Polygon Bridge](https://docs.oceanprotocol.com/tutorials/polygon-bridge/) to get mOCEAN."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import { useSiteMetadata } from '../hooks/useSiteMetadata'
|
||||
import Alert from './atoms/Alert'
|
||||
import { graphql, PageProps, useStaticQuery } from 'gatsby'
|
||||
import { useAccountPurgatory } from '../hooks/useAccountPurgatory'
|
||||
import AnnouncementBanner from './molecules/AnnouncementBanner'
|
||||
import { useWeb3 } from '../providers/Web3'
|
||||
|
||||
const contentQuery = graphql`
|
||||
@ -35,20 +36,17 @@ export default function App({
|
||||
const data = useStaticQuery(contentQuery)
|
||||
const purgatory = data.purgatory.edges[0].node.childContentJson.account
|
||||
|
||||
const { warning, warningPolygon } = useSiteMetadata()
|
||||
const { warning } = useSiteMetadata()
|
||||
const { accountId } = useWeb3()
|
||||
const { isInPurgatory, purgatoryData } = useAccountPurgatory(accountId)
|
||||
const { networkId } = useWeb3()
|
||||
|
||||
return (
|
||||
<Styles>
|
||||
<div className={styles.app}>
|
||||
{!location.pathname.includes('/asset/did') && <AnnouncementBanner />}
|
||||
<Header />
|
||||
{(props as PageProps).uri === '/' && (
|
||||
<Alert
|
||||
text={(networkId === 137 ? `${warningPolygon}\n\n` : '') + warning}
|
||||
state="info"
|
||||
/>
|
||||
<Alert text={warning.main} state="info" />
|
||||
)}
|
||||
{isInPurgatory && (
|
||||
<Alert
|
||||
|
31
src/components/molecules/AnnouncementBanner.module.css
Normal file
31
src/components/molecules/AnnouncementBanner.module.css
Normal file
@ -0,0 +1,31 @@
|
||||
.banner {
|
||||
text-align: center;
|
||||
padding: calc(var(--spacer) / 5) calc(var(--spacer) / 2);
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
background-color: var(--background-content);
|
||||
}
|
||||
|
||||
.banner > div {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.banner button {
|
||||
font-size: calc(var(--font-size-small) / 1.1);
|
||||
}
|
||||
|
||||
.text {
|
||||
font-size: var(--font-size-small);
|
||||
font-weight: var(--font-weight-bold);
|
||||
margin: 0;
|
||||
margin-right: calc(var(--spacer) / 4);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.text a {
|
||||
color: inherit;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.text p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
103
src/components/molecules/AnnouncementBanner.tsx
Normal file
103
src/components/molecules/AnnouncementBanner.tsx
Normal file
@ -0,0 +1,103 @@
|
||||
import React, { ReactElement, useEffect, useState } from 'react'
|
||||
import styles from './AnnouncementBanner.module.css'
|
||||
import Markdown from '../atoms/Markdown'
|
||||
import { useWeb3 } from '../../providers/Web3'
|
||||
import { addCustomNetwork, NetworkObject } from '../../utils/web3'
|
||||
import { getOceanConfig } from '../../utils/ocean'
|
||||
import { getProviderInfo } from 'web3modal'
|
||||
import { useOcean } from '../../providers/Ocean'
|
||||
import { useSiteMetadata } from '../../hooks/useSiteMetadata'
|
||||
import Button from '../atoms/Button'
|
||||
|
||||
export interface AnnouncementAction {
|
||||
name: string
|
||||
style?: string
|
||||
handleAction: () => void
|
||||
}
|
||||
|
||||
const network: NetworkObject = {
|
||||
chainId: 137,
|
||||
name: 'Matic Network',
|
||||
urlList: [
|
||||
'https://rpc-mainnet.matic.network',
|
||||
'https://rpc-mainnet.maticvigil.com/'
|
||||
]
|
||||
}
|
||||
|
||||
export default function AnnouncementBanner(): ReactElement {
|
||||
const { web3Provider } = useWeb3()
|
||||
const { config, connect } = useOcean()
|
||||
const { announcement } = useSiteMetadata()
|
||||
|
||||
const [text, setText] = useState<string>(announcement.main)
|
||||
const [action, setAction] = useState<AnnouncementAction>()
|
||||
|
||||
const addCustomNetworkAction = {
|
||||
name: 'Add custom network',
|
||||
handleAction: () => addCustomNetwork(web3Provider, network)
|
||||
}
|
||||
const switchToPolygonAction = {
|
||||
name: 'Switch to Polygon',
|
||||
handleAction: async () => {
|
||||
const config = getOceanConfig('polygon')
|
||||
await connect(config)
|
||||
}
|
||||
}
|
||||
const switchToEthAction = {
|
||||
name: 'Switch to ETH',
|
||||
handleAction: async () => {
|
||||
const config = getOceanConfig('mainnet')
|
||||
await connect(config)
|
||||
}
|
||||
}
|
||||
|
||||
function setBannerForMatic() {
|
||||
setText(announcement.polygon)
|
||||
setAction(undefined)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!web3Provider && !config) return
|
||||
|
||||
const providerInfo = getProviderInfo(web3Provider)
|
||||
switch (providerInfo?.name) {
|
||||
case 'Web3':
|
||||
if (config.networkId !== 137) {
|
||||
setText(announcement.main)
|
||||
setAction(switchToPolygonAction)
|
||||
} else {
|
||||
setText(announcement.polygon)
|
||||
setAction(switchToEthAction)
|
||||
}
|
||||
break
|
||||
case 'MetaMask':
|
||||
if (config.networkId === 137) {
|
||||
setBannerForMatic()
|
||||
} else {
|
||||
setText(announcement.main)
|
||||
setAction(addCustomNetworkAction)
|
||||
}
|
||||
break
|
||||
default:
|
||||
if (config.networkId === 137) {
|
||||
setBannerForMatic()
|
||||
} else {
|
||||
setText(announcement.main)
|
||||
setAction(undefined)
|
||||
}
|
||||
}
|
||||
}, [web3Provider, config, announcement])
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.banner}>
|
||||
{text && <Markdown className={styles.text} text={text} />}
|
||||
{action && (
|
||||
<Button style="text" size="small" onClick={action.handleAction}>
|
||||
{action.name}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
@ -8,6 +8,7 @@ import Conversion from '../../atoms/Price/Conversion'
|
||||
import { formatCurrency } from '@coingecko/cryptoformat'
|
||||
import { useUserPreferences } from '../../../providers/UserPreferences'
|
||||
import { useWeb3 } from '../../../providers/Web3'
|
||||
import { addOceanToWallet } from '../../../utils/web3'
|
||||
import { Logger } from '@oceanprotocol/lib'
|
||||
|
||||
export default function Details(): ReactElement {
|
||||
@ -27,39 +28,6 @@ export default function Details(): ReactElement {
|
||||
setProviderInfo(providerInfo)
|
||||
}, [web3Provider])
|
||||
|
||||
async function addOceanToWallet() {
|
||||
const tokenMetadata = {
|
||||
type: 'ERC20',
|
||||
options: {
|
||||
address: config.oceanTokenAddress,
|
||||
symbol: config.oceanTokenSymbol,
|
||||
decimals: 18,
|
||||
image:
|
||||
'https://raw.githubusercontent.com/oceanprotocol/art/main/logo/token.png'
|
||||
}
|
||||
}
|
||||
web3Provider.sendAsync(
|
||||
{
|
||||
method: 'wallet_watchAsset',
|
||||
params: tokenMetadata,
|
||||
id: Math.round(Math.random() * 100000)
|
||||
},
|
||||
(err: string, added: any) => {
|
||||
if (err || 'error' in added) {
|
||||
Logger.error(
|
||||
`Couldn't add ${tokenMetadata.options.symbol} (${
|
||||
tokenMetadata.options.address
|
||||
}) to MetaMask, error: ${err || added.error}`
|
||||
)
|
||||
} else {
|
||||
Logger.log(
|
||||
`Added ${tokenMetadata.options.symbol} (${tokenMetadata.options.address}) to MetaMask`
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!networkData) return
|
||||
|
||||
@ -112,7 +80,7 @@ export default function Details(): ReactElement {
|
||||
style="text"
|
||||
size="small"
|
||||
onClick={() => {
|
||||
addOceanToWallet()
|
||||
addOceanToWallet(config, web3Provider)
|
||||
}}
|
||||
>
|
||||
{`Add ${config.oceanTokenSymbol}`}
|
||||
|
@ -174,7 +174,7 @@ export default function Add({
|
||||
) : (
|
||||
<Alert
|
||||
className={styles.warning}
|
||||
text={content.warning}
|
||||
text={content.warning.main}
|
||||
state="info"
|
||||
action={{
|
||||
name: 'I understand',
|
||||
|
@ -129,7 +129,7 @@ export default function FormTrade({
|
||||
) : (
|
||||
<div className={styles.alertWrap}>
|
||||
<Alert
|
||||
text={content.warning}
|
||||
text={content.warning.main}
|
||||
state="info"
|
||||
action={{
|
||||
name: 'I understand',
|
||||
|
@ -20,7 +20,6 @@ import Alert from '../../atoms/Alert'
|
||||
import MetadataFeedback from '../../molecules/MetadataFeedback'
|
||||
import { useAccountPurgatory } from '../../../hooks/useAccountPurgatory'
|
||||
import { useWeb3 } from '../../../providers/Web3'
|
||||
import { useSiteMetadata } from '../../../hooks/useSiteMetadata'
|
||||
|
||||
const formName = 'ocean-publish-form'
|
||||
|
||||
@ -29,9 +28,8 @@ export default function PublishPage({
|
||||
}: {
|
||||
content: { warning: string; form: FormContent }
|
||||
}): ReactElement {
|
||||
const { warningPolygonPublish } = useSiteMetadata()
|
||||
const { debug } = useUserPreferences()
|
||||
const { accountId, networkId } = useWeb3()
|
||||
const { accountId } = useWeb3()
|
||||
const { isInPurgatory, purgatoryData } = useAccountPurgatory(accountId)
|
||||
const { publish, publishError, isLoading, publishStepText } = usePublish()
|
||||
const [success, setSuccess] = useState<string>()
|
||||
@ -114,10 +112,7 @@ export default function PublishPage({
|
||||
) : (
|
||||
<>
|
||||
<Alert
|
||||
text={
|
||||
(networkId === 137 ? `${warningPolygonPublish}\n\n` : '') +
|
||||
content.warning
|
||||
}
|
||||
text={content.warning}
|
||||
state="info"
|
||||
className={styles.alert}
|
||||
/>
|
||||
|
@ -13,9 +13,14 @@ const query = graphql`
|
||||
name
|
||||
link
|
||||
}
|
||||
warning
|
||||
warningPolygon
|
||||
warningPolygonPublish
|
||||
warning {
|
||||
main
|
||||
polygonPublish
|
||||
}
|
||||
announcement {
|
||||
main
|
||||
polygon
|
||||
}
|
||||
appConfig {
|
||||
infuraProjectId
|
||||
network
|
||||
|
@ -1,3 +1,6 @@
|
||||
import { Logger } from '@oceanprotocol/lib'
|
||||
import { ConfigHelperConfig } from '@oceanprotocol/lib/dist/node/utils/ConfigHelper'
|
||||
|
||||
export interface EthereumListsChain {
|
||||
name: string
|
||||
chainId: number
|
||||
@ -11,6 +14,12 @@ export interface EthereumListsChain {
|
||||
infoURL: string
|
||||
}
|
||||
|
||||
export interface NetworkObject {
|
||||
chainId: number
|
||||
name: string
|
||||
urlList: string[]
|
||||
}
|
||||
|
||||
export function accountTruncate(account: string): string {
|
||||
if (!account) return
|
||||
const middle = account.substring(6, 38)
|
||||
@ -40,3 +49,68 @@ export function getNetworkData(
|
||||
)[0]
|
||||
return networkData.node
|
||||
}
|
||||
|
||||
export function addCustomNetwork(
|
||||
web3Provider: any,
|
||||
network: NetworkObject
|
||||
): void {
|
||||
const newNewtworkData = {
|
||||
chainId: `0x${network.chainId.toString(16)}`,
|
||||
rpcUrls: network.urlList
|
||||
}
|
||||
web3Provider.request(
|
||||
{
|
||||
method: 'wallet_addEthereumChain',
|
||||
params: [newNewtworkData]
|
||||
},
|
||||
(err: string, added: any) => {
|
||||
if (err || 'error' in added) {
|
||||
Logger.error(
|
||||
`Couldn't add ${network.name} (0x${
|
||||
network.chainId
|
||||
}) netowrk to MetaMask, error: ${err || added.error}`
|
||||
)
|
||||
} else {
|
||||
Logger.log(
|
||||
`Added ${network.name} (0x${network.chainId}) network to MetaMask`
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
export function addOceanToWallet(
|
||||
config: ConfigHelperConfig,
|
||||
web3Provider: any
|
||||
): void {
|
||||
const tokenMetadata = {
|
||||
type: 'ERC20',
|
||||
options: {
|
||||
address: config.oceanTokenAddress,
|
||||
symbol: config.oceanTokenSymbol,
|
||||
decimals: 18,
|
||||
image:
|
||||
'https://raw.githubusercontent.com/oceanprotocol/art/main/logo/token.png'
|
||||
}
|
||||
}
|
||||
web3Provider.sendAsync(
|
||||
{
|
||||
method: 'wallet_watchAsset',
|
||||
params: tokenMetadata,
|
||||
id: Math.round(Math.random() * 100000)
|
||||
},
|
||||
(err: string, added: any) => {
|
||||
if (err || 'error' in added) {
|
||||
Logger.error(
|
||||
`Couldn't add ${tokenMetadata.options.symbol} (${
|
||||
tokenMetadata.options.address
|
||||
}) to MetaMask, error: ${err || added.error}`
|
||||
)
|
||||
} else {
|
||||
Logger.log(
|
||||
`Added ${tokenMetadata.options.symbol} (${tokenMetadata.options.address}) to MetaMask`
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user