mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
commit
53d35828e2
@ -17,7 +17,7 @@ const appConfig = {
|
||||
network,
|
||||
infuraProjectId: process.env.GATSBY_INFURA_PROJECT_ID || 'xxx',
|
||||
marketFeeAddress: process.env.GATSBY_MARKET_FEE_ADDRESS || '0xxxx',
|
||||
marketFeeAmount: process.env.GATSBY_MARKET_FEE_AMOUNT || '0.03' // in %
|
||||
marketFeeAmount: process.env.GATSBY_MARKET_FEE_AMOUNT || '0.1' // in %
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
@ -89,5 +89,19 @@
|
||||
}
|
||||
],
|
||||
"success": "Asset Created!"
|
||||
},
|
||||
"price": {
|
||||
"simple": {
|
||||
"title": "Simple: Fixed",
|
||||
"info": "Set your price for accessing this data set. A Data Token contract for this data set, worth the entered amount of OCEAN will be created."
|
||||
},
|
||||
"advanced": {
|
||||
"title": "Advanced: Dynamic",
|
||||
"info": "Let's create a decentralized, automated market for your data set. A Data Token contract for this data set worth the entered amount of OCEAN will be created. Additionally, you will provide liquidity into a Data Token/OCEAN liquidity pool with Balancer.",
|
||||
"tooltips": {
|
||||
"poolInfo": "Help me",
|
||||
"liquidityProviderFee": "Help me"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React from 'react'
|
||||
import React, { ReactElement, ReactNode } from 'react'
|
||||
import styles from './Label.module.css'
|
||||
|
||||
const Label = ({
|
||||
@ -7,9 +7,9 @@ const Label = ({
|
||||
...props
|
||||
}: {
|
||||
required?: boolean
|
||||
children: string
|
||||
children: ReactNode
|
||||
htmlFor: string
|
||||
}) => (
|
||||
}): ReactElement => (
|
||||
<label
|
||||
className={`${styles.label} ${required && styles.required}`}
|
||||
title={required ? 'Required' : ''}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React from 'react'
|
||||
import React, { ReactElement } from 'react'
|
||||
import ReactMarkdown from 'react-markdown'
|
||||
|
||||
const Markdown = ({
|
||||
@ -7,7 +7,7 @@ const Markdown = ({
|
||||
}: {
|
||||
text: string
|
||||
className?: string
|
||||
}) => {
|
||||
}): ReactElement => {
|
||||
// fix react-markdown \n transformation
|
||||
// https://github.com/rexxars/react-markdown/issues/105#issuecomment-351585313
|
||||
const textCleaned = text.replace(/\\n/g, '\n ')
|
||||
|
@ -0,0 +1,51 @@
|
||||
.tooltip {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.content {
|
||||
composes: box from './Box.module.css';
|
||||
padding: calc(var(--spacer) / 4);
|
||||
min-width: 20rem;
|
||||
max-width: 25rem;
|
||||
font-size: var(--font-size-small);
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
cursor: help;
|
||||
display: inline-block;
|
||||
margin-bottom: -0.1rem;
|
||||
margin-left: calc(var(--spacer) / 6);
|
||||
fill: var(--brand-grey-light);
|
||||
}
|
||||
|
||||
.arrow,
|
||||
.arrow::before {
|
||||
position: absolute;
|
||||
width: 1.2rem;
|
||||
height: 1.2rem;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.arrow::before {
|
||||
content: '';
|
||||
transform: rotate(45deg);
|
||||
background: var(--brand-grey-lighter);
|
||||
}
|
||||
|
||||
.content[data-placement*='top'] > .arrow {
|
||||
bottom: -4px;
|
||||
}
|
||||
|
||||
.content[data-placement*='bottom'] > .arrow {
|
||||
top: -4px;
|
||||
}
|
||||
|
||||
.content[data-placement*='left'] > .arrow {
|
||||
right: -4px;
|
||||
}
|
||||
|
||||
.content[data-placement*='right'] > .arrow {
|
||||
left: -4px;
|
||||
}
|
@ -1,24 +1,78 @@
|
||||
import React, { ReactElement, forwardRef } from 'react'
|
||||
import Tippy from '@tippyjs/react'
|
||||
import React, { ReactElement, ReactNode } from 'react'
|
||||
import loadable from '@loadable/component'
|
||||
import { useSpring, animated } from 'react-spring'
|
||||
import styles from './Tooltip.module.css'
|
||||
import { ReactComponent as Info } from '../../images/info.svg'
|
||||
|
||||
export default function Tooltip({
|
||||
content,
|
||||
children
|
||||
}: {
|
||||
content: string
|
||||
children: ReactElement
|
||||
}) {
|
||||
return (
|
||||
<Tippy content={content}>
|
||||
<CustomWrapper>{children}</CustomWrapper>
|
||||
</Tippy>
|
||||
)
|
||||
const Tippy = loadable(() => import('@tippyjs/react/headless'))
|
||||
|
||||
const animation = {
|
||||
config: { tension: 400, friction: 20 },
|
||||
from: { transform: 'scale(0.5) translateY(-3rem)' },
|
||||
to: { transform: 'scale(1) translateY(0)' }
|
||||
}
|
||||
|
||||
// Forward ref for Tippy.js
|
||||
// eslint-disable-next-line
|
||||
const CustomWrapper = forwardRef(
|
||||
({ children }: { children: ReactElement }, ref: any) => {
|
||||
return <div ref={ref}>{children}</div>
|
||||
const DefaultTrigger = React.forwardRef((props, ref: any) => {
|
||||
return <Info className={styles.icon} ref={ref} />
|
||||
})
|
||||
|
||||
export default function Tooltip({
|
||||
content,
|
||||
children,
|
||||
trigger,
|
||||
disabled
|
||||
}: {
|
||||
content: ReactNode
|
||||
children?: ReactNode
|
||||
trigger?: string
|
||||
disabled?: boolean
|
||||
}): ReactElement {
|
||||
const [props, setSpring] = useSpring(() => animation.from)
|
||||
|
||||
function onMount() {
|
||||
setSpring({
|
||||
transform: 'scale(1) translateY(0)',
|
||||
onRest: (): void => null,
|
||||
config: animation.config
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
function onHide({ unmount }: { unmount: any }) {
|
||||
setSpring({
|
||||
...animation.from,
|
||||
onRest: unmount,
|
||||
config: { ...animation.config, clamp: true }
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<Tippy
|
||||
interactive
|
||||
interactiveBorder={5}
|
||||
zIndex={1}
|
||||
trigger={trigger || 'mouseenter focus'}
|
||||
disabled={disabled || null}
|
||||
render={(attrs: any) => (
|
||||
<animated.div style={props}>
|
||||
<div className={styles.content} {...attrs}>
|
||||
{content}
|
||||
<div className={styles.arrow} data-popper-arrow />
|
||||
</div>
|
||||
</animated.div>
|
||||
)}
|
||||
appendTo={
|
||||
typeof document !== 'undefined' && document.querySelector('body')
|
||||
}
|
||||
animation
|
||||
onMount={onMount}
|
||||
onHide={onHide}
|
||||
fallback={
|
||||
<div className={styles.tooltip}>{children || <DefaultTrigger />}</div>
|
||||
}
|
||||
>
|
||||
<div className={styles.tooltip}>{children || <DefaultTrigger />}</div>
|
||||
</Tippy>
|
||||
)
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React, { ReactElement, useState, ChangeEvent, useEffect } from 'react'
|
||||
import { graphql, useStaticQuery } from 'gatsby'
|
||||
import stylesIndex from './index.module.css'
|
||||
import styles from './Advanced.module.css'
|
||||
import FormHelp from '../../../atoms/Input/Help'
|
||||
@ -10,19 +11,22 @@ import { isCorrectNetwork } from '../../../../utils/wallet'
|
||||
import { useSiteMetadata } from '../../../../hooks/useSiteMetadata'
|
||||
import InputElement from '../../../atoms/Input/InputElement'
|
||||
import Label from '../../../atoms/Input/Label'
|
||||
import Tooltip from '../../../atoms/Tooltip'
|
||||
|
||||
export default function Advanced({
|
||||
ocean,
|
||||
tokensToMint,
|
||||
weightOnDataToken,
|
||||
liquidityProviderFee,
|
||||
onOceanChange
|
||||
onOceanChange,
|
||||
content
|
||||
}: {
|
||||
ocean: string
|
||||
tokensToMint: number
|
||||
weightOnDataToken: string
|
||||
liquidityProviderFee: string
|
||||
onOceanChange: (event: ChangeEvent<HTMLInputElement>) => void
|
||||
content: any
|
||||
}): ReactElement {
|
||||
const { appConfig } = useSiteMetadata()
|
||||
const { account, balance, chainId, refreshBalance } = useOcean()
|
||||
@ -61,10 +65,7 @@ export default function Advanced({
|
||||
return (
|
||||
<div className={stylesIndex.content}>
|
||||
<div className={styles.advanced}>
|
||||
<FormHelp className={stylesIndex.help}>
|
||||
{`Let's create a decentralized, automated market for your data set. A Data Token contract for this data set worth the entered amount of OCEAN will be created. Additionally, you will provide liquidity into a Data Token/OCEAN
|
||||
liquidity pool with Balancer.`}
|
||||
</FormHelp>
|
||||
<FormHelp className={stylesIndex.help}>{content.info}</FormHelp>
|
||||
|
||||
<aside className={styles.wallet}>
|
||||
{balance && balance.ocean && (
|
||||
@ -75,7 +76,10 @@ export default function Advanced({
|
||||
<Wallet />
|
||||
</aside>
|
||||
|
||||
<h4 className={styles.title}>Data Token Liquidity Pool</h4>
|
||||
<h4 className={styles.title}>
|
||||
Data Token Liquidity Pool{' '}
|
||||
<Tooltip content={content.tooltips.poolInfo} />
|
||||
</h4>
|
||||
|
||||
<div className={styles.tokens}>
|
||||
<Coin
|
||||
@ -95,7 +99,10 @@ export default function Advanced({
|
||||
</div>
|
||||
|
||||
<footer className={styles.summary}>
|
||||
<Label htmlFor="liquidityProviderFee">Liquidity Provider Fee</Label>
|
||||
<Label htmlFor="liquidityProviderFee">
|
||||
Liquidity Provider Fee{' '}
|
||||
<Tooltip content={content.tooltips.liquidityProviderFee} />
|
||||
</Label>
|
||||
<InputElement
|
||||
value={liquidityProviderFee}
|
||||
name="liquidityProviderFee"
|
||||
|
@ -8,18 +8,17 @@ import Conversion from '../../../atoms/Price/Conversion'
|
||||
|
||||
export default function Simple({
|
||||
ocean,
|
||||
onChange
|
||||
onChange,
|
||||
content
|
||||
}: {
|
||||
ocean: string
|
||||
onChange: (event: ChangeEvent<HTMLInputElement>) => void
|
||||
content: any
|
||||
}): ReactElement {
|
||||
return (
|
||||
<div className={stylesIndex.content}>
|
||||
<div className={styles.simple}>
|
||||
<FormHelp className={stylesIndex.help}>
|
||||
Set your price for accessing this data set. A Data Token contract for
|
||||
this data set, worth the entered amount of OCEAN will be created.
|
||||
</FormHelp>
|
||||
<FormHelp className={stylesIndex.help}>{content.info}</FormHelp>
|
||||
|
||||
<div className={styles.form}>
|
||||
<Label htmlFor="ocean">Ocean Tokens</Label>
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React, { ReactElement, useState, ChangeEvent, useEffect } from 'react'
|
||||
import { graphql, useStaticQuery } from 'gatsby'
|
||||
import { InputProps } from '../../../atoms/Input'
|
||||
import styles from './index.module.css'
|
||||
import Tabs from '../../../atoms/Tabs'
|
||||
@ -6,7 +7,37 @@ import Simple from './Simple'
|
||||
import Advanced from './Advanced'
|
||||
import { useField } from 'formik'
|
||||
|
||||
const query = graphql`
|
||||
query PriceFieldQuery {
|
||||
content: allFile(filter: { relativePath: { eq: "pages/publish.json" } }) {
|
||||
edges {
|
||||
node {
|
||||
childPagesJson {
|
||||
price {
|
||||
simple {
|
||||
title
|
||||
info
|
||||
}
|
||||
advanced {
|
||||
title
|
||||
info
|
||||
tooltips {
|
||||
poolInfo
|
||||
liquidityProviderFee
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
export default function Price(props: InputProps): ReactElement {
|
||||
const data = useStaticQuery(query)
|
||||
const content = data.content.edges[0].node.childPagesJson.price
|
||||
|
||||
const [field, meta, helpers] = useField(props)
|
||||
const { weightOnDataToken, liquidityProviderFee } = field.value
|
||||
|
||||
@ -31,11 +62,17 @@ export default function Price(props: InputProps): ReactElement {
|
||||
|
||||
const tabs = [
|
||||
{
|
||||
title: 'Simple: Fixed',
|
||||
content: <Simple ocean={ocean} onChange={handleOceanChange} />
|
||||
title: content.simple.title,
|
||||
content: (
|
||||
<Simple
|
||||
ocean={ocean}
|
||||
onChange={handleOceanChange}
|
||||
content={content.simple}
|
||||
/>
|
||||
)
|
||||
},
|
||||
{
|
||||
title: 'Advanced: Dynamic',
|
||||
title: content.advanced.title,
|
||||
content: (
|
||||
<Advanced
|
||||
ocean={ocean}
|
||||
@ -43,6 +80,7 @@ export default function Price(props: InputProps): ReactElement {
|
||||
weightOnDataToken={weightOnDataToken}
|
||||
onOceanChange={handleOceanChange}
|
||||
liquidityProviderFee={liquidityProviderFee}
|
||||
content={content.advanced}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
@ -1,8 +1,5 @@
|
||||
.details {
|
||||
composes: box from '../../atoms/Box.module.css';
|
||||
padding: calc(var(--spacer) / 2) !important;
|
||||
min-width: 20rem;
|
||||
max-width: 25rem;
|
||||
padding: calc(var(--spacer) / 4);
|
||||
}
|
||||
|
||||
.balance {
|
||||
@ -31,33 +28,3 @@
|
||||
font-size: var(--font-size-small);
|
||||
color: var(--color-secondary);
|
||||
}
|
||||
|
||||
.arrow,
|
||||
.arrow::before {
|
||||
position: absolute;
|
||||
width: 1.2rem;
|
||||
height: 1.2rem;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.arrow::before {
|
||||
content: '';
|
||||
transform: rotate(45deg);
|
||||
background: var(--brand-grey-lighter);
|
||||
}
|
||||
|
||||
.details[data-placement*='top'] > .arrow {
|
||||
bottom: -4px;
|
||||
}
|
||||
|
||||
.details[data-placement*='bottom'] > .arrow {
|
||||
top: -4px;
|
||||
}
|
||||
|
||||
.details[data-placement*='left'] > .arrow {
|
||||
right: -4px;
|
||||
}
|
||||
|
||||
.details[data-placement*='right'] > .arrow {
|
||||
left: -4px;
|
||||
}
|
||||
|
@ -8,11 +8,11 @@ import { getInjectedProviderName } from 'web3modal'
|
||||
import Conversion from '../../atoms/Price/Conversion'
|
||||
import { formatCurrency } from '@coingecko/cryptoformat'
|
||||
|
||||
export default function Details({ attrs }: { attrs: any }): ReactElement {
|
||||
export default function Details(): ReactElement {
|
||||
const { balance, connect, logout, chainId } = useOcean()
|
||||
|
||||
return (
|
||||
<div className={styles.details} {...attrs}>
|
||||
<div className={styles.details}>
|
||||
<ul>
|
||||
{Object.entries(balance).map(([key, value]) => (
|
||||
<li className={styles.balance} key={key}>
|
||||
@ -41,7 +41,6 @@ export default function Details({ attrs }: { attrs: any }): ReactElement {
|
||||
</li>
|
||||
</ul>
|
||||
<Web3Feedback />
|
||||
<div className={styles.arrow} data-popper-arrow />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -1,62 +1,15 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import loadable from '@loadable/component'
|
||||
import { useSpring, animated } from 'react-spring'
|
||||
import Account from './Account'
|
||||
import Details from './Details'
|
||||
import Tooltip from '../../atoms/Tooltip'
|
||||
import { useOcean } from '@oceanprotocol/react'
|
||||
|
||||
const Tippy = loadable(() => import('@tippyjs/react/headless'))
|
||||
|
||||
const animation = {
|
||||
config: { tension: 400, friction: 20 },
|
||||
from: { transform: 'scale(0.5) translateY(-3rem)' },
|
||||
to: { transform: 'scale(1) translateY(0)' }
|
||||
}
|
||||
|
||||
export default function Wallet(): ReactElement {
|
||||
const { accountId, refreshBalance } = useOcean()
|
||||
const [props, setSpring] = useSpring(() => animation.from)
|
||||
|
||||
// always refetch balance when popover is opened
|
||||
function onMount() {
|
||||
accountId && refreshBalance()
|
||||
|
||||
setSpring({
|
||||
transform: 'scale(1) translateY(0)',
|
||||
onRest: (): void => null,
|
||||
config: animation.config
|
||||
})
|
||||
}
|
||||
|
||||
function onHide({ unmount }: { unmount: any }) {
|
||||
setSpring({
|
||||
...animation.from,
|
||||
onRest: unmount,
|
||||
config: { ...animation.config, clamp: true }
|
||||
})
|
||||
}
|
||||
const { accountId } = useOcean()
|
||||
|
||||
return (
|
||||
<Tippy
|
||||
interactive
|
||||
interactiveBorder={30}
|
||||
trigger="click focus"
|
||||
zIndex={1}
|
||||
render={(attrs: any) => (
|
||||
<animated.div style={props}>
|
||||
<Details attrs={attrs} />
|
||||
</animated.div>
|
||||
)}
|
||||
appendTo={
|
||||
typeof document !== 'undefined' && document.querySelector('body')
|
||||
}
|
||||
animation
|
||||
onMount={onMount}
|
||||
onHide={onHide}
|
||||
disabled={!accountId}
|
||||
fallback={<Account />}
|
||||
>
|
||||
<Tooltip content={<Details />} trigger="click focus" disabled={!accountId}>
|
||||
<Account />
|
||||
</Tippy>
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
|
3
src/images/info.svg
Normal file
3
src/images/info.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10 1.53846C5.32682 1.53846 1.53846 5.32682 1.53846 10C1.53846 14.6732 5.32682 18.4615 10 18.4615C14.6732 18.4615 18.4615 14.6732 18.4615 10C18.4615 5.32682 14.6732 1.53846 10 1.53846ZM0 10C0 4.47715 4.47715 0 10 0C15.5228 0 20 4.47715 20 10C20 15.5228 15.5228 20 10 20C4.47715 20 0 15.5228 0 10ZM10 8.46154C10.4248 8.46154 10.7692 8.80593 10.7692 9.23077V15.3846C10.7692 15.8094 10.4248 16.1538 10 16.1538C9.57517 16.1538 9.23077 15.8094 9.23077 15.3846V9.23077C9.23077 8.80593 9.57517 8.46154 10 8.46154ZM10 4.61538C9.36275 4.61538 8.84615 5.13198 8.84615 5.76923C8.84615 6.40648 9.36275 6.92308 10 6.92308C10.6373 6.92308 11.1538 6.40648 11.1538 5.76923C11.1538 5.13198 10.6373 4.61538 10 4.61538Z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 844 B |
@ -35,7 +35,7 @@ export const initialValues: MetadataPublishForm = {
|
||||
type: 'simple',
|
||||
tokensToMint: 1,
|
||||
weightOnDataToken: '9', // 90% on data token
|
||||
liquidityProviderFee: '0.3' // in %
|
||||
liquidityProviderFee: '0.1' // in %
|
||||
},
|
||||
files: undefined,
|
||||
description: undefined,
|
||||
|
Loading…
Reference in New Issue
Block a user