1
0
mirror of https://github.com/oceanprotocol/market.git synced 2024-12-02 05:57:29 +01:00

Merge remote-tracking branch 'origin/main' into feature/1400-shared-components-stories

This commit is contained in:
ClaudiaHolhos 2022-06-16 12:38:23 +03:00
commit e71695fed5
20 changed files with 373 additions and 299 deletions

View File

@ -18,7 +18,7 @@ import { getAccessDetails } from '@utils/accessDetailsAndPricing'
import { useIsMounted } from '@hooks/useIsMounted'
import { useMarketMetadata } from './MarketMetadata'
interface AssetProviderValue {
export interface AssetProviderValue {
isInPurgatory: boolean
purgatoryData: Purgatory
asset: AssetExtended

View File

@ -5,7 +5,9 @@ export const opcQuery = gql`
opc(id: 1) {
swapOceanFee
swapNonOceanFee
approvedTokens
approvedTokens {
id
}
id
}
}

View File

@ -36,7 +36,7 @@ function MarketMetadataProvider({
opcData.push({
chainId: appConfig.chainIdsSupported[i],
approvedTokens: response.data?.opc.approvedTokens,
approvedTokens: response.data?.opc.approvedTokens?.map((x) => x.id),
swapApprovedFee: response.data?.opc.swapOceanFee,
swapNotApprovedFee: response.data?.opc.swapNonOceanFee
} as OpcFee)

View File

@ -9,7 +9,7 @@ import Web3 from 'web3'
// TODO: Why do we have these one line functions ?!?!?!
export async function getEncryptedFiles(
files: FileMetadata[],
files: any,
providerUrl: string
): Promise<string> {
try {

View File

@ -20,15 +20,6 @@
text-align: center;
}
.button:first-child {
margin-left: 0;
}
.button:last-child {
margin-right: 0;
min-width: auto;
}
.button:hover,
.button:focus {
color: var(--brand-white);

View File

@ -23,6 +23,11 @@
margin-left: calc(var(--spacer) / 4);
}
.loader.white {
border-color: rgba(255 255 255 / 0.3);
border-top-color: var(--brand-white);
}
@keyframes loader {
to {
transform: rotate(360deg);

View File

@ -3,12 +3,13 @@ import styles from './index.module.css'
export interface LoaderProps {
message?: string
white?: boolean
}
export default function Loader({ message }: LoaderProps): ReactElement {
export default function Loader({ message, white }: LoaderProps): ReactElement {
return (
<div className={styles.loaderWrap}>
<span className={styles.loader} />
<span className={`${styles.loader} ${white ? styles.white : ''}`} />
{message && <span className={styles.message}>{message}</span>}
</div>
)

View File

@ -5,13 +5,14 @@ import AddToken from '@shared/AddToken'
import ExplorerLink from '@shared/ExplorerLink'
import Publisher from '@shared/Publisher'
import React, { ReactElement } from 'react'
import { AssetExtended } from 'src/@types/AssetExtended'
import styles from './MetaAsset.module.css'
export default function MetaAsset({
asset,
isBlockscoutExplorer
}: {
asset: Asset
asset: AssetExtended
isBlockscoutExplorer: boolean
}): ReactElement {
const { isAssetNetwork } = useAsset()

View File

@ -1,16 +1,17 @@
import { Asset } from '@oceanprotocol/lib'
import { useAsset } from '@context/Asset'
import AssetType from '@shared/AssetType'
import Time from '@shared/atoms/Time'
import Publisher from '@shared/Publisher'
import { getServiceByName } from '@utils/ddo'
import React, { ReactElement } from 'react'
import { AssetExtended } from 'src/@types/AssetExtended'
import styles from './MetaInfo.module.css'
export default function MetaInfo({
asset,
nftPublisher
}: {
asset: Asset
asset: AssetExtended
nftPublisher: string
}): ReactElement {
const isCompute = Boolean(getServiceByName(asset, 'compute'))

View File

@ -13,32 +13,3 @@
height: calc(var(--spacer) * 2);
border-bottom: 1px solid var(--border-color);
}
.nftImage {
position: relative;
margin: 0;
border-right: 1px solid var(--border-color);
width: calc(var(--spacer) * 2);
height: calc(var(--spacer) * 2);
}
.nftImage img,
.nftImage > svg:first-of-type {
width: 100%;
height: 100%;
}
.nftImage > svg:first-of-type {
transform: scale(0.7);
}
.nftImage .tooltip {
position: absolute;
padding: 0;
left: 0;
bottom: 0;
}
.nftImage .tooltip svg {
fill: var(--font-color-text);
}

View File

@ -1,14 +1,11 @@
import React, { ReactElement } from 'react'
import styles from './index.module.css'
import { AssetExtended } from 'src/@types/AssetExtended'
import { decodeTokenURI } from '@utils/nft'
import MetaAsset from './MetaAsset'
import MetaInfo from './MetaInfo'
import Tooltip from '@shared/atoms/Tooltip'
import NftTooltip from './NftTooltip'
import Logo from '@shared/atoms/Logo'
import { FormPublishData } from '../../../Publish/_types'
import { useFormikContext } from 'formik'
import Nft from '../Nft'
import { AssetExtended } from 'src/@types/AssetExtended'
const blockscoutNetworks = [1287, 2021000, 2021001, 44787, 246, 1285]
export default function MetaMain({
asset,
@ -17,51 +14,12 @@ export default function MetaMain({
asset: AssetExtended
nftPublisher: string
}): ReactElement {
const nftMetadata = decodeTokenURI(asset?.nft?.tokenURI)
const blockscoutNetworks = [1287, 2021000, 2021001, 44787, 246, 1285]
const isBlockscoutExplorer = blockscoutNetworks.includes(asset?.chainId)
// TODO: using this for the publish preview works fine, but produces a console warning
// on asset details page as there is no formik context there:
// Warning: Formik context is undefined, please verify you are calling useFormikContext()
// as child of a <Formik> component.
const formikState = useFormikContext<FormPublishData>()
// checking if the NFT has an image associated (tokenURI)
// if tokenURI is undefined, then we are in Preview
// for Preview we need to show accessDetails.dataImage
// as this is where the NFT's SVG (during publish) is stored
const nftImage = nftMetadata?.image_data
? nftMetadata.image_data
: formikState?.values?.metadata?.nft?.image_data
? formikState.values.metadata.nft.image_data
: null
return (
<aside className={styles.meta}>
<header className={styles.asset}>
<div className={styles.nftImage}>
{nftImage ? (
<img src={nftImage} alt={asset?.nft?.name} />
) : (
<Logo noWordmark />
)}
{(nftMetadata || asset?.nftAddress) && (
<Tooltip
className={styles.tooltip}
content={
<NftTooltip
nft={nftMetadata}
address={asset?.nftAddress}
chainId={asset?.chainId}
isBlockscoutExplorer={isBlockscoutExplorer}
/>
}
/>
)}
</div>
<Nft isBlockscoutExplorer={isBlockscoutExplorer} />
<MetaAsset asset={asset} isBlockscoutExplorer={isBlockscoutExplorer} />
</header>

View File

@ -7,6 +7,11 @@ import styles from './NftTooltip.module.css'
import explorerLinkStyles from '@shared/ExplorerLink/index.module.css'
import { accountTruncate } from '@utils/web3'
// Supported OpenSea networks:
// https://support.opensea.io/hc/en-us/articles/4404027708051-Which-blockchains-does-OpenSea-support-
const openSeaNetworks = [1, 137]
const openSeaTestNetworks = [4]
export default function NftTooltip({
nft,
address,
@ -18,26 +23,23 @@ export default function NftTooltip({
chainId: number
isBlockscoutExplorer: boolean
}): ReactElement {
// Currently Ocean NFTs are not displayed correctly on OpenSea
// Code prepared to easily integrate this feature once this is fixed
//
// Supported OpeanSea networks:
// https://support.opensea.io/hc/en-us/articles/4404027708051-Which-blockchains-does-OpenSea-support-
const openseaNetworks = [1, 137]
const openseaTestNetworks = [4]
const openSeaSupported = openseaNetworks
.concat(openseaTestNetworks)
const openSeaSupported = openSeaNetworks
.concat(openSeaTestNetworks)
.includes(chainId)
const openSeaBaseUri = openSeaSupported
? openseaTestNetworks.includes(chainId)
? openSeaTestNetworks.includes(chainId)
? 'https://testnets.opensea.io'
: 'https://opensea.io'
: undefined
const openSeaUrl = `${openSeaBaseUri}/assets/${
chainId === 137 ? 'matic' : ''
}/${address}/1`
return (
<div className={styles.wrapper}>
{nft && <img src={nft.image_data} alt={nft?.name} />}
{nft && <img src={nft.image_data || nft.image} alt={nft?.name} />}
<div className={styles.info}>
{nft && <h5>{nft.name}</h5>}
{address && (
@ -53,25 +55,23 @@ export default function NftTooltip({
isBlockscoutExplorer ? `tokens/${address}` : `token/${address}`
}
>
View on explorer
View on Explorer
</ExplorerLink>
)}
{openSeaSupported && nft && address && (
{openSeaSupported && address && (
<a
href={`${openSeaBaseUri}/assets/${address}/1`}
href={openSeaUrl}
target="_blank"
rel="noreferrer"
className={explorerLinkStyles.link}
>
View on OpeanSea <External />
View on OpenSea <External />
</a>
)}
</div>
{!nft?.image_data && (
<p className={styles.fallback}>
This Data NFT was not created on Ocean Market
</p>
{!nft?.image_data && !nft?.image && (
<p className={styles.fallback}>This Data NFT has no image set.</p>
)}
</div>
</div>

View File

@ -0,0 +1,28 @@
.nftImage {
position: relative;
margin: 0;
border-right: 1px solid var(--border-color);
width: calc(var(--spacer) * 2);
height: calc(var(--spacer) * 2);
}
.nftImage img,
.nftImage > svg:first-of-type {
width: 100%;
height: 100%;
}
.nftImage > svg:first-of-type {
transform: scale(0.7);
}
.nftImage .tooltip {
position: absolute;
padding: 0;
left: 0;
bottom: 0;
}
.nftImage .tooltip svg {
fill: var(--font-color-text);
}

View File

@ -0,0 +1,60 @@
import { useAsset } from '@context/Asset'
import Tooltip from '@shared/atoms/Tooltip'
import { decodeTokenURI } from '@utils/nft'
import { useFormikContext } from 'formik'
import React from 'react'
import { FormPublishData } from 'src/components/Publish/_types'
import Logo from '@shared/atoms/Logo'
import NftTooltip from './NftTooltip'
import styles from './index.module.css'
export default function Nft({
isBlockscoutExplorer
}: {
isBlockscoutExplorer: boolean
}) {
const { asset } = useAsset()
const nftMetadata = decodeTokenURI(asset?.nft?.tokenURI)
// TODO: using this for the publish preview works fine, but produces a console warning
// on asset details page as there is no formik context there:
// Warning: Formik context is undefined, please verify you are calling useFormikContext()
// as child of a <Formik> component.
const formikState = useFormikContext<FormPublishData>()
// checking if the NFT has an image associated (tokenURI)
// if tokenURI is undefined, then we are in Preview
// for Preview we need to show accessDetails.dataImage
// as this is where the NFT's SVG (during publish) is stored
const nftImage = nftMetadata?.image_data
? nftMetadata.image_data
: nftMetadata?.image
? nftMetadata.image
: formikState?.values?.metadata?.nft?.image_data
? formikState.values.metadata.nft.image_data
: null
return (
<div className={styles.nftImage}>
{nftImage ? (
<img src={nftImage} alt={asset?.nft?.name} />
) : (
<Logo noWordmark />
)}
{(nftMetadata || asset?.nftAddress) && (
<Tooltip
className={styles.tooltip}
content={
<NftTooltip
nft={nftMetadata}
address={asset?.nftAddress}
chainId={asset?.chainId}
isBlockscoutExplorer={isBlockscoutExplorer}
/>
}
/>
)}
</div>
)
}

View File

@ -61,7 +61,9 @@ export default function MarketStats(): ReactElement {
//
const getMarketStats = useCallback(async () => {
if (!mainChainIds?.length) return
const newData: {
[chainId: number]: FooterStatsValuesGlobalStatistics
} = {}
for (const chainId of mainChainIds) {
const context: OperationContext = {
url: `${getSubgraphUri(
@ -73,15 +75,12 @@ export default function MarketStats(): ReactElement {
try {
const response = await fetchData(queryGlobalStatistics, null, context)
if (!response?.data?.globalStatistics) return
setData((prevState) => ({
...prevState,
[chainId]: response.data.globalStatistics[0]
}))
newData[chainId] = response.data.globalStatistics[0]
} catch (error) {
LoggerInstance.error('Error fetching global stats: ', error.message)
}
}
setData(newData)
}, [mainChainIds])
//
@ -96,10 +95,12 @@ export default function MarketStats(): ReactElement {
//
useEffect(() => {
if (!data || !mainChainIds?.length) return
const newTotal: StatsTotal = {
...initialTotal // always start calculating beginning from initial 0 values
}
const newTVLInOcean: StatsValue = {}
const newTotalLiquidity: StatsValue = {}
const newPoolCount: StatsValue = {}
for (const chainId of mainChainIds) {
const baseTokenValue = data[chainId]?.totalLiquidity[0]?.value
@ -109,25 +110,15 @@ export default function MarketStats(): ReactElement {
? new Decimal(baseTokenValue).mul(2)
: new Decimal(0)
setTotalValueLockedInOcean((prevState) => ({
...prevState,
[chainId]: `${totalValueLockedInOcean}`
}))
newTVLInOcean[chainId] = `${totalValueLockedInOcean}`
const totalOceanLiquidity = Number(baseTokenValue) || 0
setTotalOceanLiquidity((prevState) => ({
...prevState,
[chainId]: `${totalOceanLiquidity}`
}))
newTotalLiquidity[chainId] = `${totalOceanLiquidity}`
const poolCount = data[chainId]?.poolCount || 0
setPoolCount((prevState) => ({
...prevState,
[chainId]: `${poolCount}`
}))
newPoolCount[chainId] = `${poolCount}`
const nftCount = data[chainId]?.nftCount || 0
const datatokenCount = data[chainId]?.datatokenCount || 0
const orderCount = data[chainId]?.orderCount || 0
@ -142,7 +133,9 @@ export default function MarketStats(): ReactElement {
LoggerInstance.error('Error data manipulation: ', error.message)
}
}
setTotalValueLockedInOcean(newTVLInOcean)
setTotalOceanLiquidity(newTotalLiquidity)
setPoolCount(newPoolCount)
setTotal(newTotal)
}, [data, mainChainIds, prices, currency])

View File

@ -7,6 +7,7 @@
.actions button {
margin: 0 calc(var(--spacer) / 2);
min-height: 40px;
}
.infoIcon {

View File

@ -10,6 +10,7 @@ import { useRouter } from 'next/router'
import Tooltip from '@shared/atoms/Tooltip'
import AvailableNetworks from 'src/components/Publish/AvailableNetworks'
import Info from '@images/info.svg'
import Loader from '@shared/atoms/Loader'
export default function Actions({
scrollToRef,
@ -59,6 +60,11 @@ export default function Actions({
(values.user.stepCurrent === 2 && errors.services !== undefined) ||
(values.user.stepCurrent === 3 && errors.pricing !== undefined)
const hasSubmitError =
values.feedback?.[1].status === 'error' ||
values.feedback?.[2].status === 'error' ||
values.feedback?.[3].status === 'error'
return (
<footer className={styles.actions}>
{did ? (
@ -107,7 +113,13 @@ export default function Actions({
style="primary"
disabled={isSubmitting || !isValid}
>
Submit
{isSubmitting ? (
<Loader white />
) : hasSubmitError ? (
'Retry'
) : (
'Submit'
)}
</Button>
)}
</>

View File

@ -143,13 +143,18 @@ export async function transformPublishFormToDdo(
}
// this is the default format hardcoded
const file = [
{
type: 'url',
url: files[0].url,
method: 'GET'
}
]
const file = {
nftAddress,
datatokenAddress,
files: [
{
type: 'url',
index: 0,
url: files[0].url,
method: 'GET'
}
]
}
const filesEncrypted =
!isPreview &&
files?.length &&
@ -172,7 +177,7 @@ export async function transformPublishFormToDdo(
'@context': ['https://w3id.org/did/v1'],
id: did,
nftAddress,
version: '4.0.0',
version: '4.1.0',
chainId,
metadata: newMetadata,
services: [newService],

View File

@ -11,7 +11,7 @@ import Actions from './Actions'
import Debug from './Debug'
import Navigation from './Navigation'
import { Steps } from './Steps'
import { FormPublishData, PublishFeedback } from './_types'
import { FormPublishData } from './_types'
import { useUserPreferences } from '@context/UserPreferences'
import useNftFactory from '@hooks/contracts/useNftFactory'
import { ProviderInstance, LoggerInstance, DDO } from '@oceanprotocol/lib'
@ -35,157 +35,166 @@ export default function PublishPage({
const nftFactory = useNftFactory()
const newAbortController = useAbortController()
const [feedback, setFeedback] = useState<PublishFeedback>(
initialPublishFeedback
)
// This `feedback` state is auto-synced into Formik context under `values.feedback`
// for use in other components. Syncing defined in ./Steps.tsx child component.
const [feedback, setFeedback] = useState(initialPublishFeedback)
// Collecting output of each publish step, enabling retry of failed steps
const [erc721Address, setErc721Address] = useState<string>()
const [datatokenAddress, setDatatokenAddress] = useState<string>()
const [ddo, setDdo] = useState<DDO>()
const [ddoEncrypted, setDdoEncrypted] = useState<string>()
const [did, setDid] = useState<string>()
async function handleSubmit(values: FormPublishData) {
// reset all feedback state
setFeedback(initialPublishFeedback)
// --------------------------------------------------
// 1. Create NFT & datatokens & create pricing schema
// Wrapped in conditional allowing method to run
// multiple times.
// --------------------------------------------------
if (!erc721Address && !datatokenAddress) {
try {
setFeedback((prevState) => ({
...prevState,
'1': {
...prevState['1'],
status: 'active',
txCount: values.pricing.type === 'dynamic' ? 2 : 1,
description: prevState['1'].description
}
}))
const config = getOceanConfig(chainId)
LoggerInstance.log('[publish] using config: ', config)
const { erc721Address, datatokenAddress, txHash } =
await createTokensAndPricing(
values,
accountId,
config,
nftFactory,
web3
)
const isSuccess = Boolean(erc721Address && datatokenAddress && txHash)
setErc721Address(erc721Address)
setDatatokenAddress(datatokenAddress)
LoggerInstance.log('[publish] createTokensAndPricing tx', txHash)
LoggerInstance.log('[publish] erc721Address', erc721Address)
LoggerInstance.log('[publish] datatokenAddress', datatokenAddress)
setFeedback((prevState) => ({
...prevState,
'1': {
...prevState['1'],
status: isSuccess ? 'success' : 'error',
txHash
}
}))
} catch (error) {
LoggerInstance.error('[publish] error', error.message)
if (error.message.length > 65) {
error.message = 'No Token created.'
}
setFeedback((prevState) => ({
...prevState,
'1': {
...prevState['1'],
status: 'error',
errorMessage: error.message,
description:
values.pricing.type === 'dynamic'
? prevState['1'].description.replace(
'a single transaction',
'a single transaction, after an initial approve transaction'
)
: prevState['1'].description
}
}))
// --------------------------------------------------
// 1. Create NFT & datatokens & create pricing schema
// --------------------------------------------------
async function create(values: FormPublishData): Promise<{
erc721Address: string
datatokenAddress: string
}> {
setFeedback((prevState) => ({
...prevState,
'1': {
...prevState['1'],
status: 'active',
errorMessage: null
}
}
}))
// --------------------------------------------------
// 2. Construct and encrypt DDO
// Wrapped in conditional allowing method to run
// multiple times.
// --------------------------------------------------
if (!ddoEncrypted) {
try {
setFeedback((prevState) => ({
...prevState,
'2': {
...prevState['2'],
status: 'active'
}
}))
if (!datatokenAddress || !erc721Address)
throw new Error('No NFT or Datatoken received.')
const ddo = await transformPublishFormToDdo(
values,
datatokenAddress,
erc721Address
)
setDdo(ddo)
LoggerInstance.log('[publish] Got new DDO', ddo)
const encryptedResponse = await ProviderInstance.encrypt(
ddo,
values.services[0].providerUrl.url,
newAbortController()
)
const ddoEncrypted = encryptedResponse
setDdoEncrypted(ddoEncrypted)
LoggerInstance.log('[publish] Got encrypted DDO', ddoEncrypted)
setFeedback((prevState) => ({
...prevState,
'2': {
...prevState['2'],
status: ddoEncrypted ? 'success' : 'error'
}
}))
} catch (error) {
LoggerInstance.error('[publish] error', error.message)
setFeedback((prevState) => ({
...prevState,
'2': {
...prevState['2'],
status: 'error',
errorMessage: error.message
}
}))
}
}
// --------------------------------------------------
// 3. Write DDO into NFT metadata
// --------------------------------------------------
try {
const config = getOceanConfig(chainId)
LoggerInstance.log('[publish] using config: ', config)
const { erc721Address, datatokenAddress, txHash } =
await createTokensAndPricing(
values,
accountId,
config,
nftFactory,
web3
)
const isSuccess = Boolean(erc721Address && datatokenAddress && txHash)
if (!isSuccess) throw new Error('No Token created. Please try again.')
LoggerInstance.log('[publish] createTokensAndPricing tx', txHash)
LoggerInstance.log('[publish] erc721Address', erc721Address)
LoggerInstance.log('[publish] datatokenAddress', datatokenAddress)
setFeedback((prevState) => ({
...prevState,
'3': {
...prevState['3'],
status: 'active'
'1': {
...prevState['1'],
status: 'success',
txHash
}
}))
if (!ddo || !ddoEncrypted) throw new Error('No DDO received.')
return { erc721Address, datatokenAddress }
} catch (error) {
LoggerInstance.error('[publish] error', error.message)
if (error.message.length > 65) {
error.message = 'No Token created. Please try again.'
}
setFeedback((prevState) => ({
...prevState,
'1': {
...prevState['1'],
status: 'error',
errorMessage: error.message
}
}))
}
}
// --------------------------------------------------
// 2. Construct and encrypt DDO
// --------------------------------------------------
async function encrypt(
values: FormPublishData,
erc721Address: string,
datatokenAddress: string
): Promise<{ ddo: DDO; ddoEncrypted: string }> {
setFeedback((prevState) => ({
...prevState,
'2': {
...prevState['2'],
status: 'active',
errorMessage: null
}
}))
try {
if (!datatokenAddress || !erc721Address)
throw new Error('No NFT or Datatoken received. Please try again.')
const ddo = await transformPublishFormToDdo(
values,
datatokenAddress,
erc721Address
)
if (!ddo) throw new Error('No DDO received. Please try again.')
setDdo(ddo)
LoggerInstance.log('[publish] Got new DDO', ddo)
const ddoEncrypted = await ProviderInstance.encrypt(
ddo,
values.services[0].providerUrl.url,
newAbortController()
)
if (!ddoEncrypted)
throw new Error('No encrypted DDO received. Please try again.')
setDdoEncrypted(ddoEncrypted)
LoggerInstance.log('[publish] Got encrypted DDO', ddoEncrypted)
setFeedback((prevState) => ({
...prevState,
'2': {
...prevState['2'],
status: 'success'
}
}))
return { ddo, ddoEncrypted }
} catch (error) {
LoggerInstance.error('[publish] error', error.message)
setFeedback((prevState) => ({
...prevState,
'2': {
...prevState['2'],
status: 'error',
errorMessage: error.message
}
}))
}
}
// --------------------------------------------------
// 3. Write DDO into NFT metadata
// --------------------------------------------------
async function publish(
values: FormPublishData,
ddo: DDO,
ddoEncrypted: string
): Promise<{ did: string }> {
setFeedback((prevState) => ({
...prevState,
'3': {
...prevState['3'],
status: 'active',
errorMessage: null
}
}))
try {
if (!ddo || !ddoEncrypted)
throw new Error('No DDO received. Please try again.')
const res = await setNFTMetadataAndTokenURI(
ddo,
@ -196,7 +205,7 @@ export default function PublishPage({
)
if (!res?.transactionHash)
throw new Error(
'Metadata could not be written into the NFT. Please hit Submit again to retry.'
'Metadata could not be written into the NFT. Please try again.'
)
LoggerInstance.log('[publish] setMetadata result', res)
@ -210,7 +219,7 @@ export default function PublishPage({
}
}))
setDid(ddo.id)
return { did: ddo.id }
} catch (error) {
LoggerInstance.error('[publish] error', error.message)
setFeedback((prevState) => ({
@ -224,6 +233,44 @@ export default function PublishPage({
}
}
// --------------------------------------------------
// Orchestrate publishing
// --------------------------------------------------
async function handleSubmit(values: FormPublishData) {
// Syncing variables with state, enabling retry of failed steps
let _erc721Address = erc721Address
let _datatokenAddress = datatokenAddress
let _ddo = ddo
let _ddoEncrypted = ddoEncrypted
let _did = did
if (!_erc721Address || !_datatokenAddress) {
const { erc721Address, datatokenAddress } = await create(values)
_erc721Address = erc721Address
_datatokenAddress = datatokenAddress
setErc721Address(erc721Address)
setDatatokenAddress(datatokenAddress)
}
if (!_ddo || !_ddoEncrypted) {
const { ddo, ddoEncrypted } = await encrypt(
values,
_erc721Address,
_datatokenAddress
)
_ddo = ddo
_ddoEncrypted = ddoEncrypted
setDdo(ddo)
setDdoEncrypted(ddoEncrypted)
}
if (!_did) {
const { did } = await publish(values, _ddo, _ddoEncrypted)
_did = did
setDid(did)
}
}
return isInPurgatory && purgatoryData ? null : (
<Formik
initialValues={initialValues}
@ -233,22 +280,20 @@ export default function PublishPage({
await handleSubmit(values)
}}
>
{({ values }) => {
return (
<>
<PageHeader
title={<Title networkId={values.user.chainId} />}
description={content.description}
/>
<Form className={styles.form} ref={scrollToRef}>
<Navigation />
<Steps feedback={feedback} />
<Actions scrollToRef={scrollToRef} did={did} />
</Form>
{debug && <Debug />}
</>
)
}}
{({ values }) => (
<>
<PageHeader
title={<Title networkId={values.user.chainId} />}
description={content.description}
/>
<Form className={styles.form} ref={scrollToRef}>
<Navigation />
<Steps feedback={feedback} />
<Actions scrollToRef={scrollToRef} did={did} />
</Form>
{debug && <Debug />}
</>
)}
</Formik>
)
}