diff --git a/content/pages/editMetadata.json b/content/pages/editMetadata.json index f58ada87c..ff17820ca 100644 --- a/content/pages/editMetadata.json +++ b/content/pages/editMetadata.json @@ -120,6 +120,20 @@ "placeholder": "e.g. 0X123ABC...", "help": "This address will receive the revenue from all sales. More info available in our [docs](https://docs.oceanprotocol.com/core-concepts/datanft-and-datatoken#revenue).", "required": false + }, + { + "name": "assetState", + "label": "Asset Status", + "help": "This asset will no longer be visible to other users and it won't be possible to purchase it. More info available in our [docs](https://docs.oceanprotocol.com/core-concepts/did-ddo#state).", + "type": "select", + "options": [ + "Active", + "Revoked by publisher", + "Ordering is temporary disabled", + "Asset unlisted" + ], + "sortOptions": false, + "required": false } ] } diff --git a/src/@context/Asset.tsx b/src/@context/Asset.tsx index 5c1b75367..d1ad226ec 100644 --- a/src/@context/Asset.tsx +++ b/src/@context/Asset.tsx @@ -16,6 +16,7 @@ import { getOceanConfig, getDevelopmentConfig } from '@utils/ocean' import { getAccessDetails } from '@utils/accessDetailsAndPricing' import { useIsMounted } from '@hooks/useIsMounted' import { useMarketMetadata } from './MarketMetadata' +import { assetStateToString } from '@utils/assetState' import { isValidDid } from '@utils/ddo' export interface AssetProviderValue { @@ -29,6 +30,7 @@ export interface AssetProviderValue { isOwner: boolean oceanConfig: Config loading: boolean + assetState: string fetchAsset: (token?: CancelToken) => Promise } @@ -54,6 +56,7 @@ function AssetProvider({ const [loading, setLoading] = useState(false) const [isAssetNetwork, setIsAssetNetwork] = useState() const [oceanConfig, setOceanConfig] = useState() + const [assetState, setAssetState] = useState() const newCancelToken = useCancelToken() const isMounted = useIsMounted() @@ -85,27 +88,16 @@ function AssetProvider({ return } - if ([1, 2, 3].includes(asset.nft.state)) { - // handle nft states as documented in https://docs.oceanprotocol.com/core-concepts/did-ddo/#state - let state - switch (asset.nft.state) { - case 1: - state = 'end-of-life' - break - case 2: - state = 'deprecated' - break - case 3: - state = 'revoked' - break - } - - setTitle(`This asset has been flagged as "${state}" by the publisher`) + if (asset.nft.state === (1 | 2 | 3)) { + setTitle( + `This asset has been set as "${assetStateToString( + asset.nft.state + )}" by the publisher` + ) setError(`\`${did}\`` + `\n\nPublisher Address: ${asset.nft.owner}`) LoggerInstance.error(`[asset] Failed getting asset for ${did}`, asset) return } - if (asset) { setError(undefined) setAsset((prevState) => ({ @@ -116,12 +108,13 @@ function AssetProvider({ setOwner(asset.nft?.owner) setIsInPurgatory(asset.purgatory?.state) setPurgatoryData(asset.purgatory) + setAssetState(assetStateToString(asset.nft.state)) LoggerInstance.log('[asset] Got asset', asset) } setLoading(false) }, - [did] + [did, accountId] ) // ----------------------------------- @@ -198,6 +191,14 @@ function AssetProvider({ setOceanConfig(oceanConfig) }, [asset?.chainId]) + // ----------------------------------- + // Set Asset State as a string + // ----------------------------------- + useEffect(() => { + if (!asset?.nft) return + setAssetState(assetStateToString(asset.nft.state)) + }, [asset]) + return ( diff --git a/src/@utils/aquarius/index.ts b/src/@utils/aquarius/index.ts index 480e5506f..452b34ac7 100644 --- a/src/@utils/aquarius/index.ts +++ b/src/@utils/aquarius/index.ts @@ -254,6 +254,7 @@ export async function getPublishedAssets( const filters: FilterTerm[] = [] + filters.push(getFilterTerm('nft.state', [0, 4, 5])) filters.push(getFilterTerm('nft.owner', accountId.toLowerCase())) accesType !== undefined && filters.push(getFilterTerm('services.type', accesType)) diff --git a/src/@utils/assetState.ts b/src/@utils/assetState.ts new file mode 100644 index 000000000..46010ab39 --- /dev/null +++ b/src/@utils/assetState.ts @@ -0,0 +1,39 @@ +export function assetStateToString(state: number): string { + switch (state) { + case 0: + return 'Active' + case 1: + return 'End-of-life' + case 2: + return 'Deprecated (by another asset)' + case 3: + return 'Revoked by publisher' + case 4: + return 'Ordering is temporary disabled' + case 5: + return 'Asset unlisted' + + default: + break + } +} + +export function assetStateToNumber(state: string): number { + switch (state) { + case 'Active': + return 0 + case 'End-of-life': + return 1 + case 'Deprecated (by another asset)': + return 2 + case 'Revoked by publisher': + return 3 + case 'Ordering is temporary disabled': + return 4 + case 'Asset unlisted': + return 5 + + default: + break + } +} diff --git a/src/components/Asset/AssetContent/MetaFull.test.tsx b/src/components/Asset/AssetContent/MetaFull.test.tsx index 56053d369..e7e0e8aba 100644 --- a/src/components/Asset/AssetContent/MetaFull.test.tsx +++ b/src/components/Asset/AssetContent/MetaFull.test.tsx @@ -13,5 +13,6 @@ describe('src/components/Asset/AssetContent/MetaFull.tsx', () => { it('renders metadata for an algorithm', () => { render() expect(screen.getByText('Docker Image')).toBeInTheDocument() + expect(screen.getByText('DID')).toBeInTheDocument() }) }) diff --git a/src/components/Asset/AssetContent/MetaFull.tsx b/src/components/Asset/AssetContent/MetaFull.tsx index 1e6f2ba1c..60d036ba6 100644 --- a/src/components/Asset/AssetContent/MetaFull.tsx +++ b/src/components/Asset/AssetContent/MetaFull.tsx @@ -3,14 +3,12 @@ import MetaItem from './MetaItem' import styles from './MetaFull.module.css' import Publisher from '@shared/Publisher' import { useAsset } from '@context/Asset' -// import { useWeb3 } from '@context/Web3' import { getDummyWeb3 } from '@utils/web3' import { Asset, Datatoken, LoggerInstance } from '@oceanprotocol/lib' export default function MetaFull({ ddo }: { ddo: Asset }): ReactElement { const [paymentCollector, setPaymentCollector] = useState() - const { isInPurgatory } = useAsset() - // const { web3 } = useWeb3() + const { isInPurgatory, assetState } = useAsset() useEffect(() => { async function getInitialPaymentCollector() { @@ -43,6 +41,9 @@ export default function MetaFull({ ddo }: { ddo: Asset }): ReactElement { title="Owner" content={} /> + {assetState !== 'Active' && ( + + )} {paymentCollector && paymentCollector !== ddo?.nft?.owner && ( () @@ -157,6 +159,16 @@ export default function Edit({ newAbortController() ) + if (values.assetState !== assetState) { + const nft = new Nft(web3) + + await nft.setMetadataState( + asset?.nftAddress, + accountId, + assetStateToNumber(values.assetState) + ) + } + LoggerInstance.log('[edit] setMetadata result', setMetadataTx) if (!setMetadataTx) { @@ -180,7 +192,8 @@ export default function Edit({ asset?.metadata, asset?.services[0]?.timeout, asset?.accessDetails?.price || '0', - paymentCollector + paymentCollector, + assetState )} validationSchema={validationSchema} onSubmit={async (values, { resetForm }) => { diff --git a/src/components/Asset/Edit/FormEditMetadata.tsx b/src/components/Asset/Edit/FormEditMetadata.tsx index 191629b46..d68c37a0d 100644 --- a/src/components/Asset/Edit/FormEditMetadata.tsx +++ b/src/components/Asset/Edit/FormEditMetadata.tsx @@ -135,6 +135,11 @@ export default function FormEditMetadata({ component={Input} name="paymentCollector" /> + diff --git a/src/components/Asset/Edit/_constants.ts b/src/components/Asset/Edit/_constants.ts index 4092b89ed..a0af0809e 100644 --- a/src/components/Asset/Edit/_constants.ts +++ b/src/components/Asset/Edit/_constants.ts @@ -6,7 +6,8 @@ export function getInitialValues( metadata: Metadata, timeout: number, price: string, - paymentCollector: string + paymentCollector: string, + assetState: string ): Partial { return { name: metadata?.name, @@ -17,7 +18,8 @@ export function getInitialValues( timeout: secondsToString(timeout), author: metadata?.author, tags: metadata?.tags, - paymentCollector + paymentCollector, + assetState } } diff --git a/src/components/Asset/Edit/_types.ts b/src/components/Asset/Edit/_types.ts index 923aabb5c..2a8563c58 100644 --- a/src/components/Asset/Edit/_types.ts +++ b/src/components/Asset/Edit/_types.ts @@ -9,6 +9,7 @@ export interface MetadataEditForm { links?: FileInfo[] author?: string tags?: string[] + assetState?: string } export interface ComputeEditForm { diff --git a/src/components/Asset/Edit/_validation.ts b/src/components/Asset/Edit/_validation.ts index 1ec0b960b..bc29ca701 100644 --- a/src/components/Asset/Edit/_validation.ts +++ b/src/components/Asset/Edit/_validation.ts @@ -43,7 +43,8 @@ export const validationSchema = Yup.object().shape({ (value) => { return web3.utils.isAddress(value) } - ) + ), + retireAsset: Yup.string() }) export const computeSettingsValidationSchema = Yup.object().shape({