2022-02-14 17:27:36 +01:00
|
|
|
import React, { ReactElement, useEffect, useState } from 'react'
|
|
|
|
import FileIcon from '@shared/FileIcon'
|
|
|
|
import Price from '@shared/Price'
|
|
|
|
import { useAsset } from '@context/Asset'
|
|
|
|
import { useWeb3 } from '@context/Web3'
|
|
|
|
import ButtonBuy from '@shared/ButtonBuy'
|
|
|
|
import { secondsToString } from '@utils/ddo'
|
|
|
|
import AlgorithmDatasetsListForCompute from './Compute/AlgorithmDatasetsListForCompute'
|
|
|
|
import styles from './Download.module.css'
|
2022-03-23 14:30:03 +01:00
|
|
|
import { FileMetadata, LoggerInstance, ZERO_ADDRESS } from '@oceanprotocol/lib'
|
2022-02-14 17:27:36 +01:00
|
|
|
import { order } from '@utils/order'
|
|
|
|
import { AssetExtended } from 'src/@types/AssetExtended'
|
2022-02-25 11:36:32 +01:00
|
|
|
import { buyDtFromPool } from '@utils/pool'
|
2022-02-14 17:27:36 +01:00
|
|
|
import { downloadFile } from '@utils/provider'
|
2022-03-23 14:30:03 +01:00
|
|
|
import { getOrderFeedback } from '@utils/feedback'
|
2022-02-14 17:27:36 +01:00
|
|
|
import { getOrderPriceAndFees } from '@utils/accessDetailsAndPricing'
|
|
|
|
import { OrderPriceAndFees } from 'src/@types/Price'
|
|
|
|
import { toast } from 'react-toastify'
|
|
|
|
|
|
|
|
export default function Download({
|
|
|
|
asset,
|
|
|
|
file,
|
|
|
|
isBalanceSufficient,
|
|
|
|
dtBalance,
|
|
|
|
fileIsLoading,
|
|
|
|
consumableFeedback
|
|
|
|
}: {
|
|
|
|
asset: AssetExtended
|
|
|
|
file: FileMetadata
|
|
|
|
isBalanceSufficient: boolean
|
|
|
|
dtBalance: string
|
|
|
|
fileIsLoading?: boolean
|
|
|
|
consumableFeedback?: string
|
|
|
|
}): ReactElement {
|
|
|
|
const { accountId, web3 } = useWeb3()
|
|
|
|
const { isInPurgatory, isAssetNetwork } = useAsset()
|
|
|
|
const [isDisabled, setIsDisabled] = useState(true)
|
|
|
|
const [hasDatatoken, setHasDatatoken] = useState(false)
|
|
|
|
const [statusText, setStatusText] = useState('')
|
|
|
|
const [isLoading, setIsLoading] = useState(false)
|
|
|
|
const [isOwned, setIsOwned] = useState(false)
|
|
|
|
const [validOrderTx, setValidOrderTx] = useState('')
|
2022-03-23 14:30:03 +01:00
|
|
|
|
2022-02-14 17:27:36 +01:00
|
|
|
const [orderPriceAndFees, setOrderPriceAndFees] =
|
|
|
|
useState<OrderPriceAndFees>()
|
|
|
|
useEffect(() => {
|
|
|
|
if (!asset?.accessDetails) return
|
|
|
|
|
|
|
|
setIsOwned(asset?.accessDetails?.isOwned)
|
|
|
|
setValidOrderTx(asset?.accessDetails?.validOrderTx)
|
|
|
|
// get full price and fees
|
|
|
|
async function init() {
|
2022-03-18 14:22:26 +01:00
|
|
|
if (
|
|
|
|
asset?.accessDetails?.addressOrId === ZERO_ADDRESS ||
|
|
|
|
asset?.accessDetails?.type === 'free'
|
|
|
|
)
|
|
|
|
return
|
2022-02-14 17:27:36 +01:00
|
|
|
setIsLoading(true)
|
|
|
|
setStatusText('Calculating price including fees.')
|
|
|
|
const orderPriceAndFees = await getOrderPriceAndFees(asset, ZERO_ADDRESS)
|
|
|
|
setOrderPriceAndFees(orderPriceAndFees)
|
|
|
|
|
|
|
|
setIsLoading(false)
|
|
|
|
}
|
|
|
|
|
|
|
|
init()
|
|
|
|
}, [asset, accountId])
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
setHasDatatoken(Number(dtBalance) >= 1)
|
|
|
|
}, [dtBalance])
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
if (!accountId || !asset?.accessDetails) return
|
|
|
|
setIsDisabled(
|
|
|
|
!asset?.accessDetails.isPurchasable ||
|
|
|
|
((!isBalanceSufficient || !isAssetNetwork) && !isOwned && !hasDatatoken)
|
|
|
|
)
|
|
|
|
}, [
|
|
|
|
asset?.accessDetails,
|
|
|
|
isBalanceSufficient,
|
|
|
|
isAssetNetwork,
|
|
|
|
hasDatatoken,
|
|
|
|
accountId,
|
|
|
|
isOwned
|
|
|
|
])
|
|
|
|
|
|
|
|
async function handleOrderOrDownload() {
|
|
|
|
setIsLoading(true)
|
2022-03-23 15:59:57 +01:00
|
|
|
try {
|
|
|
|
if (isOwned) {
|
|
|
|
setStatusText(
|
|
|
|
getOrderFeedback(
|
|
|
|
asset.accessDetails?.baseToken?.symbol,
|
|
|
|
asset.accessDetails?.datatoken?.symbol
|
|
|
|
)[3]
|
|
|
|
)
|
|
|
|
|
|
|
|
await downloadFile(web3, asset, accountId, validOrderTx)
|
|
|
|
} else {
|
2022-02-14 17:27:36 +01:00
|
|
|
if (!hasDatatoken && asset.accessDetails.type === 'dynamic') {
|
|
|
|
setStatusText(
|
|
|
|
getOrderFeedback(
|
|
|
|
asset.accessDetails.baseToken?.symbol,
|
|
|
|
asset.accessDetails.datatoken?.symbol
|
|
|
|
)[0]
|
|
|
|
)
|
|
|
|
const tx = await buyDtFromPool(asset.accessDetails, accountId, web3)
|
|
|
|
if (!tx) {
|
2022-03-23 15:59:57 +01:00
|
|
|
throw new Error()
|
2022-02-14 17:27:36 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
setStatusText(
|
|
|
|
getOrderFeedback(
|
|
|
|
asset.accessDetails.baseToken?.symbol,
|
|
|
|
asset.accessDetails.datatoken?.symbol
|
|
|
|
)[asset.accessDetails?.type === 'fixed' ? 2 : 1]
|
|
|
|
)
|
|
|
|
const orderTx = await order(web3, asset, orderPriceAndFees, accountId)
|
2022-03-11 12:25:51 +01:00
|
|
|
if (!orderTx) {
|
2022-03-23 15:59:57 +01:00
|
|
|
throw new Error()
|
2022-03-11 12:25:51 +01:00
|
|
|
}
|
2022-02-14 17:27:36 +01:00
|
|
|
setIsOwned(true)
|
|
|
|
setValidOrderTx(orderTx.transactionHash)
|
|
|
|
}
|
2022-03-23 15:59:57 +01:00
|
|
|
} catch (error) {
|
|
|
|
LoggerInstance.error(error)
|
|
|
|
const message = isOwned
|
|
|
|
? 'Failed to download file!'
|
|
|
|
: 'Failed to buy datatoken from pool!'
|
|
|
|
toast.error(message)
|
2022-02-14 17:27:36 +01:00
|
|
|
}
|
|
|
|
setIsLoading(false)
|
|
|
|
}
|
|
|
|
|
|
|
|
const PurchaseButton = () => (
|
|
|
|
<ButtonBuy
|
|
|
|
action="download"
|
|
|
|
disabled={isDisabled}
|
|
|
|
hasPreviousOrder={isOwned}
|
|
|
|
hasDatatoken={hasDatatoken}
|
|
|
|
dtSymbol={asset?.datatokens[0]?.symbol}
|
|
|
|
dtBalance={dtBalance}
|
|
|
|
datasetLowPoolLiquidity={!asset.accessDetails?.isPurchasable}
|
|
|
|
onClick={handleOrderOrDownload}
|
|
|
|
assetTimeout={secondsToString(asset.services[0].timeout)}
|
|
|
|
assetType={asset?.metadata?.type}
|
|
|
|
stepText={statusText}
|
|
|
|
// isLoading={pricingIsLoading || isLoading}
|
|
|
|
isLoading={isLoading}
|
|
|
|
priceType={asset.accessDetails?.type}
|
|
|
|
isConsumable={asset.accessDetails?.isPurchasable}
|
|
|
|
isBalanceSufficient={isBalanceSufficient}
|
|
|
|
consumableFeedback={consumableFeedback}
|
|
|
|
/>
|
|
|
|
)
|
|
|
|
|
|
|
|
return (
|
|
|
|
<aside className={styles.consume}>
|
|
|
|
<div className={styles.info}>
|
|
|
|
<div className={styles.filewrapper}>
|
|
|
|
<FileIcon file={file} isLoading={fileIsLoading} />
|
|
|
|
</div>
|
|
|
|
<div className={styles.pricewrapper}>
|
|
|
|
<Price
|
|
|
|
accessDetails={asset.accessDetails}
|
|
|
|
orderPriceAndFees={orderPriceAndFees}
|
|
|
|
conversion
|
2022-03-09 13:58:54 +01:00
|
|
|
size="large"
|
2022-02-14 17:27:36 +01:00
|
|
|
/>
|
|
|
|
{!isInPurgatory && <PurchaseButton />}
|
|
|
|
</div>
|
|
|
|
</div>
|
2022-03-09 15:12:37 +01:00
|
|
|
|
2022-02-14 17:27:36 +01:00
|
|
|
{asset?.metadata?.type === 'algorithm' && (
|
|
|
|
<AlgorithmDatasetsListForCompute
|
|
|
|
algorithmDid={asset.id}
|
|
|
|
asset={asset}
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
</aside>
|
|
|
|
)
|
|
|
|
}
|