1
0
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:
Bogdan Fazakas 2021-05-17 17:24:07 +03:00
commit 7cc6b9b95b
11 changed files with 235 additions and 61 deletions

View 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);
}

View 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>
)
}

View File

@ -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>

View File

@ -68,7 +68,6 @@ export default function Publisher({
>
{name}
</Link>
<div className={styles.links}>
{' — '}
{profile && (

View File

@ -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} />
}

View File

@ -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;
}

View File

@ -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"

View File

@ -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);
}

View File

@ -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}>

View File

@ -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,

View File

@ -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(