mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
Refactor pricing and various components that are involved (#1046)
* update * merge pr #1012 * fix header * fix * abort controller * up next.8 * build fix * update lock * fix * another fix * ssh fix * another ssh fix * remove optional * order mock * small cleanup * fix package * price updates * finish getPrice * fix consume * fix consume * getConsumeDetails comments * restore functionality after consumeDetails * fix some compute typings * more price fetching updates * 'minor' refactors and fixed build * package-lock fix * minor comments * minor naming changes * fix * fix pool badge * remove console.log
This commit is contained in:
parent
77c4ed42cc
commit
57be62a6b1
8596
package-lock.json
generated
8596
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -25,7 +25,6 @@
|
|||||||
"@oceanprotocol/typographies": "^0.1.0",
|
"@oceanprotocol/typographies": "^0.1.0",
|
||||||
"@portis/web3": "^4.0.6",
|
"@portis/web3": "^4.0.6",
|
||||||
"@tippyjs/react": "^4.2.6",
|
"@tippyjs/react": "^4.2.6",
|
||||||
"@urql/introspection": "^0.3.1",
|
|
||||||
"@walletconnect/web3-provider": "^1.7.1",
|
"@walletconnect/web3-provider": "^1.7.1",
|
||||||
"axios": "^0.25.0",
|
"axios": "^0.25.0",
|
||||||
"bignumber.js": "^9.0.2",
|
"bignumber.js": "^9.0.2",
|
||||||
@ -36,7 +35,6 @@
|
|||||||
"decimal.js": "^10.3.1",
|
"decimal.js": "^10.3.1",
|
||||||
"dom-confetti": "^0.2.2",
|
"dom-confetti": "^0.2.2",
|
||||||
"dotenv": "^15.0.0",
|
"dotenv": "^15.0.0",
|
||||||
"ethereum-address": "0.0.4",
|
|
||||||
"ethereum-blockies": "github:MyEtherWallet/blockies",
|
"ethereum-blockies": "github:MyEtherWallet/blockies",
|
||||||
"filesize": "^8.0.6",
|
"filesize": "^8.0.6",
|
||||||
"formik": "^2.2.9",
|
"formik": "^2.2.9",
|
||||||
@ -48,7 +46,6 @@
|
|||||||
"lodash.omit": "^4.5.0",
|
"lodash.omit": "^4.5.0",
|
||||||
"next": "^12.0.9",
|
"next": "^12.0.9",
|
||||||
"query-string": "^7.1.0",
|
"query-string": "^7.1.0",
|
||||||
"querystring": "^0.2.1",
|
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-chartjs-2": "^4.0.1",
|
"react-chartjs-2": "^4.0.1",
|
||||||
"react-clipboard.js": "^2.0.16",
|
"react-clipboard.js": "^2.0.16",
|
||||||
|
@ -9,26 +9,27 @@ import React, {
|
|||||||
} from 'react'
|
} from 'react'
|
||||||
import { Asset, Config, LoggerInstance, Purgatory } from '@oceanprotocol/lib'
|
import { Asset, Config, LoggerInstance, Purgatory } from '@oceanprotocol/lib'
|
||||||
import { CancelToken } from 'axios'
|
import { CancelToken } from 'axios'
|
||||||
import { retrieveDDO } from '@utils/aquarius'
|
import { retrieveAsset } from '@utils/aquarius'
|
||||||
import { getPrice } from '@utils/subgraph'
|
|
||||||
import { useWeb3 } from './Web3'
|
import { useWeb3 } from './Web3'
|
||||||
import { useSiteMetadata } from '@hooks/useSiteMetadata'
|
import { useSiteMetadata } from '@hooks/useSiteMetadata'
|
||||||
import { useCancelToken } from '@hooks/useCancelToken'
|
import { useCancelToken } from '@hooks/useCancelToken'
|
||||||
import { getOceanConfig, getDevelopmentConfig } from '@utils/ocean'
|
import { getOceanConfig, getDevelopmentConfig } from '@utils/ocean'
|
||||||
|
import { AssetExtended } from 'src/@types/AssetExtended'
|
||||||
|
import { getAccessDetails } from '@utils/accessDetailsAndPricing'
|
||||||
|
|
||||||
interface AssetProviderValue {
|
interface AssetProviderValue {
|
||||||
isInPurgatory: boolean
|
isInPurgatory: boolean
|
||||||
purgatoryData: Purgatory
|
purgatoryData: Purgatory
|
||||||
ddo: Asset
|
assetExtended: AssetExtended
|
||||||
title: string
|
title: string
|
||||||
owner: string
|
owner: string
|
||||||
price: BestPrice
|
accessDetails: AccessDetails
|
||||||
error?: string
|
error?: string
|
||||||
refreshInterval: number
|
refreshInterval: number
|
||||||
isAssetNetwork: boolean
|
isAssetNetwork: boolean
|
||||||
oceanConfig: Config
|
oceanConfig: Config
|
||||||
loading: boolean
|
loading: boolean
|
||||||
refreshDdo: (token?: CancelToken) => Promise<void>
|
refreshAsset: (token?: CancelToken) => Promise<void>
|
||||||
}
|
}
|
||||||
|
|
||||||
const AssetContext = createContext({} as AssetProviderValue)
|
const AssetContext = createContext({} as AssetProviderValue)
|
||||||
@ -44,12 +45,12 @@ function AssetProvider({
|
|||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { appConfig } = useSiteMetadata()
|
const { appConfig } = useSiteMetadata()
|
||||||
|
|
||||||
const { networkId } = useWeb3()
|
const { networkId, accountId } = useWeb3()
|
||||||
const [isInPurgatory, setIsInPurgatory] = useState(false)
|
const [isInPurgatory, setIsInPurgatory] = useState(false)
|
||||||
const [purgatoryData, setPurgatoryData] = useState<Purgatory>()
|
const [purgatoryData, setPurgatoryData] = useState<Purgatory>()
|
||||||
const [ddo, setDDO] = useState<Asset>()
|
const [assetExtended, setAssetExtended] = useState<Asset>()
|
||||||
const [title, setTitle] = useState<string>()
|
const [title, setTitle] = useState<string>()
|
||||||
const [price, setPrice] = useState<BestPrice>()
|
const [accessDetails, setConsumeDetails] = useState<AccessDetails>()
|
||||||
const [owner, setOwner] = useState<string>()
|
const [owner, setOwner] = useState<string>()
|
||||||
const [error, setError] = useState<string>()
|
const [error, setError] = useState<string>()
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false)
|
||||||
@ -58,32 +59,35 @@ function AssetProvider({
|
|||||||
|
|
||||||
const newCancelToken = useCancelToken()
|
const newCancelToken = useCancelToken()
|
||||||
|
|
||||||
const fetchDdo = async (token?: CancelToken) => {
|
const fetchAsset = useCallback(
|
||||||
LoggerInstance.log('[asset] Init asset, get DDO')
|
async (token?: CancelToken) => {
|
||||||
setLoading(true)
|
LoggerInstance.log('[asset] Init asset, get assetExtended')
|
||||||
const ddo = await retrieveDDO(did, token)
|
setLoading(true)
|
||||||
|
const assetExtended = await retrieveAsset(did, token)
|
||||||
|
|
||||||
if (!ddo) {
|
if (!assetExtended) {
|
||||||
setError(
|
setError(
|
||||||
`[asset] The DDO for ${did} was not found in MetadataCache. If you just published a new data set, wait some seconds and refresh this page.`
|
`[asset] The assetExtended for ${did} was not found in MetadataCache. If you just published a new data set, wait some seconds and refresh this page.`
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
setError(undefined)
|
setError(undefined)
|
||||||
}
|
}
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
return ddo
|
return assetExtended
|
||||||
}
|
},
|
||||||
|
[did]
|
||||||
|
)
|
||||||
|
|
||||||
const refreshDdo = async (token?: CancelToken) => {
|
const refreshAsset = async (token?: CancelToken) => {
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
const ddo = await fetchDdo(token)
|
const assetExtended = await fetchAsset(token)
|
||||||
LoggerInstance.debug('[asset] Got DDO', ddo)
|
LoggerInstance.debug('[asset] Got assetExtended', assetExtended)
|
||||||
setDDO(ddo)
|
setAssetExtended(assetExtended)
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
// Get and set DDO based on passed DID
|
// Get and set assetExtended based on passed DID
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!did || !appConfig.metadataCacheUri) return
|
if (!did || !appConfig.metadataCacheUri) return
|
||||||
@ -91,77 +95,89 @@ function AssetProvider({
|
|||||||
let isMounted = true
|
let isMounted = true
|
||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
const ddo = await fetchDdo(newCancelToken())
|
const assetExtended = await fetchAsset(newCancelToken())
|
||||||
if (!isMounted || !ddo) return
|
if (!isMounted || !assetExtended) return
|
||||||
LoggerInstance.debug('[asset] Got DDO', ddo)
|
LoggerInstance.debug('[asset] Got assetExtended', assetExtended)
|
||||||
setDDO(ddo)
|
setAssetExtended(assetExtended)
|
||||||
setTitle(ddo.metadata.name)
|
setTitle(assetExtended.metadata.name)
|
||||||
setOwner(ddo.nft.owner)
|
setOwner(assetExtended.nft.owner)
|
||||||
setIsInPurgatory((ddo.purgatory?.state as unknown as string) === 'true')
|
setIsInPurgatory(
|
||||||
setPurgatoryData(ddo.purgatory)
|
(assetExtended.purgatory?.state as unknown as string) === 'true'
|
||||||
|
)
|
||||||
|
setPurgatoryData(assetExtended.purgatory)
|
||||||
}
|
}
|
||||||
init()
|
init()
|
||||||
return () => {
|
return () => {
|
||||||
isMounted = false
|
isMounted = false
|
||||||
}
|
}
|
||||||
}, [did, appConfig.metadataCacheUri])
|
}, [did, appConfig.metadataCacheUri, fetchAsset, newCancelToken])
|
||||||
|
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
// Attach price to asset
|
// Attach price to asset
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
const initPrice = useCallback(async (ddo: Asset): Promise<void> => {
|
const initPrice = useCallback(
|
||||||
if (!ddo) return
|
async (assetExtended: AssetExtended, accountId: string): Promise<void> => {
|
||||||
const returnedPrice = await getPrice(ddo)
|
if (!assetExtended) return
|
||||||
setPrice({ ...returnedPrice })
|
const accessDetails = await getAccessDetails(
|
||||||
}, [])
|
assetExtended.chainId,
|
||||||
|
assetExtended.services[0].datatokenAddress,
|
||||||
|
assetExtended.services[0].timeout,
|
||||||
|
accountId
|
||||||
|
)
|
||||||
|
assetExtended.accessDetails = accessDetails
|
||||||
|
setConsumeDetails({ ...accessDetails })
|
||||||
|
setAssetExtended(assetExtended)
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!ddo) return
|
if (!assetExtended) return
|
||||||
initPrice(ddo)
|
initPrice(assetExtended, accountId)
|
||||||
}, [ddo, initPrice])
|
}, [accountId, assetExtended, initPrice])
|
||||||
|
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
// Check user network against asset network
|
// Check user network against asset network
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!networkId || !ddo) return
|
if (!networkId || !assetExtended) return
|
||||||
|
|
||||||
const isAssetNetwork = networkId === ddo?.chainId
|
const isAssetNetwork = networkId === assetExtended?.chainId
|
||||||
setIsAssetNetwork(isAssetNetwork)
|
setIsAssetNetwork(isAssetNetwork)
|
||||||
}, [networkId, ddo])
|
}, [networkId, assetExtended])
|
||||||
|
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
// Load ocean config based on asset network
|
// Load ocean config based on asset network
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!ddo?.chainId) return
|
if (!assetExtended?.chainId) return
|
||||||
|
|
||||||
const oceanConfig = {
|
const oceanConfig = {
|
||||||
...getOceanConfig(ddo?.chainId),
|
...getOceanConfig(assetExtended?.chainId),
|
||||||
|
|
||||||
// add local dev values
|
// add local dev values
|
||||||
...(ddo?.chainId === 8996 && {
|
...(assetExtended?.chainId === 8996 && {
|
||||||
...getDevelopmentConfig()
|
...getDevelopmentConfig()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
setOceanConfig(oceanConfig)
|
setOceanConfig(oceanConfig)
|
||||||
}, [ddo])
|
}, [assetExtended])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AssetContext.Provider
|
<AssetContext.Provider
|
||||||
value={
|
value={
|
||||||
{
|
{
|
||||||
ddo,
|
assetExtended,
|
||||||
did,
|
did,
|
||||||
title,
|
title,
|
||||||
owner,
|
owner,
|
||||||
price,
|
accessDetails,
|
||||||
error,
|
error,
|
||||||
isInPurgatory,
|
isInPurgatory,
|
||||||
purgatoryData,
|
purgatoryData,
|
||||||
refreshInterval,
|
refreshInterval,
|
||||||
loading,
|
loading,
|
||||||
refreshDdo,
|
refreshAsset,
|
||||||
isAssetNetwork,
|
isAssetNetwork,
|
||||||
oceanConfig
|
oceanConfig
|
||||||
} as AssetProviderValue
|
} as AssetProviderValue
|
||||||
|
@ -19,7 +19,6 @@ import { getDownloadAssets, getPublishedAssets } from '@utils/aquarius'
|
|||||||
import { useSiteMetadata } from '@hooks/useSiteMetadata'
|
import { useSiteMetadata } from '@hooks/useSiteMetadata'
|
||||||
import { accountTruncate } from '@utils/web3'
|
import { accountTruncate } from '@utils/web3'
|
||||||
import axios, { CancelToken } from 'axios'
|
import axios, { CancelToken } from 'axios'
|
||||||
import ethereumAddress from 'ethereum-address'
|
|
||||||
import get3BoxProfile from '@utils/profile'
|
import get3BoxProfile from '@utils/profile'
|
||||||
import web3 from 'web3'
|
import web3 from 'web3'
|
||||||
|
|
||||||
@ -59,7 +58,7 @@ function ProfileProvider({
|
|||||||
// when accountId is no ETH address
|
// when accountId is no ETH address
|
||||||
//
|
//
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const isEthAddress = ethereumAddress.isAddress(accountId)
|
const isEthAddress = web3.utils.isAddress(accountId)
|
||||||
setIsEthAddress(isEthAddress)
|
setIsEthAddress(isEthAddress)
|
||||||
}, [accountId])
|
}, [accountId])
|
||||||
|
|
||||||
|
@ -1,7 +1,19 @@
|
|||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import { consumeFeedback } from '@utils/feedback'
|
import { consumeFeedback } from '@utils/feedback'
|
||||||
import { LoggerInstance } from '@oceanprotocol/lib'
|
import {
|
||||||
|
approve,
|
||||||
|
Datatoken,
|
||||||
|
FreOrderParams,
|
||||||
|
LoggerInstance,
|
||||||
|
OrderParams,
|
||||||
|
Pool,
|
||||||
|
ProviderFees,
|
||||||
|
ProviderInstance,
|
||||||
|
signHash,
|
||||||
|
ZERO_ADDRESS
|
||||||
|
} from '@oceanprotocol/lib'
|
||||||
import { useWeb3 } from '@context/Web3'
|
import { useWeb3 } from '@context/Web3'
|
||||||
|
import { getOceanConfig } from '@utils/ocean'
|
||||||
|
|
||||||
interface UseConsume {
|
interface UseConsume {
|
||||||
consume: (
|
consume: (
|
||||||
@ -18,7 +30,7 @@ interface UseConsume {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function useConsume(): UseConsume {
|
function useConsume(): UseConsume {
|
||||||
const { accountId } = useWeb3()
|
const { accountId, web3, chainId } = useWeb3()
|
||||||
const [isLoading, setIsLoading] = useState(false)
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
const [consumeStep, setConsumeStep] = useState<number | undefined>()
|
const [consumeStep, setConsumeStep] = useState<number | undefined>()
|
||||||
const [consumeStepText, setConsumeStepText] = useState<string | undefined>()
|
const [consumeStepText, setConsumeStepText] = useState<string | undefined>()
|
||||||
@ -29,9 +41,10 @@ function useConsume(): UseConsume {
|
|||||||
setConsumeStepText(consumeFeedback[index])
|
setConsumeStepText(consumeFeedback[index])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: this will be done in another PR
|
||||||
async function consume(
|
async function consume(
|
||||||
did: string,
|
did: string,
|
||||||
dataTokenAddress: string,
|
datatokenAddress: string,
|
||||||
serviceType = 'access',
|
serviceType = 'access',
|
||||||
marketFeeAddress: string,
|
marketFeeAddress: string,
|
||||||
orderId?: string
|
orderId?: string
|
||||||
@ -43,46 +56,90 @@ function useConsume(): UseConsume {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
setStep(0)
|
setStep(0)
|
||||||
// if (!orderId) {
|
if (!orderId) {
|
||||||
// if we don't have a previous valid order, get one
|
const datatoken = new Datatoken(web3)
|
||||||
// const userOwnedTokens = await ocean.accounts.getTokenBalance(
|
// if we don't have a previous valid order, get one
|
||||||
// dataTokenAddress,
|
const userOwnedTokens = await datatoken.balance(
|
||||||
// account
|
datatokenAddress,
|
||||||
// )
|
accountId
|
||||||
// if (parseFloat(userOwnedTokens) < 1) {
|
)
|
||||||
// setConsumeError('Not enough datatokens')
|
|
||||||
// return 'Not enough datatokens'
|
setStep(1)
|
||||||
// } else {
|
try {
|
||||||
// setStep(1)
|
const config = getOceanConfig(chainId)
|
||||||
// try {
|
// const txApprove = await approve(
|
||||||
// orderId = await ocean.assets.order(
|
// web3,
|
||||||
// did as string,
|
// accountId,
|
||||||
// serviceType,
|
// config.oceanTokenAddress,
|
||||||
// accountId,
|
// accountId,
|
||||||
// undefined,
|
// '1',
|
||||||
// marketFeeAddress,
|
// false
|
||||||
// undefined,
|
// )
|
||||||
// null,
|
// console.log('approve tx', txApprove)
|
||||||
// false
|
|
||||||
// )
|
// const txApprove1 = await approve(
|
||||||
// LoggerInstance.log('ordercreated', orderId)
|
// web3,
|
||||||
// setStep(2)
|
// accountId,
|
||||||
// } catch (error) {
|
// config.oceanTokenAddress,
|
||||||
// setConsumeError(error.message)
|
// datatokenAddress,
|
||||||
// return error.message
|
// '1',
|
||||||
// }
|
// false
|
||||||
// }
|
// )
|
||||||
// }
|
// console.log('approve tx', txApprove1)
|
||||||
|
|
||||||
|
// diference between timeout and validUntil?
|
||||||
|
const initializeData = await ProviderInstance.initialize(
|
||||||
|
did,
|
||||||
|
'fca052c239a62523be30ab8ee70c4046867f6cd89f228185fe2996ded3d23c3c',
|
||||||
|
0,
|
||||||
|
accountId,
|
||||||
|
'https://providerv4.rinkeby.oceanprotocol.com'
|
||||||
|
)
|
||||||
|
const orderParams = {
|
||||||
|
consumer: accountId,
|
||||||
|
serviceIndex: 1,
|
||||||
|
_providerFees: initializeData.providerFee
|
||||||
|
} as OrderParams
|
||||||
|
const freParams = {
|
||||||
|
exchangeContract: config.fixedRateExchangeAddress,
|
||||||
|
exchangeId:
|
||||||
|
'0x7ac824fef114255e5e3521a161ef692ec32003916fb6f3fe985cb74790d053ca',
|
||||||
|
maxBaseTokenAmount: web3.utils.toWei('2'),
|
||||||
|
swapMarketFee: web3.utils.toWei('0'),
|
||||||
|
marketFeeAddress: ZERO_ADDRESS
|
||||||
|
} as FreOrderParams
|
||||||
|
|
||||||
|
const esttx = await datatoken.estGasBuyFromFreAndOrder(
|
||||||
|
datatokenAddress,
|
||||||
|
accountId,
|
||||||
|
orderParams,
|
||||||
|
freParams
|
||||||
|
)
|
||||||
|
const tx = await datatoken.buyFromFreAndOrder(
|
||||||
|
datatokenAddress,
|
||||||
|
accountId,
|
||||||
|
orderParams,
|
||||||
|
freParams
|
||||||
|
)
|
||||||
|
|
||||||
|
LoggerInstance.log('ordercreated', orderId)
|
||||||
|
setStep(2)
|
||||||
|
} catch (error) {
|
||||||
|
setConsumeError(error.message)
|
||||||
|
return error.message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setStep(3)
|
setStep(3)
|
||||||
// if (orderId)
|
if (orderId)
|
||||||
// await ocean.assets.download(
|
// await ocean.assets.download(
|
||||||
// did as string,
|
// did as string,
|
||||||
// orderId,
|
// orderId,
|
||||||
// dataTokenAddress,
|
// dataTokenAddress,
|
||||||
// account,
|
// account,
|
||||||
// ''
|
// ''
|
||||||
// )
|
// )
|
||||||
setStep(4)
|
setStep(4)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setConsumeError(error.message)
|
setConsumeError(error.message)
|
||||||
LoggerInstance.error(error)
|
LoggerInstance.error(error)
|
||||||
|
@ -39,6 +39,7 @@ async function getBlockHead(config: Config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// for everything else, create new web3 instance with infura
|
// for everything else, create new web3 instance with infura
|
||||||
|
// TODO: this fails randomly , WHY!?!?!?!?!
|
||||||
const web3Instance = new Web3(config.nodeUri)
|
const web3Instance = new Web3(config.nodeUri)
|
||||||
const blockHead = await web3Instance.eth.getBlockNumber()
|
const blockHead = await web3Instance.eth.getBlockNumber()
|
||||||
return blockHead
|
return blockHead
|
||||||
|
@ -9,21 +9,16 @@ import {
|
|||||||
getCreateFreePricingFeedback,
|
getCreateFreePricingFeedback,
|
||||||
getDispenseFeedback
|
getDispenseFeedback
|
||||||
} from '@utils/feedback'
|
} from '@utils/feedback'
|
||||||
import { sleep } from '@utils/index'
|
|
||||||
import { useWeb3 } from '@context/Web3'
|
import { useWeb3 } from '@context/Web3'
|
||||||
import { getOceanConfig } from '@utils/ocean'
|
import { getOceanConfig } from '@utils/ocean'
|
||||||
|
|
||||||
interface UsePricing {
|
interface UsePricing {
|
||||||
getDTSymbol: (ddo: Asset) => Promise<string>
|
getDTSymbol: (ddo: Asset) => Promise<string>
|
||||||
getDTName: (ddo: Asset) => Promise<string>
|
getDTName: (ddo: Asset) => Promise<string>
|
||||||
createPricing: (
|
|
||||||
priceOptions: PriceOptions,
|
|
||||||
ddo: Asset
|
|
||||||
) => Promise<TransactionReceipt | string | void>
|
|
||||||
mint: (tokensToMint: string, ddo: Asset) => Promise<TransactionReceipt | void>
|
mint: (tokensToMint: string, ddo: Asset) => Promise<TransactionReceipt | void>
|
||||||
buyDT: (
|
buyDT: (
|
||||||
amountDataToken: number | string,
|
amountDataToken: number | string,
|
||||||
price: BestPrice,
|
accessDetails: AccessDetails,
|
||||||
ddo: Asset
|
ddo: Asset
|
||||||
) => Promise<TransactionReceipt | void>
|
) => Promise<TransactionReceipt | void>
|
||||||
pricingStep?: number
|
pricingStep?: number
|
||||||
@ -123,7 +118,7 @@ function usePricing(): UsePricing {
|
|||||||
|
|
||||||
async function buyDT(
|
async function buyDT(
|
||||||
amountDataToken: number | string,
|
amountDataToken: number | string,
|
||||||
price: BestPrice,
|
accessDetails: AccessDetails,
|
||||||
ddo: Asset
|
ddo: Asset
|
||||||
): Promise<TransactionReceipt | void> {
|
): Promise<TransactionReceipt | void> {
|
||||||
if (!accountId) return
|
if (!accountId) return
|
||||||
@ -135,18 +130,20 @@ function usePricing(): UsePricing {
|
|||||||
setPricingError(undefined)
|
setPricingError(undefined)
|
||||||
setStep(1, 'buy', ddo)
|
setStep(1, 'buy', ddo)
|
||||||
|
|
||||||
LoggerInstance.log('Price found for buying', price)
|
LoggerInstance.log('Price found for buying', accessDetails)
|
||||||
Decimal.set({ precision: 18 })
|
Decimal.set({ precision: 18 })
|
||||||
|
|
||||||
switch (price?.type) {
|
switch (accessDetails?.type) {
|
||||||
case 'dynamic': {
|
case 'dynamic': {
|
||||||
const oceanAmmount = new Decimal(price.value).times(1.05).toString()
|
const oceanAmmount = new Decimal(accessDetails.price)
|
||||||
const maxPrice = new Decimal(price.value).times(2).toString()
|
.times(1.05)
|
||||||
|
.toString()
|
||||||
|
const maxPrice = new Decimal(accessDetails.price).times(2).toString()
|
||||||
|
|
||||||
setStep(2, 'buy', ddo)
|
setStep(2, 'buy', ddo)
|
||||||
LoggerInstance.log(
|
LoggerInstance.log(
|
||||||
'Buying token from pool',
|
'Buying token from pool',
|
||||||
price,
|
accessDetails,
|
||||||
accountId,
|
accountId,
|
||||||
oceanAmmount,
|
oceanAmmount,
|
||||||
maxPrice
|
maxPrice
|
||||||
@ -173,7 +170,11 @@ function usePricing(): UsePricing {
|
|||||||
)
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
LoggerInstance.log('Buying token from exchange', price, accountId)
|
LoggerInstance.log(
|
||||||
|
'Buying token from exchange',
|
||||||
|
accessDetails,
|
||||||
|
accountId
|
||||||
|
)
|
||||||
// await ocean.datatokens.approve(
|
// await ocean.datatokens.approve(
|
||||||
// oceanConfig.oceanTokenAddress,
|
// oceanConfig.oceanTokenAddress,
|
||||||
// oceanConfig.fixedRateExchangeAddress,
|
// oceanConfig.fixedRateExchangeAddress,
|
||||||
@ -227,77 +228,9 @@ function usePricing(): UsePricing {
|
|||||||
return tx
|
return tx
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createPricing(
|
|
||||||
priceOptions: PriceOptions,
|
|
||||||
ddo: Asset
|
|
||||||
): Promise<TransactionReceipt | void> {
|
|
||||||
const dataToken = ddo?.services[0].datatokenAddress
|
|
||||||
const dtSymbol = await getDTSymbol(ddo)
|
|
||||||
|
|
||||||
if (!accountId || !dtSymbol) return
|
|
||||||
|
|
||||||
const { type, amountOcean, price, weightOnDataToken, swapFee } =
|
|
||||||
priceOptions
|
|
||||||
|
|
||||||
let { amountDataToken } = priceOptions
|
|
||||||
const isPool = type === 'dynamic'
|
|
||||||
|
|
||||||
if (!isPool && !oceanConfig.fixedRateExchangeAddress) {
|
|
||||||
LoggerInstance.error(`'fixedRateExchangeAddress' not set in oceanConfig.`)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
setPricingIsLoading(true)
|
|
||||||
setPricingError(undefined)
|
|
||||||
|
|
||||||
setStep(99, 'pool', ddo)
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (type === 'free') {
|
|
||||||
setStep(99, 'free', ddo)
|
|
||||||
// await ocean.OceanDispenser.activate(dataToken, '1', '1', accountId)
|
|
||||||
} else {
|
|
||||||
// if fixedPrice set dt to max amount
|
|
||||||
if (!isPool) amountDataToken = 1000
|
|
||||||
await mint(`${amountDataToken}`, ddo)
|
|
||||||
}
|
|
||||||
|
|
||||||
// amountDataToken for fixed price is set to max
|
|
||||||
// const tx = isPool
|
|
||||||
// ? await ocean.pool
|
|
||||||
// .create(
|
|
||||||
// accountId,
|
|
||||||
// dataToken,
|
|
||||||
// `${amountDataToken}`,
|
|
||||||
// weightOnDataToken,
|
|
||||||
// `${amountOcean}`,
|
|
||||||
// `${swapFee}`
|
|
||||||
// )
|
|
||||||
// .next((step: number) => setStep(step, 'pool', ddo))
|
|
||||||
// : type === 'fixed'
|
|
||||||
// ? await ocean.fixedRateExchange
|
|
||||||
// .create(dataToken, `${price}`, accountId, `${amountDataToken}`)
|
|
||||||
// .next((step: number) => setStep(step, 'exchange', ddo))
|
|
||||||
// : await ocean.OceanDispenser.makeMinter(dataToken, accountId).next(
|
|
||||||
// (step: number) => setStep(step, 'free', ddo)
|
|
||||||
// )
|
|
||||||
// we should remove this sleep , why do we have sleep for 20 seconds !?!?!?!?!?!?!!?
|
|
||||||
// await sleep(20000)
|
|
||||||
// return tx
|
|
||||||
} catch (error) {
|
|
||||||
setPricingError(error.message)
|
|
||||||
LoggerInstance.error(error)
|
|
||||||
} finally {
|
|
||||||
setPricingStep(0)
|
|
||||||
setPricingStepText(undefined)
|
|
||||||
setPricingIsLoading(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
getDTSymbol,
|
getDTSymbol,
|
||||||
getDTName,
|
getDTName,
|
||||||
createPricing,
|
|
||||||
buyDT,
|
buyDT,
|
||||||
mint,
|
mint,
|
||||||
pricingStep,
|
pricingStep,
|
||||||
|
5
src/@types/AssetExtended.d.ts
vendored
Normal file
5
src/@types/AssetExtended.d.ts
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import { Asset } from '@oceanprotocol/lib'
|
||||||
|
|
||||||
|
interface AssetExtended extends Asset {
|
||||||
|
accessDetails?: AccessDetails
|
||||||
|
}
|
20
src/@types/Price.d.ts
vendored
20
src/@types/Price.d.ts
vendored
@ -1,14 +1,14 @@
|
|||||||
interface BestPrice {
|
interface AccessDetails {
|
||||||
type: 'dynamic' | 'fixed' | 'free' | ''
|
type: 'dynamic' | 'fixed' | 'free' | ''
|
||||||
address: string
|
price: number
|
||||||
value: number
|
// if type is dynamic this is the pool address, for fixed/free this is an id.
|
||||||
isConsumable?: 'true' | 'false' | ''
|
addressOrId: string
|
||||||
ocean?: number
|
baseToken: TokenInfo
|
||||||
oceanSymbol?: string
|
datatoken: TokenInfo
|
||||||
datatoken?: number
|
isConsumable?: boolean
|
||||||
datatokenSymbol?: string
|
// if there are valid orders for this
|
||||||
exchangeId?: string
|
owned: bool
|
||||||
pools: string[]
|
validOrderTx: string
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PriceOptions {
|
interface PriceOptions {
|
||||||
|
6
src/@types/TokenInfo.d.ts
vendored
Normal file
6
src/@types/TokenInfo.d.ts
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
interface TokenInfo {
|
||||||
|
address: string
|
||||||
|
name: string
|
||||||
|
symbol: string
|
||||||
|
decimals?: number
|
||||||
|
}
|
2
src/@types/aquarius/DownloadedAsset.d.ts
vendored
2
src/@types/aquarius/DownloadedAsset.d.ts
vendored
@ -2,5 +2,5 @@ interface DownloadedAsset {
|
|||||||
dtSymbol: string
|
dtSymbol: string
|
||||||
timestamp: number
|
timestamp: number
|
||||||
networkId: number
|
networkId: number
|
||||||
ddo: Asset
|
asset: Asset
|
||||||
}
|
}
|
||||||
|
4
src/@types/node_modules.d.ts
vendored
4
src/@types/node_modules.d.ts
vendored
@ -1,7 +1,3 @@
|
|||||||
declare module 'ethereum-blockies' {
|
declare module 'ethereum-blockies' {
|
||||||
export function toDataUrl(address: string): string
|
export function toDataUrl(address: string): string
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module 'ethereum-address' {
|
|
||||||
export function isAddress(address: string): boolean
|
|
||||||
}
|
|
||||||
|
282
src/@utils/accessDetailsAndPricing.ts
Normal file
282
src/@utils/accessDetailsAndPricing.ts
Normal file
@ -0,0 +1,282 @@
|
|||||||
|
import { gql, OperationResult } from 'urql'
|
||||||
|
import { fetchData, getQueryContext } from './subgraph'
|
||||||
|
import {
|
||||||
|
TokenPriceQuery,
|
||||||
|
TokenPriceQuery_token as TokenPrice
|
||||||
|
} from '../@types/subgraph/TokenPriceQuery'
|
||||||
|
import {
|
||||||
|
TokensPriceQuery,
|
||||||
|
TokensPriceQuery_tokens as TokensPrice
|
||||||
|
} from '../@types/subgraph/TokensPriceQuery'
|
||||||
|
import { Asset } from '@oceanprotocol/lib'
|
||||||
|
import { AssetExtended } from 'src/@types/AssetExtended'
|
||||||
|
|
||||||
|
const TokensPriceQuery = gql`
|
||||||
|
query TokensPriceQuery($datatokenIds: [ID!], $account: String) {
|
||||||
|
tokens(where: { id_in: $datatokenIds }) {
|
||||||
|
id
|
||||||
|
symbol
|
||||||
|
name
|
||||||
|
orders(
|
||||||
|
where: { consumer: $account }
|
||||||
|
orderBy: createdTimestamp
|
||||||
|
orderDirection: desc
|
||||||
|
) {
|
||||||
|
tx
|
||||||
|
serviceIndex
|
||||||
|
createdTimestamp
|
||||||
|
}
|
||||||
|
dispensers {
|
||||||
|
id
|
||||||
|
active
|
||||||
|
isMinter
|
||||||
|
maxBalance
|
||||||
|
token {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
symbol
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fixedRateExchanges {
|
||||||
|
id
|
||||||
|
price
|
||||||
|
baseToken {
|
||||||
|
symbol
|
||||||
|
name
|
||||||
|
address
|
||||||
|
}
|
||||||
|
datatoken {
|
||||||
|
symbol
|
||||||
|
name
|
||||||
|
address
|
||||||
|
}
|
||||||
|
active
|
||||||
|
}
|
||||||
|
pools {
|
||||||
|
id
|
||||||
|
spotPrice
|
||||||
|
isFinalized
|
||||||
|
datatokenLiquidity
|
||||||
|
baseToken {
|
||||||
|
symbol
|
||||||
|
name
|
||||||
|
address
|
||||||
|
}
|
||||||
|
datatoken {
|
||||||
|
symbol
|
||||||
|
name
|
||||||
|
address
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
const TokenPriceQuery = gql`
|
||||||
|
query TokenPriceQuery($datatokenId: ID!, $account: String) {
|
||||||
|
token(id: $datatokenId) {
|
||||||
|
id
|
||||||
|
symbol
|
||||||
|
name
|
||||||
|
orders(
|
||||||
|
where: { consumer: $account }
|
||||||
|
orderBy: createdTimestamp
|
||||||
|
orderDirection: desc
|
||||||
|
) {
|
||||||
|
tx
|
||||||
|
serviceIndex
|
||||||
|
createdTimestamp
|
||||||
|
}
|
||||||
|
dispensers {
|
||||||
|
id
|
||||||
|
active
|
||||||
|
isMinter
|
||||||
|
maxBalance
|
||||||
|
token {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
symbol
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fixedRateExchanges {
|
||||||
|
id
|
||||||
|
price
|
||||||
|
baseToken {
|
||||||
|
symbol
|
||||||
|
name
|
||||||
|
address
|
||||||
|
}
|
||||||
|
datatoken {
|
||||||
|
symbol
|
||||||
|
name
|
||||||
|
address
|
||||||
|
}
|
||||||
|
active
|
||||||
|
}
|
||||||
|
pools {
|
||||||
|
id
|
||||||
|
spotPrice
|
||||||
|
isFinalized
|
||||||
|
datatokenLiquidity
|
||||||
|
baseToken {
|
||||||
|
symbol
|
||||||
|
name
|
||||||
|
address
|
||||||
|
}
|
||||||
|
datatoken {
|
||||||
|
symbol
|
||||||
|
name
|
||||||
|
address
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
function getAccessDetailsFromTokenPrice(
|
||||||
|
tokenPrice: TokenPrice | TokensPrice,
|
||||||
|
timeout?: number
|
||||||
|
): AccessDetails {
|
||||||
|
const accessDetails = {} as AccessDetails
|
||||||
|
|
||||||
|
if (!timeout && !tokenPrice.orders && tokenPrice.orders.length > 0) {
|
||||||
|
const order = tokenPrice.orders[0]
|
||||||
|
accessDetails.owned = Date.now() / 1000 - order.createdTimestamp < timeout
|
||||||
|
accessDetails.validOrderTx = order.tx
|
||||||
|
}
|
||||||
|
|
||||||
|
// free is always the best price
|
||||||
|
if (tokenPrice.dispensers && tokenPrice.dispensers.length > 0) {
|
||||||
|
const dispenser = tokenPrice.dispensers[0]
|
||||||
|
accessDetails.type = 'free'
|
||||||
|
accessDetails.addressOrId = dispenser.id
|
||||||
|
accessDetails.price = 0
|
||||||
|
accessDetails.isConsumable = dispenser.active
|
||||||
|
accessDetails.datatoken = {
|
||||||
|
address: dispenser.token.id,
|
||||||
|
name: dispenser.token.name,
|
||||||
|
symbol: dispenser.token.symbol
|
||||||
|
}
|
||||||
|
return accessDetails
|
||||||
|
}
|
||||||
|
|
||||||
|
// checking for fixed price
|
||||||
|
if (
|
||||||
|
tokenPrice.fixedRateExchanges &&
|
||||||
|
tokenPrice.fixedRateExchanges.length > 0
|
||||||
|
) {
|
||||||
|
const fre = tokenPrice.fixedRateExchanges[0]
|
||||||
|
accessDetails.type = 'fixed'
|
||||||
|
accessDetails.addressOrId = fre.id
|
||||||
|
accessDetails.price = fre.price
|
||||||
|
// in theory we should check dt balance here, we can skip this because in the market we always create fre with minting capabilities.
|
||||||
|
accessDetails.isConsumable = fre.active
|
||||||
|
accessDetails.baseToken = {
|
||||||
|
address: fre.baseToken.address,
|
||||||
|
name: fre.baseToken.name,
|
||||||
|
symbol: fre.baseToken.symbol
|
||||||
|
}
|
||||||
|
accessDetails.datatoken = {
|
||||||
|
address: fre.datatoken.address,
|
||||||
|
name: fre.datatoken.name,
|
||||||
|
symbol: fre.datatoken.symbol
|
||||||
|
}
|
||||||
|
return accessDetails
|
||||||
|
}
|
||||||
|
|
||||||
|
// checking for pools
|
||||||
|
if (tokenPrice.pools && tokenPrice.pools.length > 0) {
|
||||||
|
const pool = tokenPrice.pools[0]
|
||||||
|
accessDetails.type = 'dynamic'
|
||||||
|
accessDetails.addressOrId = pool.id
|
||||||
|
// TODO: this needs to be consumePrice
|
||||||
|
accessDetails.price = pool.spotPrice
|
||||||
|
// TODO: pool.datatokenLiquidity > 3 is kinda random here, we shouldn't run into this anymore now , needs more thinking/testing
|
||||||
|
accessDetails.isConsumable = pool.isFinalized && pool.datatokenLiquidity > 3
|
||||||
|
accessDetails.baseToken = {
|
||||||
|
address: pool.baseToken.address,
|
||||||
|
name: pool.baseToken.name,
|
||||||
|
symbol: pool.baseToken.symbol
|
||||||
|
}
|
||||||
|
accessDetails.datatoken = {
|
||||||
|
address: pool.datatoken.address,
|
||||||
|
name: pool.datatoken.name,
|
||||||
|
symbol: pool.datatoken.symbol
|
||||||
|
}
|
||||||
|
return accessDetails
|
||||||
|
}
|
||||||
|
return accessDetails
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns various consume details for the desired datatoken
|
||||||
|
* @param chain chain on witch the dt is preset
|
||||||
|
* @param datatokenAddress address of the datatoken
|
||||||
|
* @param timeout timeout of the service , only needed if you want order details like owned and validOrderId
|
||||||
|
* @param account account that wants to consume, only needed if you want order details like owned and validOrderId
|
||||||
|
* @returns AccessDetails
|
||||||
|
*/
|
||||||
|
export async function getAccessDetails(
|
||||||
|
chain: number,
|
||||||
|
datatokenAddress: string,
|
||||||
|
timeout?: number,
|
||||||
|
account = ''
|
||||||
|
): Promise<AccessDetails> {
|
||||||
|
let accessDetails = {} as AccessDetails
|
||||||
|
const queryContext = getQueryContext(Number(chain))
|
||||||
|
const tokenQueryResult: OperationResult<TokenPriceQuery, any> =
|
||||||
|
await fetchData(
|
||||||
|
TokenPriceQuery,
|
||||||
|
{
|
||||||
|
datatokenId: datatokenAddress.toLowerCase(),
|
||||||
|
account: account.toLowerCase()
|
||||||
|
},
|
||||||
|
queryContext
|
||||||
|
)
|
||||||
|
|
||||||
|
const tokenPrice: TokenPrice = tokenQueryResult.data.token
|
||||||
|
accessDetails = getAccessDetailsFromTokenPrice(tokenPrice, timeout)
|
||||||
|
return accessDetails
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getAccessDetailsForAssets(
|
||||||
|
assets: Asset[],
|
||||||
|
account = ''
|
||||||
|
): Promise<AssetExtended[]> {
|
||||||
|
const assetsExtended: AssetExtended[] = assets
|
||||||
|
const chainAssetLists: any = {}
|
||||||
|
|
||||||
|
for (const asset of assets) {
|
||||||
|
// harcoded until we have chainId on assets
|
||||||
|
if (chainAssetLists[asset.chainId]) {
|
||||||
|
chainAssetLists[asset.chainId].push(
|
||||||
|
asset?.services[0].datatokenAddress.toLowerCase()
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
chainAssetLists[asset.chainId] = []
|
||||||
|
chainAssetLists[asset.chainId].push(
|
||||||
|
asset?.services[0].datatokenAddress.toLowerCase()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const chainKey in chainAssetLists) {
|
||||||
|
const queryContext = getQueryContext(Number(chainKey))
|
||||||
|
const tokenQueryResult: OperationResult<TokensPriceQuery, any> =
|
||||||
|
await fetchData(
|
||||||
|
TokensPriceQuery,
|
||||||
|
{
|
||||||
|
datatokenIds: chainAssetLists[chainKey],
|
||||||
|
account: account.toLowerCase()
|
||||||
|
},
|
||||||
|
queryContext
|
||||||
|
)
|
||||||
|
tokenQueryResult.data?.tokens.forEach((token) => {
|
||||||
|
const accessDetails = getAccessDetailsFromTokenPrice(token)
|
||||||
|
const currentAsset = assetsExtended.find(
|
||||||
|
(asset) => asset.services[0].datatokenAddress.toLowerCase() === token.id
|
||||||
|
)
|
||||||
|
currentAsset.accessDetails = accessDetails
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return assetsExtended
|
||||||
|
}
|
@ -4,7 +4,7 @@ import {
|
|||||||
PublisherTrustedAlgorithm
|
PublisherTrustedAlgorithm
|
||||||
} from '@oceanprotocol/lib'
|
} from '@oceanprotocol/lib'
|
||||||
import { AssetSelectionAsset } from '@shared/FormFields/AssetSelection'
|
import { AssetSelectionAsset } from '@shared/FormFields/AssetSelection'
|
||||||
import { PriceList, getAssetsPriceList } from './subgraph'
|
import { PriceList } from './subgraph'
|
||||||
import axios, { CancelToken, AxiosResponse } from 'axios'
|
import axios, { CancelToken, AxiosResponse } from 'axios'
|
||||||
import { OrdersData_orders as OrdersData } from '../@types/subgraph/OrdersData'
|
import { OrdersData_orders as OrdersData } from '../@types/subgraph/OrdersData'
|
||||||
import { metadataCacheUri } from '../../app.config'
|
import { metadataCacheUri } from '../../app.config'
|
||||||
@ -110,7 +110,7 @@ export async function queryMetadata(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function retrieveDDO(
|
export async function retrieveAsset(
|
||||||
did: string,
|
did: string,
|
||||||
cancelToken: CancelToken
|
cancelToken: CancelToken
|
||||||
): Promise<Asset> {
|
): Promise<Asset> {
|
||||||
@ -207,7 +207,8 @@ export async function transformDDOToAssetSelection(
|
|||||||
cancelToken?: CancelToken
|
cancelToken?: CancelToken
|
||||||
): Promise<AssetSelectionAsset[]> {
|
): Promise<AssetSelectionAsset[]> {
|
||||||
const didList: string[] = []
|
const didList: string[] = []
|
||||||
const priceList: PriceList = await getAssetsPriceList(ddoList)
|
// const priceList: PriceList = await getAssetsPriceList(ddoList)
|
||||||
|
const priceList: PriceList = null
|
||||||
const symbolList: any = {}
|
const symbolList: any = {}
|
||||||
const didProviderEndpointMap: any = {}
|
const didProviderEndpointMap: any = {}
|
||||||
for (const ddo of ddoList) {
|
for (const ddo of ddoList) {
|
||||||
@ -346,16 +347,16 @@ export async function getDownloadAssets(
|
|||||||
const result = await queryMetadata(query, cancelToken)
|
const result = await queryMetadata(query, cancelToken)
|
||||||
|
|
||||||
const downloadedAssets: DownloadedAsset[] = result.results
|
const downloadedAssets: DownloadedAsset[] = result.results
|
||||||
.map((ddo) => {
|
.map((asset) => {
|
||||||
const order = tokenOrders.find(
|
const order = tokenOrders.find(
|
||||||
({ datatoken }) =>
|
({ datatoken }) =>
|
||||||
datatoken?.address.toLowerCase() ===
|
datatoken?.address.toLowerCase() ===
|
||||||
ddo.services[0].datatokenAddress.toLowerCase()
|
asset.services[0].datatokenAddress.toLowerCase()
|
||||||
)
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
ddo,
|
asset,
|
||||||
networkId: ddo.chainId,
|
networkId: asset.chainId,
|
||||||
dtSymbol: order?.datatoken?.symbol,
|
dtSymbol: order?.datatoken?.symbol,
|
||||||
timestamp: order?.createdTimestamp
|
timestamp: order?.createdTimestamp
|
||||||
}
|
}
|
||||||
|
@ -1,41 +0,0 @@
|
|||||||
import { LoggerInstance } from '@oceanprotocol/lib'
|
|
||||||
import { TransactionReceipt } from 'web3-core'
|
|
||||||
|
|
||||||
export async function setMinterToPublisher(
|
|
||||||
dataTokenAddress: string,
|
|
||||||
accountId: string,
|
|
||||||
setError: (msg: string) => void
|
|
||||||
): Promise<TransactionReceipt> {
|
|
||||||
// free pricing v3 workaround part1
|
|
||||||
// const status = await ocean.OceanDispenser.status(dataTokenAddress)
|
|
||||||
// if (!status?.minterApproved) return
|
|
||||||
// const response = await ocean.OceanDispenser.cancelMinter(
|
|
||||||
// dataTokenAddress,
|
|
||||||
// accountId
|
|
||||||
// )
|
|
||||||
// if (!response) {
|
|
||||||
// setError('Updating DDO failed.')
|
|
||||||
// LoggerInstance.error('Failed at cancelMinter')
|
|
||||||
// }
|
|
||||||
// return response
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function setMinterToDispenser(
|
|
||||||
dataTokenAddress: string,
|
|
||||||
accountId: string,
|
|
||||||
setError: (msg: string) => void
|
|
||||||
): Promise<TransactionReceipt> {
|
|
||||||
// free pricing v3 workaround part2
|
|
||||||
// const response = await ocean.OceanDispenser.makeMinter(
|
|
||||||
// dataTokenAddress,
|
|
||||||
// accountId
|
|
||||||
// )
|
|
||||||
// if (!response) {
|
|
||||||
// setError('Updating DDO failed.')
|
|
||||||
// LoggerInstance.error('Failed at makeMinter')
|
|
||||||
// }
|
|
||||||
// return response
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
@ -62,7 +62,7 @@ export function generateNftCreateData(nftMetadata: NftMetadata): any {
|
|||||||
symbol: nftMetadata.symbol,
|
symbol: nftMetadata.symbol,
|
||||||
templateIndex: 1,
|
templateIndex: 1,
|
||||||
// Gas estimation fails if we add our huge tokenURI
|
// Gas estimation fails if we add our huge tokenURI
|
||||||
tokenURI: ''
|
tokenURI: '{url:"https://coolImage.com, name: "just for test"}'
|
||||||
// TODO: figure out if Buffer.from method is working in browser in final build
|
// TODO: figure out if Buffer.from method is working in browser in final build
|
||||||
// as BTOA is deprecated.
|
// as BTOA is deprecated.
|
||||||
// tokenURI: window?.btoa(JSON.stringify(nftMetadata))
|
// tokenURI: window?.btoa(JSON.stringify(nftMetadata))
|
||||||
|
@ -16,7 +16,6 @@ export function getOceanConfig(network: string | number): Config {
|
|||||||
? undefined
|
? undefined
|
||||||
: process.env.NEXT_PUBLIC_INFURA_PROJECT_ID
|
: process.env.NEXT_PUBLIC_INFURA_PROJECT_ID
|
||||||
) as Config
|
) as Config
|
||||||
|
|
||||||
// TODO: remove hack once address is fixed
|
// TODO: remove hack once address is fixed
|
||||||
if (network === 'rinkeby' || network === 4)
|
if (network === 'rinkeby' || network === 4)
|
||||||
config.oceanTokenAddress = '0x8967bcf84170c91b0d24d4302c2376283b0b3a07'
|
config.oceanTokenAddress = '0x8967bcf84170c91b0d24d4302c2376283b0b3a07'
|
||||||
|
@ -36,11 +36,6 @@ export interface PriceList {
|
|||||||
[key: string]: string
|
[key: string]: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AssetListPrices {
|
|
||||||
ddo: Asset
|
|
||||||
price: BestPrice
|
|
||||||
}
|
|
||||||
|
|
||||||
interface DidAndDatatokenMap {
|
interface DidAndDatatokenMap {
|
||||||
[name: string]: string
|
[name: string]: string
|
||||||
}
|
}
|
||||||
@ -410,195 +405,6 @@ export async function getPreviousOrders(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function transformPriceToBestPrice(
|
|
||||||
frePrice: AssetsFrePriceFixedRateExchange[],
|
|
||||||
poolPrice: AssetsPoolPricePool[],
|
|
||||||
freePrice: AssetFreePriceDispenser[]
|
|
||||||
) {
|
|
||||||
if (poolPrice?.length > 0) {
|
|
||||||
const price: BestPrice = {
|
|
||||||
type: 'dynamic',
|
|
||||||
address: poolPrice[0]?.id,
|
|
||||||
value: poolPrice[0]?.spotPrice,
|
|
||||||
ocean: poolPrice[0]?.baseTokenLiquidity,
|
|
||||||
oceanSymbol: poolPrice[0]?.baseToken.symbol,
|
|
||||||
datatoken: poolPrice[0]?.datatokenLiquidity,
|
|
||||||
pools: [poolPrice[0]?.id],
|
|
||||||
isConsumable: poolPrice[0]?.spotPrice === '-1' ? 'false' : 'true'
|
|
||||||
}
|
|
||||||
return price
|
|
||||||
} else if (frePrice?.length > 0) {
|
|
||||||
// TODO Hacky hack, temporary™: set isConsumable to true for fre assets.
|
|
||||||
// isConsumable: 'true'
|
|
||||||
const price: BestPrice = {
|
|
||||||
type: 'fixed',
|
|
||||||
value: frePrice[0]?.price,
|
|
||||||
address: frePrice[0]?.id,
|
|
||||||
exchangeId: frePrice[0]?.id,
|
|
||||||
oceanSymbol: frePrice[0]?.baseToken.symbol,
|
|
||||||
ocean: 0,
|
|
||||||
datatoken: 0,
|
|
||||||
pools: [],
|
|
||||||
isConsumable: 'true'
|
|
||||||
}
|
|
||||||
return price
|
|
||||||
} else if (freePrice?.length > 0) {
|
|
||||||
const price: BestPrice = {
|
|
||||||
type: 'free',
|
|
||||||
value: 0,
|
|
||||||
address: freePrice[0]?.token.id,
|
|
||||||
exchangeId: '',
|
|
||||||
ocean: 0,
|
|
||||||
datatoken: 0,
|
|
||||||
pools: [],
|
|
||||||
isConsumable: 'true'
|
|
||||||
}
|
|
||||||
return price
|
|
||||||
} else {
|
|
||||||
const price: BestPrice = {
|
|
||||||
type: '',
|
|
||||||
value: 0,
|
|
||||||
address: '',
|
|
||||||
exchangeId: '',
|
|
||||||
ocean: 0,
|
|
||||||
datatoken: 0,
|
|
||||||
pools: [],
|
|
||||||
isConsumable: 'false'
|
|
||||||
}
|
|
||||||
return price
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getAssetsPoolsExchangesAndDatatokenMap(
|
|
||||||
assets: Asset[]
|
|
||||||
): Promise<
|
|
||||||
[
|
|
||||||
AssetsPoolPricePool[],
|
|
||||||
AssetsFrePriceFixedRateExchange[],
|
|
||||||
AssetFreePriceDispenser[],
|
|
||||||
DidAndDatatokenMap
|
|
||||||
]
|
|
||||||
> {
|
|
||||||
const didDTMap: DidAndDatatokenMap = {}
|
|
||||||
const chainAssetLists: any = {}
|
|
||||||
|
|
||||||
for (const ddo of assets) {
|
|
||||||
didDTMap[ddo?.services[0].datatokenAddress.toLowerCase()] = ddo.id
|
|
||||||
// harcoded until we have chainId on assets
|
|
||||||
if (chainAssetLists[ddo.chainId]) {
|
|
||||||
chainAssetLists[ddo.chainId].push(
|
|
||||||
ddo?.services[0].datatokenAddress.toLowerCase()
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
chainAssetLists[ddo.chainId] = []
|
|
||||||
chainAssetLists[ddo.chainId].push(
|
|
||||||
ddo?.services[0].datatokenAddress.toLowerCase()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let poolPriceResponse: AssetsPoolPricePool[] = []
|
|
||||||
let frePriceResponse: AssetsFrePriceFixedRateExchange[] = []
|
|
||||||
let freePriceResponse: AssetFreePriceDispenser[] = []
|
|
||||||
|
|
||||||
for (const chainKey in chainAssetLists) {
|
|
||||||
const freVariables = {
|
|
||||||
datatoken_in: chainAssetLists[chainKey]
|
|
||||||
}
|
|
||||||
const poolVariables = {
|
|
||||||
datatokenAddress_in: chainAssetLists[chainKey]
|
|
||||||
}
|
|
||||||
const freeVariables = {
|
|
||||||
datatoken_in: chainAssetLists[chainKey]
|
|
||||||
}
|
|
||||||
|
|
||||||
const queryContext = getQueryContext(Number(chainKey))
|
|
||||||
|
|
||||||
const chainPoolPriceResponse: OperationResult<AssetsPoolPrice> =
|
|
||||||
await fetchData(PoolQuery, poolVariables, queryContext)
|
|
||||||
|
|
||||||
poolPriceResponse = poolPriceResponse.concat(
|
|
||||||
chainPoolPriceResponse.data.pools
|
|
||||||
)
|
|
||||||
const chainFrePriceResponse: OperationResult<AssetsFrePrice> =
|
|
||||||
await fetchData(FreQuery, freVariables, queryContext)
|
|
||||||
|
|
||||||
frePriceResponse = frePriceResponse.concat(
|
|
||||||
chainFrePriceResponse.data.fixedRateExchanges
|
|
||||||
)
|
|
||||||
|
|
||||||
const chainFreePriceResponse: OperationResult<AssetsFreePrice> =
|
|
||||||
await fetchData(FreeQuery, freeVariables, queryContext)
|
|
||||||
|
|
||||||
freePriceResponse = freePriceResponse.concat(
|
|
||||||
chainFreePriceResponse.data.dispensers
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return [poolPriceResponse, frePriceResponse, freePriceResponse, didDTMap]
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getAssetsPriceList(assets: Asset[]): Promise<PriceList> {
|
|
||||||
const priceList: PriceList = {}
|
|
||||||
|
|
||||||
const values: [
|
|
||||||
AssetsPoolPricePool[],
|
|
||||||
AssetsFrePriceFixedRateExchange[],
|
|
||||||
AssetFreePriceDispenser[],
|
|
||||||
DidAndDatatokenMap
|
|
||||||
] = await getAssetsPoolsExchangesAndDatatokenMap(assets)
|
|
||||||
const poolPriceResponse = values[0]
|
|
||||||
const frePriceResponse = values[1]
|
|
||||||
const freePriceResponse = values[2]
|
|
||||||
const didDTMap: DidAndDatatokenMap = values[3]
|
|
||||||
|
|
||||||
for (const poolPrice of poolPriceResponse) {
|
|
||||||
priceList[didDTMap[poolPrice.datatoken.address]] = poolPrice.spotPrice
|
|
||||||
}
|
|
||||||
for (const frePrice of frePriceResponse) {
|
|
||||||
priceList[didDTMap[frePrice.datatoken?.address]] = frePrice.price
|
|
||||||
}
|
|
||||||
for (const freePrice of freePriceResponse) {
|
|
||||||
priceList[didDTMap[freePrice.token?.address]] = '0'
|
|
||||||
}
|
|
||||||
return priceList
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getPrice(asset: Asset): Promise<BestPrice> {
|
|
||||||
const freVariables = {
|
|
||||||
datatoken: asset?.services[0].datatokenAddress.toLowerCase()
|
|
||||||
}
|
|
||||||
const freeVariables = {
|
|
||||||
datatoken: asset?.services[0].datatokenAddress.toLowerCase()
|
|
||||||
}
|
|
||||||
const poolVariables = {
|
|
||||||
datatokenAddress: asset?.services[0].datatokenAddress.toLowerCase()
|
|
||||||
}
|
|
||||||
const queryContext = getQueryContext(Number(asset.chainId))
|
|
||||||
|
|
||||||
const poolPriceResponse: OperationResult<AssetsPoolPrice> = await fetchData(
|
|
||||||
AssetPoolPriceQuery,
|
|
||||||
poolVariables,
|
|
||||||
queryContext
|
|
||||||
)
|
|
||||||
const frePriceResponse: OperationResult<AssetsFrePrice> = await fetchData(
|
|
||||||
AssetFreQuery,
|
|
||||||
freVariables,
|
|
||||||
queryContext
|
|
||||||
)
|
|
||||||
const freePriceResponse: OperationResult<AssetsFreePrice> = await fetchData(
|
|
||||||
AssetFreeQuery,
|
|
||||||
freeVariables,
|
|
||||||
queryContext
|
|
||||||
)
|
|
||||||
|
|
||||||
const bestPrice: BestPrice = transformPriceToBestPrice(
|
|
||||||
frePriceResponse.data.fixedRateExchanges,
|
|
||||||
poolPriceResponse.data.pools,
|
|
||||||
freePriceResponse.data.dispensers
|
|
||||||
)
|
|
||||||
|
|
||||||
return bestPrice
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getSpotPrice(asset: Asset): Promise<number> {
|
export async function getSpotPrice(asset: Asset): Promise<number> {
|
||||||
const poolVariables = {
|
const poolVariables = {
|
||||||
datatokenAddress: asset?.services[0].datatokenAddress.toLowerCase()
|
datatokenAddress: asset?.services[0].datatokenAddress.toLowerCase()
|
||||||
@ -614,49 +420,6 @@ export async function getSpotPrice(asset: Asset): Promise<number> {
|
|||||||
return poolPriceResponse.data.pools[0].spotPrice
|
return poolPriceResponse.data.pools[0].spotPrice
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getAssetsBestPrices(
|
|
||||||
assets: Asset[]
|
|
||||||
): Promise<AssetListPrices[]> {
|
|
||||||
const assetsWithPrice: AssetListPrices[] = []
|
|
||||||
|
|
||||||
const values: [
|
|
||||||
AssetsPoolPricePool[],
|
|
||||||
AssetsFrePriceFixedRateExchange[],
|
|
||||||
AssetFreePriceDispenser[],
|
|
||||||
DidAndDatatokenMap
|
|
||||||
] = await getAssetsPoolsExchangesAndDatatokenMap(assets)
|
|
||||||
|
|
||||||
const poolPriceResponse = values[0]
|
|
||||||
const frePriceResponse = values[1]
|
|
||||||
const freePriceResponse = values[2]
|
|
||||||
for (const ddo of assets) {
|
|
||||||
const dataToken = ddo.services[0].datatokenAddress.toLowerCase()
|
|
||||||
const poolPrice: AssetsPoolPricePool[] = []
|
|
||||||
const frePrice: AssetsFrePriceFixedRateExchange[] = []
|
|
||||||
const freePrice: AssetFreePriceDispenser[] = []
|
|
||||||
const pool = poolPriceResponse.find(
|
|
||||||
(pool: AssetsPoolPricePool) => pool.datatoken.address === dataToken
|
|
||||||
)
|
|
||||||
pool && poolPrice.push(pool)
|
|
||||||
const fre = frePriceResponse.find(
|
|
||||||
(fre: AssetsFrePriceFixedRateExchange) =>
|
|
||||||
fre.datatoken.address === dataToken
|
|
||||||
)
|
|
||||||
fre && frePrice.push(fre)
|
|
||||||
const free = freePriceResponse.find(
|
|
||||||
(free: AssetFreePriceDispenser) => free.token.address === dataToken
|
|
||||||
)
|
|
||||||
free && freePrice.push(free)
|
|
||||||
const bestPrice = transformPriceToBestPrice(frePrice, poolPrice, freePrice)
|
|
||||||
assetsWithPrice.push({
|
|
||||||
ddo: ddo,
|
|
||||||
price: bestPrice
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return assetsWithPrice
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getHighestLiquidityDatatokens(
|
export async function getHighestLiquidityDatatokens(
|
||||||
chainIds: number[]
|
chainIds: number[]
|
||||||
): Promise<string[]> {
|
): Promise<string[]> {
|
||||||
|
@ -7,11 +7,11 @@ import { useSiteMetadata } from '@hooks/useSiteMetadata'
|
|||||||
import { Asset } from '@oceanprotocol/lib'
|
import { Asset } from '@oceanprotocol/lib'
|
||||||
|
|
||||||
export default function AssetListTitle({
|
export default function AssetListTitle({
|
||||||
ddo,
|
asset,
|
||||||
did,
|
did,
|
||||||
title
|
title
|
||||||
}: {
|
}: {
|
||||||
ddo?: Asset
|
asset?: Asset
|
||||||
did?: string
|
did?: string
|
||||||
title?: string
|
title?: string
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
@ -20,8 +20,8 @@ export default function AssetListTitle({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (title || !appConfig.metadataCacheUri) return
|
if (title || !appConfig.metadataCacheUri) return
|
||||||
if (ddo) {
|
if (asset) {
|
||||||
setAssetTitle(ddo.metadata.name)
|
setAssetTitle(asset.metadata.name)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,16 +32,16 @@ export default function AssetListTitle({
|
|||||||
setAssetTitle(title[did])
|
setAssetTitle(title[did])
|
||||||
}
|
}
|
||||||
|
|
||||||
!ddo && did && getAssetName()
|
!asset && did && getAssetName()
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
source.cancel()
|
source.cancel()
|
||||||
}
|
}
|
||||||
}, [assetTitle, appConfig.metadataCacheUri, ddo, did, title])
|
}, [assetTitle, appConfig.metadataCacheUri, asset, did, title])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<h3 className={styles.title}>
|
<h3 className={styles.title}>
|
||||||
<Link href={`/asset/${did || ddo?.id}`}>
|
<Link href={`/asset/${did || asset?.id}`}>
|
||||||
<a>{assetTitle}</a>
|
<a>{assetTitle}</a>
|
||||||
</Link>
|
</Link>
|
||||||
</h3>
|
</h3>
|
||||||
|
@ -3,11 +3,13 @@ import React, { ReactElement, useEffect, useState } from 'react'
|
|||||||
import Pagination from '@shared/Pagination'
|
import Pagination from '@shared/Pagination'
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
import classNames from 'classnames/bind'
|
import classNames from 'classnames/bind'
|
||||||
import { getAssetsBestPrices, AssetListPrices } from '@utils/subgraph'
|
|
||||||
import Loader from '@shared/atoms/Loader'
|
import Loader from '@shared/atoms/Loader'
|
||||||
import { useUserPreferences } from '@context/UserPreferences'
|
import { useUserPreferences } from '@context/UserPreferences'
|
||||||
import { useIsMounted } from '@hooks/useIsMounted'
|
import { useIsMounted } from '@hooks/useIsMounted'
|
||||||
|
// not sure why this import is required
|
||||||
|
import { AssetExtended } from 'src/@types/AssetExtended'
|
||||||
import { Asset } from '@oceanprotocol/lib'
|
import { Asset } from '@oceanprotocol/lib'
|
||||||
|
import { getAccessDetailsForAssets } from '@utils/accessDetailsAndPricing'
|
||||||
|
|
||||||
const cx = classNames.bind(styles)
|
const cx = classNames.bind(styles)
|
||||||
|
|
||||||
@ -41,24 +43,19 @@ export default function AssetList({
|
|||||||
noPublisher
|
noPublisher
|
||||||
}: AssetListProps): ReactElement {
|
}: AssetListProps): ReactElement {
|
||||||
const { chainIds } = useUserPreferences()
|
const { chainIds } = useUserPreferences()
|
||||||
const [assetsWithPrices, setAssetsWithPrices] = useState<AssetListPrices[]>()
|
const [assetsWithPrices, setAssetsWithPrices] = useState<AssetExtended[]>()
|
||||||
const [loading, setLoading] = useState<boolean>(isLoading)
|
const [loading, setLoading] = useState<boolean>(isLoading)
|
||||||
const isMounted = useIsMounted()
|
const isMounted = useIsMounted()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!assets) return
|
if (!assets) return
|
||||||
|
setAssetsWithPrices(assets as AssetExtended[])
|
||||||
const initialAssets: AssetListPrices[] = assets.map((asset) => ({
|
|
||||||
ddo: asset,
|
|
||||||
price: null
|
|
||||||
}))
|
|
||||||
setAssetsWithPrices(initialAssets)
|
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
|
|
||||||
async function fetchPrices() {
|
async function fetchPrices() {
|
||||||
const assetsWithPrices = await getAssetsBestPrices(assets)
|
const assetsWithPrices = await getAccessDetailsForAssets(assets)
|
||||||
if (!isMounted()) return
|
if (!isMounted()) return
|
||||||
setAssetsWithPrices(assetsWithPrices)
|
setAssetsWithPrices([...assetsWithPrices])
|
||||||
}
|
}
|
||||||
fetchPrices()
|
fetchPrices()
|
||||||
}, [assets, isMounted])
|
}, [assets, isMounted])
|
||||||
@ -83,9 +80,8 @@ export default function AssetList({
|
|||||||
{assetsWithPrices.length > 0 ? (
|
{assetsWithPrices.length > 0 ? (
|
||||||
assetsWithPrices.map((assetWithPrice) => (
|
assetsWithPrices.map((assetWithPrice) => (
|
||||||
<AssetTeaser
|
<AssetTeaser
|
||||||
ddo={assetWithPrice.ddo}
|
assetExtended={assetWithPrice}
|
||||||
price={assetWithPrice.price}
|
key={assetWithPrice.id}
|
||||||
key={assetWithPrice.ddo.id}
|
|
||||||
noPublisher={noPublisher}
|
noPublisher={noPublisher}
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
|
@ -8,28 +8,25 @@ import AssetType from '@shared/AssetType'
|
|||||||
import NetworkName from '@shared/NetworkName'
|
import NetworkName from '@shared/NetworkName'
|
||||||
import styles from './AssetTeaser.module.css'
|
import styles from './AssetTeaser.module.css'
|
||||||
import { getServiceByName } from '@utils/ddo'
|
import { getServiceByName } from '@utils/ddo'
|
||||||
import { Asset } from '@oceanprotocol/lib'
|
import { AssetExtended } from 'src/@types/AssetExtended'
|
||||||
|
|
||||||
declare type AssetTeaserProps = {
|
declare type AssetTeaserProps = {
|
||||||
ddo: Asset
|
assetExtended: AssetExtended
|
||||||
price: BestPrice
|
|
||||||
noPublisher?: boolean
|
noPublisher?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function AssetTeaser({
|
export default function AssetTeaser({
|
||||||
ddo,
|
assetExtended,
|
||||||
price,
|
|
||||||
noPublisher
|
noPublisher
|
||||||
}: AssetTeaserProps): ReactElement {
|
}: AssetTeaserProps): ReactElement {
|
||||||
const { name, type, description } = ddo.metadata
|
const { name, type, description } = assetExtended.metadata
|
||||||
const { datatokens } = ddo
|
const { datatokens } = assetExtended
|
||||||
const isCompute = Boolean(getServiceByName(ddo, 'compute'))
|
const isCompute = Boolean(getServiceByName(assetExtended, 'compute'))
|
||||||
const accessType = isCompute ? 'compute' : 'access'
|
const accessType = isCompute ? 'compute' : 'access'
|
||||||
const { owner } = ddo.nft
|
const { owner } = assetExtended.nft
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<article className={`${styles.teaser} ${styles[type]}`}>
|
<article className={`${styles.teaser} ${styles[type]}`}>
|
||||||
<Link href={`/asset/${ddo.id}`}>
|
<Link href={`/asset/${assetExtended.id}`}>
|
||||||
<a className={styles.link}>
|
<a className={styles.link}>
|
||||||
<header className={styles.header}>
|
<header className={styles.header}>
|
||||||
<div className={styles.symbol}>{datatokens[0]?.symbol}</div>
|
<div className={styles.symbol}>{datatokens[0]?.symbol}</div>
|
||||||
@ -54,8 +51,11 @@ export default function AssetTeaser({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer className={styles.foot}>
|
<footer className={styles.foot}>
|
||||||
<Price price={price} small />
|
<Price accessDetails={assetExtended.accessDetails} small />
|
||||||
<NetworkName networkId={ddo.chainId} className={styles.network} />
|
<NetworkName
|
||||||
|
networkId={assetExtended.chainId}
|
||||||
|
className={styles.network}
|
||||||
|
/>
|
||||||
</footer>
|
</footer>
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
|
@ -75,7 +75,7 @@ const txHistoryQuery = gql`
|
|||||||
|
|
||||||
export interface PoolTransaction extends TransactionHistoryPoolTransactions {
|
export interface PoolTransaction extends TransactionHistoryPoolTransactions {
|
||||||
networkId: number
|
networkId: number
|
||||||
ddo: Asset
|
asset: Asset
|
||||||
}
|
}
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
@ -88,7 +88,7 @@ const columns = [
|
|||||||
{
|
{
|
||||||
name: 'Data Set',
|
name: 'Data Set',
|
||||||
selector: function getAssetRow(row: PoolTransaction) {
|
selector: function getAssetRow(row: PoolTransaction) {
|
||||||
return <AssetTitle ddo={row.ddo} />
|
return <AssetTitle asset={row.asset} />
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -187,7 +187,7 @@ export default function PoolTransactions({
|
|||||||
poolTransactions.push({
|
poolTransactions.push({
|
||||||
...data[i],
|
...data[i],
|
||||||
networkId: ddoList[i]?.chainId,
|
networkId: ddoList[i]?.chainId,
|
||||||
ddo: ddoList[i]
|
asset: ddoList[i]
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
const sortedTransactions = poolTransactions.sort(
|
const sortedTransactions = poolTransactions.sort(
|
||||||
|
@ -49,7 +49,7 @@ export default function PriceUnit({
|
|||||||
<div>
|
<div>
|
||||||
{Number.isNaN(Number(price)) ? '-' : formatPrice(price, locale)}{' '}
|
{Number.isNaN(Number(price)) ? '-' : formatPrice(price, locale)}{' '}
|
||||||
<span className={styles.symbol}>{symbol}</span>
|
<span className={styles.symbol}>{symbol}</span>
|
||||||
{type && type === 'pool' && (
|
{type && type === 'dynamic' && (
|
||||||
<Badge label="pool" className={styles.badge} />
|
<Badge label="pool" className={styles.badge} />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -5,26 +5,26 @@ import Tooltip from '../atoms/Tooltip'
|
|||||||
import PriceUnit from './PriceUnit'
|
import PriceUnit from './PriceUnit'
|
||||||
|
|
||||||
export default function Price({
|
export default function Price({
|
||||||
price,
|
accessDetails,
|
||||||
className,
|
className,
|
||||||
small,
|
small,
|
||||||
conversion
|
conversion
|
||||||
}: {
|
}: {
|
||||||
price: BestPrice
|
accessDetails: AccessDetails
|
||||||
className?: string
|
className?: string
|
||||||
small?: boolean
|
small?: boolean
|
||||||
conversion?: boolean
|
conversion?: boolean
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
return price?.value || price?.type === 'free' ? (
|
return accessDetails?.price || accessDetails?.type === 'free' ? (
|
||||||
<PriceUnit
|
<PriceUnit
|
||||||
price={`${price.value}`}
|
price={`${accessDetails.price}`}
|
||||||
symbol={price.oceanSymbol}
|
symbol={accessDetails.baseToken?.symbol}
|
||||||
className={className}
|
className={className}
|
||||||
small={small}
|
small={small}
|
||||||
conversion={conversion}
|
conversion={conversion}
|
||||||
type={price.type}
|
type={accessDetails.type}
|
||||||
/>
|
/>
|
||||||
) : !price || price?.type === '' ? (
|
) : !accessDetails || accessDetails?.type === '' ? (
|
||||||
<div className={styles.empty}>
|
<div className={styles.empty}>
|
||||||
No price set{' '}
|
No price set{' '}
|
||||||
<Tooltip content="No pricing mechanism has been set on this asset yet." />
|
<Tooltip content="No pricing mechanism has been set on this asset yet." />
|
||||||
|
@ -18,12 +18,12 @@ export default function TokenApproval({
|
|||||||
tokenAddress: string
|
tokenAddress: string
|
||||||
tokenSymbol: string
|
tokenSymbol: string
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { price, isAssetNetwork } = useAsset()
|
const { accessDetails, isAssetNetwork } = useAsset()
|
||||||
const [tokenApproved, setTokenApproved] = useState(false)
|
const [tokenApproved, setTokenApproved] = useState(false)
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false)
|
||||||
const { web3, accountId } = useWeb3()
|
const { web3, accountId } = useWeb3()
|
||||||
|
|
||||||
const spender = price?.address
|
const spender = accessDetails?.addressOrId
|
||||||
|
|
||||||
const checkTokenApproval = useCallback(async () => {
|
const checkTokenApproval = useCallback(async () => {
|
||||||
if (!web3 || !tokenAddress || !spender || !isAssetNetwork || !amount) return
|
if (!web3 || !tokenAddress || !spender || !isAssetNetwork || !amount) return
|
||||||
|
@ -11,13 +11,15 @@ import { useAsset } from '@context/Asset'
|
|||||||
|
|
||||||
export default function WalletNetworkSwitcher(): ReactElement {
|
export default function WalletNetworkSwitcher(): ReactElement {
|
||||||
const { networkId, web3Provider } = useWeb3()
|
const { networkId, web3Provider } = useWeb3()
|
||||||
const { ddo } = useAsset()
|
const { assetExtended } = useAsset()
|
||||||
const { networksList } = useNetworkMetadata()
|
const { networksList } = useNetworkMetadata()
|
||||||
const ddoNetworkData = getNetworkDataById(networksList, ddo.chainId)
|
const ddoNetworkData = getNetworkDataById(networksList, assetExtended.chainId)
|
||||||
const walletNetworkData = getNetworkDataById(networksList, networkId)
|
const walletNetworkData = getNetworkDataById(networksList, networkId)
|
||||||
|
|
||||||
const ddoNetworkName = (
|
const ddoNetworkName = (
|
||||||
<strong>{getNetworkDisplayName(ddoNetworkData, ddo.chainId)}</strong>
|
<strong>
|
||||||
|
{getNetworkDisplayName(ddoNetworkData, assetExtended.chainId)}
|
||||||
|
</strong>
|
||||||
)
|
)
|
||||||
const walletNetworkName = (
|
const walletNetworkName = (
|
||||||
<strong>{getNetworkDisplayName(walletNetworkData, networkId)}</strong>
|
<strong>{getNetworkDisplayName(walletNetworkData, networkId)}</strong>
|
||||||
@ -25,7 +27,7 @@ export default function WalletNetworkSwitcher(): ReactElement {
|
|||||||
|
|
||||||
async function switchWalletNetwork() {
|
async function switchWalletNetwork() {
|
||||||
const networkNode = await networksList.find(
|
const networkNode = await networksList.find(
|
||||||
(data) => data.chainId === ddo.chainId
|
(data) => data.chainId === assetExtended.chainId
|
||||||
)
|
)
|
||||||
addCustomNetwork(web3Provider, networkNode)
|
addCustomNetwork(web3Provider, networkNode)
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ export default function FormStartCompute({
|
|||||||
selectedComputeAssetType,
|
selectedComputeAssetType,
|
||||||
selectedComputeAssetTimeout,
|
selectedComputeAssetTimeout,
|
||||||
stepText,
|
stepText,
|
||||||
algorithmPrice,
|
algorithmConsumeDetails,
|
||||||
isConsumable,
|
isConsumable,
|
||||||
consumableFeedback
|
consumableFeedback
|
||||||
}: {
|
}: {
|
||||||
@ -56,14 +56,14 @@ export default function FormStartCompute({
|
|||||||
selectedComputeAssetType?: string
|
selectedComputeAssetType?: string
|
||||||
selectedComputeAssetTimeout?: string
|
selectedComputeAssetTimeout?: string
|
||||||
stepText: string
|
stepText: string
|
||||||
algorithmPrice: BestPrice
|
algorithmConsumeDetails: AccessDetails
|
||||||
isConsumable: boolean
|
isConsumable: boolean
|
||||||
consumableFeedback: string
|
consumableFeedback: string
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { isValid, values }: FormikContextType<{ algorithm: string }> =
|
const { isValid, values }: FormikContextType<{ algorithm: string }> =
|
||||||
useFormikContext()
|
useFormikContext()
|
||||||
const { price, ddo, isAssetNetwork } = useAsset()
|
const { accessDetails, assetExtended, isAssetNetwork } = useAsset()
|
||||||
const [totalPrice, setTotalPrice] = useState(price?.value)
|
const [totalPrice, setTotalPrice] = useState(accessDetails?.price)
|
||||||
const [isBalanceSufficient, setIsBalanceSufficient] = useState<boolean>(false)
|
const [isBalanceSufficient, setIsBalanceSufficient] = useState<boolean>(false)
|
||||||
const { accountId, balance } = useWeb3()
|
const { accountId, balance } = useWeb3()
|
||||||
const [algorithmConsumableStatus, setAlgorithmConsumableStatus] =
|
const [algorithmConsumableStatus, setAlgorithmConsumableStatus] =
|
||||||
@ -97,19 +97,19 @@ export default function FormStartCompute({
|
|||||||
// Set price for calculation output
|
// Set price for calculation output
|
||||||
//
|
//
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!price || !algorithmPrice) return
|
if (!accessDetails || !algorithmConsumeDetails) return
|
||||||
|
|
||||||
const priceDataset =
|
const priceDataset =
|
||||||
hasPreviousOrder || hasDatatoken ? 0 : Number(price.value)
|
hasPreviousOrder || hasDatatoken ? 0 : Number(accessDetails.price)
|
||||||
const priceAlgo =
|
const priceAlgo =
|
||||||
hasPreviousOrderSelectedComputeAsset || hasDatatokenSelectedComputeAsset
|
hasPreviousOrderSelectedComputeAsset || hasDatatokenSelectedComputeAsset
|
||||||
? 0
|
? 0
|
||||||
: Number(algorithmPrice.value)
|
: Number(algorithmConsumeDetails.price)
|
||||||
|
|
||||||
setTotalPrice(priceDataset + priceAlgo)
|
setTotalPrice(priceDataset + priceAlgo)
|
||||||
}, [
|
}, [
|
||||||
price,
|
accessDetails,
|
||||||
algorithmPrice,
|
algorithmConsumeDetails,
|
||||||
hasPreviousOrder,
|
hasPreviousOrder,
|
||||||
hasDatatoken,
|
hasDatatoken,
|
||||||
hasPreviousOrderSelectedComputeAsset,
|
hasPreviousOrderSelectedComputeAsset,
|
||||||
@ -143,7 +143,7 @@ export default function FormStartCompute({
|
|||||||
hasDatatoken={hasDatatoken}
|
hasDatatoken={hasDatatoken}
|
||||||
selectedComputeAssetTimeout={selectedComputeAssetTimeout}
|
selectedComputeAssetTimeout={selectedComputeAssetTimeout}
|
||||||
hasDatatokenSelectedComputeAsset={hasDatatokenSelectedComputeAsset}
|
hasDatatokenSelectedComputeAsset={hasDatatokenSelectedComputeAsset}
|
||||||
algorithmPrice={algorithmPrice}
|
algorithmConsumeDetails={algorithmConsumeDetails}
|
||||||
symbol={oceanSymbol}
|
symbol={oceanSymbol}
|
||||||
totalPrice={totalPrice}
|
totalPrice={totalPrice}
|
||||||
/>
|
/>
|
||||||
@ -159,7 +159,7 @@ export default function FormStartCompute({
|
|||||||
}
|
}
|
||||||
hasPreviousOrder={hasPreviousOrder}
|
hasPreviousOrder={hasPreviousOrder}
|
||||||
hasDatatoken={hasDatatoken}
|
hasDatatoken={hasDatatoken}
|
||||||
dtSymbol={ddo?.datatokens[0]?.symbol}
|
dtSymbol={assetExtended?.datatokens[0]?.symbol}
|
||||||
dtBalance={dtBalance}
|
dtBalance={dtBalance}
|
||||||
datasetLowPoolLiquidity={datasetLowPoolLiquidity}
|
datasetLowPoolLiquidity={datasetLowPoolLiquidity}
|
||||||
assetTimeout={assetTimeout}
|
assetTimeout={assetTimeout}
|
||||||
@ -177,8 +177,8 @@ export default function FormStartCompute({
|
|||||||
stepText={stepText}
|
stepText={stepText}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
type="submit"
|
type="submit"
|
||||||
priceType={price?.type}
|
priceType={accessDetails?.type}
|
||||||
algorithmPriceType={algorithmPrice?.type}
|
algorithmPriceType={algorithmConsumeDetails?.type}
|
||||||
isBalanceSufficient={isBalanceSufficient}
|
isBalanceSufficient={isBalanceSufficient}
|
||||||
isConsumable={isConsumable}
|
isConsumable={isConsumable}
|
||||||
consumableFeedback={consumableFeedback}
|
consumableFeedback={consumableFeedback}
|
||||||
|
@ -12,7 +12,7 @@ interface PriceOutputProps {
|
|||||||
assetTimeout: string
|
assetTimeout: string
|
||||||
hasPreviousOrderSelectedComputeAsset: boolean
|
hasPreviousOrderSelectedComputeAsset: boolean
|
||||||
hasDatatokenSelectedComputeAsset: boolean
|
hasDatatokenSelectedComputeAsset: boolean
|
||||||
algorithmPrice: BestPrice
|
algorithmConsumeDetails: AccessDetails
|
||||||
selectedComputeAssetTimeout: string
|
selectedComputeAssetTimeout: string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,10 +60,10 @@ export default function PriceOutput({
|
|||||||
symbol,
|
symbol,
|
||||||
hasPreviousOrderSelectedComputeAsset,
|
hasPreviousOrderSelectedComputeAsset,
|
||||||
hasDatatokenSelectedComputeAsset,
|
hasDatatokenSelectedComputeAsset,
|
||||||
algorithmPrice,
|
algorithmConsumeDetails,
|
||||||
selectedComputeAssetTimeout
|
selectedComputeAssetTimeout
|
||||||
}: PriceOutputProps): ReactElement {
|
}: PriceOutputProps): ReactElement {
|
||||||
const { price } = useAsset()
|
const { accessDetails } = useAsset()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.priceComponent}>
|
<div className={styles.priceComponent}>
|
||||||
@ -74,14 +74,14 @@ export default function PriceOutput({
|
|||||||
<Row
|
<Row
|
||||||
hasPreviousOrder={hasPreviousOrder}
|
hasPreviousOrder={hasPreviousOrder}
|
||||||
hasDatatoken={hasDatatoken}
|
hasDatatoken={hasDatatoken}
|
||||||
price={price?.value}
|
price={accessDetails?.price}
|
||||||
timeout={assetTimeout}
|
timeout={assetTimeout}
|
||||||
symbol={symbol}
|
symbol={symbol}
|
||||||
/>
|
/>
|
||||||
<Row
|
<Row
|
||||||
hasPreviousOrder={hasPreviousOrderSelectedComputeAsset}
|
hasPreviousOrder={hasPreviousOrderSelectedComputeAsset}
|
||||||
hasDatatoken={hasDatatokenSelectedComputeAsset}
|
hasDatatoken={hasDatatokenSelectedComputeAsset}
|
||||||
price={algorithmPrice?.value}
|
price={algorithmConsumeDetails?.price}
|
||||||
timeout={selectedComputeAssetTimeout}
|
timeout={selectedComputeAssetTimeout}
|
||||||
symbol={symbol}
|
symbol={symbol}
|
||||||
sign="+"
|
sign="+"
|
||||||
|
@ -30,16 +30,17 @@ import SuccessConfetti from '@shared/SuccessConfetti'
|
|||||||
import { getServiceByName, secondsToString } from '@utils/ddo'
|
import { getServiceByName, secondsToString } from '@utils/ddo'
|
||||||
import { AssetSelectionAsset } from '@shared/FormFields/AssetSelection'
|
import { AssetSelectionAsset } from '@shared/FormFields/AssetSelection'
|
||||||
import AlgorithmDatasetsListForCompute from './AlgorithmDatasetsListForCompute'
|
import AlgorithmDatasetsListForCompute from './AlgorithmDatasetsListForCompute'
|
||||||
import { getPreviousOrders, getPrice } from '@utils/subgraph'
|
import { getPreviousOrders } from '@utils/subgraph'
|
||||||
import AssetActionHistoryTable from '../AssetActionHistoryTable'
|
import AssetActionHistoryTable from '../AssetActionHistoryTable'
|
||||||
import ComputeJobs from '../../../Profile/History/ComputeJobs'
|
import ComputeJobs from '../../../Profile/History/ComputeJobs'
|
||||||
import { useCancelToken } from '@hooks/useCancelToken'
|
import { useCancelToken } from '@hooks/useCancelToken'
|
||||||
import { useIsMounted } from '@hooks/useIsMounted'
|
import { useIsMounted } from '@hooks/useIsMounted'
|
||||||
import { SortTermOptions } from '../../../../@types/aquarius/SearchQuery'
|
import { SortTermOptions } from '../../../../@types/aquarius/SearchQuery'
|
||||||
|
import { getAccessDetails } from '@utils/accessDetailsAndPricing'
|
||||||
|
|
||||||
export default function Compute({
|
export default function Compute({
|
||||||
ddo,
|
ddo,
|
||||||
price,
|
accessDetails,
|
||||||
dtBalance,
|
dtBalance,
|
||||||
file,
|
file,
|
||||||
fileIsLoading,
|
fileIsLoading,
|
||||||
@ -47,7 +48,7 @@ export default function Compute({
|
|||||||
consumableFeedback
|
consumableFeedback
|
||||||
}: {
|
}: {
|
||||||
ddo: Asset
|
ddo: Asset
|
||||||
price: BestPrice
|
accessDetails: AccessDetails
|
||||||
dtBalance: string
|
dtBalance: string
|
||||||
file: FileMetadata
|
file: FileMetadata
|
||||||
fileIsLoading?: boolean
|
fileIsLoading?: boolean
|
||||||
@ -70,7 +71,8 @@ export default function Compute({
|
|||||||
const [hasPreviousAlgorithmOrder, setHasPreviousAlgorithmOrder] =
|
const [hasPreviousAlgorithmOrder, setHasPreviousAlgorithmOrder] =
|
||||||
useState(false)
|
useState(false)
|
||||||
const [algorithmDTBalance, setalgorithmDTBalance] = useState<string>()
|
const [algorithmDTBalance, setalgorithmDTBalance] = useState<string>()
|
||||||
const [algorithmPrice, setAlgorithmPrice] = useState<BestPrice>()
|
const [algorithmConsumeDetails, setAlgorithmConsumeDetails] =
|
||||||
|
useState<AccessDetails>()
|
||||||
const [previousAlgorithmOrderId, setPreviousAlgorithmOrderId] =
|
const [previousAlgorithmOrderId, setPreviousAlgorithmOrderId] =
|
||||||
useState<string>()
|
useState<string>()
|
||||||
const [datasetTimeout, setDatasetTimeout] = useState<string>()
|
const [datasetTimeout, setDatasetTimeout] = useState<string>()
|
||||||
@ -169,27 +171,24 @@ export default function Compute({
|
|||||||
|
|
||||||
const initMetadata = useCallback(async (ddo: Asset): Promise<void> => {
|
const initMetadata = useCallback(async (ddo: Asset): Promise<void> => {
|
||||||
if (!ddo) return
|
if (!ddo) return
|
||||||
const price = await getPrice(ddo)
|
const accessDetails = await getAccessDetails(
|
||||||
setAlgorithmPrice(price)
|
ddo.chainId,
|
||||||
|
ddo.services[0].datatokenAddress
|
||||||
|
)
|
||||||
|
setAlgorithmConsumeDetails(accessDetails)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!algorithmPrice) return
|
if (!algorithmConsumeDetails) return
|
||||||
|
|
||||||
setIsAlgoConsumablePrice(
|
setIsAlgoConsumablePrice(algorithmConsumeDetails.isConsumable)
|
||||||
algorithmPrice.isConsumable !== undefined
|
}, [algorithmConsumeDetails])
|
||||||
? algorithmPrice.isConsumable === 'true'
|
|
||||||
: true
|
|
||||||
)
|
|
||||||
}, [algorithmPrice])
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!price) return
|
if (!accessDetails) return
|
||||||
|
|
||||||
setIsConsumablePrice(
|
setIsConsumablePrice(accessDetails.isConsumable)
|
||||||
price.isConsumable !== undefined ? price.isConsumable === 'true' : true
|
}, [accessDetails])
|
||||||
)
|
|
||||||
}, [price])
|
|
||||||
|
|
||||||
// useEffect(() => {
|
// useEffect(() => {
|
||||||
// setDatasetTimeout(secondsToString(timeout))
|
// setDatasetTimeout(secondsToString(timeout))
|
||||||
@ -392,7 +391,7 @@ export default function Compute({
|
|||||||
<>
|
<>
|
||||||
<div className={styles.info}>
|
<div className={styles.info}>
|
||||||
<FileIcon file={file} isLoading={fileIsLoading} small />
|
<FileIcon file={file} isLoading={fileIsLoading} small />
|
||||||
<Price price={price} conversion />
|
<Price accessDetails={accessDetails} conversion />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{ddo.metadata.type === 'algorithm' ? (
|
{ddo.metadata.type === 'algorithm' ? (
|
||||||
@ -426,7 +425,7 @@ export default function Compute({
|
|||||||
assetTimeout={datasetTimeout}
|
assetTimeout={datasetTimeout}
|
||||||
hasPreviousOrderSelectedComputeAsset={hasPreviousAlgorithmOrder}
|
hasPreviousOrderSelectedComputeAsset={hasPreviousAlgorithmOrder}
|
||||||
hasDatatokenSelectedComputeAsset={hasAlgoAssetDatatoken}
|
hasDatatokenSelectedComputeAsset={hasAlgoAssetDatatoken}
|
||||||
oceanSymbol={price ? price.oceanSymbol : ''}
|
oceanSymbol={accessDetails ? accessDetails.baseToken.symbol : ''}
|
||||||
dtSymbolSelectedComputeAsset={
|
dtSymbolSelectedComputeAsset={
|
||||||
selectedAlgorithmAsset?.datatokens[0]?.symbol
|
selectedAlgorithmAsset?.datatokens[0]?.symbol
|
||||||
}
|
}
|
||||||
@ -435,7 +434,7 @@ export default function Compute({
|
|||||||
selectedComputeAssetType="algorithm"
|
selectedComputeAssetType="algorithm"
|
||||||
selectedComputeAssetTimeout={algorithmTimeout}
|
selectedComputeAssetTimeout={algorithmTimeout}
|
||||||
stepText={pricingStepText || 'Starting Compute Job...'}
|
stepText={pricingStepText || 'Starting Compute Job...'}
|
||||||
algorithmPrice={algorithmPrice}
|
algorithmConsumeDetails={algorithmConsumeDetails}
|
||||||
isConsumable={isConsumable}
|
isConsumable={isConsumable}
|
||||||
consumableFeedback={consumableFeedback}
|
consumableFeedback={consumableFeedback}
|
||||||
/>
|
/>
|
||||||
@ -447,7 +446,7 @@ export default function Compute({
|
|||||||
<SuccessConfetti success="Your job started successfully! Watch the progress below or on your profile." />
|
<SuccessConfetti success="Your job started successfully! Watch the progress below or on your profile." />
|
||||||
)}
|
)}
|
||||||
</footer>
|
</footer>
|
||||||
{accountId && price?.datatoken && (
|
{accountId && accessDetails?.datatoken && (
|
||||||
<AssetActionHistoryTable title="Your Compute Jobs">
|
<AssetActionHistoryTable title="Your Compute Jobs">
|
||||||
<ComputeJobs minimal />
|
<ComputeJobs minimal />
|
||||||
</AssetActionHistoryTable>
|
</AssetActionHistoryTable>
|
||||||
|
@ -4,10 +4,6 @@ import FileIcon from '@shared/FileIcon'
|
|||||||
import Price from '@shared/Price'
|
import Price from '@shared/Price'
|
||||||
import { useSiteMetadata } from '@hooks/useSiteMetadata'
|
import { useSiteMetadata } from '@hooks/useSiteMetadata'
|
||||||
import { useAsset } from '@context/Asset'
|
import { useAsset } from '@context/Asset'
|
||||||
import { gql } from 'urql'
|
|
||||||
import { fetchData, getQueryContext } from '@utils/subgraph'
|
|
||||||
import { OrdersData } from '../../../@types/subgraph/OrdersData'
|
|
||||||
import BigNumber from 'bignumber.js'
|
|
||||||
import { useWeb3 } from '@context/Web3'
|
import { useWeb3 } from '@context/Web3'
|
||||||
import { usePricing } from '@hooks/usePricing'
|
import { usePricing } from '@hooks/usePricing'
|
||||||
import { useConsume } from '@hooks/useConsume'
|
import { useConsume } from '@hooks/useConsume'
|
||||||
@ -18,23 +14,9 @@ import styles from './Consume.module.css'
|
|||||||
import { useIsMounted } from '@hooks/useIsMounted'
|
import { useIsMounted } from '@hooks/useIsMounted'
|
||||||
import { Asset, FileMetadata } from '@oceanprotocol/lib'
|
import { Asset, FileMetadata } from '@oceanprotocol/lib'
|
||||||
|
|
||||||
const previousOrderQuery = gql`
|
|
||||||
query PreviousOrder($id: String!, $account: String!) {
|
|
||||||
orders(
|
|
||||||
first: 1
|
|
||||||
where: { datatoken: $id, payer: $account }
|
|
||||||
orderBy: createdTimestamp
|
|
||||||
orderDirection: desc
|
|
||||||
) {
|
|
||||||
createdTimestamp
|
|
||||||
tx
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
export default function Consume({
|
export default function Consume({
|
||||||
ddo,
|
ddo,
|
||||||
price,
|
accessDetails,
|
||||||
file,
|
file,
|
||||||
isBalanceSufficient,
|
isBalanceSufficient,
|
||||||
dtBalance,
|
dtBalance,
|
||||||
@ -43,7 +25,7 @@ export default function Consume({
|
|||||||
consumableFeedback
|
consumableFeedback
|
||||||
}: {
|
}: {
|
||||||
ddo: Asset
|
ddo: Asset
|
||||||
price: BestPrice
|
accessDetails: AccessDetails
|
||||||
file: FileMetadata
|
file: FileMetadata
|
||||||
isBalanceSufficient: boolean
|
isBalanceSufficient: boolean
|
||||||
dtBalance: string
|
dtBalance: string
|
||||||
@ -63,50 +45,8 @@ export default function Consume({
|
|||||||
const [hasDatatoken, setHasDatatoken] = useState(false)
|
const [hasDatatoken, setHasDatatoken] = useState(false)
|
||||||
const [isConsumablePrice, setIsConsumablePrice] = useState(true)
|
const [isConsumablePrice, setIsConsumablePrice] = useState(true)
|
||||||
const [assetTimeout, setAssetTimeout] = useState('')
|
const [assetTimeout, setAssetTimeout] = useState('')
|
||||||
const [data, setData] = useState<OrdersData>()
|
|
||||||
const isMounted = useIsMounted()
|
const isMounted = useIsMounted()
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!ddo || !accountId) return
|
|
||||||
|
|
||||||
const context = getQueryContext(ddo.chainId)
|
|
||||||
const variables = {
|
|
||||||
id: ddo.services[0].datatokenAddress?.toLowerCase(),
|
|
||||||
account: accountId?.toLowerCase()
|
|
||||||
}
|
|
||||||
fetchData(previousOrderQuery, variables, context).then((result: any) => {
|
|
||||||
isMounted() && setData(result.data)
|
|
||||||
})
|
|
||||||
}, [ddo, accountId, hasPreviousOrder, isMounted])
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (
|
|
||||||
!data ||
|
|
||||||
!assetTimeout ||
|
|
||||||
data.orders.length === 0 ||
|
|
||||||
!accountId ||
|
|
||||||
!isAssetNetwork
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
const lastOrder = data.orders[0]
|
|
||||||
if (assetTimeout === '0') {
|
|
||||||
setPreviousOrderId(lastOrder.tx)
|
|
||||||
setHasPreviousOrder(true)
|
|
||||||
} else {
|
|
||||||
const expiry = new BigNumber(lastOrder.createdTimestamp).plus(
|
|
||||||
assetTimeout
|
|
||||||
)
|
|
||||||
const unixTime = new BigNumber(Math.floor(Date.now() / 1000))
|
|
||||||
if (unixTime.isLessThan(expiry)) {
|
|
||||||
setPreviousOrderId(lastOrder.tx)
|
|
||||||
setHasPreviousOrder(true)
|
|
||||||
} else {
|
|
||||||
setHasPreviousOrder(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [data, assetTimeout, accountId, isAssetNetwork])
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!ddo) return
|
if (!ddo) return
|
||||||
|
|
||||||
@ -115,12 +55,12 @@ export default function Consume({
|
|||||||
}, [ddo])
|
}, [ddo])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!price) return
|
if (!accessDetails) return
|
||||||
|
|
||||||
setIsConsumablePrice(
|
setIsConsumablePrice(accessDetails.isConsumable)
|
||||||
price.isConsumable !== undefined ? price.isConsumable === 'true' : true
|
setHasPreviousOrder(accessDetails.owned)
|
||||||
)
|
setPreviousOrderId(accessDetails.validOrderTx)
|
||||||
}, [price])
|
}, [accessDetails])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setHasDatatoken(Number(dtBalance) >= 1)
|
setHasDatatoken(Number(dtBalance) >= 1)
|
||||||
@ -151,10 +91,10 @@ export default function Consume({
|
|||||||
])
|
])
|
||||||
|
|
||||||
async function handleConsume() {
|
async function handleConsume() {
|
||||||
if (!hasPreviousOrder && !hasDatatoken) {
|
// if (!hasPreviousOrder && !hasDatatoken) {
|
||||||
const tx = await buyDT('1', price, ddo)
|
// const tx = await buyDT('1', price, ddo)
|
||||||
if (tx === undefined) return
|
// if (tx === undefined) return
|
||||||
}
|
// }
|
||||||
const error = await consume(
|
const error = await consume(
|
||||||
ddo.id,
|
ddo.id,
|
||||||
ddo.services[0].datatokenAddress,
|
ddo.services[0].datatokenAddress,
|
||||||
@ -188,7 +128,7 @@ export default function Consume({
|
|||||||
assetType={ddo?.metadata?.type}
|
assetType={ddo?.metadata?.type}
|
||||||
stepText={consumeStepText || pricingStepText}
|
stepText={consumeStepText || pricingStepText}
|
||||||
isLoading={pricingIsLoading || isLoading}
|
isLoading={pricingIsLoading || isLoading}
|
||||||
priceType={price?.type}
|
priceType={accessDetails?.type}
|
||||||
isConsumable={isConsumable}
|
isConsumable={isConsumable}
|
||||||
isBalanceSufficient={isBalanceSufficient}
|
isBalanceSufficient={isBalanceSufficient}
|
||||||
consumableFeedback={consumableFeedback}
|
consumableFeedback={consumableFeedback}
|
||||||
@ -202,7 +142,7 @@ export default function Consume({
|
|||||||
<FileIcon file={file} isLoading={fileIsLoading} />
|
<FileIcon file={file} isLoading={fileIsLoading} />
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.pricewrapper}>
|
<div className={styles.pricewrapper}>
|
||||||
<Price price={price} conversion />
|
<Price accessDetails={accessDetails} conversion />
|
||||||
{!isInPurgatory && <PurchaseButton />}
|
{!isInPurgatory && <PurchaseButton />}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -60,8 +60,14 @@ const initialPoolInfoCreator: Partial<PoolInfoUser> = initialPoolInfoUser
|
|||||||
|
|
||||||
export default function Pool(): ReactElement {
|
export default function Pool(): ReactElement {
|
||||||
const { accountId } = useWeb3()
|
const { accountId } = useWeb3()
|
||||||
const { isInPurgatory, ddo, owner, price, refreshInterval, isAssetNetwork } =
|
const {
|
||||||
useAsset()
|
isInPurgatory,
|
||||||
|
assetExtended,
|
||||||
|
owner,
|
||||||
|
accessDetails,
|
||||||
|
refreshInterval,
|
||||||
|
isAssetNetwork
|
||||||
|
} = useAsset()
|
||||||
|
|
||||||
const [poolData, setPoolData] = useState<PoolDataPoolData>()
|
const [poolData, setPoolData] = useState<PoolDataPoolData>()
|
||||||
const [poolInfo, setPoolInfo] = useState<PoolInfo>(
|
const [poolInfo, setPoolInfo] = useState<PoolInfo>(
|
||||||
@ -82,11 +88,11 @@ export default function Pool(): ReactElement {
|
|||||||
const [fetchInterval, setFetchInterval] = useState<NodeJS.Timeout>()
|
const [fetchInterval, setFetchInterval] = useState<NodeJS.Timeout>()
|
||||||
|
|
||||||
const fetchAllData = useCallback(async () => {
|
const fetchAllData = useCallback(async () => {
|
||||||
if (!ddo?.chainId || !price?.address || !owner) return
|
if (!assetExtended?.chainId || !accessDetails?.addressOrId || !owner) return
|
||||||
|
|
||||||
const response = await getPoolData(
|
const response = await getPoolData(
|
||||||
ddo.chainId,
|
assetExtended.chainId,
|
||||||
price.address,
|
accessDetails.addressOrId,
|
||||||
owner,
|
owner,
|
||||||
accountId || ''
|
accountId || ''
|
||||||
)
|
)
|
||||||
@ -101,7 +107,7 @@ export default function Pool(): ReactElement {
|
|||||||
LoggerInstance.log('[pool] Fetched pool data:', response.poolData)
|
LoggerInstance.log('[pool] Fetched pool data:', response.poolData)
|
||||||
LoggerInstance.log('[pool] Fetched user data:', response.poolDataUser)
|
LoggerInstance.log('[pool] Fetched user data:', response.poolDataUser)
|
||||||
LoggerInstance.log('[pool] Fetched pool snapshots:', response.poolSnapshots)
|
LoggerInstance.log('[pool] Fetched pool snapshots:', response.poolSnapshots)
|
||||||
}, [ddo?.chainId, price?.address, owner, accountId])
|
}, [assetExtended?.chainId, accessDetails?.addressOrId, owner, accountId])
|
||||||
|
|
||||||
// Helper: start interval fetching
|
// Helper: start interval fetching
|
||||||
const initFetchInterval = useCallback(() => {
|
const initFetchInterval = useCallback(() => {
|
||||||
@ -233,7 +239,12 @@ export default function Pool(): ReactElement {
|
|||||||
// 3 User Pool Info
|
// 3 User Pool Info
|
||||||
//
|
//
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!poolData || !poolInfo?.totalPoolTokens || !ddo?.chainId || !accountId)
|
if (
|
||||||
|
!poolData ||
|
||||||
|
!poolInfo?.totalPoolTokens ||
|
||||||
|
!assetExtended?.chainId ||
|
||||||
|
!accountId
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
const poolShare =
|
const poolShare =
|
||||||
@ -299,7 +310,7 @@ export default function Pool(): ReactElement {
|
|||||||
poolData,
|
poolData,
|
||||||
poolInfoUser?.poolShares,
|
poolInfoUser?.poolShares,
|
||||||
accountId,
|
accountId,
|
||||||
ddo?.chainId,
|
assetExtended?.chainId,
|
||||||
owner,
|
owner,
|
||||||
poolInfo?.totalPoolTokens
|
poolInfo?.totalPoolTokens
|
||||||
])
|
])
|
||||||
@ -317,7 +328,7 @@ export default function Pool(): ReactElement {
|
|||||||
{showAdd ? (
|
{showAdd ? (
|
||||||
<Add
|
<Add
|
||||||
setShowAdd={setShowAdd}
|
setShowAdd={setShowAdd}
|
||||||
poolAddress={price?.address}
|
poolAddress={accessDetails?.addressOrId}
|
||||||
totalPoolTokens={poolInfo?.totalPoolTokens}
|
totalPoolTokens={poolInfo?.totalPoolTokens}
|
||||||
totalBalance={{
|
totalBalance={{
|
||||||
baseToken: new Decimal(poolData?.baseTokenLiquidity).toString(),
|
baseToken: new Decimal(poolData?.baseTokenLiquidity).toString(),
|
||||||
@ -332,7 +343,7 @@ export default function Pool(): ReactElement {
|
|||||||
) : showRemove ? (
|
) : showRemove ? (
|
||||||
<Remove
|
<Remove
|
||||||
setShowRemove={setShowRemove}
|
setShowRemove={setShowRemove}
|
||||||
poolAddress={price?.address}
|
poolAddress={accessDetails?.addressOrId}
|
||||||
poolTokens={poolInfoUser?.poolShares}
|
poolTokens={poolInfoUser?.poolShares}
|
||||||
totalPoolTokens={poolInfo?.totalPoolTokens}
|
totalPoolTokens={poolInfo?.totalPoolTokens}
|
||||||
tokenOutAddress={poolInfo?.baseTokenAddress}
|
tokenOutAddress={poolInfo?.baseTokenAddress}
|
||||||
@ -350,17 +361,18 @@ export default function Pool(): ReactElement {
|
|||||||
<Tooltip content={content.pool.tooltips.price} />
|
<Tooltip content={content.pool.tooltips.price} />
|
||||||
<div className={styles.dataTokenLinks}>
|
<div className={styles.dataTokenLinks}>
|
||||||
<ExplorerLink
|
<ExplorerLink
|
||||||
networkId={ddo?.chainId}
|
networkId={assetExtended?.chainId}
|
||||||
path={`address/${price?.address}`}
|
path={`address/${accessDetails?.addressOrId}`}
|
||||||
>
|
>
|
||||||
Pool
|
Pool
|
||||||
</ExplorerLink>
|
</ExplorerLink>
|
||||||
<ExplorerLink
|
<ExplorerLink
|
||||||
networkId={ddo?.chainId}
|
networkId={assetExtended?.chainId}
|
||||||
path={
|
path={
|
||||||
ddo?.chainId === 2021000 || ddo?.chainId === 1287
|
assetExtended?.chainId === 2021000 ||
|
||||||
? `tokens/${ddo.services[0].datatokenAddress}`
|
assetExtended?.chainId === 1287
|
||||||
: `token/${ddo.services[0].datatokenAddress}`
|
? `tokens/${assetExtended.services[0].datatokenAddress}`
|
||||||
|
: `token/${assetExtended.services[0].datatokenAddress}`
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
Datatoken
|
Datatoken
|
||||||
@ -466,8 +478,8 @@ export default function Pool(): ReactElement {
|
|||||||
<AssetActionHistoryTable title="Your Pool Transactions">
|
<AssetActionHistoryTable title="Your Pool Transactions">
|
||||||
<PoolTransactions
|
<PoolTransactions
|
||||||
accountId={accountId}
|
accountId={accountId}
|
||||||
poolAddress={price?.address}
|
poolAddress={accessDetails?.addressOrId}
|
||||||
poolChainId={[ddo?.chainId]}
|
poolChainId={[assetExtended?.chainId]}
|
||||||
minimal
|
minimal
|
||||||
/>
|
/>
|
||||||
</AssetActionHistoryTable>
|
</AssetActionHistoryTable>
|
||||||
|
@ -14,19 +14,18 @@ import { useAsset } from '@context/Asset'
|
|||||||
import { FormTradeData } from './_types'
|
import { FormTradeData } from './_types'
|
||||||
import { initialValues } from './_constants'
|
import { initialValues } from './_constants'
|
||||||
import content from '../../../../../content/price.json'
|
import content from '../../../../../content/price.json'
|
||||||
|
import { AssetExtended } from 'src/@types/AssetExtended'
|
||||||
|
|
||||||
export default function FormTrade({
|
export default function FormTrade({
|
||||||
ddo,
|
assetExtended,
|
||||||
balance,
|
balance,
|
||||||
maxDt,
|
maxDt,
|
||||||
maxOcean,
|
maxOcean
|
||||||
price
|
|
||||||
}: {
|
}: {
|
||||||
ddo: Asset
|
assetExtended: AssetExtended
|
||||||
balance: PoolBalance
|
balance: PoolBalance
|
||||||
maxDt: string
|
maxDt: string
|
||||||
maxOcean: string
|
maxOcean: string
|
||||||
price: BestPrice
|
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { accountId } = useWeb3()
|
const { accountId } = useWeb3()
|
||||||
const { isAssetNetwork } = useAsset()
|
const { isAssetNetwork } = useAsset()
|
||||||
@ -111,11 +110,10 @@ export default function FormTrade({
|
|||||||
<>
|
<>
|
||||||
{isWarningAccepted ? (
|
{isWarningAccepted ? (
|
||||||
<Swap
|
<Swap
|
||||||
ddo={ddo}
|
assetExtended={assetExtended}
|
||||||
balance={balance}
|
balance={balance}
|
||||||
maxDt={maxDt}
|
maxDt={maxDt}
|
||||||
maxOcean={maxOcean}
|
maxOcean={maxOcean}
|
||||||
price={price}
|
|
||||||
setCoin={setCoinFrom}
|
setCoin={setCoinFrom}
|
||||||
setMaximumOcean={setMaximumOcean}
|
setMaximumOcean={setMaximumOcean}
|
||||||
setMaximumDt={setMaximumDt}
|
setMaximumDt={setMaximumDt}
|
||||||
|
@ -12,24 +12,23 @@ import Decimal from 'decimal.js'
|
|||||||
import { useAsset } from '@context/Asset'
|
import { useAsset } from '@context/Asset'
|
||||||
import { FormTradeData, TradeItem } from './_types'
|
import { FormTradeData, TradeItem } from './_types'
|
||||||
import { Asset } from '@oceanprotocol/lib'
|
import { Asset } from '@oceanprotocol/lib'
|
||||||
|
import { AssetExtended } from 'src/@types/AssetExtended'
|
||||||
|
|
||||||
Decimal.set({ toExpNeg: -18, precision: 18, rounding: 1 })
|
Decimal.set({ toExpNeg: -18, precision: 18, rounding: 1 })
|
||||||
|
|
||||||
export default function Swap({
|
export default function Swap({
|
||||||
ddo,
|
assetExtended,
|
||||||
maxDt,
|
maxDt,
|
||||||
maxOcean,
|
maxOcean,
|
||||||
balance,
|
balance,
|
||||||
price,
|
|
||||||
setMaximumDt,
|
setMaximumDt,
|
||||||
setMaximumOcean,
|
setMaximumOcean,
|
||||||
setCoin
|
setCoin
|
||||||
}: {
|
}: {
|
||||||
ddo: Asset
|
assetExtended: AssetExtended
|
||||||
maxDt: string
|
maxDt: string
|
||||||
maxOcean: string
|
maxOcean: string
|
||||||
balance: PoolBalance
|
balance: PoolBalance
|
||||||
price: BestPrice
|
|
||||||
setMaximumDt: (value: string) => void
|
setMaximumDt: (value: string) => void
|
||||||
setMaximumOcean: (value: string) => void
|
setMaximumOcean: (value: string) => void
|
||||||
setCoin: (value: string) => void
|
setCoin: (value: string) => void
|
||||||
@ -37,12 +36,12 @@ export default function Swap({
|
|||||||
const { isAssetNetwork } = useAsset()
|
const { isAssetNetwork } = useAsset()
|
||||||
const [oceanItem, setOceanItem] = useState<TradeItem>({
|
const [oceanItem, setOceanItem] = useState<TradeItem>({
|
||||||
amount: '0',
|
amount: '0',
|
||||||
token: price.oceanSymbol,
|
token: assetExtended.accessDetails.baseToken?.symbol,
|
||||||
maxAmount: '0'
|
maxAmount: '0'
|
||||||
})
|
})
|
||||||
const [dtItem, setDtItem] = useState<TradeItem>({
|
const [dtItem, setDtItem] = useState<TradeItem>({
|
||||||
amount: '0',
|
amount: '0',
|
||||||
token: ddo.datatokens[0].symbol,
|
token: assetExtended.accessDetails.datatoken.symbol,
|
||||||
maxAmount: '0'
|
maxAmount: '0'
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -59,7 +58,7 @@ export default function Swap({
|
|||||||
const [tokenAmount, setTokenAmount] = useState<string>()
|
const [tokenAmount, setTokenAmount] = useState<string>()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!ddo || !balance || !values?.type || !price) return
|
if (!assetExtended || !balance || !values?.type) return
|
||||||
|
|
||||||
async function calculateMaximum() {
|
async function calculateMaximum() {
|
||||||
const amountDataToken =
|
const amountDataToken =
|
||||||
@ -115,11 +114,10 @@ export default function Swap({
|
|||||||
}
|
}
|
||||||
calculateMaximum()
|
calculateMaximum()
|
||||||
}, [
|
}, [
|
||||||
ddo,
|
assetExtended,
|
||||||
maxOcean,
|
maxOcean,
|
||||||
maxDt,
|
maxDt,
|
||||||
balance,
|
balance,
|
||||||
price,
|
|
||||||
values?.type,
|
values?.type,
|
||||||
setMaximumDt,
|
setMaximumDt,
|
||||||
setMaximumOcean
|
setMaximumOcean
|
||||||
@ -127,7 +125,9 @@ export default function Swap({
|
|||||||
|
|
||||||
const switchTokens = () => {
|
const switchTokens = () => {
|
||||||
setFieldValue('type', values.type === 'buy' ? 'sell' : 'buy')
|
setFieldValue('type', values.type === 'buy' ? 'sell' : 'buy')
|
||||||
setCoin(values.type === 'sell' ? 'OCEAN' : ddo.datatokens[0].symbol)
|
setCoin(
|
||||||
|
values.type === 'sell' ? 'OCEAN' : assetExtended.datatokens[0].symbol
|
||||||
|
)
|
||||||
// don't reset form because we don't want to reset type
|
// don't reset form because we don't want to reset type
|
||||||
setFieldValue('datatoken', 0)
|
setFieldValue('datatoken', 0)
|
||||||
setFieldValue('ocean', 0)
|
setFieldValue('ocean', 0)
|
||||||
@ -223,7 +223,7 @@ export default function Swap({
|
|||||||
<Output
|
<Output
|
||||||
dtSymbol={dtItem.token}
|
dtSymbol={dtItem.token}
|
||||||
oceanSymbol={oceanItem.token}
|
oceanSymbol={oceanItem.token}
|
||||||
poolAddress={price?.address}
|
poolAddress={assetExtended.accessDetails?.addressOrId}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<PriceImpact
|
<PriceImpact
|
||||||
|
@ -2,8 +2,6 @@ import React, { ReactElement, useEffect, useState } from 'react'
|
|||||||
import FormTrade from './FormTrade'
|
import FormTrade from './FormTrade'
|
||||||
import { useAsset } from '@context/Asset'
|
import { useAsset } from '@context/Asset'
|
||||||
import { useWeb3 } from '@context/Web3'
|
import { useWeb3 } from '@context/Web3'
|
||||||
|
|
||||||
import { isValidNumber } from '@utils/numbers'
|
|
||||||
import Decimal from 'decimal.js'
|
import Decimal from 'decimal.js'
|
||||||
import { Datatoken } from '@oceanprotocol/lib'
|
import { Datatoken } from '@oceanprotocol/lib'
|
||||||
|
|
||||||
@ -13,7 +11,7 @@ export default function Trade(): ReactElement {
|
|||||||
const { accountId, balance, web3 } = useWeb3()
|
const { accountId, balance, web3 } = useWeb3()
|
||||||
const { isAssetNetwork } = useAsset()
|
const { isAssetNetwork } = useAsset()
|
||||||
const [tokenBalance, setTokenBalance] = useState<PoolBalance>()
|
const [tokenBalance, setTokenBalance] = useState<PoolBalance>()
|
||||||
const { price, ddo } = useAsset()
|
const { assetExtended } = useAsset()
|
||||||
const [maxDt, setMaxDt] = useState('0')
|
const [maxDt, setMaxDt] = useState('0')
|
||||||
const [maxOcean, setMaxOcean] = useState('0')
|
const [maxOcean, setMaxOcean] = useState('0')
|
||||||
|
|
||||||
@ -25,14 +23,14 @@ export default function Trade(): ReactElement {
|
|||||||
!isAssetNetwork ||
|
!isAssetNetwork ||
|
||||||
!balance?.ocean ||
|
!balance?.ocean ||
|
||||||
!accountId ||
|
!accountId ||
|
||||||
!ddo?.services[0].datatokenAddress
|
!assetExtended?.services[0].datatokenAddress
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
async function getTokenBalance() {
|
async function getTokenBalance() {
|
||||||
const datatokenInstance = new Datatoken(web3)
|
const datatokenInstance = new Datatoken(web3)
|
||||||
const dtBalance = await datatokenInstance.balance(
|
const dtBalance = await datatokenInstance.balance(
|
||||||
ddo.services[0].datatokenAddress,
|
assetExtended.services[0].datatokenAddress,
|
||||||
accountId
|
accountId
|
||||||
)
|
)
|
||||||
setTokenBalance({
|
setTokenBalance({
|
||||||
@ -41,11 +39,16 @@ export default function Trade(): ReactElement {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
getTokenBalance()
|
getTokenBalance()
|
||||||
}, [web3, balance.ocean, accountId, ddo, isAssetNetwork])
|
}, [web3, balance.ocean, accountId, assetExtended, isAssetNetwork])
|
||||||
|
|
||||||
// Get maximum amount for either OCEAN or datatoken
|
// Get maximum amount for either OCEAN or datatoken
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isAssetNetwork || !price || price.value === 0) return
|
if (
|
||||||
|
!isAssetNetwork ||
|
||||||
|
!assetExtended.accessDetails ||
|
||||||
|
assetExtended.accessDetails.price === 0
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
async function getMaximum() {
|
async function getMaximum() {
|
||||||
// const maxTokensInPool = await ocean.pool.getDTMaxBuyQuantity(
|
// const maxTokensInPool = await ocean.pool.getDTMaxBuyQuantity(
|
||||||
@ -66,12 +69,11 @@ export default function Trade(): ReactElement {
|
|||||||
// )
|
// )
|
||||||
}
|
}
|
||||||
getMaximum()
|
getMaximum()
|
||||||
}, [isAssetNetwork, balance.ocean, price])
|
}, [isAssetNetwork, balance.ocean, assetExtended])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormTrade
|
<FormTrade
|
||||||
ddo={ddo}
|
assetExtended={assetExtended}
|
||||||
price={price}
|
|
||||||
balance={tokenBalance}
|
balance={tokenBalance}
|
||||||
maxDt={maxDt}
|
maxDt={maxDt}
|
||||||
maxOcean={maxOcean}
|
maxOcean={maxOcean}
|
||||||
|
@ -24,10 +24,10 @@ import { FormPublishData } from 'src/components/Publish/_types'
|
|||||||
|
|
||||||
export default function AssetActions({
|
export default function AssetActions({
|
||||||
ddo,
|
ddo,
|
||||||
price
|
accessDetails
|
||||||
}: {
|
}: {
|
||||||
ddo: Asset
|
ddo: Asset
|
||||||
price: BestPrice
|
accessDetails: AccessDetails
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { accountId, balance, web3 } = useWeb3()
|
const { accountId, balance, web3 } = useWeb3()
|
||||||
const { isAssetNetwork } = useAsset()
|
const { isAssetNetwork } = useAsset()
|
||||||
@ -112,22 +112,24 @@ export default function AssetActions({
|
|||||||
|
|
||||||
// Check user balance against price
|
// Check user balance against price
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (price?.type === 'free') setIsBalanceSufficient(true)
|
if (accessDetails?.type === 'free') setIsBalanceSufficient(true)
|
||||||
if (!price?.value || !accountId || !balance?.ocean || !dtBalance) return
|
if (!accessDetails?.price || !accountId || !balance?.ocean || !dtBalance)
|
||||||
|
return
|
||||||
|
|
||||||
setIsBalanceSufficient(
|
setIsBalanceSufficient(
|
||||||
compareAsBN(balance.ocean, `${price.value}`) || Number(dtBalance) >= 1
|
compareAsBN(balance.ocean, `${accessDetails.price}`) ||
|
||||||
|
Number(dtBalance) >= 1
|
||||||
)
|
)
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
setIsBalanceSufficient(false)
|
setIsBalanceSufficient(false)
|
||||||
}
|
}
|
||||||
}, [balance, accountId, price, dtBalance])
|
}, [balance, accountId, accessDetails, dtBalance])
|
||||||
|
|
||||||
const UseContent = isCompute ? (
|
const UseContent = isCompute ? (
|
||||||
<Compute
|
<Compute
|
||||||
ddo={ddo}
|
ddo={ddo}
|
||||||
price={price}
|
accessDetails={accessDetails}
|
||||||
dtBalance={dtBalance}
|
dtBalance={dtBalance}
|
||||||
file={fileMetadata}
|
file={fileMetadata}
|
||||||
fileIsLoading={fileIsLoading}
|
fileIsLoading={fileIsLoading}
|
||||||
@ -137,7 +139,7 @@ export default function AssetActions({
|
|||||||
) : (
|
) : (
|
||||||
<Consume
|
<Consume
|
||||||
ddo={ddo}
|
ddo={ddo}
|
||||||
price={price}
|
accessDetails={accessDetails}
|
||||||
dtBalance={dtBalance}
|
dtBalance={dtBalance}
|
||||||
isBalanceSufficient={isBalanceSufficient}
|
isBalanceSufficient={isBalanceSufficient}
|
||||||
file={fileMetadata}
|
file={fileMetadata}
|
||||||
@ -154,17 +156,17 @@ export default function AssetActions({
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
price?.type === 'dynamic' &&
|
accessDetails?.type === 'dynamic' &&
|
||||||
tabs.push(
|
tabs.push(
|
||||||
{
|
{
|
||||||
title: 'Pool',
|
title: 'Pool',
|
||||||
content: <Pool />,
|
content: <Pool />,
|
||||||
disabled: !price.datatoken
|
disabled: !accessDetails.datatoken
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Trade',
|
title: 'Trade',
|
||||||
content: <Trade />,
|
content: <Trade />,
|
||||||
disabled: !price.datatoken
|
disabled: !accessDetails.datatoken
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ const getReceipts = gql`
|
|||||||
`
|
`
|
||||||
|
|
||||||
export default function EditHistory(): ReactElement {
|
export default function EditHistory(): ReactElement {
|
||||||
const { ddo } = useAsset()
|
const { assetExtended } = useAsset()
|
||||||
|
|
||||||
function getUpdateType(type: string): string {
|
function getUpdateType(type: string): string {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@ -49,17 +49,17 @@ export default function EditHistory(): ReactElement {
|
|||||||
const [queryContext, setQueryContext] = useState<OperationContext>()
|
const [queryContext, setQueryContext] = useState<OperationContext>()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!ddo) return
|
if (!assetExtended) return
|
||||||
|
|
||||||
const queryContext = getQueryContext(ddo.chainId)
|
const queryContext = getQueryContext(assetExtended.chainId)
|
||||||
setQueryContext(queryContext)
|
setQueryContext(queryContext)
|
||||||
}, [ddo])
|
}, [assetExtended])
|
||||||
|
|
||||||
const [result] = useQuery({
|
const [result] = useQuery({
|
||||||
query: getReceipts,
|
query: getReceipts,
|
||||||
variables: { address: ddo?.nft.address.toLowerCase() },
|
variables: { address: assetExtended?.nft.address.toLowerCase() },
|
||||||
context: queryContext,
|
context: queryContext,
|
||||||
pause: !ddo || !queryContext
|
pause: !assetExtended || !queryContext
|
||||||
})
|
})
|
||||||
const { data } = result
|
const { data } = result
|
||||||
|
|
||||||
@ -80,7 +80,10 @@ export default function EditHistory(): ReactElement {
|
|||||||
<ul className={styles.history}>
|
<ul className={styles.history}>
|
||||||
{receipts?.map((receipt) => (
|
{receipts?.map((receipt) => (
|
||||||
<li key={receipt.id} className={styles.item}>
|
<li key={receipt.id} className={styles.item}>
|
||||||
<ExplorerLink networkId={ddo?.chainId} path={`/tx/${receipt.tx}`}>
|
<ExplorerLink
|
||||||
|
networkId={assetExtended?.chainId}
|
||||||
|
path={`/tx/${receipt.tx}`}
|
||||||
|
>
|
||||||
{getUpdateType(receipt.type)}{' '}
|
{getUpdateType(receipt.type)}{' '}
|
||||||
<Time date={`${receipt.timestamp}`} relative isUnix />
|
<Time date={`${receipt.timestamp}`} relative isUnix />
|
||||||
</ExplorerLink>
|
</ExplorerLink>
|
||||||
|
@ -16,11 +16,11 @@ import content from '../../../../content/purgatory.json'
|
|||||||
import { Asset } from '@oceanprotocol/lib'
|
import { Asset } from '@oceanprotocol/lib'
|
||||||
|
|
||||||
export default function AssetContent({
|
export default function AssetContent({
|
||||||
ddo,
|
asset,
|
||||||
price
|
accessDetails
|
||||||
}: {
|
}: {
|
||||||
ddo: Asset
|
asset: Asset
|
||||||
price: BestPrice
|
accessDetails: AccessDetails
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { debug } = useUserPreferences()
|
const { debug } = useUserPreferences()
|
||||||
const { isInPurgatory, purgatoryData } = useAsset()
|
const { isInPurgatory, purgatoryData } = useAsset()
|
||||||
@ -28,14 +28,14 @@ export default function AssetContent({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={styles.networkWrap}>
|
<div className={styles.networkWrap}>
|
||||||
<NetworkName networkId={ddo?.chainId} className={styles.network} />
|
<NetworkName networkId={asset?.chainId} className={styles.network} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<article className={styles.grid}>
|
<article className={styles.grid}>
|
||||||
<div>
|
<div>
|
||||||
<div className={styles.content}>
|
<div className={styles.content}>
|
||||||
<MetaMain ddo={ddo} />
|
<MetaMain ddo={asset} />
|
||||||
{price?.datatoken !== null && <Bookmark did={ddo?.id} />}
|
{accessDetails?.datatoken !== null && <Bookmark did={asset?.id} />}
|
||||||
|
|
||||||
{isInPurgatory === true ? (
|
{isInPurgatory === true ? (
|
||||||
<Alert
|
<Alert
|
||||||
@ -48,20 +48,20 @@ export default function AssetContent({
|
|||||||
<>
|
<>
|
||||||
<Markdown
|
<Markdown
|
||||||
className={styles.description}
|
className={styles.description}
|
||||||
text={ddo?.metadata.description || ''}
|
text={asset?.metadata.description || ''}
|
||||||
/>
|
/>
|
||||||
<MetaSecondary ddo={ddo} />
|
<MetaSecondary ddo={asset} />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<MetaFull ddo={ddo} />
|
<MetaFull ddo={asset} />
|
||||||
<EditHistory />
|
<EditHistory />
|
||||||
{debug === true && <DebugOutput title="DDO" output={ddo} />}
|
{debug === true && <DebugOutput title="DDO" output={asset} />}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={styles.actions}>
|
<div className={styles.actions}>
|
||||||
<AssetActions ddo={ddo} price={price} />
|
<AssetActions ddo={asset} accessDetails={accessDetails} />
|
||||||
|
|
||||||
{/*
|
{/*
|
||||||
TODO: restore edit actions, ideally put edit screens on new page
|
TODO: restore edit actions, ideally put edit screens on new page
|
||||||
|
@ -8,7 +8,6 @@ import { useUserPreferences } from '@context/UserPreferences'
|
|||||||
import DebugEditCompute from './DebugEditCompute'
|
import DebugEditCompute from './DebugEditCompute'
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
// import { transformComputeFormToServiceComputePrivacy } from '@utils/compute'
|
// import { transformComputeFormToServiceComputePrivacy } from '@utils/compute'
|
||||||
import { setMinterToDispenser, setMinterToPublisher } from '@utils/freePrice'
|
|
||||||
import Web3Feedback from '@shared/Web3Feedback'
|
import Web3Feedback from '@shared/Web3Feedback'
|
||||||
import { getInitialValues, validationSchema } from './_constants'
|
import { getInitialValues, validationSchema } from './_constants'
|
||||||
import content from '../../../../content/pages/editComputeDataset.json'
|
import content from '../../../../content/pages/editComputeDataset.json'
|
||||||
@ -20,7 +19,7 @@ export default function EditComputeDataset({
|
|||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { debug } = useUserPreferences()
|
const { debug } = useUserPreferences()
|
||||||
const { accountId } = useWeb3()
|
const { accountId } = useWeb3()
|
||||||
const { ddo, price, isAssetNetwork, refreshDdo } = useAsset()
|
const { assetExtended, isAssetNetwork, refreshAsset } = useAsset()
|
||||||
const [success, setSuccess] = useState<string>()
|
const [success, setSuccess] = useState<string>()
|
||||||
const [error, setError] = useState<string>()
|
const [error, setError] = useState<string>()
|
||||||
|
|
||||||
@ -112,7 +111,7 @@ export default function EditComputeDataset({
|
|||||||
/>
|
/>
|
||||||
</article>
|
</article>
|
||||||
<Web3Feedback
|
<Web3Feedback
|
||||||
networkId={ddo?.chainId}
|
networkId={assetExtended?.chainId}
|
||||||
isAssetNetwork={isAssetNetwork}
|
isAssetNetwork={isAssetNetwork}
|
||||||
/>
|
/>
|
||||||
{debug === true && (
|
{debug === true && (
|
||||||
|
@ -28,12 +28,12 @@ export default function FormEditComputeDataset({
|
|||||||
setShowEdit: (show: boolean) => void
|
setShowEdit: (show: boolean) => void
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { appConfig } = useSiteMetadata()
|
const { appConfig } = useSiteMetadata()
|
||||||
const { ddo } = useAsset()
|
const { assetExtended } = useAsset()
|
||||||
const { values }: FormikContextType<ComputePrivacyForm> = useFormikContext()
|
const { values }: FormikContextType<ComputePrivacyForm> = useFormikContext()
|
||||||
const [allAlgorithms, setAllAlgorithms] = useState<AssetSelectionAsset[]>()
|
const [allAlgorithms, setAllAlgorithms] = useState<AssetSelectionAsset[]>()
|
||||||
const newCancelToken = useCancelToken()
|
const newCancelToken = useCancelToken()
|
||||||
const { publisherTrustedAlgorithms } = getServiceByName(
|
const { publisherTrustedAlgorithms } = getServiceByName(
|
||||||
ddo,
|
assetExtended,
|
||||||
'compute'
|
'compute'
|
||||||
).compute
|
).compute
|
||||||
|
|
||||||
@ -41,14 +41,14 @@ export default function FormEditComputeDataset({
|
|||||||
publisherTrustedAlgorithms: PublisherTrustedAlgorithm[]
|
publisherTrustedAlgorithms: PublisherTrustedAlgorithm[]
|
||||||
): Promise<AssetSelectionAsset[]> {
|
): Promise<AssetSelectionAsset[]> {
|
||||||
const baseParams = {
|
const baseParams = {
|
||||||
chainIds: [ddo.chainId],
|
chainIds: [assetExtended.chainId],
|
||||||
sort: { sortBy: SortTermOptions.Created },
|
sort: { sortBy: SortTermOptions.Created },
|
||||||
filters: [getFilterTerm('service.attributes.main.type', 'algorithm')]
|
filters: [getFilterTerm('service.attributes.main.type', 'algorithm')]
|
||||||
} as BaseQueryParams
|
} as BaseQueryParams
|
||||||
|
|
||||||
const query = generateBaseQuery(baseParams)
|
const query = generateBaseQuery(baseParams)
|
||||||
const querryResult = await queryMetadata(query, newCancelToken())
|
const querryResult = await queryMetadata(query, newCancelToken())
|
||||||
const datasetComputeService = getServiceByName(ddo, 'compute')
|
const datasetComputeService = getServiceByName(assetExtended, 'compute')
|
||||||
const algorithmSelectionList = await transformDDOToAssetSelection(
|
const algorithmSelectionList = await transformDDOToAssetSelection(
|
||||||
datasetComputeService?.serviceEndpoint,
|
datasetComputeService?.serviceEndpoint,
|
||||||
querryResult.results,
|
querryResult.results,
|
||||||
|
@ -10,7 +10,6 @@ import { getServiceByName, mapTimeoutStringToSeconds } from '@utils/ddo'
|
|||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
import { LoggerInstance } from '@oceanprotocol/lib'
|
import { LoggerInstance } from '@oceanprotocol/lib'
|
||||||
import { useWeb3 } from '@context/Web3'
|
import { useWeb3 } from '@context/Web3'
|
||||||
import { setMinterToDispenser, setMinterToPublisher } from '@utils/freePrice'
|
|
||||||
import content from '../../../../content/pages/edit.json'
|
import content from '../../../../content/pages/edit.json'
|
||||||
import { MetadataEditForm } from './_types'
|
import { MetadataEditForm } from './_types'
|
||||||
|
|
||||||
@ -23,11 +22,11 @@ export default function Edit({
|
|||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { debug } = useUserPreferences()
|
const { debug } = useUserPreferences()
|
||||||
const { accountId } = useWeb3()
|
const { accountId } = useWeb3()
|
||||||
const { ddo, refreshDdo, price } = useAsset()
|
const { assetExtended, refreshAsset, accessDetails } = useAsset()
|
||||||
const [success, setSuccess] = useState<string>()
|
const [success, setSuccess] = useState<string>()
|
||||||
const [error, setError] = useState<string>()
|
const [error, setError] = useState<string>()
|
||||||
const [timeoutStringValue, setTimeoutStringValue] = useState<string>()
|
const [timeoutStringValue, setTimeoutStringValue] = useState<string>()
|
||||||
const { timeout } = ddo.services[0]
|
const { timeout } = assetExtended.services[0]
|
||||||
|
|
||||||
const hasFeedback = error || success
|
const hasFeedback = error || success
|
||||||
|
|
||||||
@ -119,7 +118,11 @@ export default function Edit({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Formik
|
<Formik
|
||||||
initialValues={getInitialValues(ddo.metadata, timeout, price.value)}
|
initialValues={getInitialValues(
|
||||||
|
assetExtended.metadata,
|
||||||
|
timeout,
|
||||||
|
accessDetails.price
|
||||||
|
)}
|
||||||
validationSchema={validationSchema}
|
validationSchema={validationSchema}
|
||||||
onSubmit={async (values, { resetForm }) => {
|
onSubmit={async (values, { resetForm }) => {
|
||||||
// move user's focus to top of screen
|
// move user's focus to top of screen
|
||||||
@ -145,7 +148,7 @@ export default function Edit({
|
|||||||
/> */}
|
/> */}
|
||||||
|
|
||||||
<aside>
|
<aside>
|
||||||
<Web3Feedback networkId={ddo?.chainId} />
|
<Web3Feedback networkId={assetExtended?.chainId} />
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
{/* {debug === true && <Debug values={values} ddo={ddo} />} */}
|
{/* {debug === true && <Debug values={values} ddo={ddo} />} */}
|
||||||
|
@ -6,20 +6,21 @@ import { useAsset } from '@context/Asset'
|
|||||||
import AssetContent from './AssetContent'
|
import AssetContent from './AssetContent'
|
||||||
|
|
||||||
export default function AssetDetails({ uri }: { uri: string }): ReactElement {
|
export default function AssetDetails({ uri }: { uri: string }): ReactElement {
|
||||||
const { ddo, title, error, isInPurgatory, loading, price } = useAsset()
|
const { assetExtended, title, error, isInPurgatory, loading, accessDetails } =
|
||||||
|
useAsset()
|
||||||
const [pageTitle, setPageTitle] = useState<string>()
|
const [pageTitle, setPageTitle] = useState<string>()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!ddo || error) {
|
if (!assetExtended || error) {
|
||||||
setPageTitle('Could not retrieve asset')
|
setPageTitle('Could not retrieve asset')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
setPageTitle(isInPurgatory ? '' : title)
|
setPageTitle(isInPurgatory ? '' : title)
|
||||||
}, [ddo, error, isInPurgatory, title])
|
}, [assetExtended, error, isInPurgatory, title])
|
||||||
|
|
||||||
return ddo && pageTitle !== undefined && !loading ? (
|
return assetExtended && pageTitle !== undefined && !loading ? (
|
||||||
<Page title={pageTitle} uri={uri}>
|
<Page title={pageTitle} uri={uri}>
|
||||||
<AssetContent ddo={ddo} price={price} />
|
<AssetContent asset={assetExtended} accessDetails={accessDetails} />
|
||||||
</Page>
|
</Page>
|
||||||
) : error ? (
|
) : error ? (
|
||||||
<Page title={pageTitle} noPageHeader uri={uri}>
|
<Page title={pageTitle} noPageHeader uri={uri}>
|
||||||
|
@ -6,27 +6,29 @@ import Price from '@shared/Price'
|
|||||||
import Tooltip from '@shared/atoms/Tooltip'
|
import Tooltip from '@shared/atoms/Tooltip'
|
||||||
import AssetTitle from '@shared/AssetList/AssetListTitle'
|
import AssetTitle from '@shared/AssetList/AssetListTitle'
|
||||||
import { retrieveDDOListByDIDs } from '@utils/aquarius'
|
import { retrieveDDOListByDIDs } from '@utils/aquarius'
|
||||||
import { getAssetsBestPrices, AssetListPrices } from '@utils/subgraph'
|
|
||||||
import { CancelToken } from 'axios'
|
import { CancelToken } from 'axios'
|
||||||
import { useSiteMetadata } from '@hooks/useSiteMetadata'
|
import { useSiteMetadata } from '@hooks/useSiteMetadata'
|
||||||
import { useCancelToken } from '@hooks/useCancelToken'
|
import { useCancelToken } from '@hooks/useCancelToken'
|
||||||
|
import { AssetExtended } from 'src/@types/AssetExtended'
|
||||||
|
import { getAccessDetailsForAssets } from '@utils/accessDetailsAndPricing'
|
||||||
|
import { useWeb3 } from '@context/Web3'
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
name: 'Data Set',
|
name: 'Data Set',
|
||||||
selector: function getAssetRow(row: AssetListPrices) {
|
selector: function getAssetRow(row: AssetExtended) {
|
||||||
const { metadata } = row.ddo
|
const { metadata } = row
|
||||||
return <AssetTitle title={metadata.name} ddo={row.ddo} />
|
return <AssetTitle title={metadata.name} asset={row} />
|
||||||
},
|
},
|
||||||
maxWidth: '45rem',
|
maxWidth: '45rem',
|
||||||
grow: 1
|
grow: 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Datatoken Symbol',
|
name: 'Datatoken Symbol',
|
||||||
selector: function getAssetRow(row: AssetListPrices) {
|
selector: function getAssetRow(row: AssetExtended) {
|
||||||
return (
|
return (
|
||||||
<Tooltip content={row.ddo.datatokens[0].name}>
|
<Tooltip content={row.datatokens[0].name}>
|
||||||
{row.ddo.datatokens[0].symbol}
|
{row.datatokens[0].symbol}
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -34,8 +36,8 @@ const columns = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Price',
|
name: 'Price',
|
||||||
selector: function getAssetRow(row: AssetListPrices) {
|
selector: function getAssetRow(row: AssetExtended) {
|
||||||
return <Price price={row.price} small />
|
return <Price accessDetails={row.accessDetails} small />
|
||||||
},
|
},
|
||||||
right: true
|
right: true
|
||||||
}
|
}
|
||||||
@ -43,9 +45,10 @@ const columns = [
|
|||||||
|
|
||||||
export default function Bookmarks(): ReactElement {
|
export default function Bookmarks(): ReactElement {
|
||||||
const { appConfig } = useSiteMetadata()
|
const { appConfig } = useSiteMetadata()
|
||||||
|
const { accountId } = useWeb3()
|
||||||
const { bookmarks } = useUserPreferences()
|
const { bookmarks } = useUserPreferences()
|
||||||
|
|
||||||
const [pinned, setPinned] = useState<AssetListPrices[]>()
|
const [pinned, setPinned] = useState<AssetExtended[]>()
|
||||||
const [isLoading, setIsLoading] = useState<boolean>()
|
const [isLoading, setIsLoading] = useState<boolean>()
|
||||||
const { chainIds } = useUserPreferences()
|
const { chainIds } = useUserPreferences()
|
||||||
const newCancelToken = useCancelToken()
|
const newCancelToken = useCancelToken()
|
||||||
@ -87,8 +90,9 @@ export default function Bookmarks(): ReactElement {
|
|||||||
chainIds,
|
chainIds,
|
||||||
newCancelToken()
|
newCancelToken()
|
||||||
)
|
)
|
||||||
const pinnedAssets: AssetListPrices[] = await getAssetsBestPrices(
|
const pinnedAssets: AssetExtended[] = await getAccessDetailsForAssets(
|
||||||
resultPinned
|
resultPinned,
|
||||||
|
accountId
|
||||||
)
|
)
|
||||||
setPinned(pinnedAssets)
|
setPinned(pinnedAssets)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -102,6 +106,7 @@ export default function Bookmarks(): ReactElement {
|
|||||||
appConfig?.metadataCacheUri,
|
appConfig?.metadataCacheUri,
|
||||||
bookmarks,
|
bookmarks,
|
||||||
chainIds,
|
chainIds,
|
||||||
|
accountId,
|
||||||
getAssetsBookmarked,
|
getAssetsBookmarked,
|
||||||
newCancelToken
|
newCancelToken
|
||||||
])
|
])
|
||||||
|
@ -53,7 +53,7 @@ function SectionQueryResult({
|
|||||||
queryData?: string[]
|
queryData?: string[]
|
||||||
}) {
|
}) {
|
||||||
const { chainIds } = useUserPreferences()
|
const { chainIds } = useUserPreferences()
|
||||||
const [result, setResult] = useState<any>()
|
const [result, setResult] = useState<PagedAssets>()
|
||||||
const [loading, setLoading] = useState<boolean>()
|
const [loading, setLoading] = useState<boolean>()
|
||||||
const isMounted = useIsMounted()
|
const isMounted = useIsMounted()
|
||||||
const newCancelToken = useCancelToken()
|
const newCancelToken = useCancelToken()
|
||||||
|
@ -3,7 +3,6 @@ import React, { useEffect, useState, ReactElement } from 'react'
|
|||||||
import { useUserPreferences } from '@context/UserPreferences'
|
import { useUserPreferences } from '@context/UserPreferences'
|
||||||
import {
|
import {
|
||||||
getAccountLiquidityInOwnAssets,
|
getAccountLiquidityInOwnAssets,
|
||||||
getAssetsBestPrices,
|
|
||||||
UserLiquidity,
|
UserLiquidity,
|
||||||
calculateUserLiquidity
|
calculateUserLiquidity
|
||||||
} from '@utils/subgraph'
|
} from '@utils/subgraph'
|
||||||
@ -12,6 +11,7 @@ import NumberUnit from './NumberUnit'
|
|||||||
import styles from './Stats.module.css'
|
import styles from './Stats.module.css'
|
||||||
import { useProfile } from '@context/Profile'
|
import { useProfile } from '@context/Profile'
|
||||||
import { PoolShares_poolShares as PoolShare } from '../../../@types/subgraph/PoolShares'
|
import { PoolShares_poolShares as PoolShare } from '../../../@types/subgraph/PoolShares'
|
||||||
|
import { getAccessDetailsForAssets } from '@utils/accessDetailsAndPricing'
|
||||||
|
|
||||||
async function getPoolSharesLiquidity(
|
async function getPoolSharesLiquidity(
|
||||||
poolShares: PoolShare[]
|
poolShares: PoolShare[]
|
||||||
@ -50,10 +50,12 @@ export default function Stats({
|
|||||||
async function getPublisherLiquidity() {
|
async function getPublisherLiquidity() {
|
||||||
try {
|
try {
|
||||||
const accountPoolAdresses: string[] = []
|
const accountPoolAdresses: string[] = []
|
||||||
const assetsPrices = await getAssetsBestPrices(assets)
|
const assetsPrices = await getAccessDetailsForAssets(assets)
|
||||||
for (const priceInfo of assetsPrices) {
|
for (const priceInfo of assetsPrices) {
|
||||||
if (priceInfo.price.type === 'dynamic') {
|
if (priceInfo.accessDetails.type === 'dynamic') {
|
||||||
accountPoolAdresses.push(priceInfo.price.address.toLowerCase())
|
accountPoolAdresses.push(
|
||||||
|
priceInfo.accessDetails.addressOrId.toLowerCase()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const userLiquidity = await getAccountLiquidityInOwnAssets(
|
const userLiquidity = await getAccountLiquidityInOwnAssets(
|
||||||
|
@ -3,7 +3,7 @@ import Time from '@shared/atoms/Time'
|
|||||||
import Button from '@shared/atoms/Button'
|
import Button from '@shared/atoms/Button'
|
||||||
import Modal from '@shared/atoms/Modal'
|
import Modal from '@shared/atoms/Modal'
|
||||||
import External from '@images/external.svg'
|
import External from '@images/external.svg'
|
||||||
import { retrieveDDO } from '@utils/aquarius'
|
import { retrieveAsset } from '@utils/aquarius'
|
||||||
import Results from './Results'
|
import Results from './Results'
|
||||||
import styles from './Details.module.css'
|
import styles from './Details.module.css'
|
||||||
import { useCancelToken } from '@hooks/useCancelToken'
|
import { useCancelToken } from '@hooks/useCancelToken'
|
||||||
@ -46,7 +46,7 @@ function DetailsAssets({ job }: { job: ComputeJobMetaData }) {
|
|||||||
const newCancelToken = useCancelToken()
|
const newCancelToken = useCancelToken()
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function getAlgoMetadata() {
|
async function getAlgoMetadata() {
|
||||||
const ddo = await retrieveDDO(job.algoDID, newCancelToken())
|
const ddo = await retrieveAsset(job.algoDID, newCancelToken())
|
||||||
setAlgoDtSymbol(ddo.datatokens[0].symbol)
|
setAlgoDtSymbol(ddo.datatokens[0].symbol)
|
||||||
setAlgoName(ddo?.metadata.name)
|
setAlgoName(ddo?.metadata.name)
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ export default function ComputeJobs({
|
|||||||
minimal?: boolean
|
minimal?: boolean
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { accountId, networkId } = useWeb3()
|
const { accountId, networkId } = useWeb3()
|
||||||
const { ddo } = useAsset()
|
const { assetExtended } = useAsset()
|
||||||
const { chainIds } = useUserPreferences()
|
const { chainIds } = useUserPreferences()
|
||||||
const [isLoading, setIsLoading] = useState(false)
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
const [jobs, setJobs] = useState<ComputeJobMetaData[]>([])
|
const [jobs, setJobs] = useState<ComputeJobMetaData[]>([])
|
||||||
@ -96,7 +96,7 @@ export default function ComputeJobs({
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
LoggerInstance.error(error.message)
|
LoggerInstance.error(error.message)
|
||||||
}
|
}
|
||||||
}, [chainIds, accountId, ddo, isMounted])
|
}, [chainIds, accountId, assetExtended, isMounted])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchJobs()
|
fetchJobs()
|
||||||
|
@ -9,7 +9,7 @@ const columns = [
|
|||||||
{
|
{
|
||||||
name: 'Data Set',
|
name: 'Data Set',
|
||||||
selector: function getAssetRow(row: DownloadedAsset) {
|
selector: function getAssetRow(row: DownloadedAsset) {
|
||||||
return <AssetTitle ddo={row.ddo} />
|
return <AssetTitle asset={row.asset} />
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -27,7 +27,7 @@ interface AssetPoolShare {
|
|||||||
poolShare: PoolShare
|
poolShare: PoolShare
|
||||||
networkId: number
|
networkId: number
|
||||||
createTime: number
|
createTime: number
|
||||||
ddo: Asset
|
asset: Asset
|
||||||
}
|
}
|
||||||
|
|
||||||
function Liquidity({ row, type }: { row: AssetPoolShare; type: string }) {
|
function Liquidity({ row, type }: { row: AssetPoolShare; type: string }) {
|
||||||
@ -83,7 +83,7 @@ const columns = [
|
|||||||
{
|
{
|
||||||
name: 'Data Set',
|
name: 'Data Set',
|
||||||
selector: function getAssetRow(row: AssetPoolShare) {
|
selector: function getAssetRow(row: AssetPoolShare) {
|
||||||
return <AssetTitle ddo={row.ddo} />
|
return <AssetTitle asset={row.asset} />
|
||||||
},
|
},
|
||||||
grow: 2
|
grow: 2
|
||||||
},
|
},
|
||||||
@ -140,7 +140,7 @@ async function getPoolSharesAssets(
|
|||||||
userLiquidity: userLiquidity,
|
userLiquidity: userLiquidity,
|
||||||
networkId: ddoList[i].chainId,
|
networkId: ddoList[i].chainId,
|
||||||
createTime: data[i].pool.createdTimestamp,
|
createTime: data[i].pool.createdTimestamp,
|
||||||
ddo: ddoList[i]
|
asset: ddoList[i]
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
const assets = assetList.sort((a, b) => b.createTime - a.createTime)
|
const assets = assetList.sort((a, b) => b.createTime - a.createTime)
|
||||||
|
@ -7,24 +7,34 @@ import { transformPublishFormToDdo } from '../_utils'
|
|||||||
import { Asset } from '@oceanprotocol/lib'
|
import { Asset } from '@oceanprotocol/lib'
|
||||||
|
|
||||||
export default function Preview(): ReactElement {
|
export default function Preview(): ReactElement {
|
||||||
const [ddo, setDdo] = useState<Asset>()
|
const [asset, setAsset] = useState<Asset>()
|
||||||
const [price, setPrice] = useState<BestPrice>()
|
const [accessDetails, setAccessDetails] = useState<AccessDetails>()
|
||||||
const { values } = useFormikContext<FormPublishData>()
|
const { values } = useFormikContext<FormPublishData>()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function makeDdo() {
|
async function makeDdo() {
|
||||||
const ddo = await transformPublishFormToDdo(values)
|
const asset = await transformPublishFormToDdo(values)
|
||||||
setDdo(ddo as Asset)
|
setAsset(asset as Asset)
|
||||||
|
|
||||||
// dummy BestPrice to trigger certain AssetActions
|
// dummy BestPrice to trigger certain AssetActions
|
||||||
const price: BestPrice = {
|
const accessDetails: AccessDetails = {
|
||||||
type: values.pricing.type,
|
type: values.pricing.type,
|
||||||
address: '0x...',
|
addressOrId: '0x...',
|
||||||
value: values.pricing.price,
|
price: values.pricing.price,
|
||||||
pools: [],
|
baseToken: {
|
||||||
oceanSymbol: 'OCEAN'
|
address: '0x..',
|
||||||
|
name: '',
|
||||||
|
symbol: ''
|
||||||
|
},
|
||||||
|
datatoken: {
|
||||||
|
address: '0x..',
|
||||||
|
name: '',
|
||||||
|
symbol: ''
|
||||||
|
},
|
||||||
|
owned: false,
|
||||||
|
validOrderTx: ''
|
||||||
}
|
}
|
||||||
setPrice(price)
|
setAccessDetails(accessDetails)
|
||||||
}
|
}
|
||||||
makeDdo()
|
makeDdo()
|
||||||
}, [values])
|
}, [values])
|
||||||
@ -34,7 +44,7 @@ export default function Preview(): ReactElement {
|
|||||||
<h2 className={styles.previewTitle}>Preview</h2>
|
<h2 className={styles.previewTitle}>Preview</h2>
|
||||||
|
|
||||||
<h3 className={styles.assetTitle}>{values.metadata.name}</h3>
|
<h3 className={styles.assetTitle}>{values.metadata.name}</h3>
|
||||||
<AssetContent ddo={ddo} price={price} />
|
<AssetContent asset={asset} accessDetails={accessDetails} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ export async function transformPublishFormToDdo(
|
|||||||
const did = nftAddress ? generateDid(nftAddress, chainId) : '0x...'
|
const did = nftAddress ? generateDid(nftAddress, chainId) : '0x...'
|
||||||
const currentTime = dateToStringNoMS(new Date())
|
const currentTime = dateToStringNoMS(new Date())
|
||||||
const isPreview = !datatokenAddress && !nftAddress
|
const isPreview = !datatokenAddress && !nftAddress
|
||||||
console.log('did', did, isPreview)
|
|
||||||
// Transform from files[0].url to string[] assuming only 1 file
|
// Transform from files[0].url to string[] assuming only 1 file
|
||||||
const filesTransformed = files?.length &&
|
const filesTransformed = files?.length &&
|
||||||
files[0].valid && [files[0].url.replace('javascript:', '')]
|
files[0].valid && [files[0].url.replace('javascript:', '')]
|
||||||
|
@ -6,7 +6,6 @@ import AssetProvider from '@context/Asset'
|
|||||||
export default function PageAssetDetails(): ReactElement {
|
export default function PageAssetDetails(): ReactElement {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const { did } = router.query
|
const { did } = router.query
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AssetProvider did={did as string}>
|
<AssetProvider did={did as string}>
|
||||||
<PageTemplateAssetDetails uri={router.pathname} />
|
<PageTemplateAssetDetails uri={router.pathname} />
|
||||||
|
@ -5,8 +5,8 @@ import { accountTruncate } from '@utils/web3'
|
|||||||
import { useWeb3 } from '@context/Web3'
|
import { useWeb3 } from '@context/Web3'
|
||||||
import ProfileProvider from '@context/Profile'
|
import ProfileProvider from '@context/Profile'
|
||||||
import { getEnsAddress, getEnsName } from '@utils/ens'
|
import { getEnsAddress, getEnsName } from '@utils/ens'
|
||||||
import ethereumAddress from 'ethereum-address'
|
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
|
import web3 from 'web3'
|
||||||
|
|
||||||
export default function PageProfile(): ReactElement {
|
export default function PageProfile(): ReactElement {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
@ -29,7 +29,7 @@ export default function PageProfile(): ReactElement {
|
|||||||
const pathAccount = router.query.account as string
|
const pathAccount = router.query.account as string
|
||||||
|
|
||||||
// Path has ETH addreess
|
// Path has ETH addreess
|
||||||
if (ethereumAddress.isAddress(pathAccount)) {
|
if (web3.utils.isAddress(pathAccount)) {
|
||||||
const finalAccountId = pathAccount || accountId
|
const finalAccountId = pathAccount || accountId
|
||||||
setFinalAccountId(finalAccountId)
|
setFinalAccountId(finalAccountId)
|
||||||
|
|
||||||
|
@ -2,9 +2,9 @@ import React, { ReactElement, useState } from 'react'
|
|||||||
import Search from '../components/Search'
|
import Search from '../components/Search'
|
||||||
import Page from '@shared/Page'
|
import Page from '@shared/Page'
|
||||||
import { accountTruncate } from '@utils/web3'
|
import { accountTruncate } from '@utils/web3'
|
||||||
import ethereumAddress from 'ethereum-address'
|
|
||||||
import { MAXIMUM_NUMBER_OF_PAGES_WITH_RESULTS } from '@utils/aquarius'
|
import { MAXIMUM_NUMBER_OF_PAGES_WITH_RESULTS } from '@utils/aquarius'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
|
import web3 from 'web3'
|
||||||
|
|
||||||
export default function PageSearch(): ReactElement {
|
export default function PageSearch(): ReactElement {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
@ -13,7 +13,7 @@ export default function PageSearch(): ReactElement {
|
|||||||
const [totalResults, setTotalResults] = useState<number>()
|
const [totalResults, setTotalResults] = useState<number>()
|
||||||
const [totalPagesNumber, setTotalPagesNumber] = useState<number>()
|
const [totalPagesNumber, setTotalPagesNumber] = useState<number>()
|
||||||
|
|
||||||
const isETHAddress = ethereumAddress.isAddress(text as string)
|
const isETHAddress = web3.utils.isAddress(text as string)
|
||||||
const searchValue =
|
const searchValue =
|
||||||
(isETHAddress ? accountTruncate(text as string) : text) ||
|
(isETHAddress ? accountTruncate(text as string) : text) ||
|
||||||
tags ||
|
tags ||
|
||||||
|
Loading…
x
Reference in New Issue
Block a user