From 6a1a6a76445b71777d62a0089850dda3df22e452 Mon Sep 17 00:00:00 2001 From: Jamie Hewitt Date: Thu, 2 Feb 2023 11:20:56 +0300 Subject: [PATCH] Changing state of assets (#1795) * Adding option to retire asset * Adding retireAsset to edit form validation * CHanging to select box * Updating assetState from edit form * Adding asset state on the asset detail page * Refactoring * Adding a test for MetaFull component * Increasing test coverage by also testing with an algorithm * Adjusting example algorithm * Adding additional tests * Additional test for Bookmark component * Allowing NFT owners to view their own assets * Only showing asset state when it isn't Active * Restricting options to just Active or unlisted * Removing logs * Removing logs * Updating tests * Updating tests * Fixing form * Updating asset state options * Adding utils for converting asset state to and from string | number * Using new functions to convert asset state from string to number * Allowing people to order assets that are unlisted * Changing condition for making the asset unavailable * only showing the asset on the profile if it has state 1,4 or 5 * Renaming jest fixtures * Avoiding getInitialPaymentCollector failure (#1816) * early return is no web3 or ddo * Creating test for MetaFull * adding test: src/components/Asset/AssetContent/MetaSecondary.test.tsx * Adding test for bookmarks * Adding test for displaying payment collector * Removing comments * Renaming assetAquarius * Renaming assetWithAccessDetails * Ensuring that the payment collector is shown even without a wallet connected * Removing broken test * Using getDummyWeb3 for fetching the payment collector address * fixing assetState import * google validation (#1835) * Updating validation to exclude any google link * Updating Yup validation * Checking if domain includes google.com * Updating isGoogleUrl function * Moving isGoogleUrl into @utils/url/index file * isGoogleUrl function * Updating tests * Adding additional tests for other google domains * Updating tests * Updating isGoogleUrl file path * Early return if no data available in getNetworkDisplayName * Updating pricing message (#1842) * Bump @storybook/addon-essentials from 6.5.13 to 6.5.15 (#1841) Bumps [@storybook/addon-essentials](https://github.com/storybookjs/storybook/tree/HEAD/addons/essentials) from 6.5.13 to 6.5.15. - [Release notes](https://github.com/storybookjs/storybook/releases) - [Changelog](https://github.com/storybookjs/storybook/blob/v6.5.15/CHANGELOG.md) - [Commits](https://github.com/storybookjs/storybook/commits/v6.5.15/addons/essentials) --- updated-dependencies: - dependency-name: "@storybook/addon-essentials" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump @types/jest from 29.2.3 to 29.2.5 (#1840) Bumps [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) from 29.2.3 to 29.2.5. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest) --- updated-dependencies: - dependency-name: "@types/jest" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump prettier from 2.8.0 to 2.8.1 (#1837) Bumps [prettier](https://github.com/prettier/prettier) from 2.8.0 to 2.8.1. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/2.8.0...2.8.1) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump react-select from 5.6.1 to 5.7.0 (#1839) Bumps [react-select](https://github.com/JedWatson/react-select) from 5.6.1 to 5.7.0. - [Release notes](https://github.com/JedWatson/react-select/releases) - [Changelog](https://github.com/JedWatson/react-select/blob/master/docs/CHANGELOG.md) - [Commits](https://github.com/JedWatson/react-select/compare/react-select@5.6.1...react-select@5.7.0) --- updated-dependencies: - dependency-name: react-select dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump react-tabs from 5.1.0 to 6.0.0 (#1838) Bumps [react-tabs](https://github.com/reactjs/react-tabs) from 5.1.0 to 6.0.0. - [Release notes](https://github.com/reactjs/react-tabs/releases) - [Commits](https://github.com/reactjs/react-tabs/compare/v5.1.0...v6.0.0) --- updated-dependencies: - dependency-name: react-tabs dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix asset route (#1836) * updating the buy button message for free assets * Updating pricing text for compute and algorithms * Updating tests * Adding a seperate sentence about paying gas fees for network charges with free assets * Fixing tests Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mihaisc * Showing hosting type in File Info (#1846) * Bump @storybook/addon-essentials from 6.5.13 to 6.5.15 (#1841) Bumps [@storybook/addon-essentials](https://github.com/storybookjs/storybook/tree/HEAD/addons/essentials) from 6.5.13 to 6.5.15. - [Release notes](https://github.com/storybookjs/storybook/releases) - [Changelog](https://github.com/storybookjs/storybook/blob/v6.5.15/CHANGELOG.md) - [Commits](https://github.com/storybookjs/storybook/commits/v6.5.15/addons/essentials) --- updated-dependencies: - dependency-name: "@storybook/addon-essentials" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump @types/jest from 29.2.3 to 29.2.5 (#1840) Bumps [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) from 29.2.3 to 29.2.5. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest) --- updated-dependencies: - dependency-name: "@types/jest" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump prettier from 2.8.0 to 2.8.1 (#1837) Bumps [prettier](https://github.com/prettier/prettier) from 2.8.0 to 2.8.1. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/2.8.0...2.8.1) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump react-select from 5.6.1 to 5.7.0 (#1839) Bumps [react-select](https://github.com/JedWatson/react-select) from 5.6.1 to 5.7.0. - [Release notes](https://github.com/JedWatson/react-select/releases) - [Changelog](https://github.com/JedWatson/react-select/blob/master/docs/CHANGELOG.md) - [Commits](https://github.com/JedWatson/react-select/compare/react-select@5.6.1...react-select@5.7.0) --- updated-dependencies: - dependency-name: react-select dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump react-tabs from 5.1.0 to 6.0.0 (#1838) Bumps [react-tabs](https://github.com/reactjs/react-tabs) from 5.1.0 to 6.0.0. - [Release notes](https://github.com/reactjs/react-tabs/releases) - [Commits](https://github.com/reactjs/react-tabs/compare/v5.1.0...v6.0.0) --- updated-dependencies: - dependency-name: react-tabs dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix asset route (#1836) * Adding hosting type to the file info component * Writting smart contract hosting type across two lines Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mihaisc * add initial price value for not supported price assets (#1851) * Fix compute basetoken issue (#1829) * fix lint * add dynamic provider fees * fixes * cleanup and more fixes * bump oceanlib to 2.6.0 * fix 404 styling (#1850) * Fixing bug that was preventing assets from showing on the profile page * fixing the overwritting transaction * Setting error message if the asset state has been set to 1, 2 or 3 --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mihaisc Co-authored-by: Bogdan Fazakas Co-authored-by: EnzoVezzaro --- content/pages/editMetadata.json | 14 +++++++ src/@context/Asset.tsx | 40 ++++++++++--------- src/@utils/aquarius/index.ts | 1 + src/@utils/assetState.ts | 39 ++++++++++++++++++ .../Asset/AssetContent/MetaFull.test.tsx | 1 + .../Asset/AssetContent/MetaFull.tsx | 7 ++-- src/components/Asset/Edit/EditMetadata.tsx | 19 +++++++-- .../Asset/Edit/FormEditMetadata.tsx | 5 +++ src/components/Asset/Edit/_constants.ts | 6 ++- src/components/Asset/Edit/_types.ts | 1 + src/components/Asset/Edit/_validation.ts | 3 +- 11 files changed, 108 insertions(+), 28 deletions(-) create mode 100644 src/@utils/assetState.ts 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({