diff --git a/example/src/App.tsx b/example/src/App.tsx index be35a7a..05baf6c 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -29,7 +29,7 @@ function App() { return (
- +
diff --git a/example/src/Publish.tsx b/example/src/Publish.tsx index 2fe0db4..6e59af5 100644 --- a/example/src/Publish.tsx +++ b/example/src/Publish.tsx @@ -5,7 +5,7 @@ import { useState } from 'react' export function Publish() { const { accountId } = useOcean() - const { publish } = usePublish() + const { publish, publishStepText } = usePublish() const [ddo, setDdo] = useState() const asset = { @@ -44,6 +44,7 @@ export function Publish() {
+
Status: {publishStepText}
DID: {ddo && ddo.id}
) diff --git a/src/hooks/usePublish/usePublish.ts b/src/hooks/usePublish/usePublish.ts index dd4ebe4..f85929b 100644 --- a/src/hooks/usePublish/usePublish.ts +++ b/src/hooks/usePublish/usePublish.ts @@ -1,12 +1,10 @@ -import { useEffect } from 'react' +import { useEffect, useState } from 'react' import { DDO, Metadata, DataTokens, Logger } from '@oceanprotocol/lib' import { useOcean } from '../../providers' import ProviderStatus from '../../providers/OceanProvider/ProviderStatus' -import { - Service, - ServiceType -} from '@oceanprotocol/lib/dist/node/ddo/interfaces/Service' +import { Service } from '@oceanprotocol/lib/dist/node/ddo/interfaces/Service' import { ServiceConfig } from './ServiceConfig' +import { publishFeedback } from '../../utils' interface UsePublish { publish: ( @@ -16,79 +14,109 @@ interface UsePublish { serviceConfigs: ServiceConfig[] ) => Promise mint: (tokenAddress: string, tokensToMint: string) => void + giveMarketAllowance: ( + tokenAddress: string, + marketAddress: string, + tokens: string + ) => void + publishStep?: number + publishStepText?: string + publishError?: string + isLoading: boolean } function usePublish(): UsePublish { const { web3, ocean, status, account, accountId, config } = useOcean() + const [isLoading, setIsLoading] = useState(false) + const [publishStep, setPublishStep] = useState() + const [publishStepText, setPublishStepText] = useState() + const [publishError, setPublishError] = useState() - function createDataToken() { - return new DataTokens( - ocean.datatokens.factoryAddress, - ocean.datatokens.factoryABI.abi, - ocean.datatokens.datatokensABI.abi, - web3 - ) + function setStep(index: number) { + setPublishStep(index) + setPublishStepText(publishFeedback[index]) } + /** + * 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} Returns the newly published ddo + */ async function publish( asset: Metadata, tokensToMint: string, marketAddress: string, serviceConfigs: ServiceConfig[] ): Promise { - if (status !== ProviderStatus.CONNECTED) return + 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) - Logger.log('ocean dt', ocean.datatokens) - 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) - Logger.log('tokens to mint', tokensToMint) + setStep(1) + await mint(tokenAddress, tokensToMint) + Logger.log(`minted ${tokensToMint} tokens`) - await mint(tokenAddress, tokensToMint) - - Logger.log('giving allowance to ', marketAddress) - await giveMarketAllowance(tokenAddress, marketAddress, tokensToMint) - Logger.log('tokenAddress created', tokenAddress) - const publishedDate = new Date(Date.now()).toISOString().split('.')[0] + 'Z' - const timeout = 0 - const services: Service[] = [] - - 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 + 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 + } } - case 'compute': { - const computeService = await ocean.assets.createAccessServiceAttributes( - account, - price, - publishedDate, - 0 - ) - services.push(computeService) - break - } - } - }) + }) + Logger.log('services created', services) + setStep(4) + const ddo = await ocean.assets.create( + asset, + account, + services, + tokenAddress + ) + setStep(5) - const ddo = await ocean.assets.create( - asset, - account, - services, - tokenAddress - ) - - return ddo + return ddo + } catch (error) { + setPublishError(error.message) + Logger.error(error) + setStep(undefined) + } finally { + setIsLoading(false) + } } async function mint(tokenAddress: string, tokensToMint: string) { @@ -111,7 +139,12 @@ function usePublish(): UsePublish { return { publish, - mint + mint, + giveMarketAllowance, + publishStep, + publishStepText, + isLoading, + publishError } } diff --git a/src/providers/OceanProvider/OceanProvider.tsx b/src/providers/OceanProvider/OceanProvider.tsx index bb96f73..b48cbf5 100644 --- a/src/providers/OceanProvider/OceanProvider.tsx +++ b/src/providers/OceanProvider/OceanProvider.tsx @@ -36,7 +36,10 @@ function OceanProvider({ const [account, setAccount] = useState() const [accountId, setAccountId] = useState() const [balance, setBalance] = useState() - const [status, setStatus] = useState(ProviderStatus.NOT_AVAILABLE) + const [status, setStatus] = useState( + ProviderStatus.NOT_AVAILABLE + ) + const [web3ModalOpts, setWeb3ModalOpts] = useState>() function init() { Logger.log('Ocean Provider init') @@ -64,10 +67,6 @@ function OceanProvider({ const web3 = new Web3(provider) setWeb3(web3) - // const factory = require('@oceanprotocol/contracts/artifacts/development/Factory.json') - // const datatokensTemplate = require('@oceanprotocol/contracts/artifacts/development/DataTokenTemplate.json') - // config.factoryABI = factory.abi - // config.datatokensABI = datatokensTemplate.abi config.web3Provider = web3 const ocean = await Ocean.getInstance(config) @@ -115,22 +114,29 @@ function OceanProvider({ const handleAccountsChanged = async (accounts: string[]) => { console.debug("Handling 'accountsChanged' event with payload", accounts) - if (accounts.length > 0) { - setAccountId(accounts[0]) - - if (web3) { - const balance = await getBalance(web3, accounts[0]) - setBalance(balance) - } + if (status === ProviderStatus.CONNECTED) { + connect(web3ModalOpts) } + // if (accounts.length > 0) { + // setAccountId(accounts[0]) + + // if (web3) { + // const balance = await getBalance(web3, accounts[0]) + // setBalance(balance) + // } + // } } // ToDo need to handle this, it's not implemented, need to update chainId and reinitialize ocean lib const handleNetworkChanged = async (networkId: string | number) => { - console.debug("Handling 'networkChanged' event with payload", networkId) - web3Provider.autoRefreshOnNetworkChange = false - // init(networkId) - // handleConnect(ethProvider) + console.debug( + "Handling 'networkChanged' event with payload", + networkId, + status + ) + if (status === ProviderStatus.CONNECTED) { + connect(web3ModalOpts) + } } useEffect(() => { @@ -145,7 +151,7 @@ function OceanProvider({ web3Provider.removeListener('networkChanged', handleNetworkChanged) } } - }, [web3, web3Modal, web3Provider]) + }, [web3Modal, web3Provider]) return (