mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
prototype feedback data structure & flow
This commit is contained in:
parent
453458814e
commit
245a604a99
@ -2,12 +2,17 @@ import { ReactElement, useEffect } from 'react'
|
||||
import { useFormikContext } from 'formik'
|
||||
import { wizardSteps } from './_constants'
|
||||
import { useWeb3 } from '@context/Web3'
|
||||
import { FormPublishData } from './_types'
|
||||
import { FormPublishData, PublishFeedback } from './_types'
|
||||
|
||||
export function Steps(): ReactElement {
|
||||
export function Steps({
|
||||
feedback
|
||||
}: {
|
||||
feedback: PublishFeedback
|
||||
}): ReactElement {
|
||||
const { chainId, accountId } = useWeb3()
|
||||
const { values, setFieldValue } = useFormikContext<FormPublishData>()
|
||||
|
||||
// auto-sync user chainId & account into form data values
|
||||
useEffect(() => {
|
||||
if (!chainId || !accountId) return
|
||||
|
||||
@ -15,6 +20,11 @@ export function Steps(): ReactElement {
|
||||
setFieldValue('user.accountId', accountId)
|
||||
}, [chainId, accountId, setFieldValue])
|
||||
|
||||
// auto-sync publish feedback into form data values
|
||||
useEffect(() => {
|
||||
setFieldValue('feedback', feedback)
|
||||
}, [feedback, setFieldValue])
|
||||
|
||||
const { component } = wizardSteps.filter(
|
||||
(stepContent) => stepContent.step === values.user.stepCurrent
|
||||
)[0]
|
||||
|
18
src/components/Publish/Submission/Feedback.tsx
Normal file
18
src/components/Publish/Submission/Feedback.tsx
Normal file
@ -0,0 +1,18 @@
|
||||
import { ListItem } from '@shared/atoms/Lists'
|
||||
import { useFormikContext } from 'formik'
|
||||
import React, { ReactElement } from 'react'
|
||||
import { FormPublishData } from '../_types'
|
||||
|
||||
export function Feedback(): ReactElement {
|
||||
const { values } = useFormikContext<FormPublishData>()
|
||||
|
||||
const items = Object.entries(values.feedback).map(([key, value], index) => {
|
||||
return (
|
||||
<ListItem ol key={index}>
|
||||
{value.name}
|
||||
</ListItem>
|
||||
)
|
||||
})
|
||||
|
||||
return <ol>{items}</ol>
|
||||
}
|
@ -2,6 +2,7 @@ import React, { ReactElement } from 'react'
|
||||
import styles from './index.module.css'
|
||||
import { FormPublishData } from '../_types'
|
||||
import { useFormikContext } from 'formik'
|
||||
import { Feedback } from './Feedback'
|
||||
|
||||
export default function Submission(): ReactElement {
|
||||
const { values, handleSubmit } = useFormikContext<FormPublishData>()
|
||||
@ -12,6 +13,7 @@ export default function Submission(): ReactElement {
|
||||
Place to teach about what happens next, output all the steps in background
|
||||
in some list, after submission continously update this list with the
|
||||
status of the submission.
|
||||
<Feedback />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ export interface FormPublishData {
|
||||
}
|
||||
services: FormPublishService[]
|
||||
pricing: PriceOptions
|
||||
feedback?: PublishFeedback
|
||||
}
|
||||
|
||||
export interface StepContent {
|
||||
@ -50,3 +51,11 @@ export interface StepContent {
|
||||
title: string
|
||||
component: ReactElement
|
||||
}
|
||||
|
||||
export interface PublishFeedback {
|
||||
[key: number]: {
|
||||
name: string
|
||||
status: 'success' | 'error' | 'pending'
|
||||
message?: string
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ import Actions from './Actions'
|
||||
import Debug from './Debug'
|
||||
import Navigation from './Navigation'
|
||||
import { Steps } from './Steps'
|
||||
import { FormPublishData } from './_types'
|
||||
import { FormPublishData, PublishFeedback } from './_types'
|
||||
import { useUserPreferences } from '@context/UserPreferences'
|
||||
import useNftFactory from '@hooks/contracts/useNftFactory'
|
||||
import { Nft, getHash, ProviderInstance } from '@oceanprotocol/lib'
|
||||
@ -32,22 +32,33 @@ export default function PublishPage({
|
||||
const { debug } = useUserPreferences()
|
||||
const { accountId, web3, chainId } = useWeb3()
|
||||
const { isInPurgatory, purgatoryData } = useAccountPurgatory(accountId)
|
||||
|
||||
// TODO: success & error states need to be handled for each step we want to display
|
||||
// most likely with a nested data structure.
|
||||
const [success, setSuccess] = useState<string>()
|
||||
const [error, setError] = useState<string>()
|
||||
const scrollToRef = useRef()
|
||||
const { appConfig } = useSiteMetadata()
|
||||
const nftFactory = useNftFactory()
|
||||
const newCancelToken = useCancelToken()
|
||||
|
||||
async function handleSubmit(values: FormPublishData) {
|
||||
try {
|
||||
// --------------------------------------------------
|
||||
// 1. Create NFT & datatokens & create pricing schema
|
||||
// --------------------------------------------------
|
||||
const [feedback, setFeedback] = useState<PublishFeedback>({
|
||||
1: {
|
||||
name: 'Create Tokens & Pricing',
|
||||
status: 'pending'
|
||||
},
|
||||
2: {
|
||||
name: 'Encrypt DDO',
|
||||
status: 'pending'
|
||||
},
|
||||
3: {
|
||||
name: 'Publish DDO',
|
||||
status: 'pending'
|
||||
}
|
||||
})
|
||||
|
||||
async function handleSubmit(values: FormPublishData) {
|
||||
let _erc721Address, _datatokenAddress, _ddo, _encryptedDdo
|
||||
|
||||
// --------------------------------------------------
|
||||
// 1. Create NFT & datatokens & create pricing schema
|
||||
// --------------------------------------------------
|
||||
try {
|
||||
const config = getOceanConfig(chainId)
|
||||
console.log('config', config)
|
||||
|
||||
@ -60,16 +71,41 @@ export default function PublishPage({
|
||||
web3
|
||||
)
|
||||
|
||||
// --------------------------------------------------
|
||||
// 2. Construct and publish DDO
|
||||
// --------------------------------------------------
|
||||
const isSuccess = erc721Address && datatokenAddress
|
||||
_erc721Address = erc721Address
|
||||
_datatokenAddress = datatokenAddress
|
||||
|
||||
setFeedback({
|
||||
...feedback,
|
||||
1: {
|
||||
...feedback[1],
|
||||
status: isSuccess ? 'success' : 'error'
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('error', error.message)
|
||||
setFeedback({
|
||||
...feedback,
|
||||
1: {
|
||||
...feedback[1],
|
||||
status: 'error',
|
||||
message: error.message
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
// 2. Construct and encypt DDO
|
||||
// --------------------------------------------------
|
||||
try {
|
||||
const ddo = await transformPublishFormToDdo(
|
||||
values,
|
||||
datatokenAddress,
|
||||
erc721Address
|
||||
_datatokenAddress,
|
||||
_erc721Address
|
||||
)
|
||||
|
||||
_ddo = ddo
|
||||
|
||||
const encryptedResponse = await ProviderInstance.encrypt(
|
||||
ddo,
|
||||
values.services[0].providerUrl.url,
|
||||
@ -82,84 +118,123 @@ export default function PublishPage({
|
||||
})
|
||||
}
|
||||
)
|
||||
const encryptedDddo = encryptedResponse.data
|
||||
const encryptedDdo = encryptedResponse.data
|
||||
|
||||
_encryptedDdo = encryptedDdo
|
||||
|
||||
console.log('ddo', JSON.stringify(ddo))
|
||||
|
||||
setFeedback({
|
||||
...feedback,
|
||||
2: {
|
||||
...feedback[2],
|
||||
status: encryptedDdo ? 'success' : 'error'
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('error', error.message)
|
||||
setFeedback({
|
||||
...feedback,
|
||||
2: {
|
||||
...feedback[2],
|
||||
status: 'error',
|
||||
message: error.message
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
// 3. Publish DDO
|
||||
// --------------------------------------------------
|
||||
try {
|
||||
// TODO: this whole setMetadata needs to go in a function ,too many hardcoded/calculated params
|
||||
// TODO: hash generation : this needs to be moved in a function (probably on ocean.js) after we figure out what is going on in provider, leave it here for now
|
||||
const metadataHash = getHash(JSON.stringify(ddo))
|
||||
const metadataHash = getHash(JSON.stringify(_ddo))
|
||||
const nft = new Nft(web3)
|
||||
|
||||
// theoretically used by aquarius or provider, not implemented yet, will remain hardcoded
|
||||
const flags = '0x2'
|
||||
|
||||
const res = await nft.setMetadata(
|
||||
erc721Address,
|
||||
_erc721Address,
|
||||
accountId,
|
||||
0,
|
||||
config.providerUri,
|
||||
values.services[0].providerUrl.url,
|
||||
'',
|
||||
flags,
|
||||
encryptedDddo,
|
||||
_encryptedDdo,
|
||||
'0x' + metadataHash
|
||||
)
|
||||
|
||||
console.log('result', res)
|
||||
|
||||
// --------------------------------------------------
|
||||
// 3. Integrity check of DDO before & after publishing
|
||||
// --------------------------------------------------
|
||||
|
||||
// TODO: not sure we want to do this at this step, seems overkill
|
||||
|
||||
// if we want to do this we just need to fetch it from aquarius. If we want to fetch from chain and decrypt, we would have more metamask pop-ups (not UX friendly)
|
||||
// decrypt also validates the checksum
|
||||
|
||||
// TODO: remove the commented lines of code until `setSuccess`, didn't remove them yet because maybe i missed something
|
||||
|
||||
// --------------------------------------------------
|
||||
// 1. Mint NFT & datatokens & put in pool
|
||||
// --------------------------------------------------
|
||||
// const nftOptions = values.metadata.nft
|
||||
// const nftCreateData = generateNftCreateData(nftOptions)
|
||||
|
||||
// figure out syntax of ercParams we most likely need to pass
|
||||
// to createNftWithErc() as we need to pass options for the datatoken.
|
||||
// const ercParams = {}
|
||||
// const priceOptions = {
|
||||
// // swapFee is tricky: to get 0.1% you need to send 0.001 as value
|
||||
// swapFee: `${values.pricing.swapFee / 100}`
|
||||
// }
|
||||
// const txMint = await createNftWithErc(accountId, nftCreateData)
|
||||
|
||||
// figure out how to get nftAddress & datatokenAddress from tx log.
|
||||
// const { nftAddress, datatokenAddress } = txMint.logs[0].args
|
||||
// if (!nftAddress || !datatokenAddress) { throw new Error() }
|
||||
//
|
||||
// --------------------------------------------------
|
||||
// 2. Construct and publish DDO
|
||||
// --------------------------------------------------
|
||||
// const did = sha256(`${nftAddress}${chainId}`)
|
||||
// const ddo = transformPublishFormToDdo(values, datatokenAddress, nftAddress)
|
||||
// const txPublish = await publish(ddo)
|
||||
//
|
||||
// --------------------------------------------------
|
||||
// 3. Integrity check of DDO before & after publishing
|
||||
// --------------------------------------------------
|
||||
// const checksumBefore = sha256(ddo)
|
||||
// const ddoFromChain = await getDdoFromChain(ddo.id)
|
||||
// const ddoFromChainDecrypted = await decryptDdo(ddoFromChain)
|
||||
// const checksumAfter = sha256(ddoFromChainDecrypted)
|
||||
|
||||
// if (checksumBefore !== checksumAfter) {
|
||||
// throw new Error('DDO integrity check failed!')
|
||||
// }
|
||||
setSuccess('Your DDO was published successfully!')
|
||||
setFeedback({
|
||||
...feedback,
|
||||
3: {
|
||||
...feedback[3],
|
||||
status: res ? 'success' : 'error'
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
setError(error.message)
|
||||
console.log('err', error)
|
||||
console.error('error', error.message)
|
||||
setFeedback({
|
||||
...feedback,
|
||||
3: {
|
||||
...feedback[3],
|
||||
status: 'error',
|
||||
message: error.message
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
// 3. Integrity check of DDO before & after publishing
|
||||
// --------------------------------------------------
|
||||
|
||||
// TODO: not sure we want to do this at this step, seems overkill
|
||||
|
||||
// if we want to do this we just need to fetch it from aquarius. If we want to fetch from chain and decrypt, we would have more metamask pop-ups (not UX friendly)
|
||||
// decrypt also validates the checksum
|
||||
|
||||
// TODO: remove the commented lines of code until `setSuccess`, didn't remove them yet because maybe i missed something
|
||||
|
||||
// --------------------------------------------------
|
||||
// 1. Mint NFT & datatokens & put in pool
|
||||
// --------------------------------------------------
|
||||
// const nftOptions = values.metadata.nft
|
||||
// const nftCreateData = generateNftCreateData(nftOptions)
|
||||
|
||||
// figure out syntax of ercParams we most likely need to pass
|
||||
// to createNftWithErc() as we need to pass options for the datatoken.
|
||||
// const ercParams = {}
|
||||
// const priceOptions = {
|
||||
// // swapFee is tricky: to get 0.1% you need to send 0.001 as value
|
||||
// swapFee: `${values.pricing.swapFee / 100}`
|
||||
// }
|
||||
// const txMint = await createNftWithErc(accountId, nftCreateData)
|
||||
|
||||
// figure out how to get nftAddress & datatokenAddress from tx log.
|
||||
// const { nftAddress, datatokenAddress } = txMint.logs[0].args
|
||||
// if (!nftAddress || !datatokenAddress) { throw new Error() }
|
||||
//
|
||||
// --------------------------------------------------
|
||||
// 2. Construct and publish DDO
|
||||
// --------------------------------------------------
|
||||
// const did = sha256(`${nftAddress}${chainId}`)
|
||||
// const ddo = transformPublishFormToDdo(values, datatokenAddress, nftAddress)
|
||||
// const txPublish = await publish(ddo)
|
||||
//
|
||||
// --------------------------------------------------
|
||||
// 3. Integrity check of DDO before & after publishing
|
||||
// --------------------------------------------------
|
||||
// const checksumBefore = sha256(ddo)
|
||||
// const ddoFromChain = await getDdoFromChain(ddo.id)
|
||||
// const ddoFromChainDecrypted = await decryptDdo(ddoFromChain)
|
||||
// const checksumAfter = sha256(ddoFromChainDecrypted)
|
||||
|
||||
// if (checksumBefore !== checksumAfter) {
|
||||
// throw new Error('DDO integrity check failed!')
|
||||
// }
|
||||
}
|
||||
|
||||
return isInPurgatory && purgatoryData ? null : (
|
||||
@ -179,7 +254,7 @@ export default function PublishPage({
|
||||
/>
|
||||
<Form className={styles.form} ref={scrollToRef}>
|
||||
<Navigation />
|
||||
<Steps />
|
||||
<Steps feedback={feedback} />
|
||||
<Actions scrollToRef={scrollToRef} />
|
||||
</Form>
|
||||
{debug && <Debug />}
|
||||
|
Loading…
Reference in New Issue
Block a user