From d5b1acc16e2e3b2ebb9904e67ccef8e1db7e0707 Mon Sep 17 00:00:00 2001 From: Serkan Reis Date: Sun, 23 Jul 2023 21:54:14 +0300 Subject: [PATCH 01/22] Create OpenEditionMinterDetailsDataProps --- .../openEdition/OpenEditionMinterCreator.tsx | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/components/openEdition/OpenEditionMinterCreator.tsx b/components/openEdition/OpenEditionMinterCreator.tsx index 3f0fce3..6fe8763 100644 --- a/components/openEdition/OpenEditionMinterCreator.tsx +++ b/components/openEdition/OpenEditionMinterCreator.tsx @@ -47,13 +47,24 @@ import { type RoyaltyDetailsDataProps, RoyaltyDetails } from './RoyaltyDetails' export type MetadataStorageMethod = 'off-chain' | 'on-chain' +export interface OpenEditionMinterDetailsDataProps { + imageUploadDetails?: ImageUploadDetailsDataProps + collectionDetails?: CollectionDetailsDataProps + royaltyDetails?: RoyaltyDetailsDataProps + onChainMetadataInputDetails?: OnChainMetadataInputDetailsDataProps + offChainMetadataUploadDetails?: OffChainMetadataUploadDetailsDataProps + mintingDetails?: MintingDetailsDataProps +} + interface OpenEditionMinterCreatorProps { onChange: (data: OpenEditionMinterCreatorDataProps) => void + onDetailsChange: (data: OpenEditionMinterDetailsDataProps) => void openEditionMinterUpdatableCreationFee?: string openEditionMinterCreationFee?: string minimumMintPrice?: string minimumUpdatableMintPrice?: string minterType?: MinterType + importedOpenEditionMinterDetails?: OpenEditionMinterCreatorDataProps } export interface OpenEditionMinterCreatorDataProps { @@ -65,6 +76,7 @@ export interface OpenEditionMinterCreatorDataProps { export const OpenEditionMinterCreator = ({ onChange, + onDetailsChange, openEditionMinterCreationFee, openEditionMinterUpdatableCreationFee, minimumMintPrice, @@ -585,6 +597,26 @@ export const OpenEditionMinterCreator = ({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [metadataStorageMethod, openEditionMinterContractAddress, sg721ContractAddress, transactionHash]) + useEffect(() => { + const data: OpenEditionMinterDetailsDataProps = { + imageUploadDetails: imageUploadDetails ? imageUploadDetails : undefined, + collectionDetails: collectionDetails ? collectionDetails : undefined, + royaltyDetails: royaltyDetails ? royaltyDetails : undefined, + onChainMetadataInputDetails: onChainMetadataInputDetails ? onChainMetadataInputDetails : undefined, + offChainMetadataUploadDetails: offChainMetadataUploadDetails ? offChainMetadataUploadDetails : undefined, + mintingDetails: mintingDetails ? mintingDetails : undefined, + } + onDetailsChange(data) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [ + imageUploadDetails, + collectionDetails, + royaltyDetails, + onChainMetadataInputDetails, + offChainMetadataUploadDetails, + mintingDetails, + ]) + return (
{/* TODO: Cancel once we're able to index on-chain metadata */} From e074413a9ebacfb260a40ff540838c927bd96c6c Mon Sep 17 00:00:00 2001 From: Serkan Reis Date: Mon, 24 Jul 2023 21:57:53 +0300 Subject: [PATCH 02/22] Update AddressList --- components/forms/AddressList.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/components/forms/AddressList.tsx b/components/forms/AddressList.tsx index 59dad9d..b95db84 100644 --- a/components/forms/AddressList.tsx +++ b/components/forms/AddressList.tsx @@ -31,6 +31,7 @@ export function AddressList(props: AddressListProps) { {entries.map(([id], i) => (
(isLast ? FaPlus : FaMinus), [isLast]) @@ -60,6 +62,7 @@ export function Address({ id, isLast, onAdd, onChange, onRemove }: AddressProps) id: `ib-address-${htmlId}`, name: `ib-address-${htmlId}`, title: ``, + defaultValue: defaultValue?.address, }) const resolveAddress = async (name: string) => { From 8921938c6c3f73b6a6fd9f44a6b323031b5d274a Mon Sep 17 00:00:00 2001 From: Serkan Reis Date: Tue, 25 Jul 2023 22:24:40 +0300 Subject: [PATCH 03/22] Initial export/import logic --- pages/collections/create.tsx | 103 ++++++++++++++++++++++++++++------- 1 file changed, 83 insertions(+), 20 deletions(-) diff --git a/pages/collections/create.tsx b/pages/collections/create.tsx index 6a99323..2399ce2 100644 --- a/pages/collections/create.tsx +++ b/pages/collections/create.tsx @@ -42,6 +42,7 @@ import type { DispatchExecuteArgs as VendingFactoryDispatchExecuteArgs } from 'c import { dispatchExecute as vendingFactoryDispatchExecute } from 'contracts/vendingFactory/messages/execute' import type { NextPage } from 'next' import { NextSeo } from 'next-seo' +import type { ChangeEvent } from 'react' import { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { toast } from 'react-hot-toast' import { upload } from 'services/upload' @@ -71,6 +72,7 @@ import { uid } from 'utils/random' import type { MinterType } from '../../components/collections/actions/Combobox' import type { UploadMethod } from '../../components/collections/creation/UploadDetails' import { ConfirmationModal } from '../../components/ConfirmationModal' +import type { OpenEditionMinterDetailsDataProps } from '../../components/openEdition/OpenEditionMinterCreator' import { getAssetType } from '../../utils/getAssetType' import { isValidAddress } from '../../utils/isValidAddress' @@ -96,10 +98,23 @@ const CollectionCreationPage: NextPage = () => { [baseFactoryContract, wallet.address], ) + const [importedDetails, setImportedDetails] = useState<{ + minterType: MinterType + collectionDetails: CollectionDetailsDataProps + uploadDetails: UploadDetailsDataProps + mintingDetails: MintingDetailsDataProps + whitelistDetails: WhitelistDetailsDataProps + royaltyDetails: RoyaltyDetailsDataProps + baseMinterDetails: BaseMinterDetailsDataProps + openEditionMinterDetails: OpenEditionMinterDetailsDataProps + }>() + const [uploadDetails, setUploadDetails] = useState(null) const [collectionDetails, setCollectionDetails] = useState(null) const [baseMinterDetails, setBaseMinterDetails] = useState(null) - const [openEditionMinterDetails, setOpenEditionMinterDetails] = useState( + const [openEditionMinterCreatorData, setOpenEditionMinterCreatorData] = + useState(null) + const [openEditionMinterDetails, setOpenEditionMinterDetails] = useState( null, ) const [mintingDetails, setMintingDetails] = useState(null) @@ -1159,27 +1174,60 @@ const CollectionCreationPage: NextPage = () => { }) } + // function to export all details as a .json file + const exportDetails = () => { + const details = { + minterType, + collectionDetails, + uploadDetails, + mintingDetails, + whitelistDetails, + royaltyDetails, + baseMinterDetails, + openEditionMinterDetails, + } + const element = document.createElement('a') + const file = new Blob([JSON.stringify(details)], { type: 'text/plain' }) + element.href = URL.createObjectURL(file) + element.download = 'details.json' + document.body.appendChild(element) // Required for this to work in FireFox + element.click() + } + // function to import all details from a .json file + const importDetails = (event: ChangeEvent) => { + if (event.target.files === null) return toast.error('No files selected.') + const file = event.target.files[0] + const reader = new FileReader() + reader.onload = (e) => { + const contents = e.target?.result + const details = JSON.parse(contents as string) + setMinterType(details.minterType) + setImportedDetails(details) + } + reader.readAsText(file) + } + const syncCollections = useCallback(async () => { const collectionAddress = - minterType === 'openEdition' ? openEditionMinterDetails?.sg721ContractAddress : sg721ContractAddress + minterType === 'openEdition' ? openEditionMinterCreatorData?.sg721ContractAddress : sg721ContractAddress if (collectionAddress && SYNC_COLLECTIONS_API_URL) { await axios.get(`${SYNC_COLLECTIONS_API_URL}/${collectionAddress}`).catch((error) => { console.error('Sync collections: ', error) }) } - }, [minterType, openEditionMinterDetails?.sg721ContractAddress, sg721ContractAddress]) + }, [minterType, openEditionMinterCreatorData?.sg721ContractAddress, sg721ContractAddress]) useEffect(() => { if ( vendingMinterContractAddress !== null || - openEditionMinterDetails?.openEditionMinterContractAddress || + openEditionMinterCreatorData?.openEditionMinterContractAddress || isMintingComplete ) { scrollRef.current?.scrollIntoView({ behavior: 'smooth' }) } if ( (minterType === 'vending' && vendingMinterContractAddress !== null) || - (minterType === 'openEdition' && openEditionMinterDetails?.openEditionMinterContractAddress) || + (minterType === 'openEdition' && openEditionMinterCreatorData?.openEditionMinterContractAddress) || (minterType === 'base' && vendingMinterContractAddress !== null && isMintingComplete) ) { void syncCollections() @@ -1192,7 +1240,7 @@ const CollectionCreationPage: NextPage = () => { } }, [ vendingMinterContractAddress, - openEditionMinterDetails?.openEditionMinterContractAddress, + openEditionMinterCreatorData?.openEditionMinterContractAddress, isMintingComplete, minterType, syncCollections, @@ -1222,7 +1270,15 @@ const CollectionCreationPage: NextPage = () => { : 'Create Collection' } /> - + + importDetails(e)} + type="file" + />

{minterType === 'base' && baseMinterDetails?.baseMinterAcquisitionMethod === 'existing' @@ -1244,7 +1300,7 @@ const CollectionCreationPage: NextPage = () => {

@@ -1253,10 +1309,10 @@ const CollectionCreationPage: NextPage = () => { className="text-stargaze hover:underline" external href={`/contracts/openEditionMinter/query/?contractAddress=${ - openEditionMinterDetails?.openEditionMinterContractAddress as string + openEditionMinterCreatorData?.openEditionMinterContractAddress as string }`} > - {openEditionMinterDetails?.openEditionMinterContractAddress as string} + {openEditionMinterCreatorData?.openEditionMinterContractAddress as string}
SG721 Contract Address:{' '} @@ -1264,10 +1320,10 @@ const CollectionCreationPage: NextPage = () => { className="text-stargaze hover:underline" external href={`/contracts/sg721/query/?contractAddress=${ - openEditionMinterDetails?.sg721ContractAddress as string + openEditionMinterCreatorData?.sg721ContractAddress as string }`} > - {openEditionMinterDetails?.sg721ContractAddress as string} + {openEditionMinterCreatorData?.sg721ContractAddress as string}
Transaction Hash: {' '} @@ -1275,18 +1331,18 @@ const CollectionCreationPage: NextPage = () => { - {openEditionMinterDetails?.transactionHash} + {openEditionMinterCreatorData?.transactionHash} - {openEditionMinterDetails?.transactionHash} + {openEditionMinterCreatorData?.transactionHash}
@@ -1295,7 +1351,7 @@ const CollectionCreationPage: NextPage = () => { className="text-white" external href={`${STARGAZE_URL}/launchpad/${ - openEditionMinterDetails?.openEditionMinterContractAddress as string + openEditionMinterCreatorData?.openEditionMinterContractAddress as string }`} > View on Launchpad @@ -1564,7 +1620,8 @@ const CollectionCreationPage: NextPage = () => { minimumMintPrice={minimumOpenEditionMintPrice as string} minimumUpdatableMintPrice={minimumOpenEditionUpdatableMintPrice as string} minterType={minterType} - onChange={setOpenEditionMinterDetails} + onChange={setOpenEditionMinterCreatorData} + onDetailsChange={setOpenEditionMinterDetails} openEditionMinterCreationFee={openEditionMinterCreationFee as string} openEditionMinterUpdatableCreationFee={openEditionMinterUpdatableCreationFee as string} /> @@ -1573,6 +1630,7 @@ const CollectionCreationPage: NextPage = () => { @@ -1593,6 +1651,7 @@ const CollectionCreationPage: NextPage = () => { > { { >
- +
- +
From 2a38e791913fcb628d7f00d92800a2f6641e8436 Mon Sep 17 00:00:00 2001 From: Serkan Reis Date: Tue, 25 Jul 2023 22:26:29 +0300 Subject: [PATCH 04/22] Surface open edition collection configuration --- components/openEdition/CollectionDetails.tsx | 19 ++++++++++++ components/openEdition/ImageUploadDetails.tsx | 15 +++++++++- components/openEdition/MintingDetails.tsx | 19 +++++++++++- .../OffChainMetadataUploadDetails.tsx | 15 ++++++++++ .../OnChainMetadataInputDetails.tsx | 27 ++++++++++++++++- .../openEdition/OpenEditionMinterCreator.tsx | 29 ++++++++++++++++--- components/openEdition/RoyaltyDetails.tsx | 12 +++++++- 7 files changed, 128 insertions(+), 8 deletions(-) diff --git a/components/openEdition/CollectionDetails.tsx b/components/openEdition/CollectionDetails.tsx index c919b73..4c46fff 100644 --- a/components/openEdition/CollectionDetails.tsx +++ b/components/openEdition/CollectionDetails.tsx @@ -28,6 +28,7 @@ interface CollectionDetailsProps { uploadMethod: UploadMethod coverImageUrl: string metadataStorageMethod: MetadataStorageMethod + importedCollectionDetails?: CollectionDetailsDataProps } export interface CollectionDetailsDataProps { @@ -46,6 +47,7 @@ export const CollectionDetails = ({ uploadMethod, metadataStorageMethod, coverImageUrl, + importedCollectionDetails, }: CollectionDetailsProps) => { const [coverImage, setCoverImage] = useState(null) const [timestamp, setTimestamp] = useState() @@ -152,6 +154,23 @@ export const CollectionDetails = ({ } }, [updatable]) + useEffect(() => { + if (importedCollectionDetails) { + nameState.onChange(importedCollectionDetails.name) + descriptionState.onChange(importedCollectionDetails.description) + symbolState.onChange(importedCollectionDetails.symbol) + setCoverImage(importedCollectionDetails.imageFile[0] || null) + externalLinkState.onChange(importedCollectionDetails.externalLink || '') + setTimestamp( + importedCollectionDetails.startTradingTime + ? new Date(parseInt(importedCollectionDetails.startTradingTime) / 1_000_000) + : undefined, + ) + setExplicit(importedCollectionDetails.explicit) + setUpdatable(importedCollectionDetails.updatable) + } + }, [importedCollectionDetails]) + const videoPreview = useMemo(() => { if (uploadMethod === 'new' && coverImage) { return ( diff --git a/components/openEdition/ImageUploadDetails.tsx b/components/openEdition/ImageUploadDetails.tsx index ad84b0e..f8748f2 100644 --- a/components/openEdition/ImageUploadDetails.tsx +++ b/components/openEdition/ImageUploadDetails.tsx @@ -20,6 +20,7 @@ export type UploadMethod = 'new' | 'existing' interface ImageUploadDetailsProps { onChange: (value: ImageUploadDetailsDataProps) => void + importedImageUploadDetails?: ImageUploadDetailsDataProps } export interface ImageUploadDetailsDataProps { @@ -33,7 +34,7 @@ export interface ImageUploadDetailsDataProps { coverImageUrl?: string } -export const ImageUploadDetails = ({ onChange }: ImageUploadDetailsProps) => { +export const ImageUploadDetails = ({ onChange, importedImageUploadDetails }: ImageUploadDetailsProps) => { const [assetFile, setAssetFile] = useState() const [uploadMethod, setUploadMethod] = useState('new') const [uploadService, setUploadService] = useState('nft-storage') @@ -140,6 +141,18 @@ export const ImageUploadDetails = ({ onChange }: ImageUploadDetailsProps) => { imageUrlState.onChange('') }, [uploadMethod]) + useEffect(() => { + if (importedImageUploadDetails) { + setUploadMethod(importedImageUploadDetails.uploadMethod) + setUploadService(importedImageUploadDetails.uploadService) + nftStorageApiKeyState.onChange(importedImageUploadDetails.nftStorageApiKey || '') + pinataApiKeyState.onChange(importedImageUploadDetails.pinataApiKey || '') + pinataSecretKeyState.onChange(importedImageUploadDetails.pinataSecretKey || '') + imageUrlState.onChange(importedImageUploadDetails.imageUrl || '') + coverImageUrlState.onChange(importedImageUploadDetails.coverImageUrl || '') + } + }, [importedImageUploadDetails]) + const previewUrl = imageUrlState.value.toLowerCase().trim().startsWith('ipfs://') ? `https://ipfs-gw.stargaze-apis.com/ipfs/${imageUrlState.value.substring(7)}` : imageUrlState.value diff --git a/components/openEdition/MintingDetails.tsx b/components/openEdition/MintingDetails.tsx index 8b6acd5..0938a7d 100644 --- a/components/openEdition/MintingDetails.tsx +++ b/components/openEdition/MintingDetails.tsx @@ -15,6 +15,7 @@ interface MintingDetailsProps { onChange: (data: MintingDetailsDataProps) => void uploadMethod: UploadMethod minimumMintPrice: number + importedMintingDetails?: MintingDetailsDataProps } export interface MintingDetailsDataProps { @@ -25,7 +26,12 @@ export interface MintingDetailsDataProps { paymentAddress?: string } -export const MintingDetails = ({ onChange, uploadMethod, minimumMintPrice }: MintingDetailsProps) => { +export const MintingDetails = ({ + onChange, + uploadMethod, + minimumMintPrice, + importedMintingDetails, +}: MintingDetailsProps) => { const wallet = useWallet() const [timestamp, setTimestamp] = useState() @@ -81,6 +87,17 @@ export const MintingDetails = ({ onChange, uploadMethod, minimumMintPrice }: Min // eslint-disable-next-line react-hooks/exhaustive-deps }, [unitPriceState.value, perAddressLimitState.value, timestamp, endTimestamp, paymentAddressState.value]) + useEffect(() => { + if (importedMintingDetails) { + unitPriceState.onChange(Number(importedMintingDetails.unitPrice)) + perAddressLimitState.onChange(importedMintingDetails.perAddressLimit) + setTimestamp(new Date(Number(importedMintingDetails.startTime) / 1_000_000)) + setEndTimestamp(new Date(Number(importedMintingDetails.endTime) / 1_000_000)) + paymentAddressState.onChange(importedMintingDetails.paymentAddress ? importedMintingDetails.paymentAddress : '') + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [importedMintingDetails]) + return (
diff --git a/components/openEdition/OffChainMetadataUploadDetails.tsx b/components/openEdition/OffChainMetadataUploadDetails.tsx index 02c4ce3..02e8703 100644 --- a/components/openEdition/OffChainMetadataUploadDetails.tsx +++ b/components/openEdition/OffChainMetadataUploadDetails.tsx @@ -28,6 +28,7 @@ export type UploadMethod = 'new' | 'existing' interface OffChainMetadataUploadDetailsProps { onChange: (value: OffChainMetadataUploadDetailsDataProps) => void metadataStorageMethod?: MetadataStorageMethod + importedOffChainMetadataUploadDetails?: OffChainMetadataUploadDetailsDataProps } export interface OffChainMetadataUploadDetailsDataProps { @@ -46,6 +47,7 @@ export interface OffChainMetadataUploadDetailsDataProps { export const OffChainMetadataUploadDetails = ({ onChange, metadataStorageMethod, + importedOffChainMetadataUploadDetails, }: OffChainMetadataUploadDetailsProps) => { const [assetFilesArray, setAssetFilesArray] = useState([]) const [metadataFilesArray, setMetadataFilesArray] = useState([]) @@ -233,6 +235,19 @@ export const OffChainMetadataUploadDetails = ({ coverImageUrlState.onChange('') }, [uploadMethod, metadataStorageMethod]) + useEffect(() => { + if (importedOffChainMetadataUploadDetails) { + setUploadService(importedOffChainMetadataUploadDetails.uploadService) + nftStorageApiKeyState.onChange(importedOffChainMetadataUploadDetails.nftStorageApiKey || '') + pinataApiKeyState.onChange(importedOffChainMetadataUploadDetails.pinataApiKey || '') + pinataSecretKeyState.onChange(importedOffChainMetadataUploadDetails.pinataSecretKey || '') + setUploadMethod('existing') + tokenUriState.onChange(importedOffChainMetadataUploadDetails.tokenURI || '') + coverImageUrlState.onChange(importedOffChainMetadataUploadDetails.imageUrl || '') + setOpenEditionMinterMetadataFile(importedOffChainMetadataUploadDetails.openEditionMinterMetadataFile) + } + }, [importedOffChainMetadataUploadDetails]) + return (
diff --git a/components/openEdition/OnChainMetadataInputDetails.tsx b/components/openEdition/OnChainMetadataInputDetails.tsx index 2fb0eed..f71fa23 100644 --- a/components/openEdition/OnChainMetadataInputDetails.tsx +++ b/components/openEdition/OnChainMetadataInputDetails.tsx @@ -21,6 +21,7 @@ import type { UploadMethod } from './ImageUploadDetails' interface OnChainMetadataInputDetailsProps { onChange: (data: OnChainMetadataInputDetailsDataProps) => void uploadMethod: UploadMethod | undefined + importedOnChainMetadataInputDetails?: OnChainMetadataInputDetailsDataProps } export interface OnChainMetadataInputDetailsDataProps { @@ -34,7 +35,11 @@ export interface OnChainMetadataInputDetailsDataProps { youtube_url?: string } -export const OnChainMetadataInputDetails = ({ onChange, uploadMethod }: OnChainMetadataInputDetailsProps) => { +export const OnChainMetadataInputDetails = ({ + onChange, + uploadMethod, + importedOnChainMetadataInputDetails, +}: OnChainMetadataInputDetailsProps) => { const wallet = useWallet() const [timestamp, setTimestamp] = useState(undefined) const [metadataFile, setMetadataFile] = useState() @@ -196,6 +201,26 @@ export const OnChainMetadataInputDetails = ({ onChange, uploadMethod }: OnChainM youtubeUrlState.value, ]) + useEffect(() => { + if (importedOnChainMetadataInputDetails) { + nameState.onChange(importedOnChainMetadataInputDetails.name || '') + descriptionState.onChange(importedOnChainMetadataInputDetails.description || '') + externalUrlState.onChange(importedOnChainMetadataInputDetails.external_url || '') + youtubeUrlState.onChange(importedOnChainMetadataInputDetails.youtube_url || '') + animationUrlState.onChange(importedOnChainMetadataInputDetails.animation_url || '') + imageDataState.onChange(importedOnChainMetadataInputDetails.image_data || '') + if (importedOnChainMetadataInputDetails.attributes) { + attributesState.reset() + importedOnChainMetadataInputDetails.attributes.forEach((attr) => { + attributesState.add({ + trait_type: attr.trait_type, + value: attr.value, + }) + }) + } + } + }, [importedOnChainMetadataInputDetails]) + return (
NFT Metadata diff --git a/components/openEdition/OpenEditionMinterCreator.tsx b/components/openEdition/OpenEditionMinterCreator.tsx index 6fe8763..bfd893a 100644 --- a/components/openEdition/OpenEditionMinterCreator.tsx +++ b/components/openEdition/OpenEditionMinterCreator.tsx @@ -54,6 +54,7 @@ export interface OpenEditionMinterDetailsDataProps { onChainMetadataInputDetails?: OnChainMetadataInputDetailsDataProps offChainMetadataUploadDetails?: OffChainMetadataUploadDetailsDataProps mintingDetails?: MintingDetailsDataProps + metadataStorageMethod?: MetadataStorageMethod } interface OpenEditionMinterCreatorProps { @@ -64,7 +65,7 @@ interface OpenEditionMinterCreatorProps { minimumMintPrice?: string minimumUpdatableMintPrice?: string minterType?: MinterType - importedOpenEditionMinterDetails?: OpenEditionMinterCreatorDataProps + importedOpenEditionMinterDetails?: OpenEditionMinterDetailsDataProps } export interface OpenEditionMinterCreatorDataProps { @@ -82,6 +83,7 @@ export const OpenEditionMinterCreator = ({ minimumMintPrice, minimumUpdatableMintPrice, minterType, + importedOpenEditionMinterDetails, }: OpenEditionMinterCreatorProps) => { const wallet = useWallet() const { openEditionMinter: openEditionMinterContract, openEditionFactory: openEditionFactoryContract } = @@ -605,6 +607,7 @@ export const OpenEditionMinterCreator = ({ onChainMetadataInputDetails: onChainMetadataInputDetails ? onChainMetadataInputDetails : undefined, offChainMetadataUploadDetails: offChainMetadataUploadDetails ? offChainMetadataUploadDetails : undefined, mintingDetails: mintingDetails ? mintingDetails : undefined, + metadataStorageMethod, } onDetailsChange(data) // eslint-disable-next-line react-hooks/exhaustive-deps @@ -617,6 +620,12 @@ export const OpenEditionMinterCreator = ({ mintingDetails, ]) + useEffect(() => { + if (importedOpenEditionMinterDetails) { + setMetadataStorageMethod(importedOpenEditionMinterDetails.metadataStorageMethod as MetadataStorageMethod) + } + }, [importedOpenEditionMinterDetails]) + return (
{/* TODO: Cancel once we're able to index on-chain metadata */} @@ -667,13 +676,20 @@ export const OpenEditionMinterCreator = ({
- +
- + @@ -687,6 +703,7 @@ export const OpenEditionMinterCreator = ({ ? (offChainMetadataUploadDetails?.imageUrl as string) : (imageUploadDetails?.coverImageUrl as string) } + importedCollectionDetails={importedOpenEditionMinterDetails?.collectionDetails} metadataStorageMethod={metadataStorageMethod} onChange={setCollectionDetails} uploadMethod={ @@ -696,6 +713,7 @@ export const OpenEditionMinterCreator = ({ } />
- +
- importDetails(e)} - type="file" - /> +

{minterType === 'base' && baseMinterDetails?.baseMinterAcquisitionMethod === 'existing' @@ -1436,6 +1437,7 @@ const CollectionCreationPage: NextPage = () => { on how to create your collection

+
{ className={clsx( 'mx-10 mt-5', 'grid before:absolute relative grid-cols-3 grid-flow-col items-stretch rounded', - 'before:inset-x-0 before:bottom-0 before:border-white/25', + 'before:inset-x-0 before:bottom-0 before:border-white/25', + minterType !== 'base' ? 'rounded-none border-b-2 border-white/25' : 'border-0', )} >
{
+ + +
+ importDetails(e)} + type="file" + /> + +
+
+
+ {minterType === 'base' && (
From 5578c408a51a666b864690f39cd16322ab7422e1 Mon Sep 17 00:00:00 2001 From: Serkan Reis Date: Mon, 21 Aug 2023 15:00:06 +0300 Subject: [PATCH 19/22] Bump Studio version --- .env.example | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.env.example b/.env.example index ffe2835..170dd6e 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,4 @@ -APP_VERSION=0.7.3 +APP_VERSION=0.7.4 NEXT_PUBLIC_PINATA_ENDPOINT_URL=https://api.pinata.cloud/pinning/pinFileToIPFS NEXT_PUBLIC_SG721_CODE_ID=2595 diff --git a/package.json b/package.json index ff54c94..acc68fe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "stargaze-studio", - "version": "0.7.3", + "version": "0.7.4", "workspaces": [ "packages/*" ], From f25807f35579cbb1e2df4892ae2d7d19242f56b7 Mon Sep 17 00:00:00 2001 From: Serkan Reis Date: Mon, 21 Aug 2023 16:29:52 +0300 Subject: [PATCH 20/22] Unmicro whitelist unit price --- components/collections/creation/WhitelistDetails.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/components/collections/creation/WhitelistDetails.tsx b/components/collections/creation/WhitelistDetails.tsx index aa0d908..880bf7b 100644 --- a/components/collections/creation/WhitelistDetails.tsx +++ b/components/collections/creation/WhitelistDetails.tsx @@ -160,7 +160,9 @@ export const WhitelistDetails = ({ whitelistAddressState.onChange( importedWhitelistDetails.contractAddress ? importedWhitelistDetails.contractAddress : '', ) - unitPriceState.onChange(importedWhitelistDetails.unitPrice ? Number(importedWhitelistDetails.unitPrice) : 0) + unitPriceState.onChange( + importedWhitelistDetails.unitPrice ? Number(importedWhitelistDetails.unitPrice) / 1000000 : 0, + ) memberLimitState.onChange(importedWhitelistDetails.memberLimit ? importedWhitelistDetails.memberLimit : 0) perAddressLimitState.onChange( importedWhitelistDetails.perAddressLimit ? importedWhitelistDetails.perAddressLimit : 0, From 1ca1d08b2ac7991d67b265286ee822cb63106f22 Mon Sep 17 00:00:00 2001 From: Serkan Reis Date: Mon, 21 Aug 2023 16:43:05 +0300 Subject: [PATCH 21/22] Reset upload details on import for 1/1 collections --- components/collections/creation/UploadDetails.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/collections/creation/UploadDetails.tsx b/components/collections/creation/UploadDetails.tsx index 519f879..bb99e3b 100644 --- a/components/collections/creation/UploadDetails.tsx +++ b/components/collections/creation/UploadDetails.tsx @@ -280,7 +280,7 @@ export const UploadDetails = ({ setMetadataFilesArray([]) if (assetFilesRef.current) assetFilesRef.current.value = '' setAssetFilesArray([]) - if (!importedUploadDetails) { + if (!importedUploadDetails || minterType === 'base') { baseTokenUriState.onChange('') coverImageUrlState.onChange('') } From 391b712bde688dcb01b923ec7cf151122b2e957f Mon Sep 17 00:00:00 2001 From: Serkan Reis Date: Mon, 21 Aug 2023 19:45:23 +0300 Subject: [PATCH 22/22] Prevent duplicate protocol in the base token uri --- pages/collections/create.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/collections/create.tsx b/pages/collections/create.tsx index 5311fba..4ba9555 100644 --- a/pages/collections/create.tsx +++ b/pages/collections/create.tsx @@ -1297,7 +1297,7 @@ const CollectionCreationPage: NextPage = () => { baseMinterDetails, openEditionMinterDetails, vendingMinterContractAddress, - baseTokenUri: `ipfs://${baseTokenUri}`, + baseTokenUri: `${baseTokenUri?.startsWith('ipfs://') ? baseTokenUri : `ipfs://${baseTokenUri}`}`, coverImageUrl: uploadDetails?.uploadMethod === 'new' ? `ipfs://${coverImageUrl}/${collectionDetails?.imageFile[0]?.name as string}`