Display summary upon adding new tokens to a 1/1 collection

This commit is contained in:
Serkan Reis 2023-04-04 15:30:05 +03:00
parent bff03ffc66
commit ac467fb750
3 changed files with 192 additions and 62 deletions

View File

@ -22,6 +22,7 @@ export type BaseMinterAcquisitionMethod = 'existing' | 'new'
export interface MinterInfo { export interface MinterInfo {
name: string name: string
minter: string minter: string
contractAddress: string
} }
interface BaseMinterDetailsProps { interface BaseMinterDetailsProps {
@ -32,6 +33,8 @@ interface BaseMinterDetailsProps {
export interface BaseMinterDetailsDataProps { export interface BaseMinterDetailsDataProps {
baseMinterAcquisitionMethod: BaseMinterAcquisitionMethod baseMinterAcquisitionMethod: BaseMinterAcquisitionMethod
existingBaseMinter: string | undefined existingBaseMinter: string | undefined
selectedCollectionAddress: string | undefined
collectionTokenCount: number | undefined
} }
export const BaseMinterDetails = ({ onChange, minterType }: BaseMinterDetailsProps) => { export const BaseMinterDetails = ({ onChange, minterType }: BaseMinterDetailsProps) => {
@ -39,6 +42,8 @@ export const BaseMinterDetails = ({ onChange, minterType }: BaseMinterDetailsPro
const [myBaseMinterContracts, setMyBaseMinterContracts] = useState<MinterInfo[]>([]) const [myBaseMinterContracts, setMyBaseMinterContracts] = useState<MinterInfo[]>([])
const [baseMinterAcquisitionMethod, setBaseMinterAcquisitionMethod] = useState<BaseMinterAcquisitionMethod>('new') const [baseMinterAcquisitionMethod, setBaseMinterAcquisitionMethod] = useState<BaseMinterAcquisitionMethod>('new')
const [selectedCollectionAddress, setSelectedCollectionAddress] = useState<string | undefined>(undefined)
const [collectionTokenCount, setCollectionTokenCount] = useState<number | undefined>(undefined)
const existingBaseMinterState = useInputState({ const existingBaseMinterState = useInputState({
id: 'existingMinter', id: 'existingMinter',
@ -54,7 +59,7 @@ export const BaseMinterDetails = ({ onChange, minterType }: BaseMinterDetailsPro
.then((response) => { .then((response) => {
const collectionData = response.data const collectionData = response.data
const minterContracts = collectionData.map((collection: any) => { const minterContracts = collectionData.map((collection: any) => {
return { name: collection.name, minter: collection.minter } return { name: collection.name, minter: collection.minter, contractAddress: collection.contractAddress }
}) })
return minterContracts return minterContracts
}) })
@ -111,6 +116,8 @@ export const BaseMinterDetails = ({ onChange, minterType }: BaseMinterDetailsPro
const debouncedWalletAddress = useDebounce(wallet.address, 300) const debouncedWalletAddress = useDebounce(wallet.address, 300)
const debouncedExistingBaseMinterContract = useDebounce(existingBaseMinterState.value, 300)
const displayToast = async () => { const displayToast = async () => {
await toast.promise(filterBaseMinterContracts(), { await toast.promise(filterBaseMinterContracts(), {
loading: 'Retrieving previous 1/1 collections...', loading: 'Retrieving previous 1/1 collections...',
@ -119,6 +126,38 @@ export const BaseMinterDetails = ({ onChange, minterType }: BaseMinterDetailsPro
}) })
} }
const fetchSg721Address = async () => {
if (debouncedExistingBaseMinterContract.length === 0) return
await wallet.client
?.queryContractSmart(debouncedExistingBaseMinterContract, {
config: {},
})
.then((response) => {
console.log(response.collection_address)
setSelectedCollectionAddress(response.collection_address)
})
.catch((err) => {
console.log(err)
console.log('Unable to retrieve collection address')
})
}
const fetchCollectionTokenCount = async () => {
if (selectedCollectionAddress === undefined) return
await wallet.client
?.queryContractSmart(selectedCollectionAddress, {
num_tokens: {},
})
.then((response) => {
console.log(response)
setCollectionTokenCount(Number(response.count))
})
.catch((err) => {
console.log(err)
console.log('Unable to retrieve collection token count')
})
}
useEffect(() => { useEffect(() => {
if (debouncedWalletAddress && baseMinterAcquisitionMethod === 'existing') { if (debouncedWalletAddress && baseMinterAcquisitionMethod === 'existing') {
setMyBaseMinterContracts([]) setMyBaseMinterContracts([])
@ -130,14 +169,34 @@ export const BaseMinterDetails = ({ onChange, minterType }: BaseMinterDetailsPro
} }
}, [debouncedWalletAddress, baseMinterAcquisitionMethod]) }, [debouncedWalletAddress, baseMinterAcquisitionMethod])
useEffect(() => {
if (baseMinterAcquisitionMethod === 'existing') {
void fetchSg721Address()
}
}, [debouncedExistingBaseMinterContract])
useEffect(() => {
if (baseMinterAcquisitionMethod === 'existing') {
void fetchCollectionTokenCount()
}
}, [selectedCollectionAddress])
useEffect(() => { useEffect(() => {
const data: BaseMinterDetailsDataProps = { const data: BaseMinterDetailsDataProps = {
baseMinterAcquisitionMethod, baseMinterAcquisitionMethod,
existingBaseMinter: existingBaseMinterState.value, existingBaseMinter: existingBaseMinterState.value,
selectedCollectionAddress,
collectionTokenCount,
} }
onChange(data) onChange(data)
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [existingBaseMinterState.value, baseMinterAcquisitionMethod, wallet.initialized]) }, [
existingBaseMinterState.value,
baseMinterAcquisitionMethod,
wallet.initialized,
selectedCollectionAddress,
collectionTokenCount,
])
return ( return (
<div className="mx-10 mb-4 rounded border-2 border-white/20"> <div className="mx-10 mb-4 rounded border-2 border-white/20">

View File

@ -105,7 +105,7 @@ export const MintingDetails = ({ onChange, numberOfTokens, uploadMethod }: Minti
<InputDateTime minDate={new Date()} onChange={(date) => setTimestamp(date)} value={timestamp} /> <InputDateTime minDate={new Date()} onChange={(date) => setTimestamp(date)} value={timestamp} />
</FormControl> </FormControl>
</FormGroup> </FormGroup>
<TextInput className="p-4 mt-5" {...paymentAddressState} /> <TextInput className="p-4 mt-10" {...paymentAddressState} />
</div> </div>
) )
} }

View File

@ -9,6 +9,7 @@ import { coin } from '@cosmjs/proto-signing'
import clsx from 'clsx' import clsx from 'clsx'
import { Alert } from 'components/Alert' import { Alert } from 'components/Alert'
import { Anchor } from 'components/Anchor' import { Anchor } from 'components/Anchor'
import { AnchorButton } from 'components/AnchorButton'
import { Button } from 'components/Button' import { Button } from 'components/Button'
import { import {
CollectionDetails, CollectionDetails,
@ -297,12 +298,12 @@ const CollectionCreationPage: NextPage = () => {
if (!wallet.initialized) throw new Error('Wallet not connected') if (!wallet.initialized) throw new Error('Wallet not connected')
if (!baseMinterContract) throw new Error('Contract not found') if (!baseMinterContract) throw new Error('Contract not found')
setCreatingCollection(true) setCreatingCollection(true)
setIsMintingComplete(false)
setBaseTokenUri(null) setBaseTokenUri(null)
setCoverImageUrl(null) setCoverImageUrl(null)
setVendingMinterContractAddress(null) setVendingMinterContractAddress(null)
setSg721ContractAddress(null) setSg721ContractAddress(null)
setTransactionHash(null) setTransactionHash(null)
if (uploadDetails?.uploadMethod === 'new') { if (uploadDetails?.uploadMethod === 'new') {
console.log(JSON.stringify(uploadDetails.baseMinterMetadataFile?.text())) console.log(JSON.stringify(uploadDetails.baseMinterMetadataFile?.text()))
setUploading(true) setUploading(true)
@ -330,7 +331,6 @@ const CollectionCreationPage: NextPage = () => {
return result return result
} }
setBaseTokenUri(baseUri) setBaseTokenUri(baseUri)
const result = await baseMinterContract const result = await baseMinterContract
.use(baseMinterDetails?.existingBaseMinter as string) .use(baseMinterDetails?.existingBaseMinter as string)
?.batchMint(wallet.address, `ipfs://${baseUri}`, uploadDetails.assetFiles.length) ?.batchMint(wallet.address, `ipfs://${baseUri}`, uploadDetails.assetFiles.length)
@ -343,6 +343,8 @@ const CollectionCreationPage: NextPage = () => {
duration: 5000, duration: 5000,
}) })
setIsMintingComplete(true) setIsMintingComplete(true)
setSg721ContractAddress(baseMinterDetails?.selectedCollectionAddress as string)
setTransactionHash(result as string)
}) })
.catch((error) => { .catch((error) => {
toast.error(error.message, { style: { maxWidth: 'none' } }) toast.error(error.message, { style: { maxWidth: 'none' } })
@ -361,6 +363,9 @@ const CollectionCreationPage: NextPage = () => {
style: { maxWidth: 'none' }, style: { maxWidth: 'none' },
duration: 5000, duration: 5000,
}) })
setIsMintingComplete(true)
setSg721ContractAddress(baseMinterDetails?.selectedCollectionAddress as string)
setTransactionHash(result)
}) })
.catch((error) => { .catch((error) => {
toast.error(error.message, { style: { maxWidth: 'none' } }) toast.error(error.message, { style: { maxWidth: 'none' } })
@ -933,8 +938,9 @@ const CollectionCreationPage: NextPage = () => {
} }
} }
useEffect(() => { useEffect(() => {
if (vendingMinterContractAddress !== null) scrollRef.current?.scrollIntoView({ behavior: 'smooth' }) if (vendingMinterContractAddress !== null || isMintingComplete)
}, [vendingMinterContractAddress]) scrollRef.current?.scrollIntoView({ behavior: 'smooth' })
}, [vendingMinterContractAddress, isMintingComplete])
useEffect(() => { useEffect(() => {
setBaseTokenUri(uploadDetails?.baseTokenURI as string) setBaseTokenUri(uploadDetails?.baseTokenURI as string)
@ -981,7 +987,7 @@ const CollectionCreationPage: NextPage = () => {
</p> </p>
</div> </div>
<div className="mx-10" ref={scrollRef}> <div className="mx-10" ref={scrollRef}>
<Conditional test={vendingMinterContractAddress !== null}> <Conditional test={vendingMinterContractAddress !== null || isMintingComplete}>
<Alert className="mt-5" type="info"> <Alert className="mt-5" type="info">
<div> <div>
<Conditional test={minterType === 'vending' || isMintingComplete}> <Conditional test={minterType === 'vending' || isMintingComplete}>
@ -1007,7 +1013,66 @@ const CollectionCreationPage: NextPage = () => {
</Anchor> </Anchor>
)} )}
<br /> <br />
<Conditional test={vendingMinterContractAddress === null && isMintingComplete}>
Transaction Hash: {' '}
<Conditional test={NETWORK === 'testnet'}>
<Anchor
className="text-stargaze hover:underline"
external
href={`${BLOCK_EXPLORER_URL}/tx/${transactionHash as string}`}
>
{transactionHash}
</Anchor>
</Conditional> </Conditional>
<Conditional test={NETWORK === 'mainnet'}>
<Anchor
className="text-stargaze hover:underline"
external
href={`${BLOCK_EXPLORER_URL}/txs/${transactionHash as string}`}
>
{transactionHash}
</Anchor>
</Conditional>
<br />
Minter Contract Address:{' '}
<Anchor
className="text-stargaze hover:underline"
external
href={`/contracts/baseMinter/query/?contractAddress=${
baseMinterDetails?.existingBaseMinter as string
}`}
>
{baseMinterDetails?.existingBaseMinter as string}
</Anchor>
<br />
SG721 Contract Address:{' '}
<Anchor
className="text-stargaze hover:underline"
external
href={`/contracts/sg721/query/?contractAddress=${sg721ContractAddress as string}`}
>
{sg721ContractAddress}
</Anchor>
<br />
<div className="flex flex-row mt-2">
<AnchorButton className="text-white" external href={`${STARGAZE_URL}/profile/${wallet.address}`}>
Visit Your Profile
</AnchorButton>
<AnchorButton
className="ml-2 text-white"
external
href={`${STARGAZE_URL}/marketplace/${sg721ContractAddress as string}/${
baseMinterDetails?.collectionTokenCount
? (baseMinterDetails.collectionTokenCount + 1).toString()
: '1'
}`}
>
View the Token(s) on Marketplace
</AnchorButton>
</div>
</Conditional>
</Conditional>
<Conditional test={vendingMinterContractAddress !== null}>
Minter Contract Address:{' '} Minter Contract Address:{' '}
<Anchor <Anchor
className="text-stargaze hover:underline" className="text-stargaze hover:underline"
@ -1072,15 +1137,21 @@ const CollectionCreationPage: NextPage = () => {
</Button> </Button>
</Conditional> </Conditional>
<Conditional test={minterType === 'base'}> <Conditional test={minterType === 'base'}>
<Button className="mt-2"> <div className="flex flex-row mt-2">
<Anchor <AnchorButton className="text-white" external href={`${STARGAZE_URL}/profile/${wallet.address}`}>
className="text-white" Visit Your Profile
</AnchorButton>
<AnchorButton
className="ml-2 text-white"
external external
href={`${STARGAZE_URL}/marketplace/${sg721ContractAddress as string}?sort=price_asc`} href={`${STARGAZE_URL}/marketplace/${sg721ContractAddress as string}${
!isMintingComplete ? `?sort=price_asc` : `/1`
}`}
> >
View on Marketplace View the Collection on Marketplace
</Anchor> </AnchorButton>
</Button> </div>
</Conditional>
</Conditional> </Conditional>
</div> </div>
</Alert> </Alert>