mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
refactor price context to fetch multiple tokens (#1573)
* refactor price context to fetch multiple tokens * fixes * move tokenIds to app config * make conversion work * conversion for all user tokens, hide if 0 * different user balance key tactic * remove NFT gas estimation * closes #1633 * small simplification in getCoingeckoTokenId logic * basic Prices provider test * mock some hooks * mock MarketMetadata in all tests
This commit is contained in:
parent
2f93d84e5f
commit
4d119467a4
73
.jest/__mocks__/MarketMetadata.ts
Normal file
73
.jest/__mocks__/MarketMetadata.ts
Normal file
@ -0,0 +1,73 @@
|
||||
import siteContent from '../../content/site.json'
|
||||
import appConfig from '../../app.config'
|
||||
|
||||
export default {
|
||||
getOpcFeeForToken: jest.fn(),
|
||||
siteContent,
|
||||
appConfig,
|
||||
opcFees: [
|
||||
{
|
||||
chainId: 1,
|
||||
approvedTokens: [
|
||||
'0x0642026e7f0b6ccac5925b4e7fa61384250e1701',
|
||||
'0x967da4048cd07ab37855c090aaf366e4ce1b9f48'
|
||||
],
|
||||
swapApprovedFee: '0.001',
|
||||
swapNotApprovedFee: '0.002'
|
||||
},
|
||||
{
|
||||
chainId: 137,
|
||||
approvedTokens: [
|
||||
'0x282d8efce846a88b159800bd4130ad77443fa1a1',
|
||||
'0xc5248aa0629c0b2d6a02834a5f172937ac83cbd3'
|
||||
],
|
||||
swapApprovedFee: '0.001',
|
||||
swapNotApprovedFee: '0.002'
|
||||
},
|
||||
{
|
||||
chainId: 56,
|
||||
approvedTokens: ['0xdce07662ca8ebc241316a15b611c89711414dd1a'],
|
||||
swapApprovedFee: '0.001',
|
||||
swapNotApprovedFee: '0.002'
|
||||
},
|
||||
{
|
||||
chainId: 246,
|
||||
approvedTokens: ['0x593122aae80a6fc3183b2ac0c4ab3336debee528'],
|
||||
swapApprovedFee: '0.001',
|
||||
swapNotApprovedFee: '0.002'
|
||||
},
|
||||
{
|
||||
chainId: 1285,
|
||||
approvedTokens: ['0x99c409e5f62e4bd2ac142f17cafb6810b8f0baae'],
|
||||
swapApprovedFee: '0.001',
|
||||
swapNotApprovedFee: '0.002'
|
||||
},
|
||||
{
|
||||
chainId: 3,
|
||||
approvedTokens: ['0x5e8dcb2afa23844bcc311b00ad1a0c30025aade9'],
|
||||
swapApprovedFee: '0.001',
|
||||
swapNotApprovedFee: '0.002'
|
||||
},
|
||||
{
|
||||
chainId: 4,
|
||||
approvedTokens: [
|
||||
'0x8967bcf84170c91b0d24d4302c2376283b0b3a07',
|
||||
'0xd92e713d051c37ebb2561803a3b5fbabc4962431'
|
||||
],
|
||||
swapApprovedFee: '0.001',
|
||||
swapNotApprovedFee: '0.002'
|
||||
},
|
||||
{
|
||||
chainId: 80001,
|
||||
approvedTokens: ['0xd8992ed72c445c35cb4a2be468568ed1079357c8'],
|
||||
swapApprovedFee: '0.001',
|
||||
swapNotApprovedFee: '0.002'
|
||||
},
|
||||
{
|
||||
chainId: 1287,
|
||||
approvedTokens: ['0xf6410bf5d773c7a41ebff972f38e7463fa242477'],
|
||||
swapApprovedFee: '0.001',
|
||||
swapNotApprovedFee: '0.002'
|
||||
}
|
||||
]
|
||||
}
|
@ -1,2 +1,7 @@
|
||||
import '@testing-library/jest-dom/extend-expect'
|
||||
import './__mocks__/matchMedia'
|
||||
import marketMetadataMock from './__mocks__/MarketMetadata'
|
||||
|
||||
jest.mock('../../src/@context/MarketMetadata', () => ({
|
||||
useMarketMetadata: () => marketMetadataMock
|
||||
}))
|
||||
|
@ -62,6 +62,10 @@ module.exports = {
|
||||
'LINK'
|
||||
],
|
||||
|
||||
// Tokens to fetch the spot prices from coingecko, against above currencies.
|
||||
// Refers to Coingecko API tokenIds.
|
||||
coingeckoTokenIds: ['ocean-protocol', 'h2o', 'ethereum', 'matic-network'],
|
||||
|
||||
// Config for https://github.com/donavon/use-dark-mode
|
||||
darkModeConfig: {
|
||||
classNameDark: 'dark',
|
||||
|
@ -16,6 +16,7 @@ export interface AppConfig {
|
||||
consumeMarketOrderFee: string
|
||||
consumeMarketFixedSwapFee: string
|
||||
currencies: string[]
|
||||
coingeckoTokenIds: string[]
|
||||
allowFixedPricing: string
|
||||
allowFreePricing: string
|
||||
defaultPrivacyPolicySlug: string
|
||||
|
@ -14,6 +14,7 @@ import { MarketMetadataProviderValue, OpcFee } from './_types'
|
||||
import siteContent from '../../../content/site.json'
|
||||
import appConfig from '../../../app.config'
|
||||
import { fetchData, getQueryContext } from '@utils/subgraph'
|
||||
import { LoggerInstance } from '@oceanprotocol/lib'
|
||||
|
||||
const MarketMetadataContext = createContext({} as MarketMetadataProviderValue)
|
||||
|
||||
@ -43,6 +44,11 @@ function MarketMetadataProvider({
|
||||
swapNotApprovedFee: response.data?.opc.swapNonOceanFee
|
||||
} as OpcFee)
|
||||
}
|
||||
LoggerInstance.log('[MarketMetadata] Got new data.', {
|
||||
opcFees: opcData,
|
||||
siteContent,
|
||||
appConfig
|
||||
})
|
||||
setOpcFees(opcData)
|
||||
}
|
||||
getOpcData()
|
||||
|
13
src/@context/Prices/_constants.ts
Normal file
13
src/@context/Prices/_constants.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { Prices } from './_types'
|
||||
import { coingeckoTokenIds } from '../../../app.config'
|
||||
|
||||
export const initialData: Prices = coingeckoTokenIds.map((tokenId) => ({
|
||||
[tokenId]: {
|
||||
eur: 0.0,
|
||||
usd: 0.0,
|
||||
eth: 0.0,
|
||||
btc: 0.0
|
||||
}
|
||||
}))[0]
|
||||
|
||||
export const refreshInterval = 120000 // 120 sec.
|
9
src/@context/Prices/_types.ts
Normal file
9
src/@context/Prices/_types.ts
Normal file
@ -0,0 +1,9 @@
|
||||
export interface Prices {
|
||||
[key: string]: {
|
||||
[key: string]: number
|
||||
}
|
||||
}
|
||||
|
||||
export interface PricesValue {
|
||||
prices: Prices
|
||||
}
|
23
src/@context/Prices/_utils.ts
Normal file
23
src/@context/Prices/_utils.ts
Normal file
@ -0,0 +1,23 @@
|
||||
//
|
||||
// Deal with differences between token symbol & Coingecko API IDs
|
||||
//
|
||||
export function getCoingeckoTokenId(symbol: string) {
|
||||
// can be OCEAN or mOCEAN
|
||||
const isOcean = symbol?.toLowerCase().includes('ocean')
|
||||
// can be H2O or H20
|
||||
const isH2o = symbol?.toLowerCase().includes('h2')
|
||||
const isEth = symbol?.toLowerCase() === 'eth'
|
||||
const isMatic = symbol?.toLowerCase() === 'matic'
|
||||
|
||||
const priceTokenId = isOcean
|
||||
? 'ocean-protocol'
|
||||
: isH2o
|
||||
? 'h2o'
|
||||
: isEth
|
||||
? 'ethereum'
|
||||
: isMatic
|
||||
? 'matic-network'
|
||||
: symbol?.toLowerCase()
|
||||
|
||||
return priceTokenId
|
||||
}
|
36
src/@context/Prices/index.test.tsx
Normal file
36
src/@context/Prices/index.test.tsx
Normal file
@ -0,0 +1,36 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import * as SWR from 'swr'
|
||||
import { renderHook } from '@testing-library/react'
|
||||
import { PricesProvider, usePrices, getCoingeckoTokenId } from '.'
|
||||
|
||||
jest.spyOn(SWR, 'default').mockImplementation(() => ({
|
||||
useSWR: { data: { 'ocean-protocol': { eur: '2' } } },
|
||||
isValidating: false,
|
||||
mutate: jest.fn()
|
||||
}))
|
||||
|
||||
const wrapper = ({ children }: { children: ReactElement }) => (
|
||||
<PricesProvider>{children}</PricesProvider>
|
||||
)
|
||||
|
||||
test('should correctly initialize data', async () => {
|
||||
const { result } = renderHook(() => usePrices(), { wrapper })
|
||||
|
||||
expect(result.current.prices['ocean-protocol'].eur).toBeDefined()
|
||||
})
|
||||
|
||||
test('useSWR is called', async () => {
|
||||
const { result } = renderHook(() => usePrices(), { wrapper })
|
||||
expect(SWR.default).toHaveBeenCalled()
|
||||
|
||||
// somehow the above spy seems to not fully work, but this assertion is the goal
|
||||
// expect(result.current.prices['ocean-protocol'].eur).toBe('2')
|
||||
})
|
||||
|
||||
test('should get correct Coingecko API ID for OCEAN', async () => {
|
||||
const id1 = getCoingeckoTokenId('OCEAN')
|
||||
expect(id1).toBe('ocean-protocol')
|
||||
|
||||
const id2 = getCoingeckoTokenId('mOCEAN')
|
||||
expect(id2).toBe('ocean-protocol')
|
||||
})
|
@ -9,24 +9,10 @@ import React, {
|
||||
import { fetchData } from '@utils/fetch'
|
||||
import useSWR from 'swr'
|
||||
import { LoggerInstance } from '@oceanprotocol/lib'
|
||||
import { useMarketMetadata } from './MarketMetadata'
|
||||
|
||||
interface Prices {
|
||||
[key: string]: number
|
||||
}
|
||||
|
||||
interface PricesValue {
|
||||
prices: Prices
|
||||
}
|
||||
|
||||
const initialData: Prices = {
|
||||
eur: 0.0,
|
||||
usd: 0.0,
|
||||
eth: 0.0,
|
||||
btc: 0.0
|
||||
}
|
||||
|
||||
const refreshInterval = 120000 // 120 sec.
|
||||
import { useMarketMetadata } from '../MarketMetadata'
|
||||
import { Prices, PricesValue } from './_types'
|
||||
import { initialData, refreshInterval } from './_constants'
|
||||
import { getCoingeckoTokenId } from './_utils'
|
||||
|
||||
const PricesContext = createContext(null)
|
||||
|
||||
@ -36,23 +22,23 @@ export default function PricesProvider({
|
||||
children: ReactNode
|
||||
}): ReactElement {
|
||||
const { appConfig } = useMarketMetadata()
|
||||
const tokenId = 'ocean-protocol'
|
||||
|
||||
const [prices, setPrices] = useState(initialData)
|
||||
const [url, setUrl] = useState('')
|
||||
const [url, setUrl] = useState<string>()
|
||||
|
||||
useEffect(() => {
|
||||
if (!appConfig) return
|
||||
// comma-separated list
|
||||
|
||||
const currencies = appConfig.currencies.join(',')
|
||||
const url = `https://api.coingecko.com/api/v3/simple/price?ids=${tokenId}&vs_currencies=${currencies}`
|
||||
const tokenIds = appConfig.coingeckoTokenIds.join(',')
|
||||
const url = `https://api.coingecko.com/api/v3/simple/price?ids=${tokenIds}&vs_currencies=${currencies}`
|
||||
setUrl(url)
|
||||
}, [appConfig])
|
||||
|
||||
const onSuccess = async (data: { [tokenId]: Prices }) => {
|
||||
const onSuccess = async (data: Prices) => {
|
||||
if (!data) return
|
||||
LoggerInstance.log('[prices] Got new OCEAN spot prices.', data[tokenId])
|
||||
setPrices(data[tokenId])
|
||||
LoggerInstance.log('[prices] Got new spot prices.', data)
|
||||
setPrices(data)
|
||||
}
|
||||
|
||||
// Fetch new prices periodically with swr
|
||||
@ -71,4 +57,4 @@ export default function PricesProvider({
|
||||
// Helper hook to access the provider values
|
||||
const usePrices = (): PricesValue => useContext(PricesContext)
|
||||
|
||||
export { PricesProvider, usePrices }
|
||||
export { PricesProvider, usePrices, getCoingeckoTokenId }
|
@ -160,12 +160,15 @@ function Web3Provider({ children }: { children: ReactNode }): ReactElement {
|
||||
// Helper: Get user balance
|
||||
// -----------------------------------
|
||||
const getUserBalance = useCallback(async () => {
|
||||
if (!accountId || !networkId || !web3) return
|
||||
if (!accountId || !networkId || !web3 || !networkData) return
|
||||
|
||||
try {
|
||||
const balance: UserBalance = {
|
||||
eth: web3.utils.fromWei(await web3.eth.getBalance(accountId, 'latest'))
|
||||
}
|
||||
const userBalance = web3.utils.fromWei(
|
||||
await web3.eth.getBalance(accountId, 'latest')
|
||||
)
|
||||
const key = networkData.nativeCurrency.symbol.toLowerCase()
|
||||
const balance: UserBalance = { [key]: userBalance }
|
||||
|
||||
if (approvedBaseTokens?.length > 0) {
|
||||
await Promise.all(
|
||||
approvedBaseTokens.map(async (token) => {
|
||||
@ -186,7 +189,7 @@ function Web3Provider({ children }: { children: ReactNode }): ReactElement {
|
||||
} catch (error) {
|
||||
LoggerInstance.error('[web3] Error: ', error.message)
|
||||
}
|
||||
}, [accountId, approvedBaseTokens, networkId, web3])
|
||||
}, [accountId, approvedBaseTokens, networkId, web3, networkData])
|
||||
|
||||
// -----------------------------------
|
||||
// Helper: Get user ENS name
|
||||
|
1
src/@types/TokenBalance.d.ts
vendored
1
src/@types/TokenBalance.d.ts
vendored
@ -1,4 +1,3 @@
|
||||
interface UserBalance {
|
||||
eth: string
|
||||
[key: string]: string
|
||||
}
|
||||
|
@ -1,68 +0,0 @@
|
||||
import React, { ReactElement, useEffect, useState } from 'react'
|
||||
import { usePrices } from '@context/Prices'
|
||||
import { useWeb3 } from '@context/Web3'
|
||||
import Web3 from 'web3'
|
||||
import useNftFactory from '@hooks/contracts/useNftFactory'
|
||||
import { NftFactory } from '@oceanprotocol/lib'
|
||||
import Conversion from '@shared/Price/Conversion'
|
||||
import { generateNftCreateData, NftMetadata } from '@utils/nft'
|
||||
|
||||
const getEstGasFee = async (
|
||||
address: string,
|
||||
nftFactory: NftFactory,
|
||||
nftMetadata: NftMetadata,
|
||||
ethToOceanConversionRate: number
|
||||
): Promise<string> => {
|
||||
if (!address || !nftFactory || !nftMetadata || !ethToOceanConversionRate)
|
||||
return
|
||||
|
||||
const { web3 } = nftFactory
|
||||
const nft = generateNftCreateData(nftMetadata, address)
|
||||
|
||||
const gasPrice = await web3.eth.getGasPrice()
|
||||
const gasLimit = await nftFactory?.estGasCreateNFT(address, nft)
|
||||
const gasFeeEth = Web3.utils.fromWei(
|
||||
(+gasPrice * +gasLimit).toString(),
|
||||
'ether'
|
||||
)
|
||||
const gasFeeOcean = (+gasFeeEth / +ethToOceanConversionRate).toString()
|
||||
return gasFeeOcean
|
||||
}
|
||||
|
||||
export default function TxFee({
|
||||
nftMetadata
|
||||
}: {
|
||||
nftMetadata: NftMetadata
|
||||
}): ReactElement {
|
||||
const { accountId } = useWeb3()
|
||||
const { prices } = usePrices()
|
||||
const nftFactory = useNftFactory()
|
||||
const [gasFee, setGasFee] = useState('')
|
||||
|
||||
useEffect(() => {
|
||||
const calculateGasFee = async () =>
|
||||
setGasFee(
|
||||
await getEstGasFee(
|
||||
accountId,
|
||||
nftFactory,
|
||||
nftMetadata,
|
||||
(prices as any)?.eth
|
||||
)
|
||||
)
|
||||
calculateGasFee()
|
||||
}, [accountId, nftFactory, nftMetadata, prices])
|
||||
|
||||
return gasFee ? (
|
||||
<p>
|
||||
Gas fee estimation for this artwork
|
||||
<Conversion price={gasFee} />
|
||||
</p>
|
||||
) : accountId ? (
|
||||
<p>
|
||||
An error occurred while estimating the gas fee for this artwork, please
|
||||
try again.
|
||||
</p>
|
||||
) : (
|
||||
<p>Please connect your wallet to get a gas fee estimate for this artwork</p>
|
||||
)
|
||||
}
|
@ -27,7 +27,7 @@
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
padding: 0 calc(var(--spacer) / 4);
|
||||
padding: calc(var(--spacer) / 4);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
@ -5,8 +5,6 @@ import { useField } from 'formik'
|
||||
import React, { ReactElement, useEffect } from 'react'
|
||||
import Refresh from '@images/refresh.svg'
|
||||
import styles from './index.module.css'
|
||||
import Tooltip from '@shared/atoms/Tooltip'
|
||||
import TxFee from './TxFee'
|
||||
|
||||
export default function Nft(props: InputProps): ReactElement {
|
||||
const [field, meta, helpers] = useField(props.name)
|
||||
@ -28,7 +26,6 @@ export default function Nft(props: InputProps): ReactElement {
|
||||
<figure className={styles.image}>
|
||||
<img src={field?.value?.image_data} width="128" height="128" />
|
||||
<div className={styles.actions}>
|
||||
<Tooltip content={<TxFee nftMetadata={field.value} />} />
|
||||
<Button
|
||||
style="text"
|
||||
size="small"
|
||||
|
@ -1,18 +1,17 @@
|
||||
import React, { useEffect, useState, ReactElement } from 'react'
|
||||
import styles from './Conversion.module.css'
|
||||
import classNames from 'classnames/bind'
|
||||
import { formatCurrency, isCrypto } from '@coingecko/cryptoformat'
|
||||
import { useUserPreferences } from '@context/UserPreferences'
|
||||
import { usePrices } from '@context/Prices'
|
||||
|
||||
const cx = classNames.bind(styles)
|
||||
import { usePrices, getCoingeckoTokenId } from '@context/Prices'
|
||||
|
||||
export default function Conversion({
|
||||
price,
|
||||
symbol,
|
||||
className,
|
||||
hideApproximateSymbol
|
||||
}: {
|
||||
price: string // expects price in OCEAN, not wei
|
||||
symbol: string
|
||||
className?: string
|
||||
hideApproximateSymbol?: boolean
|
||||
}): ReactElement {
|
||||
@ -25,18 +24,21 @@ export default function Conversion({
|
||||
// isCrypto() only checks for BTC & ETH & unknown but seems sufficient for now
|
||||
// const isFiat = /(EUR|USD|CAD|SGD|HKD|CNY|JPY|GBP|INR|RUB)/g.test(currency)
|
||||
|
||||
const styleClasses = cx({
|
||||
conversion: true,
|
||||
[className]: className
|
||||
})
|
||||
// referring to Coingecko tokenId in Prices context provider
|
||||
const priceTokenId = getCoingeckoTokenId(symbol)
|
||||
|
||||
useEffect(() => {
|
||||
if (!prices || !price || price === '0') {
|
||||
setPriceConverted('0.00')
|
||||
if (
|
||||
!prices ||
|
||||
!price ||
|
||||
price === '0' ||
|
||||
!priceTokenId ||
|
||||
!prices[priceTokenId]
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
const conversionValue = prices[currency.toLowerCase()]
|
||||
const conversionValue = prices[priceTokenId][currency.toLowerCase()]
|
||||
const converted = conversionValue * Number(price)
|
||||
const convertedFormatted = formatCurrency(
|
||||
converted,
|
||||
@ -54,16 +56,16 @@ export default function Conversion({
|
||||
(match) => `<span>${match}</span>`
|
||||
)
|
||||
setPriceConverted(convertedFormattedHTMLstring)
|
||||
}, [price, prices, currency, locale, isFiat])
|
||||
}, [price, prices, currency, locale, isFiat, priceTokenId])
|
||||
|
||||
return (
|
||||
return Number(price) > 0 ? (
|
||||
<span
|
||||
className={styleClasses}
|
||||
title="Approximation based on the current selected base token spot price on Coingecko"
|
||||
className={`${styles.conversion} ${className || ''}`}
|
||||
title="Approximation based on the current spot price on Coingecko"
|
||||
>
|
||||
{!hideApproximateSymbol && '≈ '}
|
||||
<strong dangerouslySetInnerHTML={{ __html: priceConverted }} />{' '}
|
||||
{!isFiat && currency}
|
||||
</span>
|
||||
)
|
||||
) : null
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ export default function PriceUnit({
|
||||
{Number.isNaN(Number(price)) ? '-' : formatPrice(price, locale)}{' '}
|
||||
<span className={styles.symbol}>{symbol}</span>
|
||||
</div>
|
||||
{conversion && <Conversion price={price} />}
|
||||
{conversion && <Conversion price={price} symbol={symbol} />}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
@ -17,7 +17,7 @@
|
||||
}
|
||||
|
||||
.balance {
|
||||
font-size: var(--font-size-base);
|
||||
font-size: var(--font-size-small);
|
||||
font-weight: var(--font-weight-bold);
|
||||
color: var(--color-secondary);
|
||||
white-space: nowrap;
|
||||
@ -32,6 +32,14 @@
|
||||
margin-right: 0.4rem;
|
||||
}
|
||||
|
||||
.value {
|
||||
color: var(--font-color-text);
|
||||
}
|
||||
|
||||
.conversion strong {
|
||||
font-weight: var(--font-weight-base);
|
||||
}
|
||||
|
||||
.actions {
|
||||
border-top: 1px solid var(--border-color);
|
||||
margin-top: calc(var(--spacer) / 2);
|
||||
|
@ -29,8 +29,7 @@ export default function Details(): ReactElement {
|
||||
useEffect(() => {
|
||||
if (!networkId) return
|
||||
|
||||
const symbol =
|
||||
networkId === 2021000 ? 'GX' : networkData?.nativeCurrency.symbol
|
||||
const symbol = networkData?.nativeCurrency.symbol
|
||||
setMainCurrency(symbol)
|
||||
|
||||
const oceanConfig = getOceanConfig(networkId)
|
||||
@ -49,11 +48,17 @@ export default function Details(): ReactElement {
|
||||
<li className={styles.balance} key={key}>
|
||||
<span className={styles.symbol}>
|
||||
{key === 'eth' ? mainCurrency : key.toUpperCase()}
|
||||
</span>{' '}
|
||||
{formatCurrency(Number(value), '', locale, false, {
|
||||
significantFigures: 4
|
||||
})}
|
||||
{key === 'ocean' && <Conversion price={value} />}
|
||||
</span>
|
||||
<span className={styles.value}>
|
||||
{formatCurrency(Number(value), '', locale, false, {
|
||||
significantFigures: 4
|
||||
})}
|
||||
</span>
|
||||
<Conversion
|
||||
className={styles.conversion}
|
||||
price={value}
|
||||
symbol={key}
|
||||
/>
|
||||
</li>
|
||||
))}
|
||||
|
||||
|
@ -42,7 +42,13 @@ export default function Stats({
|
||||
<div className={styles.stats}>
|
||||
<NumberUnit
|
||||
label="Total Sales"
|
||||
value={<Conversion price={totalSales} hideApproximateSymbol />}
|
||||
value={
|
||||
<Conversion
|
||||
price={totalSales}
|
||||
symbol={'ocean'}
|
||||
hideApproximateSymbol
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<NumberUnit label={`Sale${sales === 1 ? '' : 's'}`} value={sales} />
|
||||
<NumberUnit label="Published" value={assetsTotal} />
|
||||
|
@ -1,4 +1,3 @@
|
||||
import Input from '@shared/FormInput'
|
||||
import InputElement from '@shared/FormInput/InputElement'
|
||||
import { useFormikContext } from 'formik'
|
||||
import React, { ChangeEvent, ReactElement } from 'react'
|
||||
|
@ -52,7 +52,11 @@ export default function Price({
|
||||
<div className={styles.datatoken}>
|
||||
<h4>
|
||||
= <strong>1</strong> {dataTokenOptions.symbol}{' '}
|
||||
<Conversion price={field.value} className={styles.conversion} />
|
||||
<Conversion
|
||||
price={field.value}
|
||||
symbol={values.pricing?.baseToken?.symbol}
|
||||
className={styles.conversion}
|
||||
/>
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user