diff --git a/pages/collections/create.tsx b/pages/collections/create.tsx index 84a4425..c732ef3 100644 --- a/pages/collections/create.tsx +++ b/pages/collections/create.tsx @@ -141,26 +141,34 @@ const CollectionCreationPage: NextPage = () => { checkUploadDetails() checkCollectionDetails() checkMintingDetails() - void checkRoyaltyDetails() + void checkExistingTokenURI() .then(() => { - checkWhitelistDetails() + void checkRoyaltyDetails() .then(() => { - checkwalletBalance() - setReadyToCreateVm(true) + checkWhitelistDetails() + .then(() => { + checkwalletBalance() + setReadyToCreateVm(true) + }) + .catch((error) => { + if (String(error.message).includes('Insufficient wallet balance')) { + toast.error(`${error.message}`, { style: { maxWidth: 'none' } }) + addLogItem({ id: uid(), message: error.message, type: 'Error', timestamp: new Date() }) + } else { + toast.error(`Error in Whitelist Configuration: ${error.message}`, { style: { maxWidth: 'none' } }) + addLogItem({ id: uid(), message: error.message, type: 'Error', timestamp: new Date() }) + } + setReadyToCreateVm(false) + }) }) .catch((error) => { - if (String(error.message).includes('Insufficient wallet balance')) { - toast.error(`${error.message}`, { style: { maxWidth: 'none' } }) - addLogItem({ id: uid(), message: error.message, type: 'Error', timestamp: new Date() }) - } else { - toast.error(`Error in Whitelist Configuration: ${error.message}`, { style: { maxWidth: 'none' } }) - addLogItem({ id: uid(), message: error.message, type: 'Error', timestamp: new Date() }) - } + toast.error(`Error in Royalty Details: ${error.message}`, { style: { maxWidth: 'none' } }) + addLogItem({ id: uid(), message: error.message, type: 'Error', timestamp: new Date() }) setReadyToCreateVm(false) }) }) .catch((error) => { - toast.error(`Error in Royalty Details: ${error.message}`, { style: { maxWidth: 'none' } }) + toast.error(`Error in Base Token URI: ${error.message}`, { style: { maxWidth: 'none' } }) addLogItem({ id: uid(), message: error.message, type: 'Error', timestamp: new Date() }) setReadyToCreateVm(false) }) @@ -836,6 +844,9 @@ const CollectionCreationPage: NextPage = () => { } const checkExistingTokenURI = async () => { + if (minterType === 'vending' && uploadDetails && uploadDetails.uploadMethod === 'existing') { + await checkTokenUri(uploadDetails.baseTokenURI as string, true) + } if (minterType === 'base' && uploadDetails && uploadDetails.uploadMethod === 'existing') { await checkTokenUri(uploadDetails.baseTokenURI as string) } diff --git a/utils/isValidTokenUri.ts b/utils/isValidTokenUri.ts index 0ca2d44..ac857fa 100644 --- a/utils/isValidTokenUri.ts +++ b/utils/isValidTokenUri.ts @@ -1,21 +1,71 @@ /* eslint-disable eslint-comments/disable-enable-pair */ /* eslint-disable @typescript-eslint/no-unsafe-call */ -/* eslint-disable @typescript-eslint/no-unsafe-assignment */ -export const checkTokenUri = async (tokenUri: string) => { - const file = await fetch(tokenUri.replace('ipfs://', 'https://ipfs.io/ipfs/')) - .then((res) => - res.json().catch((err: any) => { - throw Error(`Metadata file could not be parsed. Please check that it is valid JSON.`) - }), - ) - .catch((err: any) => { - throw Error(`Unable to fetch metadata from ${tokenUri}`) - }) - - if (!file.image) { - throw Error('Token URI must contain an image URL.') - } - if (file.image && !file.image.startsWith('ipfs://')) { - throw Error('Metadata file: The corresponding value for image must be an IPFS URL.') +export const checkTokenUri = async (tokenUri: string, isBaseTokenUri?: boolean) => { + if (isBaseTokenUri) { + await fetch(tokenUri.replace('ipfs://', 'https://ipfs.io/ipfs/').concat(tokenUri.endsWith('/') ? '1' : '/1')) + .then((res) => + res + .json() + .then((data) => { + if (!data.image) { + throw Error('Metadata validation failed. The metadata files must contain an image URL.') + } + if (!data.image.startsWith('ipfs://')) { + throw Error('Metadata file validation failed: The corresponding value for image must be an IPFS URL.') + } + }) + .catch(() => { + throw Error( + `Metadata validation failed. Please check that the metadata files in the IPFS folder are valid JSON.`, + ) + }), + ) + .catch(async () => { + await fetch( + tokenUri.replace('ipfs://', 'https://ipfs.io/ipfs/').concat(tokenUri.endsWith('/') ? '1.json' : '/1.json'), + ) + .then((response) => + response + .json() + .then((file) => { + if (!file.image) { + throw Error('Metadata validation failed. The metadata files must contain an image URL.') + } + if (!file.image.startsWith('ipfs://')) { + throw Error('Metadata file validation failed: The corresponding value for image must be an IPFS URL.') + } + }) + .catch(() => { + throw Error( + `Metadata validation failed. Please check that the metadata files in the IPFS folder are valid JSON.`, + ) + }), + ) + .catch(() => { + throw Error( + `Unable to fetch metadata from ${tokenUri}. Metadata validation failed. Please check that the base token URI points to an IPFS folder with metadata files in it.`, + ) + }) + }) + } else { + await fetch(tokenUri.replace('ipfs://', 'https://ipfs.io/ipfs/')) + .then((res) => + res + .json() + .then((file) => { + if (!file.image) { + throw Error('Token URI must contain an image URL.') + } + if (!file.image.startsWith('ipfs://')) { + throw Error('Metadata file: The corresponding value for image must be an IPFS URL.') + } + }) + .catch(() => { + throw Error(`Metadata file could not be parsed. Please check that it is valid JSON.`) + }), + ) + .catch(() => { + throw Error(`Unable to fetch metadata from ${tokenUri}`) + }) } }