mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
Merge branch 'main' into fix/issue583-start-second-job
This commit is contained in:
commit
7cc6b9b95b
71
src/components/atoms/AddToken.module.css
Normal file
71
src/components/atoms/AddToken.module.css
Normal file
@ -0,0 +1,71 @@
|
||||
.button {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
min-width: auto;
|
||||
}
|
||||
|
||||
.button:hover,
|
||||
.button:focus {
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.logoWrap {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.logoWrap::before {
|
||||
content: '+';
|
||||
color: var(--color-secondary);
|
||||
font-family: var(--font-family-base);
|
||||
font-weight: var(--font-weight-base);
|
||||
font-size: 1.25em;
|
||||
position: absolute;
|
||||
right: 0.05em;
|
||||
top: 0.05em;
|
||||
line-height: 0;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 1.6em;
|
||||
height: 1.6em;
|
||||
display: inline-block;
|
||||
margin-bottom: -0.35em;
|
||||
border-radius: 50%;
|
||||
border: 0.065rem solid var(--color-secondary);
|
||||
margin-right: calc(var(--spacer) / 10);
|
||||
transition: 0.2s ease-out;
|
||||
}
|
||||
|
||||
.button:hover .logo,
|
||||
.button:focus .logo {
|
||||
border-color: var(--color-primary);
|
||||
}
|
||||
|
||||
.button:hover .logoWrap::before,
|
||||
.button:focus .logoWrap::before {
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
.text {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.minimal .text {
|
||||
opacity: 0;
|
||||
transform: translate3d(-1rem, 0, 0);
|
||||
transition: 0.2s ease-out;
|
||||
z-index: 0;
|
||||
white-space: pre;
|
||||
position: absolute;
|
||||
left: 100%;
|
||||
top: 0.15rem;
|
||||
}
|
||||
|
||||
.minimal:hover .text,
|
||||
.minimal:focus .text {
|
||||
opacity: 1;
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
53
src/components/atoms/AddToken.tsx
Normal file
53
src/components/atoms/AddToken.tsx
Normal file
@ -0,0 +1,53 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import classNames from 'classnames/bind'
|
||||
import { addTokenToWallet } from '../../utils/web3'
|
||||
import { useWeb3 } from '../../providers/Web3'
|
||||
import Button from './Button'
|
||||
import styles from './AddToken.module.css'
|
||||
|
||||
const cx = classNames.bind(styles)
|
||||
|
||||
export default function AddToken({
|
||||
address,
|
||||
symbol,
|
||||
logo,
|
||||
text,
|
||||
className,
|
||||
minimal
|
||||
}: {
|
||||
address: string
|
||||
symbol: string
|
||||
logo: string // needs to be a remote image
|
||||
text?: string
|
||||
className?: string
|
||||
minimal?: boolean
|
||||
}): ReactElement {
|
||||
const { web3Provider } = useWeb3()
|
||||
|
||||
const styleClasses = cx({
|
||||
button: true,
|
||||
minimal: minimal,
|
||||
[className]: className
|
||||
})
|
||||
|
||||
async function handleAddToken() {
|
||||
if (!web3Provider) return
|
||||
|
||||
await addTokenToWallet(web3Provider, address, symbol, logo)
|
||||
}
|
||||
|
||||
return (
|
||||
<Button
|
||||
className={styleClasses}
|
||||
style="text"
|
||||
size="small"
|
||||
onClick={handleAddToken}
|
||||
>
|
||||
<span className={styles.logoWrap}>
|
||||
<img src={logo} className={styles.logo} width="16" height="16" />
|
||||
</span>
|
||||
|
||||
<span className={styles.text}>{text || `Add ${symbol}`}</span>
|
||||
</Button>
|
||||
)
|
||||
}
|
@ -1,20 +1,30 @@
|
||||
import React, { ReactElement, ReactNode, useEffect, useState } from 'react'
|
||||
import { ReactComponent as External } from '../../images/external.svg'
|
||||
import styles from './ExplorerLink.module.css'
|
||||
import classNames from 'classnames/bind'
|
||||
import { ConfigHelperConfig } from '@oceanprotocol/lib'
|
||||
import { useOcean } from '../../providers/Ocean'
|
||||
import styles from './ExplorerLink.module.css'
|
||||
|
||||
const cx = classNames.bind(styles)
|
||||
|
||||
export default function ExplorerLink({
|
||||
path,
|
||||
children
|
||||
children,
|
||||
className
|
||||
}: {
|
||||
networkId: number
|
||||
path: string
|
||||
children: ReactNode
|
||||
className?: string
|
||||
}): ReactElement {
|
||||
const { config } = useOcean()
|
||||
const [url, setUrl] = useState<string>()
|
||||
|
||||
const styleClasses = cx({
|
||||
link: true,
|
||||
[className]: className
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
setUrl((config as ConfigHelperConfig).explorerUri)
|
||||
}, [config])
|
||||
@ -25,7 +35,7 @@ export default function ExplorerLink({
|
||||
title={`View on ${(config as ConfigHelperConfig).explorerUri}`}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className={styles.link}
|
||||
className={styleClasses}
|
||||
>
|
||||
{children} <External />
|
||||
</a>
|
||||
|
@ -68,7 +68,6 @@ export default function Publisher({
|
||||
>
|
||||
{name}
|
||||
</Link>
|
||||
|
||||
<div className={styles.links}>
|
||||
{' — '}
|
||||
{profile && (
|
||||
|
@ -2,7 +2,6 @@ import React, { ReactElement, useEffect, useState } from 'react'
|
||||
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 AnnouncementBanner, {
|
||||
@ -19,7 +18,7 @@ const networkMatic: NetworkObject = {
|
||||
}
|
||||
|
||||
export default function NetworkBanner(): ReactElement {
|
||||
const { web3Provider } = useWeb3()
|
||||
const { web3Provider, web3ProviderInfo } = useWeb3()
|
||||
const { config, connect } = useOcean()
|
||||
const { announcement } = useSiteMetadata()
|
||||
|
||||
@ -51,10 +50,9 @@ export default function NetworkBanner(): ReactElement {
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!web3Provider && !config) return
|
||||
if (!web3ProviderInfo || (!web3Provider && !config)) return
|
||||
|
||||
const providerInfo = getProviderInfo(web3Provider)
|
||||
switch (providerInfo?.name) {
|
||||
switch (web3ProviderInfo.name) {
|
||||
case 'Web3':
|
||||
if (config.networkId !== 137) {
|
||||
setText(announcement.main)
|
||||
@ -80,7 +78,7 @@ export default function NetworkBanner(): ReactElement {
|
||||
setAction(undefined)
|
||||
}
|
||||
}
|
||||
}, [web3Provider, config, announcement])
|
||||
}, [web3Provider, web3ProviderInfo, config, announcement])
|
||||
|
||||
return <AnnouncementBanner text={text} action={action} />
|
||||
}
|
||||
|
@ -42,7 +42,7 @@
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.actions span {
|
||||
.walletLogoWrap {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@ -84,3 +84,7 @@
|
||||
.walletInfo button {
|
||||
margin-top: calc(var(--spacer) / 5) !important;
|
||||
}
|
||||
|
||||
.addToken {
|
||||
margin-left: 0.3rem;
|
||||
}
|
||||
|
@ -1,33 +1,29 @@
|
||||
import React, { ReactElement, useEffect, useState } from 'react'
|
||||
import Button from '../../atoms/Button'
|
||||
import styles from './Details.module.css'
|
||||
import { useOcean } from '../../../providers/Ocean'
|
||||
import Web3Feedback from './Feedback'
|
||||
import { getProviderInfo, IProviderInfo } from 'web3modal'
|
||||
import Conversion from '../../atoms/Price/Conversion'
|
||||
import { formatCurrency } from '@coingecko/cryptoformat'
|
||||
import { useOcean } from '../../../providers/Ocean'
|
||||
import { useUserPreferences } from '../../../providers/UserPreferences'
|
||||
import Button from '../../atoms/Button'
|
||||
import AddToken from '../../atoms/AddToken'
|
||||
import Conversion from '../../atoms/Price/Conversion'
|
||||
import { useWeb3 } from '../../../providers/Web3'
|
||||
import { addOceanToWallet } from '../../../utils/web3'
|
||||
import { Logger } from '@oceanprotocol/lib'
|
||||
|
||||
import Web3Feedback from './Feedback'
|
||||
import styles from './Details.module.css'
|
||||
|
||||
export default function Details(): ReactElement {
|
||||
const { web3Provider, connect, logout, networkData } = useWeb3()
|
||||
const {
|
||||
web3Provider,
|
||||
web3ProviderInfo,
|
||||
connect,
|
||||
logout,
|
||||
networkData
|
||||
} = useWeb3()
|
||||
const { balance, config } = useOcean()
|
||||
const { locale } = useUserPreferences()
|
||||
|
||||
const [providerInfo, setProviderInfo] = useState<IProviderInfo>()
|
||||
const [mainCurrency, setMainCurrency] = useState<string>()
|
||||
// const [portisNetwork, setPortisNetwork] = useState<string>()
|
||||
|
||||
// Workaround cause getInjectedProviderName() always returns `MetaMask`
|
||||
// https://github.com/oceanprotocol/market/issues/332
|
||||
useEffect(() => {
|
||||
if (!web3Provider) return
|
||||
const providerInfo = getProviderInfo(web3Provider)
|
||||
setProviderInfo(providerInfo)
|
||||
}, [web3Provider])
|
||||
|
||||
useEffect(() => {
|
||||
if (!networkData) return
|
||||
|
||||
@ -61,11 +57,11 @@ export default function Details(): ReactElement {
|
||||
|
||||
<li className={styles.actions}>
|
||||
<div title="Connected provider" className={styles.walletInfo}>
|
||||
<span>
|
||||
<img className={styles.walletLogo} src={providerInfo?.logo} />
|
||||
{providerInfo?.name}
|
||||
<span className={styles.walletLogoWrap}>
|
||||
<img className={styles.walletLogo} src={web3ProviderInfo?.logo} />
|
||||
{web3ProviderInfo?.name}
|
||||
</span>
|
||||
{/* {providerInfo?.name === 'Portis' && (
|
||||
{/* {web3ProviderInfo?.name === 'Portis' && (
|
||||
<InputElement
|
||||
name="network"
|
||||
type="select"
|
||||
@ -75,20 +71,17 @@ export default function Details(): ReactElement {
|
||||
onChange={handlePortisNetworkChange}
|
||||
/>
|
||||
)} */}
|
||||
{providerInfo?.name === 'MetaMask' && (
|
||||
<Button
|
||||
style="text"
|
||||
size="small"
|
||||
onClick={() => {
|
||||
addOceanToWallet(config, web3Provider)
|
||||
}}
|
||||
>
|
||||
{`Add ${config.oceanTokenSymbol}`}
|
||||
</Button>
|
||||
{web3ProviderInfo?.name === 'MetaMask' && (
|
||||
<AddToken
|
||||
address={config.oceanTokenAddress}
|
||||
symbol={config.oceanTokenSymbol}
|
||||
logo="https://raw.githubusercontent.com/oceanprotocol/art/main/logo/token.png"
|
||||
className={styles.addToken}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<p>
|
||||
{providerInfo?.name === 'Portis' && (
|
||||
{web3ProviderInfo?.name === 'Portis' && (
|
||||
<Button
|
||||
style="text"
|
||||
size="small"
|
||||
|
@ -27,6 +27,11 @@
|
||||
margin-right: calc(var(--spacer) / 4);
|
||||
}
|
||||
|
||||
.datatoken {
|
||||
white-space: pre;
|
||||
margin-right: calc(var(--spacer) / 3);
|
||||
}
|
||||
|
||||
.byline {
|
||||
font-size: var(--font-size-small);
|
||||
}
|
||||
@ -34,3 +39,13 @@
|
||||
.updated {
|
||||
font-size: var(--font-size-mini);
|
||||
}
|
||||
|
||||
.addWrap {
|
||||
padding-left: calc(var(--spacer) / 5);
|
||||
border-left: 1px solid var(--border-color);
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.add {
|
||||
font-size: var(--font-size-mini);
|
||||
}
|
||||
|
@ -3,13 +3,14 @@ import { useAsset } from '../../../providers/Asset'
|
||||
import { useWeb3 } from '../../../providers/Web3'
|
||||
import ExplorerLink from '../../atoms/ExplorerLink'
|
||||
import Publisher from '../../atoms/Publisher'
|
||||
import AddToken from '../../atoms/AddToken'
|
||||
import Time from '../../atoms/Time'
|
||||
import styles from './MetaMain.module.css'
|
||||
import AssetType from '../../atoms/AssetType'
|
||||
import styles from './MetaMain.module.css'
|
||||
|
||||
export default function MetaMain(): ReactElement {
|
||||
const { ddo, owner, type } = useAsset()
|
||||
const { networkId } = useWeb3()
|
||||
const { networkId, web3ProviderInfo } = useWeb3()
|
||||
const isCompute = Boolean(ddo?.findServiceByType('compute'))
|
||||
const accessType = isCompute ? 'compute' : 'access'
|
||||
|
||||
@ -22,6 +23,7 @@ export default function MetaMain(): ReactElement {
|
||||
className={styles.assetType}
|
||||
/>
|
||||
<ExplorerLink
|
||||
className={styles.datatoken}
|
||||
networkId={networkId}
|
||||
path={
|
||||
networkId === 137 || networkId === 1287
|
||||
@ -31,6 +33,19 @@ export default function MetaMain(): ReactElement {
|
||||
>
|
||||
{`${ddo?.dataTokenInfo.name} — ${ddo?.dataTokenInfo.symbol}`}
|
||||
</ExplorerLink>
|
||||
|
||||
{web3ProviderInfo?.name === 'MetaMask' && (
|
||||
<span className={styles.addWrap}>
|
||||
<AddToken
|
||||
address={ddo?.dataTokenInfo.address}
|
||||
symbol={ddo?.dataTokenInfo.symbol}
|
||||
logo="https://raw.githubusercontent.com/oceanprotocol/art/main/logo/datatoken.png"
|
||||
text={`Add ${ddo?.dataTokenInfo.symbol} to wallet`}
|
||||
className={styles.add}
|
||||
minimal
|
||||
/>
|
||||
</span>
|
||||
)}
|
||||
</header>
|
||||
|
||||
<div className={styles.byline}>
|
||||
|
@ -8,7 +8,7 @@ import React, {
|
||||
useCallback
|
||||
} from 'react'
|
||||
import Web3 from 'web3'
|
||||
import Web3Modal from 'web3modal'
|
||||
import Web3Modal, { getProviderInfo, IProviderInfo } from 'web3modal'
|
||||
import { infuraProjectId as infuraId, portisId } from '../../app.config'
|
||||
import WalletConnectProvider from '@walletconnect/web3-provider'
|
||||
import { Logger } from '@oceanprotocol/lib'
|
||||
@ -24,6 +24,7 @@ interface Web3ProviderValue {
|
||||
web3: Web3
|
||||
web3Provider: any
|
||||
web3Modal: Web3Modal
|
||||
web3ProviderInfo: IProviderInfo
|
||||
accountId: string
|
||||
networkId: number
|
||||
networkDisplayName: string
|
||||
@ -106,6 +107,7 @@ function Web3Provider({ children }: { children: ReactNode }): ReactElement {
|
||||
const [web3, setWeb3] = useState<Web3>()
|
||||
const [web3Provider, setWeb3Provider] = useState<any>()
|
||||
const [web3Modal, setWeb3Modal] = useState<Web3Modal>()
|
||||
const [web3ProviderInfo, setWeb3ProviderInfo] = useState<IProviderInfo>()
|
||||
const [networkId, setNetworkId] = useState<number>()
|
||||
const [networkDisplayName, setNetworkDisplayName] = useState<string>()
|
||||
const [networkData, setNetworkData] = useState<EthereumListsChain>()
|
||||
@ -209,6 +211,18 @@ function Web3Provider({ children }: { children: ReactNode }): ReactElement {
|
||||
getBlock()
|
||||
}, [web3, networkId])
|
||||
|
||||
// -----------------------------------
|
||||
// Get and set web3 provider info
|
||||
// -----------------------------------
|
||||
// Workaround cause getInjectedProviderName() always returns `MetaMask`
|
||||
// https://github.com/oceanprotocol/market/issues/332
|
||||
useEffect(() => {
|
||||
if (!web3Provider) return
|
||||
|
||||
const providerInfo = getProviderInfo(web3Provider)
|
||||
setWeb3ProviderInfo(providerInfo)
|
||||
}, [web3Provider])
|
||||
|
||||
// -----------------------------------
|
||||
// Logout helper
|
||||
// -----------------------------------
|
||||
@ -255,6 +269,7 @@ function Web3Provider({ children }: { children: ReactNode }): ReactElement {
|
||||
web3,
|
||||
web3Provider,
|
||||
web3Modal,
|
||||
web3ProviderInfo,
|
||||
accountId,
|
||||
networkId,
|
||||
networkDisplayName,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Logger, ConfigHelperConfig } from '@oceanprotocol/lib'
|
||||
import { Logger } from '@oceanprotocol/lib'
|
||||
|
||||
export interface EthereumListsChain {
|
||||
name: string
|
||||
@ -79,32 +79,33 @@ export function addCustomNetwork(
|
||||
)
|
||||
}
|
||||
|
||||
export function addOceanToWallet(
|
||||
config: ConfigHelperConfig,
|
||||
web3Provider: any
|
||||
): void {
|
||||
export async function addTokenToWallet(
|
||||
web3Provider: any,
|
||||
address: string,
|
||||
symbol: string,
|
||||
logo?: string
|
||||
): Promise<void> {
|
||||
const image =
|
||||
logo ||
|
||||
'https://raw.githubusercontent.com/oceanprotocol/art/main/logo/token.png'
|
||||
|
||||
const tokenMetadata = {
|
||||
type: 'ERC20',
|
||||
options: {
|
||||
address: config.oceanTokenAddress,
|
||||
symbol: config.oceanTokenSymbol,
|
||||
decimals: 18,
|
||||
image:
|
||||
'https://raw.githubusercontent.com/oceanprotocol/art/main/logo/token.png'
|
||||
}
|
||||
options: { address, symbol, image, decimals: 18 }
|
||||
}
|
||||
|
||||
web3Provider.sendAsync(
|
||||
{
|
||||
method: 'wallet_watchAsset',
|
||||
params: tokenMetadata,
|
||||
id: Math.round(Math.random() * 100000)
|
||||
},
|
||||
(err: string, added: any) => {
|
||||
(err: { code: number; message: 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}`
|
||||
}) to MetaMask, error: ${err.message || added.error}`
|
||||
)
|
||||
} else {
|
||||
Logger.log(
|
||||
|
Loading…
Reference in New Issue
Block a user