react/src/hooks/usePublish/usePublish.ts

153 lines
4.5 KiB
TypeScript
Raw Normal View History

2020-07-17 12:24:46 +02:00
import { useEffect, useState } from 'react'
2020-07-13 11:57:27 +02:00
import { DDO, Metadata, DataTokens, Logger } from '@oceanprotocol/lib'
2020-07-14 13:34:08 +02:00
import { useOcean } from '../../providers'
2020-07-09 14:33:22 +02:00
import ProviderStatus from '../../providers/OceanProvider/ProviderStatus'
2020-07-17 12:24:46 +02:00
import { Service } from '@oceanprotocol/lib/dist/node/ddo/interfaces/Service'
2020-07-16 16:03:26 +02:00
import { ServiceConfig } from './ServiceConfig'
2020-07-17 12:24:46 +02:00
import { publishFeedback } from '../../utils'
2020-07-09 14:33:22 +02:00
interface UsePublish {
2020-07-14 13:34:08 +02:00
publish: (
asset: Metadata,
2020-07-16 11:25:01 +02:00
tokensToMint: string,
2020-07-15 11:18:22 +02:00
marketAddress: string,
2020-07-16 16:03:26 +02:00
serviceConfigs: ServiceConfig[]
2020-07-14 13:34:08 +02:00
) => Promise<DDO>
2020-07-16 11:25:01 +02:00
mint: (tokenAddress: string, tokensToMint: string) => void
2020-07-17 12:24:46 +02:00
giveMarketAllowance: (
tokenAddress: string,
marketAddress: string,
tokens: string
) => void
publishStep?: number
publishStepText?: string
publishError?: string
isLoading: boolean
2020-07-09 14:33:22 +02:00
}
function usePublish(): UsePublish {
2020-07-14 13:34:08 +02:00
const { web3, ocean, status, account, accountId, config } = useOcean()
2020-07-17 12:24:46 +02:00
const [isLoading, setIsLoading] = useState(false)
const [publishStep, setPublishStep] = useState<number | undefined>()
const [publishStepText, setPublishStepText] = useState<string | undefined>()
const [publishError, setPublishError] = useState<string | undefined>()
2020-07-14 13:34:08 +02:00
2020-07-17 12:24:46 +02:00
function setStep(index: number) {
setPublishStep(index)
setPublishStepText(publishFeedback[index])
2020-07-16 11:25:01 +02:00
}
2020-07-17 12:24:46 +02:00
/**
* Publish an asset.It also creates the datatoken, mints tokens and gives the market allowance
* @param {Metadata} asset The metadata of the asset.
* @param {string} tokensToMint Numer of tokens to mint and give allowance to market
* @param {string} marketAddress The address of the market
* @param {ServiceConfig[]} serviceConfigs Desired services of the asset, ex: [{serviceType: 'access', cost:'1'}]
* @return {Promise<DDO>} Returns the newly published ddo
*/
2020-07-14 13:34:08 +02:00
async function publish(
asset: Metadata,
2020-07-16 11:25:01 +02:00
tokensToMint: string,
2020-07-15 11:18:22 +02:00
marketAddress: string,
2020-07-16 16:03:26 +02:00
serviceConfigs: ServiceConfig[]
2020-07-14 13:34:08 +02:00
): Promise<DDO> {
2020-07-17 12:24:46 +02:00
if (status !== ProviderStatus.CONNECTED || !ocean || !account) return
setIsLoading(true)
setPublishError(undefined)
try {
setStep(0)
const data = { t: 1, url: config.metadataStoreUri }
const blob = JSON.stringify(data)
const tokenAddress = await ocean.datatokens.create(blob, accountId)
Logger.log('datatoken created', tokenAddress)
2020-07-14 13:34:08 +02:00
2020-07-17 12:24:46 +02:00
setStep(1)
await mint(tokenAddress, tokensToMint)
Logger.log(`minted ${tokensToMint} tokens`)
2020-07-14 13:34:08 +02:00
2020-07-17 12:24:46 +02:00
setStep(2)
await giveMarketAllowance(tokenAddress, marketAddress, tokensToMint)
Logger.log('allowance to market', marketAddress)
const publishedDate =
new Date(Date.now()).toISOString().split('.')[0] + 'Z'
const timeout = 0
const services: Service[] = []
setStep(3)
serviceConfigs.forEach(async (serviceConfig) => {
const price = ocean.datatokens.toWei(serviceConfig.cost)
switch (serviceConfig.serviceType) {
case 'access': {
const accessService = await ocean.assets.createAccessServiceAttributes(
account,
price,
publishedDate,
timeout
)
Logger.log('access service created', accessService)
services.push(accessService)
break
}
case 'compute': {
const computeService = await ocean.assets.createAccessServiceAttributes(
account,
price,
publishedDate,
0
)
services.push(computeService)
break
}
2020-07-16 16:03:26 +02:00
}
2020-07-17 12:24:46 +02:00
})
Logger.log('services created', services)
setStep(4)
const ddo = await ocean.assets.create(
asset,
account,
services,
tokenAddress
)
setStep(5)
2020-07-14 13:34:08 +02:00
2020-07-17 12:24:46 +02:00
return ddo
} catch (error) {
setPublishError(error.message)
Logger.error(error)
setStep(undefined)
} finally {
setIsLoading(false)
}
2020-07-14 13:34:08 +02:00
}
2020-07-16 16:03:26 +02:00
async function mint(tokenAddress: string, tokensToMint: string) {
2020-07-16 11:25:01 +02:00
Logger.log('mint function', tokenAddress, accountId)
2020-07-16 16:03:26 +02:00
await ocean.datatokens.mint(tokenAddress, accountId, tokensToMint)
2020-07-14 13:34:08 +02:00
}
async function giveMarketAllowance(
tokenAddress: string,
marketAddress: string,
2020-07-16 16:03:26 +02:00
tokens: string
2020-07-14 13:34:08 +02:00
) {
2020-07-16 16:03:26 +02:00
await ocean.datatokens.approve(
tokenAddress,
marketAddress,
tokens,
accountId
)
2020-07-14 13:34:08 +02:00
}
return {
publish,
2020-07-17 12:24:46 +02:00
mint,
giveMarketAllowance,
publishStep,
publishStepText,
isLoading,
publishError
2020-07-14 13:34:08 +02:00
}
2020-07-09 14:33:22 +02:00
}
export { usePublish, UsePublish }
export default usePublish