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

Merge branch 'main' into feature/previousOrders

This commit is contained in:
mihaisc 2020-10-23 16:40:01 +03:00
commit 7b0af5e062
No known key found for this signature in database
GPG Key ID: 4FB0C2329B4C6E29
21 changed files with 122 additions and 125 deletions

View File

@ -2,5 +2,4 @@
GATSBY_NETWORK="rinkeby"
#GATSBY_INFURA_PROJECT_ID="xxx"
#GATSBY_METADATA_CACHE_URI="xxx"
#GATSBY_MARKET_FEE_ADDRESS="0xxx"

View File

@ -19,8 +19,7 @@
- [🛳 Production](#-production)
- [⬆️ Deployment](#-deployment)
- [Manual Deployment](#manual-deployment)
- [🏗 Ocean Protocol Infrastructure](#-ocean-protocol-infrastructure)
- [🏛 License](#-license)
- [<EFBFBD> License](#-license)
## 🏄 Get Started
@ -154,34 +153,6 @@ vercel
vercel alias
```
## 🏗 Ocean Protocol Infrastructure
The following Metadata Store & Provider instances specifically for marketplace are deployed in Ocean Protocol's AWS K8:
**Rinkeby (Staging)**
- K8 namespace: `xxx`
- `[aquarius.rinkeby.v3.dev-ocean.com](https://aquarius.rinkeby.v3.dev-ocean.com)`
- `[provider.rinkeby.v3.dev-ocean.com](https://provider.rinkeby.v3.dev-ocean.com)`
Edit command with `kubectl`, e.g.:
```bash
kubectl edit deployment -n xxx aquarius
```
**Main (Production)**
- K8 namespace: `xxx`
- `xxx`
- `xxx`
Edit command with `kubectl`, e.g.:
```bash
kubectl edit deployment -n xxx aquarius
```
## 🏛 License
```text

View File

@ -1,7 +1,10 @@
module.exports = {
// The default network and its associated config the app should connect to
// on start. App will automatically switch network configs when user switches
// networks in their wallet.
// Ocean Protocol contracts are deployed for: 'mainnet', 'rinkeby', 'development'
network: process.env.GATSBY_NETWORK || 'rinkeby',
infuraProjectId: process.env.GATSBY_INFURA_PROJECT_ID || 'xxx',
metadataCacheUri: process.env.GATSBY_METADATA_CACHE_URI,
// The ETH address the marketplace fee will be sent to.
marketFeeAddress:
process.env.GATSBY_MARKET_FEE_ADDRESS ||

View File

@ -38,7 +38,7 @@
"label": "Access Type",
"help": "Choose how you want your files to be accessible for the specified price.",
"type": "select",
"options": ["Download", "Compute"],
"options": ["Download"],
"required": true
},
{

25
package-lock.json generated
View File

@ -3850,9 +3850,9 @@
"integrity": "sha512-p0oOHXr60hXZuLNsQ/PsOQtCfia79thm7MjPxTrnnBvD+csJoHzARYMB0IFj/KTw6U5vLXODgjJAn8x6QksLwg=="
},
"@oceanprotocol/lib": {
"version": "0.7.5",
"resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-0.7.5.tgz",
"integrity": "sha512-frqMwfsqhyQ7+wfY6ak7+vmrbMVXDd7DuYdXHL2gyzom9uqcLLWhmWFNWo/1hOh750GhZ5d8BT4iX0O9P1JPTw==",
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-0.8.0.tgz",
"integrity": "sha512-FZALOw3LMAPo2US+YjJv5Fkz7IDS9m89PZzF7uKZKYT8V3xB/m0PV91vV1pEPC0eVWk3Sl1IXyT0L3ASFEUjvg==",
"requires": {
"@ethereum-navigator/navigator": "^0.5.0",
"@oceanprotocol/contracts": "^0.5.7",
@ -3876,6 +3876,25 @@
"decimal.js": "^10.2.1",
"web3": "^1.3.0",
"web3modal": "^1.9.1"
},
"dependencies": {
"@oceanprotocol/lib": {
"version": "0.7.5",
"resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-0.7.5.tgz",
"integrity": "sha512-frqMwfsqhyQ7+wfY6ak7+vmrbMVXDd7DuYdXHL2gyzom9uqcLLWhmWFNWo/1hOh750GhZ5d8BT4iX0O9P1JPTw==",
"requires": {
"@ethereum-navigator/navigator": "^0.5.0",
"@oceanprotocol/contracts": "^0.5.7",
"decimal.js": "^10.2.0",
"fs": "0.0.1-security",
"lzma": "^2.3.2",
"node-fetch": "^2.6.1",
"save-file": "^2.3.1",
"uuid": "^8.3.0",
"web3": "^1.3.0",
"web3-eth-contract": "^1.3.0"
}
}
}
},
"@oceanprotocol/typographies": {

View File

@ -22,7 +22,7 @@
"@coingecko/cryptoformat": "^0.4.2",
"@loadable/component": "5.13.1",
"@oceanprotocol/art": "^3.0.0",
"@oceanprotocol/lib": "^0.7.5",
"@oceanprotocol/lib": "^0.8.0",
"@oceanprotocol/react": "^0.3.7",
"@oceanprotocol/typographies": "^0.1.0",
"@sindresorhus/slugify": "^1.0.0",

View File

@ -1,19 +1,21 @@
import React, { ReactElement, ReactNode } from 'react'
import { getNetworkName } from '../../utils/wallet'
import { ReactComponent as External } from '../../images/external.svg'
import styles from './EtherscanLink.module.css'
export default function EtherscanLink({
network,
networkId,
path,
children
}: {
network?: 'rinkeby' | 'kovan' | 'ropsten'
networkId: number
path: string
children: ReactNode
}): ReactElement {
const url = network
? `https://${network}.etherscan.io`
: `https://etherscan.io`
const url =
networkId === 1
? `https://etherscan.io`
: `https://${getNetworkName(networkId).toLowerCase()}.etherscan.io`
return (
<a

View File

@ -2,7 +2,7 @@ import { useOcean } from '@oceanprotocol/react'
import { toDataUrl } from 'ethereum-blockies'
import React, { FormEvent } from 'react'
import { ReactComponent as Caret } from '../../../images/caret.svg'
import { accountTruncate, isCorrectNetwork } from '../../../utils/wallet'
import { accountTruncate } from '../../../utils/wallet'
import Status from '../../atoms/Status'
import styles from './Account.module.css'
@ -24,7 +24,7 @@ const Blockies = ({ account }: { account: string | undefined }) => {
// eslint-disable-next-line
const Account = React.forwardRef((props, ref: any) => {
const { accountId, status, connect, networkId } = useOcean()
const hasSuccess = status === 1 && isCorrectNetwork(networkId)
const hasSuccess = status === 1 && networkId === 1
async function handleActivation(e: FormEvent<HTMLButtonElement>) {
// prevent accidentially submitting a form the button might be in

View File

@ -1,5 +1,6 @@
.details {
padding: calc(var(--spacer) / 4);
min-width: 17rem;
}
.details > section[class*='feedback'] {

View File

@ -3,14 +3,13 @@ import Button from '../../atoms/Button'
import styles from './Details.module.css'
import { useOcean } from '@oceanprotocol/react'
import Web3Feedback from './Feedback'
import { getNetworkName } from '../../../utils/wallet'
import { getInjectedProviderName } from 'web3modal'
import Conversion from '../../atoms/Price/Conversion'
import { formatCurrency } from '@coingecko/cryptoformat'
import { useUserPreferences } from '../../../providers/UserPreferences'
export default function Details(): ReactElement {
const { balance, connect, logout, networkId } = useOcean()
const { balance, connect, logout } = useOcean()
const { locale } = useUserPreferences()
return (
@ -27,11 +26,7 @@ export default function Details(): ReactElement {
))}
<li className={styles.actions}>
<span title="Connected provider">
{getInjectedProviderName()}
<br />
{getNetworkName(networkId)}
</span>
<span title="Connected provider">{getInjectedProviderName()}</span>
<Button
style="text"
size="small"

View File

@ -2,8 +2,7 @@ import React, { ReactElement } from 'react'
import Status from '../../atoms/Status'
import styles from './Feedback.module.css'
import { useOcean } from '@oceanprotocol/react'
import { isCorrectNetwork } from '../../../utils/wallet'
import { useSiteMetadata } from '../../../hooks/useSiteMetadata'
import { getNetworkName } from '../../../utils/wallet'
export declare type Web3Error = {
status: 'error' | 'warning' | 'success'
@ -16,23 +15,18 @@ export default function Web3Feedback({
}: {
isBalanceSufficient?: boolean
}): ReactElement {
const { appConfig } = useSiteMetadata()
const { account, status, networkId } = useOcean()
const isOceanConnectionError = status === -1
const correctNetwork = isCorrectNetwork(networkId)
const isMainnet = networkId === 1
const showFeedback =
!account ||
isOceanConnectionError ||
!correctNetwork ||
!isMainnet ||
isBalanceSufficient === false
const desiredNetworkName = appConfig.network.replace(/^\w/, (c: string) =>
c.toUpperCase()
)
const state = !account
? 'error'
: !correctNetwork
: !isMainnet
? 'warning'
: account && isBalanceSufficient
? 'success'
@ -42,8 +36,8 @@ export default function Web3Feedback({
? 'No account connected'
: isOceanConnectionError
? 'Error connecting to Ocean'
: !correctNetwork
? 'Wrong Network'
: !isMainnet
? getNetworkName(networkId)
: account
? isBalanceSufficient === false
? 'Insufficient balance'
@ -54,8 +48,8 @@ export default function Web3Feedback({
? 'Please connect your Web3 wallet.'
: isOceanConnectionError
? 'Please try again.'
: !correctNetwork
? `Please connect to ${desiredNetworkName}.`
: !isMainnet
? undefined
: isBalanceSufficient === false
? 'You do not have enough OCEAN in your wallet to purchase this asset.'
: 'Something went wrong.'
@ -64,7 +58,7 @@ export default function Web3Feedback({
<section className={styles.feedback}>
<Status state={state} aria-hidden />
<h3 className={styles.title}>{title}</h3>
<p className={styles.error}>{message}</p>
{message && <p className={styles.error}>{message}</p>}
</section>
) : null
}

View File

@ -20,3 +20,7 @@
.hasTokens {
composes: hasTokens from './index.module.css';
}
.feedback {
width: 100%;
}

View File

@ -4,6 +4,7 @@ import Button from '../../../atoms/Button'
import styles from './Actions.module.css'
import EtherscanLink from '../../../atoms/EtherscanLink'
import SuccessConfetti from '../../../atoms/SuccessConfetti'
import { useOcean } from '@oceanprotocol/react'
export default function Actions({
isLoading,
@ -18,6 +19,8 @@ export default function Actions({
actionName: string
action: () => void
}): ReactElement {
const { networkId } = useOcean()
return (
<>
<div className={styles.actions}>
@ -33,7 +36,7 @@ export default function Actions({
<SuccessConfetti
success="Successfully added liquidity."
action={
<EtherscanLink network="rinkeby" path={`/tx/${txId}`}>
<EtherscanLink networkId={networkId} path={`/tx/${txId}`}>
See on Etherscan
</EtherscanLink>
}

View File

@ -43,7 +43,7 @@ export default function Pool({ ddo }: { ddo: DDO }): ReactElement {
const data = useStaticQuery(contentQuery)
const content = data.content.edges[0].node.childContentJson.pool
const { ocean, accountId } = useOcean()
const { ocean, accountId, networkId } = useOcean()
const { price } = useMetadata(ddo)
const { dtSymbol } = usePricing(ddo)
@ -153,12 +153,15 @@ export default function Pool({ ddo }: { ddo: DDO }): ReactElement {
<Tooltip content={content.tooltips.price} />
<div className={styles.dataTokenLinks}>
<EtherscanLink
network="rinkeby"
networkId={networkId}
path={`address/${price.address}`}
>
Pool
</EtherscanLink>
<EtherscanLink network="rinkeby" path={`token/${ddo.dataToken}`}>
<EtherscanLink
networkId={networkId}
path={`token/${ddo.dataToken}`}
>
Datatoken
</EtherscanLink>
</div>

View File

@ -5,7 +5,7 @@ import styles from './MetaFull.module.css'
import { MetadataMarket } from '../../../@types/MetaData'
import { DDO } from '@oceanprotocol/lib'
import EtherscanLink from '../../atoms/EtherscanLink'
import { usePricing } from '@oceanprotocol/react'
import { useOcean, usePricing } from '@oceanprotocol/react'
export default function MetaFull({
ddo,
@ -14,6 +14,7 @@ export default function MetaFull({
ddo: DDO
metadata: MetadataMarket
}): ReactElement {
const { networkId } = useOcean()
const { id, dataToken } = ddo
const { dateCreated, datePublished, author, license } = metadata.main
const { dtSymbol, dtName } = usePricing(ddo)
@ -48,7 +49,7 @@ export default function MetaFull({
<MetaItem
title="Datatoken"
content={
<EtherscanLink network="rinkeby" path={`token/${dataToken}`}>
<EtherscanLink networkId={networkId} path={`token/${dataToken}`}>
{dtName ? `${dtName} - ${dtSymbol}` : <code>{dataToken}</code>}
</EtherscanLink>
}

View File

@ -56,7 +56,5 @@
.alertArea {
margin-left: -2rem;
margin-right: -2rem;
padding: var(--spacer) calc(var(--spacer) / 2);
padding-bottom: 0;
margin-top: var(--spacer);
padding: 0 calc(var(--spacer) / 2);
}

View File

@ -1,8 +1,6 @@
import { useOcean, usePricing } from '@oceanprotocol/react'
import PriceUnit from '../../../../atoms/Price/PriceUnit'
import React, { ReactElement, useEffect, useState } from 'react'
import { useSiteMetadata } from '../../../../../hooks/useSiteMetadata'
import { isCorrectNetwork } from '../../../../../utils/wallet'
import Alert from '../../../../atoms/Alert'
import FormHelp from '../../../../atoms/Input/Help'
import Tooltip from '../../../../atoms/Tooltip'
@ -22,7 +20,6 @@ export default function Dynamic({
ddo: DDO
content: any
}): ReactElement {
const { appConfig } = useSiteMetadata()
const { account, balance, networkId, refreshBalance } = useOcean()
const { dtSymbol, dtName } = usePricing(ddo)
@ -31,23 +28,17 @@ export default function Dynamic({
const { price, weightOnDataToken } = values as PriceOptionsMarket
const [error, setError] = useState<string>()
const correctNetwork = isCorrectNetwork(networkId)
const desiredNetworkName = appConfig.network.replace(/^\w/, (c: string) =>
c.toUpperCase()
)
// Check: account, network & insufficient balance
useEffect(() => {
if (!account) {
setError(`No account connected. Please connect your Web3 wallet.`)
} else if (!correctNetwork) {
setError(`Wrong Network. Please connect to ${desiredNetworkName}.`)
} else if (Number(balance.ocean) < Number(price)) {
setError(`Insufficient balance. You need at least ${price} OCEAN`)
} else {
setError(undefined)
}
}, [price, networkId, account, balance, correctNetwork, desiredNetworkName])
}, [price, networkId, account, balance])
// refetch balance periodically
useEffect(() => {

View File

@ -17,7 +17,7 @@ function AssetTitle({ did }: { did: string }): ReactElement {
}
function Title({ row }: { row: PoolTransaction }) {
const { ocean } = useOcean()
const { ocean, networkId } = useOcean()
const [dtSymbol, setDtSymbol] = useState<string>()
const title = row.tokenAmountIn
@ -37,7 +37,7 @@ function Title({ row }: { row: PoolTransaction }) {
}, [ocean, row])
return (
<EtherscanLink network="rinkeby" path={`/tx/${row.transactionHash}`}>
<EtherscanLink networkId={networkId} path={`/tx/${row.transactionHash}`}>
{title}
</EtherscanLink>
)

View File

@ -1,47 +1,63 @@
import React, { ReactElement, useEffect } from 'react'
import { useOcean } from '@oceanprotocol/react'
import { getOceanConfig } from './wrapRootElement'
import appConfig from '../../app.config'
import { Logger } from '@oceanprotocol/lib'
import { ConfigHelperConfig } from '@oceanprotocol/lib/dist/node/utils/ConfigHelper'
export function NetworkMonitor(): ReactElement {
const { metadataCacheUri } = appConfig
const { connect, web3Provider } = useOcean()
const { connect, web3Provider, web3, networkId, config } = useOcean()
async function handleNetworkChanged(chainId: string | number) {
const initialNewConfig = getOceanConfig(
typeof chainId === 'string' ? Number(chainId.replace('0x', '')) : chainId
)
const newConfig = {
...initialNewConfig,
// add local dev values
...(chainId === '8996' && {
factoryAddress: '0x312213d6f6b5FCF9F56B7B8946A6C727Bf4Bc21f',
poolFactoryAddress: '0xF9E633CBeEB2A474D3Fe22261046C99e805beeC4',
fixedRateExchangeAddress: '0xefdcb16b16C7842ec27c6fdCf56adc316B9B29B8',
metadataContractAddress: '0xEBe77E16736359Bf0F9013F6017242a5971cAE76'
})
}
try {
await connect(newConfig)
} catch (error) {
Logger.error(error.message)
}
}
// Re-connect on mount when network is different from user network.
// Bit nasty to just overwrite the initialConfig passed to OceanProvider
// while it's connecting to that, but YOLO.
useEffect(() => {
if (!web3 || !networkId) return
async function init() {
if (
(await web3.eth.getChainId()) ===
(config as ConfigHelperConfig).networkId
)
return
await handleNetworkChanged(networkId)
}
init()
}, [web3, networkId])
// Handle network change events
useEffect(() => {
if (!web3Provider) return
async function handleNetworkChanged(chainId: string) {
const initialConfig = getOceanConfig(Number(chainId.replace('0x', '')))
const newConfig = {
...initialConfig,
// add metadataCacheUri only when defined
...(metadataCacheUri && { metadataCacheUri })
}
if (chainId === '8996') {
newConfig.factoryAddress = '0x312213d6f6b5FCF9F56B7B8946A6C727Bf4Bc21f'
newConfig.poolFactoryAddress =
'0xF9E633CBeEB2A474D3Fe22261046C99e805beeC4'
newConfig.fixedRateExchangeAddress =
'0xefdcb16b16C7842ec27c6fdCf56adc316B9B29B8'
newConfig.metadataContractAddress =
'0xEBe77E16736359Bf0F9013F6017242a5971cAE76'
}
try {
await connect(newConfig)
} catch (error) {
Logger.error(error.message)
}
}
web3Provider.on('chainChanged', handleNetworkChanged)
return () => {
web3Provider.removeListener('chainChanged', handleNetworkChanged)
}
}, [web3Provider, connect, metadataCacheUri])
}, [web3Provider])
return <></>
}

View File

@ -24,17 +24,14 @@ export default function wrapRootElement({
}: {
element: ReactElement
}): ReactElement {
const { metadataCacheUri, network } = appConfig
const { network } = appConfig
const oceanInitialConfig = getOceanConfig(network)
const initialConfig = {
...oceanInitialConfig,
// add metadataCacheUri only when defined
...(metadataCacheUri && { metadataCacheUri })
}
return (
<OceanProvider initialConfig={initialConfig} web3ModalOpts={web3ModalOpts}>
<OceanProvider
initialConfig={oceanInitialConfig}
web3ModalOpts={web3ModalOpts}
>
<UserPreferencesProvider>
<NetworkMonitor />
{element}

View File

@ -50,7 +50,7 @@ export function getNetworkId(network: string): number {
}
}
export function isCorrectNetwork(networkId: number): boolean {
export function isDefaultNetwork(networkId: number): boolean {
const configuredNetwork = getNetworkId(network)
return configuredNetwork === networkId
}