2022-08-03 07:25:08 +00:00
/* eslint-disable eslint-comments/disable-enable-pair */
2023-05-26 11:50:35 +00:00
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
2023-02-26 09:42:21 +00:00
/* eslint-disable no-nested-ternary */
2023-01-24 11:14:29 +00:00
2022-08-16 07:04:33 +00:00
/* eslint-disable @typescript-eslint/restrict-template-expressions */
2022-08-04 09:16:42 +00:00
/* eslint-disable @typescript-eslint/no-unsafe-argument */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
2022-08-03 07:25:08 +00:00
2023-04-05 11:54:34 +00:00
import { toUtf8 } from '@cosmjs/encoding'
2022-08-04 09:16:42 +00:00
import { coin } from '@cosmjs/proto-signing'
2023-06-06 09:16:46 +00:00
import { Sidetab } from '@typeform/embed-react'
2023-06-29 19:26:09 +00:00
import axios from 'axios'
2022-12-13 12:52:43 +00:00
import clsx from 'clsx'
2022-08-10 12:04:18 +00:00
import { Alert } from 'components/Alert'
2022-08-10 09:42:00 +00:00
import { Anchor } from 'components/Anchor'
2023-04-04 12:30:05 +00:00
import { AnchorButton } from 'components/AnchorButton'
2022-08-15 08:50:15 +00:00
import { Button } from 'components/Button'
2022-08-04 09:16:42 +00:00
import {
CollectionDetails ,
MintingDetails ,
RoyaltyDetails ,
UploadDetails ,
WhitelistDetails ,
} from 'components/collections/creation'
2022-12-26 13:17:09 +00:00
import type { BaseMinterDetailsDataProps } from 'components/collections/creation/BaseMinterDetails'
import { BaseMinterDetails } from 'components/collections/creation/BaseMinterDetails'
2022-08-04 09:16:42 +00:00
import type { CollectionDetailsDataProps } from 'components/collections/creation/CollectionDetails'
import type { MintingDetailsDataProps } from 'components/collections/creation/MintingDetails'
import type { RoyaltyDetailsDataProps } from 'components/collections/creation/RoyaltyDetails'
import type { UploadDetailsDataProps } from 'components/collections/creation/UploadDetails'
import type { WhitelistDetailsDataProps } from 'components/collections/creation/WhitelistDetails'
2022-08-10 09:07:05 +00:00
import { Conditional } from 'components/Conditional'
2023-08-21 11:59:12 +00:00
import { FormControl } from 'components/FormControl'
2022-08-10 09:07:05 +00:00
import { LoadingModal } from 'components/LoadingModal'
2023-06-14 09:41:16 +00:00
import type { OpenEditionMinterCreatorDataProps } from 'components/openEdition/OpenEditionMinterCreator'
import { OpenEditionMinterCreator } from 'components/openEdition/OpenEditionMinterCreator'
2023-08-02 19:56:41 +00:00
import { flexibleVendingMinterList , openEditionMinterList , vendingMinterList } from 'config/minter'
2023-07-31 09:25:57 +00:00
import type { TokenInfo } from 'config/token'
2022-08-04 09:16:42 +00:00
import { useContracts } from 'contexts/contracts'
2023-05-03 18:18:09 +00:00
import { addLogItem } from 'contexts/log'
2022-08-04 09:16:42 +00:00
import { useWallet } from 'contexts/wallet'
2022-12-13 18:50:42 +00:00
import type { DispatchExecuteArgs as BaseFactoryDispatchExecuteArgs } from 'contracts/baseFactory/messages/execute'
import { dispatchExecute as baseFactoryDispatchExecute } from 'contracts/baseFactory/messages/execute'
import type { DispatchExecuteArgs as VendingFactoryDispatchExecuteArgs } from 'contracts/vendingFactory/messages/execute'
import { dispatchExecute as vendingFactoryDispatchExecute } from 'contracts/vendingFactory/messages/execute'
2022-07-27 06:49:36 +00:00
import type { NextPage } from 'next'
import { NextSeo } from 'next-seo'
2023-07-25 19:24:40 +00:00
import type { ChangeEvent } from 'react'
2023-06-29 19:26:09 +00:00
import { useCallback , useEffect , useMemo , useRef , useState } from 'react'
2022-08-03 07:25:08 +00:00
import { toast } from 'react-hot-toast'
import { upload } from 'services/upload'
2022-08-09 11:42:55 +00:00
import { compareFileArrays } from 'utils/compareFileArrays'
2022-09-23 17:36:34 +00:00
import {
2022-12-13 18:50:42 +00:00
BASE_FACTORY_ADDRESS ,
2023-02-26 09:36:34 +00:00
BASE_FACTORY_UPDATABLE_ADDRESS ,
2022-09-23 17:36:34 +00:00
BLOCK_EXPLORER_URL ,
NETWORK ,
2023-06-13 09:04:08 +00:00
OPEN_EDITION_FACTORY_ADDRESS ,
2023-06-14 09:41:16 +00:00
OPEN_EDITION_UPDATABLE_FACTORY_ADDRESS ,
2022-09-23 17:36:34 +00:00
SG721_CODE_ID ,
2023-02-26 09:36:34 +00:00
SG721_UPDATABLE_CODE_ID ,
2022-09-23 17:36:34 +00:00
STARGAZE_URL ,
2023-06-29 19:26:09 +00:00
SYNC_COLLECTIONS_API_URL ,
2022-10-21 01:02:52 +00:00
VENDING_FACTORY_ADDRESS ,
2023-04-27 17:19:42 +00:00
VENDING_FACTORY_FLEX_ADDRESS ,
2023-02-26 09:36:34 +00:00
VENDING_FACTORY_UPDATABLE_ADDRESS ,
2022-09-23 17:36:34 +00:00
WHITELIST_CODE_ID ,
2023-04-27 17:19:42 +00:00
WHITELIST_FLEX_CODE_ID ,
2022-09-23 17:36:34 +00:00
} from 'utils/constants'
2023-07-03 14:17:16 +00:00
import { checkTokenUri } from 'utils/isValidTokenUri'
2022-07-27 06:49:36 +00:00
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
2023-05-03 18:18:09 +00:00
import { uid } from 'utils/random'
2022-08-03 07:25:08 +00:00
2022-12-13 12:52:43 +00:00
import type { MinterType } from '../../components/collections/actions/Combobox'
2022-08-16 07:04:33 +00:00
import type { UploadMethod } from '../../components/collections/creation/UploadDetails'
2022-09-01 06:27:23 +00:00
import { ConfirmationModal } from '../../components/ConfirmationModal'
2023-07-31 09:25:57 +00:00
import type { OpenEditionMinterDetailsDataProps } from '../../components/openEdition/OpenEditionMinterCreator'
2023-07-31 13:49:35 +00:00
import { stars , tokensList } from '../../config/token'
2022-08-09 09:08:10 +00:00
import { getAssetType } from '../../utils/getAssetType'
2023-01-12 10:01:11 +00:00
import { isValidAddress } from '../../utils/isValidAddress'
2022-08-09 09:08:10 +00:00
2022-08-04 09:16:42 +00:00
const CollectionCreationPage : NextPage = ( ) = > {
const wallet = useWallet ( )
2022-10-21 01:02:52 +00:00
const {
2022-12-13 18:50:42 +00:00
baseMinter : baseMinterContract ,
2022-12-09 08:27:50 +00:00
vendingMinter : vendingMinterContract ,
2022-10-21 01:02:52 +00:00
whitelist : whitelistContract ,
vendingFactory : vendingFactoryContract ,
2022-12-13 18:50:42 +00:00
baseFactory : baseFactoryContract ,
2022-10-21 01:02:52 +00:00
} = useContracts ( )
2022-08-10 12:04:18 +00:00
const scrollRef = useRef < HTMLDivElement > ( null )
2023-06-28 15:24:43 +00:00
const sidetabRef = useRef < any > ( null )
2022-10-21 04:14:49 +00:00
2023-07-25 19:24:40 +00:00
const [ importedDetails , setImportedDetails ] = useState < {
minterType : MinterType
collectionDetails : CollectionDetailsDataProps
uploadDetails : UploadDetailsDataProps
mintingDetails : MintingDetailsDataProps
whitelistDetails : WhitelistDetailsDataProps
royaltyDetails : RoyaltyDetailsDataProps
baseMinterDetails : BaseMinterDetailsDataProps
openEditionMinterDetails : OpenEditionMinterDetailsDataProps
} > ( )
2022-08-04 09:16:42 +00:00
const [ uploadDetails , setUploadDetails ] = useState < UploadDetailsDataProps | null > ( null )
const [ collectionDetails , setCollectionDetails ] = useState < CollectionDetailsDataProps | null > ( null )
2022-12-26 13:17:09 +00:00
const [ baseMinterDetails , setBaseMinterDetails ] = useState < BaseMinterDetailsDataProps | null > ( null )
2023-07-31 09:25:57 +00:00
const [ openEditionMinterCreatorData , setOpenEditionMinterCreatorData ] =
useState < OpenEditionMinterCreatorDataProps | null > ( null )
const [ openEditionMinterDetails , setOpenEditionMinterDetails ] = useState < OpenEditionMinterDetailsDataProps | null > (
2023-06-14 09:41:16 +00:00
null ,
)
2022-08-04 09:16:42 +00:00
const [ mintingDetails , setMintingDetails ] = useState < MintingDetailsDataProps | null > ( null )
const [ whitelistDetails , setWhitelistDetails ] = useState < WhitelistDetailsDataProps | null > ( null )
const [ royaltyDetails , setRoyaltyDetails ] = useState < RoyaltyDetailsDataProps | null > ( null )
2022-12-13 12:52:43 +00:00
const [ minterType , setMinterType ] = useState < MinterType > ( 'vending' )
2022-08-04 09:16:42 +00:00
2023-04-01 13:45:49 +00:00
const [ vendingMinterCreationFee , setVendingMinterCreationFee ] = useState < string | null > ( null )
const [ baseMinterCreationFee , setBaseMinterCreationFee ] = useState < string | null > ( null )
const [ vendingMinterUpdatableCreationFee , setVendingMinterUpdatableCreationFee ] = useState < string | null > ( null )
2023-06-14 09:41:16 +00:00
const [ openEditionMinterCreationFee , setOpenEditionMinterCreationFee ] = useState < string | null > ( null )
const [ openEditionMinterUpdatableCreationFee , setOpenEditionMinterUpdatableCreationFee ] = useState < string | null > (
null ,
)
2023-04-27 17:19:42 +00:00
const [ vendingMinterFlexCreationFee , setVendingMinterFlexCreationFee ] = useState < string | null > ( null )
2023-04-01 13:45:49 +00:00
const [ baseMinterUpdatableCreationFee , setBaseMinterUpdatableCreationFee ] = useState < string | null > ( null )
2023-04-07 09:24:38 +00:00
const [ minimumMintPrice , setMinimumMintPrice ] = useState < string | null > ( '0' )
const [ minimumUpdatableMintPrice , setMinimumUpdatableMintPrice ] = useState < string | null > ( '0' )
2023-06-14 09:41:16 +00:00
const [ minimumOpenEditionMintPrice , setMinimumOpenEditionMintPrice ] = useState < string | null > ( '0' )
const [ minimumOpenEditionUpdatableMintPrice , setMinimumOpenEditionUpdatableMintPrice ] = useState < string | null > ( '0' )
2023-04-27 17:19:42 +00:00
const [ minimumFlexMintPrice , setMinimumFlexMintPrice ] = useState < string | null > ( '0' )
2023-04-01 13:45:49 +00:00
2023-07-31 13:49:35 +00:00
const [ mintTokenFromOpenEditionFactory , setMintTokenFromOpenEditionFactory ] = useState < TokenInfo | undefined > ( stars )
2023-08-02 19:56:41 +00:00
const [ mintTokenFromVendingFactory , setMintTokenFromVendingFactory ] = useState < TokenInfo | undefined > ( stars )
2023-08-06 15:44:22 +00:00
const [ vendingFactoryAddress , setVendingFactoryAddress ] = useState < string | null > ( VENDING_FACTORY_ADDRESS )
const vendingFactoryMessages = useMemo (
( ) = > vendingFactoryContract ? . use ( vendingFactoryAddress as string ) ,
2023-08-29 11:13:57 +00:00
[ vendingFactoryContract , wallet . address , vendingFactoryAddress ] ,
2023-08-06 15:44:22 +00:00
)
const baseFactoryMessages = useMemo (
( ) = > baseFactoryContract ? . use ( BASE_FACTORY_ADDRESS ) ,
[ baseFactoryContract , wallet . address ] ,
)
2023-07-31 09:25:57 +00:00
2022-08-10 09:07:05 +00:00
const [ uploading , setUploading ] = useState ( false )
2022-12-26 13:17:09 +00:00
const [ isMintingComplete , setIsMintingComplete ] = useState ( false )
2023-08-15 17:07:51 +00:00
const [ initialParametersFetched , setInitialParametersFetched ] = useState ( false )
2022-09-02 18:45:42 +00:00
const [ creatingCollection , setCreatingCollection ] = useState ( false )
2022-12-13 12:52:43 +00:00
const [ readyToCreateVm , setReadyToCreateVm ] = useState ( false )
const [ readyToCreateBm , setReadyToCreateBm ] = useState ( false )
const [ readyToUploadAndMint , setReadyToUploadAndMint ] = useState ( false )
2022-12-09 08:27:50 +00:00
const [ vendingMinterContractAddress , setVendingMinterContractAddress ] = useState < string | null > ( null )
2022-08-10 12:04:18 +00:00
const [ sg721ContractAddress , setSg721ContractAddress ] = useState < string | null > ( null )
2022-09-11 17:54:28 +00:00
const [ whitelistContractAddress , setWhitelistContractAddress ] = useState < string | null | undefined > ( null )
2022-08-10 12:04:18 +00:00
const [ baseTokenUri , setBaseTokenUri ] = useState < string | null > ( null )
2022-08-16 07:04:33 +00:00
const [ coverImageUrl , setCoverImageUrl ] = useState < string | null > ( null )
2022-08-04 09:16:42 +00:00
const [ transactionHash , setTransactionHash ] = useState < string | null > ( null )
2022-12-13 12:52:43 +00:00
const performVendingMinterChecks = ( ) = > {
2022-09-01 06:27:23 +00:00
try {
2022-12-13 12:52:43 +00:00
setReadyToCreateVm ( false )
2022-09-08 06:22:27 +00:00
checkUploadDetails ( )
checkCollectionDetails ( )
checkMintingDetails ( )
2023-07-04 05:20:28 +00:00
void checkExistingTokenURI ( )
2022-10-06 13:16:58 +00:00
. then ( ( ) = > {
2023-07-04 05:20:28 +00:00
void checkRoyaltyDetails ( )
2023-04-05 11:54:34 +00:00
. then ( ( ) = > {
2023-07-04 05:20:28 +00:00
checkWhitelistDetails ( )
. then ( ( ) = > {
2023-07-05 06:01:10 +00:00
void checkwalletBalance ( )
. then ( ( ) = > {
setReadyToCreateVm ( true )
} )
. catch ( ( error ) = > {
toast . error ( ` ${ error . message } ` , { style : { maxWidth : 'none' } } )
addLogItem ( { id : uid ( ) , message : error.message , type : 'Error' , timestamp : new Date ( ) } )
setReadyToCreateVm ( false )
} )
2023-07-04 05:20:28 +00:00
} )
. 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 )
} )
2023-04-05 11:54:34 +00:00
} )
2023-05-03 18:18:09 +00:00
. catch ( ( error ) = > {
2023-07-04 05:20:28 +00:00
toast . error ( ` Error in Royalty Details: ${ error . message } ` , { style : { maxWidth : 'none' } } )
addLogItem ( { id : uid ( ) , message : error.message , type : 'Error' , timestamp : new Date ( ) } )
2023-04-05 11:54:34 +00:00
setReadyToCreateVm ( false )
} )
2022-10-06 13:16:58 +00:00
} )
2023-05-03 18:18:09 +00:00
. catch ( ( error ) = > {
2023-07-04 05:20:28 +00:00
toast . error ( ` Error in Base Token URI: ${ error . message } ` , { style : { maxWidth : 'none' } } )
2023-05-03 18:18:09 +00:00
addLogItem ( { id : uid ( ) , message : error.message , type : 'Error' , timestamp : new Date ( ) } )
2022-12-13 12:52:43 +00:00
setReadyToCreateVm ( false )
2022-10-06 13:16:58 +00:00
} )
2022-09-01 06:27:23 +00:00
} catch ( error : any ) {
2022-11-02 07:53:17 +00:00
toast . error ( error . message , { style : { maxWidth : 'none' } } )
2023-05-03 18:18:09 +00:00
addLogItem ( { id : uid ( ) , message : error.message , type : 'Error' , timestamp : new Date ( ) } )
2022-09-01 06:27:23 +00:00
setUploading ( false )
2022-12-21 07:36:43 +00:00
setReadyToCreateVm ( false )
2022-09-01 06:27:23 +00:00
}
}
2022-12-13 12:52:43 +00:00
const performBaseMinterChecks = ( ) = > {
try {
setReadyToCreateBm ( false )
checkUploadDetails ( )
2022-12-13 18:50:42 +00:00
checkCollectionDetails ( )
2023-07-03 14:17:16 +00:00
void checkExistingTokenURI ( )
2022-12-13 12:52:43 +00:00
. then ( ( ) = > {
2023-07-03 14:17:16 +00:00
void checkRoyaltyDetails ( )
2023-04-05 11:54:34 +00:00
. then ( ( ) = > {
2023-07-03 14:17:16 +00:00
checkWhitelistDetails ( )
. then ( ( ) = > {
2023-07-05 06:01:10 +00:00
void checkwalletBalance ( )
. then ( ( ) = > {
setReadyToCreateBm ( true )
} )
. catch ( ( error ) = > {
toast . error ( ` ${ error . message } ` , { style : { maxWidth : 'none' } } )
addLogItem ( { id : uid ( ) , message : error.message , type : 'Error' , timestamp : new Date ( ) } )
setReadyToCreateVm ( false )
} )
2023-07-03 14:17:16 +00:00
} )
. catch ( ( error ) = > {
toast . error ( ` ${ error . message } ` , { style : { maxWidth : 'none' } } )
addLogItem ( { id : uid ( ) , message : error.message , type : 'Error' , timestamp : new Date ( ) } )
setReadyToCreateBm ( false )
} )
2023-04-05 11:54:34 +00:00
} )
2023-05-03 18:18:09 +00:00
. catch ( ( error ) = > {
2023-07-03 14:17:16 +00:00
toast . error ( ` Error in Royalty Configuration: ${ error . message } ` , { style : { maxWidth : 'none' } } )
2023-05-03 18:18:09 +00:00
addLogItem ( { id : uid ( ) , message : error.message , type : 'Error' , timestamp : new Date ( ) } )
2023-04-05 11:54:34 +00:00
setReadyToCreateBm ( false )
} )
2022-12-13 12:52:43 +00:00
} )
2023-05-03 18:18:09 +00:00
. catch ( ( error ) = > {
2023-07-03 14:17:16 +00:00
toast . error ( ` Error in Existing Token URI: ${ error . message } ` , { style : { maxWidth : 'none' } } )
2023-05-03 18:18:09 +00:00
addLogItem ( { id : uid ( ) , message : error.message , type : 'Error' , timestamp : new Date ( ) } )
2022-12-13 12:52:43 +00:00
setReadyToCreateBm ( false )
} )
} catch ( error : any ) {
toast . error ( error . message , { style : { maxWidth : 'none' } } )
2023-05-03 18:18:09 +00:00
addLogItem ( { id : uid ( ) , message : error.message , type : 'Error' , timestamp : new Date ( ) } )
2022-12-13 12:52:43 +00:00
setUploading ( false )
}
}
const performUploadAndMintChecks = ( ) = > {
try {
setReadyToUploadAndMint ( false )
checkUploadDetails ( )
2023-07-03 14:17:16 +00:00
checkExistingTokenURI ( )
2022-12-13 12:52:43 +00:00
. then ( ( ) = > {
2023-07-03 14:17:16 +00:00
checkWhitelistDetails ( )
. then ( ( ) = > {
setReadyToUploadAndMint ( true )
} )
. catch ( ( error ) = > {
toast . error ( ` ${ error . message } ` , { style : { maxWidth : 'none' } } )
addLogItem ( { id : uid ( ) , message : error.message , type : 'Error' , timestamp : new Date ( ) } )
setReadyToUploadAndMint ( false )
} )
2022-12-13 12:52:43 +00:00
} )
2023-05-03 18:18:09 +00:00
. catch ( ( error ) = > {
2023-07-03 14:17:16 +00:00
toast . error ( ` Error in Token URI: ${ error . message } ` , { style : { maxWidth : 'none' } } )
2023-05-03 18:18:09 +00:00
addLogItem ( { id : uid ( ) , message : error.message , type : 'Error' , timestamp : new Date ( ) } )
2022-12-13 12:52:43 +00:00
setReadyToUploadAndMint ( false )
} )
} catch ( error : any ) {
toast . error ( error . message , { style : { maxWidth : 'none' } } )
2023-05-03 18:18:09 +00:00
addLogItem ( { id : uid ( ) , message : error.message , type : 'Error' , timestamp : new Date ( ) } )
2022-12-13 12:52:43 +00:00
setUploading ( false )
}
}
2022-12-13 18:50:42 +00:00
const resetReadyFlags = ( ) = > {
setReadyToCreateVm ( false )
setReadyToCreateBm ( false )
setReadyToUploadAndMint ( false )
}
2022-12-13 12:52:43 +00:00
const createVendingMinterCollection = async ( ) = > {
try {
setCreatingCollection ( true )
setBaseTokenUri ( null )
setCoverImageUrl ( null )
setVendingMinterContractAddress ( null )
setSg721ContractAddress ( null )
setWhitelistContractAddress ( null )
setTransactionHash ( null )
if ( uploadDetails ? . uploadMethod === 'new' ) {
setUploading ( true )
const baseUri = await uploadFiles ( )
//upload coverImageUri and append the file name
const coverImageUri = await upload (
collectionDetails ? . imageFile as File [ ] ,
uploadDetails . uploadService ,
'cover' ,
uploadDetails . nftStorageApiKey as string ,
uploadDetails . pinataApiKey as string ,
uploadDetails . pinataSecretKey as string ,
)
setUploading ( false )
setBaseTokenUri ( baseUri )
setCoverImageUrl ( coverImageUri )
let whitelist : string | undefined
2023-04-24 10:14:06 +00:00
if ( whitelistDetails ? . whitelistState === 'existing' ) whitelist = whitelistDetails . contractAddress
else if ( whitelistDetails ? . whitelistState === 'new' ) whitelist = await instantiateWhitelist ( )
2022-12-13 12:52:43 +00:00
setWhitelistContractAddress ( whitelist as string )
2022-12-13 18:50:42 +00:00
await instantiateVendingMinter ( baseUri , coverImageUri , whitelist )
2022-12-13 12:52:43 +00:00
} else {
setBaseTokenUri ( uploadDetails ? . baseTokenURI as string )
setCoverImageUrl ( uploadDetails ? . imageUrl as string )
let whitelist : string | undefined
2023-04-24 10:14:06 +00:00
if ( whitelistDetails ? . whitelistState === 'existing' ) whitelist = whitelistDetails . contractAddress
else if ( whitelistDetails ? . whitelistState === 'new' ) whitelist = await instantiateWhitelist ( )
2022-12-13 12:52:43 +00:00
setWhitelistContractAddress ( whitelist as string )
2022-12-13 18:50:42 +00:00
await instantiateVendingMinter ( baseTokenUri as string , coverImageUrl as string , whitelist )
2022-12-13 12:52:43 +00:00
}
setCreatingCollection ( false )
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch ( error : any ) {
2023-02-04 08:10:06 +00:00
toast . error ( error . message , { style : { maxWidth : 'none' } , duration : 10000 } )
2023-05-03 18:18:09 +00:00
addLogItem ( { id : uid ( ) , message : error.message , type : 'Error' , timestamp : new Date ( ) } )
2022-12-13 12:52:43 +00:00
setCreatingCollection ( false )
setUploading ( false )
}
}
const createBaseMinterCollection = async ( ) = > {
try {
setCreatingCollection ( true )
setBaseTokenUri ( null )
setCoverImageUrl ( null )
setVendingMinterContractAddress ( null )
2022-12-26 13:17:09 +00:00
setIsMintingComplete ( false )
2022-12-13 12:52:43 +00:00
setSg721ContractAddress ( null )
setWhitelistContractAddress ( null )
setTransactionHash ( null )
if ( uploadDetails ? . uploadMethod === 'new' ) {
setUploading ( true )
const baseUri = await uploadFiles ( )
//upload coverImageUri and append the file name
const coverImageUri = await upload (
collectionDetails ? . imageFile as File [ ] ,
uploadDetails . uploadService ,
'cover' ,
uploadDetails . nftStorageApiKey as string ,
uploadDetails . pinataApiKey as string ,
uploadDetails . pinataSecretKey as string ,
)
setUploading ( false )
2023-01-16 13:48:38 +00:00
if ( uploadDetails . assetFiles . length === 1 ) {
setBaseTokenUri (
` ${ baseUri } / ${ ( uploadDetails . baseMinterMetadataFile as File ) . name . substring (
0 ,
( uploadDetails . baseMinterMetadataFile as File ) . name . lastIndexOf ( '.' ) ,
) } ` ,
)
} else {
setBaseTokenUri ( baseUri )
}
2022-12-13 12:52:43 +00:00
setCoverImageUrl ( coverImageUri )
2023-01-16 13:48:38 +00:00
if ( uploadDetails . assetFiles . length === 1 ) {
await instantiateBaseMinter (
` ipfs:// ${ baseUri } / ${ ( uploadDetails . baseMinterMetadataFile as File ) . name . substring (
0 ,
( uploadDetails . baseMinterMetadataFile as File ) . name . lastIndexOf ( '.' ) ,
) } ` ,
coverImageUri ,
)
} else {
await instantiateBaseMinter ( ` ipfs:// ${ baseUri } ` , coverImageUri )
}
2022-12-13 12:52:43 +00:00
} else {
setBaseTokenUri ( uploadDetails ? . baseTokenURI as string )
setCoverImageUrl ( uploadDetails ? . imageUrl as string )
2022-12-13 18:50:42 +00:00
await instantiateBaseMinter ( uploadDetails ? . baseTokenURI as string , uploadDetails ? . imageUrl as string )
2022-12-13 12:52:43 +00:00
}
setCreatingCollection ( false )
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch ( error : any ) {
2023-02-04 08:10:06 +00:00
toast . error ( error . message , { style : { maxWidth : 'none' } , duration : 10000 } )
2023-05-03 18:18:09 +00:00
addLogItem ( { id : uid ( ) , message : error.message , type : 'Error' , timestamp : new Date ( ) } )
2022-12-13 12:52:43 +00:00
setCreatingCollection ( false )
setUploading ( false )
}
}
const uploadAndMint = async ( ) = > {
2022-08-04 09:16:42 +00:00
try {
2022-12-13 18:50:42 +00:00
if ( ! wallet . initialized ) throw new Error ( 'Wallet not connected' )
if ( ! baseMinterContract ) throw new Error ( 'Contract not found' )
2022-09-02 18:45:42 +00:00
setCreatingCollection ( true )
2023-04-04 12:30:05 +00:00
setIsMintingComplete ( false )
2022-08-10 12:04:18 +00:00
setBaseTokenUri ( null )
2022-08-16 07:04:33 +00:00
setCoverImageUrl ( null )
2022-12-09 08:27:50 +00:00
setVendingMinterContractAddress ( null )
2022-08-10 12:04:18 +00:00
setSg721ContractAddress ( null )
setTransactionHash ( null )
2022-08-16 07:04:33 +00:00
if ( uploadDetails ? . uploadMethod === 'new' ) {
2022-12-26 13:17:09 +00:00
console . log ( JSON . stringify ( uploadDetails . baseMinterMetadataFile ? . text ( ) ) )
2022-08-16 07:04:33 +00:00
setUploading ( true )
2022-12-13 18:50:42 +00:00
await uploadFiles ( )
. then ( async ( baseUri ) = > {
setUploading ( false )
2023-01-17 13:23:17 +00:00
if ( uploadDetails . assetFiles . length === 1 ) {
setBaseTokenUri (
` ${ baseUri } / ${ ( uploadDetails . baseMinterMetadataFile as File ) . name . substring (
2022-12-26 13:17:09 +00:00
0 ,
( uploadDetails . baseMinterMetadataFile as File ) . name . lastIndexOf ( '.' ) ,
) } ` ,
)
2023-01-17 13:23:17 +00:00
const result = await baseMinterContract
. use ( baseMinterDetails ? . existingBaseMinter as string )
? . mint (
wallet . address ,
` ipfs:// ${ baseUri } / ${ ( uploadDetails . baseMinterMetadataFile as File ) . name . substring (
0 ,
( uploadDetails . baseMinterMetadataFile as File ) . name . lastIndexOf ( '.' ) ,
) } ` ,
)
console . log ( result )
return result
}
setBaseTokenUri ( baseUri )
const result = await baseMinterContract
. use ( baseMinterDetails ? . existingBaseMinter as string )
? . batchMint ( wallet . address , ` ipfs:// ${ baseUri } ` , uploadDetails . assetFiles . length )
2022-12-13 18:50:42 +00:00
console . log ( result )
return result
} )
. then ( ( result ) = > {
2023-03-31 16:25:32 +00:00
toast . success ( ` Token(s) minted & added to the collection successfully! Tx Hash: ${ result } ` , {
2023-01-08 17:09:05 +00:00
style : { maxWidth : 'none' } ,
duration : 5000 ,
} )
2022-12-26 13:17:09 +00:00
setIsMintingComplete ( true )
2023-04-04 12:30:05 +00:00
setSg721ContractAddress ( baseMinterDetails ? . selectedCollectionAddress as string )
setTransactionHash ( result as string )
2022-12-13 18:50:42 +00:00
} )
. catch ( ( error ) = > {
toast . error ( error . message , { style : { maxWidth : 'none' } } )
2023-05-03 18:18:09 +00:00
addLogItem ( { id : uid ( ) , message : error.message , type : 'Error' , timestamp : new Date ( ) } )
2022-12-13 18:50:42 +00:00
setUploading ( false )
setCreatingCollection ( false )
2022-12-26 13:17:09 +00:00
setIsMintingComplete ( false )
2022-12-13 18:50:42 +00:00
} )
2022-08-16 07:04:33 +00:00
} else {
setBaseTokenUri ( uploadDetails ? . baseTokenURI as string )
2022-12-13 18:50:42 +00:00
setUploading ( false )
await baseMinterContract
2022-12-26 13:17:09 +00:00
. use ( baseMinterDetails ? . existingBaseMinter as string )
? . mint ( wallet . address , ` ${ uploadDetails ? . baseTokenURI ? . trim ( ) } ` )
2022-12-13 18:50:42 +00:00
. then ( ( result ) = > {
2023-03-31 16:25:32 +00:00
toast . success ( ` Token minted & added to the collection successfully! Tx Hash: ${ result } ` , {
2023-01-08 17:09:05 +00:00
style : { maxWidth : 'none' } ,
duration : 5000 ,
} )
2023-04-04 12:30:05 +00:00
setIsMintingComplete ( true )
setSg721ContractAddress ( baseMinterDetails ? . selectedCollectionAddress as string )
setTransactionHash ( result )
2022-12-13 18:50:42 +00:00
} )
. catch ( ( error ) = > {
toast . error ( error . message , { style : { maxWidth : 'none' } } )
2023-05-03 18:18:09 +00:00
addLogItem ( { id : uid ( ) , message : error.message , type : 'Error' , timestamp : new Date ( ) } )
2022-12-13 18:50:42 +00:00
setUploading ( false )
setCreatingCollection ( false )
} )
2022-08-16 07:04:33 +00:00
}
2022-09-02 18:45:42 +00:00
setCreatingCollection ( false )
2022-08-04 09:16:42 +00:00
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch ( error : any ) {
2022-11-02 07:53:17 +00:00
toast . error ( error . message , { style : { maxWidth : 'none' } } )
2023-05-03 18:18:09 +00:00
addLogItem ( { id : uid ( ) , message : error.message , type : 'Error' , timestamp : new Date ( ) } )
2022-09-02 18:45:42 +00:00
setCreatingCollection ( false )
2022-08-10 09:07:05 +00:00
setUploading ( false )
2022-08-04 09:16:42 +00:00
}
2022-08-03 07:25:08 +00:00
}
2022-08-04 09:16:42 +00:00
const instantiateWhitelist = async ( ) = > {
if ( ! wallet . initialized ) throw new Error ( 'Wallet not connected' )
if ( ! whitelistContract ) throw new Error ( 'Contract not found' )
2023-04-27 17:19:42 +00:00
const standardMsg = {
2022-08-04 09:16:42 +00:00
members : whitelistDetails?.members ,
start_time : whitelistDetails?.startTime ,
end_time : whitelistDetails?.endTime ,
2023-08-06 18:09:43 +00:00
mint_price : coin (
String ( Number ( whitelistDetails ? . unitPrice ) ) ,
mintTokenFromVendingFactory ? mintTokenFromVendingFactory . denom : 'ustars' ,
) ,
2022-08-04 09:16:42 +00:00
per_address_limit : whitelistDetails?.perAddressLimit ,
member_limit : whitelistDetails?.memberLimit ,
2023-03-08 20:53:12 +00:00
admins : whitelistDetails?.admins || [ wallet . address ] ,
admins_mutable : whitelistDetails?.adminsMutable ,
2022-08-03 07:25:08 +00:00
}
2022-08-04 09:16:42 +00:00
2023-04-27 17:19:42 +00:00
const flexMsg = {
members : whitelistDetails?.members ,
start_time : whitelistDetails?.startTime ,
end_time : whitelistDetails?.endTime ,
2023-08-06 18:09:43 +00:00
mint_price : coin (
String ( Number ( whitelistDetails ? . unitPrice ) ) ,
mintTokenFromVendingFactory ? mintTokenFromVendingFactory . denom : 'ustars' ,
) ,
2023-04-27 17:19:42 +00:00
member_limit : whitelistDetails?.memberLimit ,
admins : whitelistDetails?.admins || [ wallet . address ] ,
admins_mutable : whitelistDetails?.adminsMutable ,
}
2023-03-18 06:48:49 +00:00
const data = await whitelistContract . instantiate (
2023-04-27 17:19:42 +00:00
whitelistDetails ? . whitelistType === 'standard' ? WHITELIST_CODE_ID : WHITELIST_FLEX_CODE_ID ,
whitelistDetails ? . whitelistType === 'standard' ? standardMsg : flexMsg ,
2023-03-18 06:48:49 +00:00
'Stargaze Whitelist Contract' ,
wallet . address ,
)
2022-08-04 09:16:42 +00:00
return data . contractAddress
2022-08-03 07:25:08 +00:00
}
2022-12-13 18:50:42 +00:00
const instantiateVendingMinter = async ( baseUri : string , coverImageUri : string , whitelist? : string ) = > {
2022-08-04 09:16:42 +00:00
if ( ! wallet . initialized ) throw new Error ( 'Wallet not connected' )
2022-12-13 18:50:42 +00:00
if ( ! vendingFactoryContract ) throw new Error ( 'Contract not found' )
2022-08-04 09:16:42 +00:00
let royaltyInfo = null
2022-08-05 11:13:27 +00:00
if ( royaltyDetails ? . royaltyType === 'new' ) {
2022-08-04 09:16:42 +00:00
royaltyInfo = {
2023-04-05 13:46:18 +00:00
payment_address : royaltyDetails.paymentAddress.trim ( ) ,
2022-08-09 11:42:55 +00:00
share : ( Number ( royaltyDetails . share ) / 100 ) . toString ( ) ,
2022-08-03 07:25:08 +00:00
}
}
2022-09-01 06:27:23 +00:00
2022-08-04 09:16:42 +00:00
const msg = {
2022-10-21 01:02:52 +00:00
create_minter : {
init_msg : {
2022-10-27 07:15:26 +00:00
base_token_uri : ` ${ uploadDetails ? . uploadMethod === 'new' ? ` ipfs:// ${ baseUri } ` : ` ${ baseUri } ` } ` ,
2022-10-21 01:02:52 +00:00
start_time : mintingDetails?.startTime ,
num_tokens : mintingDetails?.numTokens ,
2023-03-18 13:11:40 +00:00
payment_address : mintingDetails?.paymentAddress ? mintingDetails.paymentAddress : undefined ,
2022-10-21 01:02:52 +00:00
mint_price : {
amount : mintingDetails?.unitPrice ,
2023-08-02 19:56:41 +00:00
denom : ( mintTokenFromVendingFactory ? . denom as string ) || 'ustars' ,
2022-10-21 01:02:52 +00:00
} ,
per_address_limit : mintingDetails?.perAddressLimit ,
whitelist ,
} ,
collection_params : {
2023-08-06 18:57:03 +00:00
code_id : collectionDetails?.updatable ? SG721_UPDATABLE_CODE_ID : SG721_CODE_ID ,
2022-10-21 01:02:52 +00:00
name : collectionDetails?.name ,
symbol : collectionDetails ? . symbol ,
info : {
creator : wallet.address ,
2023-08-04 08:54:22 +00:00
description : collectionDetails?.description.replaceAll ( '\\n' , '\n' ) ,
2022-10-21 01:02:52 +00:00
image : ` ${
uploadDetails ? . uploadMethod === 'new'
? ` ipfs:// ${ coverImageUri } / ${ collectionDetails ? . imageFile [ 0 ] . name as string } `
: ` ${ coverImageUri } `
} ` ,
external_link : collectionDetails?.externalLink ,
explicit_content : collectionDetails?.explicit ,
royalty_info : royaltyInfo ,
start_trading_time : collectionDetails?.startTradingTime || null ,
} ,
2022-08-04 09:16:42 +00:00
} ,
} ,
2022-08-03 07:25:08 +00:00
}
2022-12-13 18:50:42 +00:00
const payload : VendingFactoryDispatchExecuteArgs = {
2023-08-06 15:44:22 +00:00
contract : vendingFactoryAddress as string ,
2022-12-13 18:50:42 +00:00
messages : vendingFactoryMessages ,
2022-10-21 01:02:52 +00:00
txSigner : wallet.address ,
msg ,
2023-04-01 13:45:49 +00:00
funds : [
coin (
2023-04-28 12:00:39 +00:00
whitelistDetails ? . whitelistState !== 'none' && whitelistDetails ? . whitelistType === 'flex'
2023-04-27 17:19:42 +00:00
? ( vendingMinterFlexCreationFee as string )
: collectionDetails ? . updatable
2023-04-01 13:45:49 +00:00
? ( vendingMinterUpdatableCreationFee as string )
: ( vendingMinterCreationFee as string ) ,
'ustars' ,
) ,
] ,
2023-02-26 10:08:03 +00:00
updatable : collectionDetails?.updatable ,
2023-04-28 12:00:39 +00:00
flex : whitelistDetails?.whitelistState !== 'none' && whitelistDetails ? . whitelistType === 'flex' ,
2022-10-21 01:02:52 +00:00
}
2022-12-13 18:50:42 +00:00
const data = await vendingFactoryDispatchExecute ( payload )
2022-08-04 09:16:42 +00:00
setTransactionHash ( data . transactionHash )
2022-12-09 08:27:50 +00:00
setVendingMinterContractAddress ( data . vendingMinterAddress )
2022-10-21 01:02:52 +00:00
setSg721ContractAddress ( data . sg721Address )
2022-08-04 09:16:42 +00:00
}
2022-12-13 18:50:42 +00:00
const instantiateBaseMinter = async ( baseUri : string , coverImageUri : string ) = > {
if ( ! wallet . initialized ) throw new Error ( 'Wallet not connected' )
if ( ! baseFactoryContract ) throw new Error ( 'Contract not found' )
2022-12-15 11:59:05 +00:00
if ( ! baseMinterContract ) throw new Error ( 'Contract not found' )
2022-12-13 18:50:42 +00:00
let royaltyInfo = null
if ( royaltyDetails ? . royaltyType === 'new' ) {
royaltyInfo = {
2023-04-05 13:46:18 +00:00
payment_address : royaltyDetails.paymentAddress.trim ( ) ,
2022-12-13 18:50:42 +00:00
share : ( Number ( royaltyDetails . share ) / 100 ) . toString ( ) ,
}
}
const msg = {
create_minter : {
init_msg : null ,
collection_params : {
2023-02-26 09:36:34 +00:00
code_id : collectionDetails?.updatable ? SG721_UPDATABLE_CODE_ID : SG721_CODE_ID ,
2022-12-13 18:50:42 +00:00
name : collectionDetails?.name ,
symbol : collectionDetails ? . symbol ,
info : {
creator : wallet.address ,
2023-08-04 08:54:22 +00:00
description : collectionDetails?.description.replaceAll ( '\\n' , '\n' ) ,
2022-12-13 18:50:42 +00:00
image : ` ${
uploadDetails ? . uploadMethod === 'new'
? ` ipfs:// ${ coverImageUri } / ${ collectionDetails ? . imageFile [ 0 ] . name as string } `
: ` ${ coverImageUri } `
} ` ,
external_link : collectionDetails?.externalLink ,
explicit_content : collectionDetails?.explicit ,
royalty_info : royaltyInfo ,
2023-04-03 19:22:27 +00:00
start_trading_time : null , //collectionDetails?.startTradingTime || null,
2022-12-13 18:50:42 +00:00
} ,
} ,
} ,
}
const payload : BaseFactoryDispatchExecuteArgs = {
2023-02-26 09:36:34 +00:00
contract : collectionDetails?.updatable ? BASE_FACTORY_UPDATABLE_ADDRESS : BASE_FACTORY_ADDRESS ,
2022-12-13 18:50:42 +00:00
messages : baseFactoryMessages ,
txSigner : wallet.address ,
msg ,
2023-04-01 13:45:49 +00:00
funds : [
coin (
collectionDetails ? . updatable ? ( baseMinterUpdatableCreationFee as string ) : ( baseMinterCreationFee as string ) ,
'ustars' ,
) ,
] ,
2023-02-26 10:08:03 +00:00
updatable : collectionDetails?.updatable ,
2022-12-13 18:50:42 +00:00
}
2022-12-15 11:59:05 +00:00
await baseFactoryDispatchExecute ( payload )
. then ( async ( data ) = > {
setTransactionHash ( data . transactionHash )
setVendingMinterContractAddress ( data . baseMinterAddress )
setSg721ContractAddress ( data . sg721Address )
2023-02-04 07:47:38 +00:00
if ( uploadDetails ? . assetFiles . length === 1 || uploadDetails ? . uploadMethod === 'existing' ) {
2023-01-16 13:48:38 +00:00
await toast
. promise (
baseMinterContract . use ( data . baseMinterAddress ) ? . mint ( wallet . address , baseUri ) as Promise < string > ,
{
loading : 'Minting token...' ,
success : ( result ) = > {
setIsMintingComplete ( true )
return ` Token minted successfully! Tx Hash: ${ result } `
} ,
error : ( error ) = > ` Failed to mint token: ${ error . message } ` ,
2022-12-26 13:17:09 +00:00
} ,
2023-01-16 13:48:38 +00:00
{ style : { maxWidth : 'none' } } ,
)
. catch ( ( error ) = > {
toast . error ( error . message , { style : { maxWidth : 'none' } } )
2023-05-03 18:18:09 +00:00
addLogItem ( { id : uid ( ) , message : error.message , type : 'Error' , timestamp : new Date ( ) } )
2023-01-16 13:48:38 +00:00
setUploading ( false )
setIsMintingComplete ( false )
setCreatingCollection ( false )
} )
} else {
await toast
. promise (
baseMinterContract
. use ( data . baseMinterAddress )
? . batchMint ( wallet . address , baseUri , uploadDetails ? . assetFiles . length as number ) as Promise < string > ,
{
loading : 'Minting tokens...' ,
success : ( result ) = > {
setIsMintingComplete ( true )
return ` Tokens minted successfully! Tx Hash: ${ result } `
} ,
error : ( error ) = > ` Failed to mint tokens: ${ error . message } ` ,
} ,
{ style : { maxWidth : 'none' } } ,
)
. catch ( ( error ) = > {
toast . error ( error . message , { style : { maxWidth : 'none' } } )
2023-05-03 18:18:09 +00:00
addLogItem ( { id : uid ( ) , message : error.message , type : 'Error' , timestamp : new Date ( ) } )
2023-01-16 13:48:38 +00:00
setUploading ( false )
setIsMintingComplete ( false )
setCreatingCollection ( false )
} )
}
2022-12-15 11:59:05 +00:00
setUploading ( false )
setCreatingCollection ( false )
} )
. catch ( ( error ) = > {
toast . error ( error . message , { style : { maxWidth : 'none' } } )
2023-05-03 18:18:09 +00:00
addLogItem ( { id : uid ( ) , message : error.message , type : 'Error' , timestamp : new Date ( ) } )
2022-12-15 11:59:05 +00:00
setUploading ( false )
setCreatingCollection ( false )
} )
2022-12-13 18:50:42 +00:00
}
2022-08-04 09:16:42 +00:00
const uploadFiles = async ( ) : Promise < string > = > {
if ( ! uploadDetails ) throw new Error ( 'Please upload asset and metadata' )
return new Promise ( ( resolve , reject ) = > {
upload (
uploadDetails . assetFiles ,
uploadDetails . uploadService ,
'assets' ,
uploadDetails . nftStorageApiKey as string ,
uploadDetails . pinataApiKey as string ,
uploadDetails . pinataSecretKey as string ,
)
2023-09-09 19:01:25 +00:00
. then ( async ( assetUri : string ) = > {
let thumbnailUri : string | undefined
if ( uploadDetails . thumbnailFiles && uploadDetails . thumbnailFiles . length > 0 ) {
thumbnailUri = await upload (
uploadDetails . thumbnailFiles ,
uploadDetails . uploadService ,
'thumbnail' ,
uploadDetails . nftStorageApiKey as string ,
uploadDetails . pinataApiKey as string ,
uploadDetails . pinataSecretKey as string ,
)
}
console . log ( 'Thumbnail URI: ' , thumbnailUri )
2023-01-16 13:48:38 +00:00
if ( minterType === 'vending' || ( minterType === 'base' && uploadDetails . assetFiles . length > 1 ) ) {
2022-12-26 13:17:09 +00:00
const fileArray : File [ ] = [ ]
let reader : FileReader
for ( let i = 0 ; i < uploadDetails . metadataFiles . length ; i ++ ) {
reader = new FileReader ( )
reader . onload = ( e ) = > {
const data : any = JSON . parse ( e . target ? . result as string )
if (
getAssetType ( uploadDetails . assetFiles [ i ] . name ) === 'audio' ||
2023-01-24 11:14:29 +00:00
getAssetType ( uploadDetails . assetFiles [ i ] . name ) === 'video' ||
getAssetType ( uploadDetails . assetFiles [ i ] . name ) === 'html'
2022-12-26 13:17:09 +00:00
) {
data . animation_url = ` ipfs:// ${ assetUri } / ${ uploadDetails . assetFiles [ i ] . name } `
}
2023-09-09 19:01:25 +00:00
data . image = ` ipfs:// ${
thumbnailUri &&
( uploadDetails . thumbnailCompatibleAssetFileNames as string [ ] ) . includes (
uploadDetails . assetFiles [ i ] . name . split ( '.' ) [ 0 ] ,
)
? thumbnailUri
: assetUri
} / $ {
thumbnailUri &&
( uploadDetails . thumbnailCompatibleAssetFileNames as string [ ] ) . includes (
uploadDetails . assetFiles [ i ] . name . split ( '.' ) [ 0 ] ,
)
? uploadDetails . thumbnailFiles ? . find (
( thumbnailFile ) = >
thumbnailFile . name . split ( '.' ) [ 0 ] === uploadDetails . assetFiles [ i ] . name . split ( '.' ) [ 0 ] ,
) ? . name
: uploadDetails . assetFiles [ i ] . name
} `
2023-08-22 18:52:31 +00:00
if ( data . description ) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
data . description = data . description . replaceAll ( '\\n' , '\n' )
}
2022-12-26 13:17:09 +00:00
const metadataFileBlob = new Blob ( [ JSON . stringify ( data ) ] , {
type : 'application/json' ,
} )
const updatedMetadataFile = new File (
[ metadataFileBlob ] ,
uploadDetails . metadataFiles [ i ] . name . substring (
0 ,
uploadDetails . metadataFiles [ i ] . name . lastIndexOf ( '.' ) ,
) ,
{
type : 'application/json' ,
} ,
)
fileArray . push ( updatedMetadataFile )
}
reader . onloadend = ( ) = > {
if ( i === uploadDetails . metadataFiles . length - 1 ) {
upload (
fileArray ,
uploadDetails . uploadService ,
'metadata' ,
uploadDetails . nftStorageApiKey as string ,
uploadDetails . pinataApiKey as string ,
uploadDetails . pinataSecretKey as string ,
)
. then ( resolve )
. catch ( reject )
}
}
reader . readAsText ( uploadDetails . metadataFiles [ i ] , 'utf8' )
}
2023-01-16 13:48:38 +00:00
} else if ( minterType === 'base' && uploadDetails . assetFiles . length === 1 ) {
2022-12-26 13:17:09 +00:00
const fileArray : File [ ] = [ ]
const reader : FileReader = new FileReader ( )
2022-09-01 06:27:23 +00:00
2022-08-04 09:16:42 +00:00
reader . onload = ( e ) = > {
const data : any = JSON . parse ( e . target ? . result as string )
2022-09-01 06:27:23 +00:00
2022-08-09 09:08:10 +00:00
if (
2022-12-26 13:17:09 +00:00
getAssetType ( uploadDetails . assetFiles [ 0 ] . name ) === 'audio' ||
2023-06-21 19:52:14 +00:00
getAssetType ( uploadDetails . assetFiles [ 0 ] . name ) === 'video' ||
getAssetType ( uploadDetails . assetFiles [ 0 ] . name ) === 'html'
2022-08-09 09:08:10 +00:00
) {
2022-12-26 13:17:09 +00:00
data . animation_url = ` ipfs:// ${ assetUri } / ${ uploadDetails . assetFiles [ 0 ] . name } `
2022-08-09 09:08:10 +00:00
}
2023-09-09 19:01:25 +00:00
data . image = ` ipfs:// ${
uploadDetails . thumbnailFiles && uploadDetails . thumbnailFiles . length > 0 ? thumbnailUri : assetUri
} / $ {
uploadDetails . thumbnailFiles && uploadDetails . thumbnailFiles . length > 0
? uploadDetails . thumbnailFiles [ 0 ] . name
: uploadDetails . assetFiles [ 0 ] . name
} `
2022-09-01 06:27:23 +00:00
2022-08-04 09:16:42 +00:00
const metadataFileBlob = new Blob ( [ JSON . stringify ( data ) ] , {
type : 'application/json' ,
} )
2022-09-01 06:27:23 +00:00
2023-08-22 18:52:31 +00:00
if ( data . description ) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
data . description = data . description . replaceAll ( '\\n' , '\n' )
}
2022-12-26 13:17:09 +00:00
console . log ( 'Name: ' , ( uploadDetails . baseMinterMetadataFile as File ) . name )
2022-08-10 06:57:20 +00:00
const updatedMetadataFile = new File (
[ metadataFileBlob ] ,
2022-12-26 13:17:09 +00:00
( uploadDetails . baseMinterMetadataFile as File ) . name . substring (
0 ,
( uploadDetails . baseMinterMetadataFile as File ) . name . lastIndexOf ( '.' ) ,
) ,
2022-08-10 06:57:20 +00:00
{
type : 'application/json' ,
} ,
)
2022-09-01 06:27:23 +00:00
2022-08-04 09:16:42 +00:00
fileArray . push ( updatedMetadataFile )
}
reader . onloadend = ( ) = > {
2022-12-26 13:17:09 +00:00
upload (
fileArray ,
uploadDetails . uploadService ,
'metadata' ,
uploadDetails . nftStorageApiKey as string ,
uploadDetails . pinataApiKey as string ,
uploadDetails . pinataSecretKey as string ,
)
. then ( resolve )
. catch ( reject )
2022-08-04 09:16:42 +00:00
}
2022-12-26 13:17:09 +00:00
console . log ( 'File: ' , uploadDetails . baseMinterMetadataFile )
reader . readAsText ( uploadDetails . baseMinterMetadataFile as File , 'utf8' )
2022-08-04 09:16:42 +00:00
}
2022-08-03 07:25:08 +00:00
} )
2022-08-04 09:16:42 +00:00
. catch ( reject )
} )
}
const checkUploadDetails = ( ) = > {
2022-12-13 18:58:40 +00:00
if ( ! wallet . initialized ) throw new Error ( 'Wallet not connected.' )
2022-08-04 09:16:42 +00:00
if ( ! uploadDetails ) {
2022-08-10 06:57:20 +00:00
throw new Error ( 'Please select assets and metadata' )
2022-08-04 09:16:42 +00:00
}
2023-02-04 08:28:41 +00:00
if (
minterType === 'base' &&
uploadDetails . uploadMethod === 'new' &&
uploadDetails . assetFiles . length > 1 &&
uploadDetails . metadataFiles . length === 0
) {
throw new Error ( 'Please select metadata files' )
}
2022-08-16 07:04:33 +00:00
if ( uploadDetails . uploadMethod === 'new' && uploadDetails . assetFiles . length === 0 ) {
2022-08-10 06:57:20 +00:00
throw new Error ( 'Please select the assets' )
2022-08-04 09:16:42 +00:00
}
2022-12-26 13:17:09 +00:00
if ( minterType === 'vending' && uploadDetails . uploadMethod === 'new' && uploadDetails . metadataFiles . length === 0 ) {
2022-08-10 06:57:20 +00:00
throw new Error ( 'Please select the metadata files' )
2022-08-04 09:16:42 +00:00
}
2022-12-15 10:58:38 +00:00
if ( uploadDetails . uploadMethod === 'new' && minterType === 'vending' )
compareFileArrays ( uploadDetails . assetFiles , uploadDetails . metadataFiles )
2022-08-16 07:04:33 +00:00
if ( uploadDetails . uploadMethod === 'new' ) {
if ( uploadDetails . uploadService === 'nft-storage' ) {
if ( uploadDetails . nftStorageApiKey === '' ) {
2022-09-11 17:54:28 +00:00
throw new Error ( 'Please enter a valid NFT.Storage API key' )
2022-08-16 07:04:33 +00:00
}
} else if ( uploadDetails . pinataApiKey === '' || uploadDetails . pinataSecretKey === '' ) {
throw new Error ( 'Please enter Pinata API and secret keys' )
2022-08-03 07:25:08 +00:00
}
2022-08-16 07:04:33 +00:00
}
if ( uploadDetails . uploadMethod === 'existing' && ! uploadDetails . baseTokenURI ? . includes ( 'ipfs://' ) ) {
throw new Error ( 'Please specify a valid base token URI' )
}
2022-12-26 13:17:09 +00:00
if ( baseMinterDetails ? . baseMinterAcquisitionMethod === 'existing' && ! baseMinterDetails . existingBaseMinter ) {
2022-12-13 18:50:42 +00:00
throw new Error ( 'Please specify a valid Base Minter contract address' )
}
2022-08-03 07:25:08 +00:00
}
2022-08-04 09:16:42 +00:00
2023-07-03 14:17:16 +00:00
const checkExistingTokenURI = async ( ) = > {
2023-07-04 05:20:28 +00:00
if ( minterType === 'vending' && uploadDetails && uploadDetails . uploadMethod === 'existing' ) {
await checkTokenUri ( uploadDetails . baseTokenURI as string , true )
}
2023-07-03 14:17:16 +00:00
if ( minterType === 'base' && uploadDetails && uploadDetails . uploadMethod === 'existing' ) {
await checkTokenUri ( uploadDetails . baseTokenURI as string )
}
}
2022-08-04 09:16:42 +00:00
const checkCollectionDetails = ( ) = > {
if ( ! collectionDetails ) throw new Error ( 'Please fill out the collection details' )
2022-08-09 11:42:55 +00:00
if ( collectionDetails . name === '' ) throw new Error ( 'Collection name is required' )
if ( collectionDetails . description === '' ) throw new Error ( 'Collection description is required' )
2023-01-08 16:53:58 +00:00
if ( collectionDetails . description . length > 512 )
throw new Error ( 'Collection description cannot exceed 512 characters' )
2022-08-16 07:04:33 +00:00
if ( uploadDetails ? . uploadMethod === 'new' && collectionDetails . imageFile . length === 0 )
throw new Error ( 'Collection cover image is required' )
2022-10-21 01:02:52 +00:00
if (
collectionDetails . startTradingTime &&
Number ( collectionDetails . startTradingTime ) < new Date ( ) . getTime ( ) * 1000000
)
throw new Error ( 'Invalid trading start time' )
if (
collectionDetails . startTradingTime &&
Number ( collectionDetails . startTradingTime ) < Number ( mintingDetails ? . startTime )
)
throw new Error ( 'Trading start time must be after minting start time' )
2023-01-09 06:38:13 +00:00
if ( collectionDetails . externalLink ) {
try {
const url = new URL ( collectionDetails . externalLink )
} catch ( e : any ) {
throw new Error ( ` Invalid external link: Make sure to include the protocol (e.g. https://) ` )
}
}
2022-08-03 07:25:08 +00:00
}
2022-08-04 09:16:42 +00:00
const checkMintingDetails = ( ) = > {
if ( ! mintingDetails ) throw new Error ( 'Please fill out the minting details' )
if ( mintingDetails . numTokens < 1 || mintingDetails . numTokens > 10000 ) throw new Error ( 'Invalid number of tokens' )
2023-05-03 08:52:26 +00:00
if ( mintingDetails . unitPrice === '' ) throw new Error ( 'Public mint price is required' )
2023-04-28 12:00:39 +00:00
if ( whitelistDetails ? . whitelistState !== 'none' && whitelistDetails ? . whitelistType === 'flex' ) {
2023-04-27 17:19:42 +00:00
if ( Number ( mintingDetails . unitPrice ) < Number ( minimumFlexMintPrice ) )
2023-08-06 15:44:22 +00:00
throw new Error (
` Invalid unit price: The minimum unit price is ${ Number ( minimumFlexMintPrice ) / 1000000 } ${
mintTokenFromVendingFactory ? mintTokenFromVendingFactory . displayName : 'STARS'
} ` ,
)
2023-04-27 17:19:42 +00:00
} else if ( collectionDetails ? . updatable ) {
2023-04-07 09:24:38 +00:00
if ( Number ( mintingDetails . unitPrice ) < Number ( minimumUpdatableMintPrice ) )
throw new Error (
2023-08-06 15:44:22 +00:00
` Invalid unit price: The minimum unit price is ${ Number ( minimumUpdatableMintPrice ) / 1000000 } ${
mintTokenFromVendingFactory ? mintTokenFromVendingFactory . displayName : 'STARS'
} ` ,
2023-04-07 09:24:38 +00:00
)
} else if ( Number ( mintingDetails . unitPrice ) < Number ( minimumMintPrice ) )
2023-08-06 15:44:22 +00:00
throw new Error (
` Invalid unit price: The minimum unit price is ${ Number ( minimumMintPrice ) / 1000000 } ${
mintTokenFromVendingFactory ? mintTokenFromVendingFactory . displayName : 'STARS'
} ` ,
)
2022-08-09 11:42:55 +00:00
if (
2022-12-26 13:17:09 +00:00
! mintingDetails . perAddressLimit ||
2022-08-09 11:42:55 +00:00
mintingDetails . perAddressLimit < 1 ||
mintingDetails . perAddressLimit > 50 ||
mintingDetails . perAddressLimit > mintingDetails . numTokens
)
throw new Error ( 'Invalid limit for tokens per address' )
2023-03-03 08:05:16 +00:00
if ( mintingDetails . numTokens < 100 && mintingDetails . perAddressLimit > 3 )
throw new Error (
'Invalid limit for tokens per address. Tokens per address limit cannot exceed 3 for collections with less than 100 tokens in total.' ,
)
2022-10-21 01:02:52 +00:00
if (
2023-03-03 08:05:16 +00:00
mintingDetails . numTokens >= 100 &&
mintingDetails . perAddressLimit > Math . ceil ( ( mintingDetails . numTokens / 100 ) * 3 )
2022-10-21 01:02:52 +00:00
)
2023-03-03 08:05:16 +00:00
throw new Error (
'Invalid limit for tokens per address. Tokens per address limit cannot exceed 3% of the total number of tokens in the collection.' ,
)
2022-08-04 09:16:42 +00:00
if ( mintingDetails . startTime === '' ) throw new Error ( 'Start time is required' )
2022-09-01 06:27:23 +00:00
if ( Number ( mintingDetails . startTime ) < new Date ( ) . getTime ( ) * 1000000 ) throw new Error ( 'Invalid start time' )
2023-03-27 09:18:39 +00:00
if (
mintingDetails . paymentAddress &&
( ! isValidAddress ( mintingDetails . paymentAddress ) || ! mintingDetails . paymentAddress . startsWith ( 'stars1' ) )
)
2023-03-18 13:11:40 +00:00
throw new Error ( 'Invalid payment address' )
2022-08-04 09:16:42 +00:00
}
2022-10-06 13:16:58 +00:00
const checkWhitelistDetails = async ( ) = > {
2022-08-04 09:16:42 +00:00
if ( ! whitelistDetails ) throw new Error ( 'Please fill out the whitelist details' )
2023-04-24 10:14:06 +00:00
if ( whitelistDetails . whitelistState === 'existing' ) {
2022-08-05 11:13:27 +00:00
if ( whitelistDetails . contractAddress === '' ) throw new Error ( 'Whitelist contract address is required' )
2022-10-06 13:16:58 +00:00
else {
const contract = whitelistContract ? . use ( whitelistDetails . contractAddress )
//check if the address belongs to a whitelist contract (see performChecks())
const config = await contract ? . config ( )
2023-04-28 12:00:39 +00:00
if ( JSON . stringify ( config ) . includes ( 'whale_cap' ) ) whitelistDetails . whitelistType = 'flex'
else whitelistDetails . whitelistType = 'standard'
2022-11-18 16:15:06 +00:00
if ( Number ( config ? . start_time ) !== Number ( mintingDetails ? . startTime ) ) {
const whitelistStartDate = new Date ( Number ( config ? . start_time ) / 1000000 )
throw Error ( ` Whitelist start time ( ${ whitelistStartDate . toLocaleString ( ) } ) does not match minting start time ` )
}
2023-03-04 09:43:04 +00:00
if ( mintingDetails ? . numTokens && config ? . per_address_limit ) {
if ( mintingDetails . numTokens >= 100 && Number ( config . per_address_limit ) > 50 ) {
throw Error (
` Invalid limit for tokens per address ( ${ config . per_address_limit } tokens). Tokens per address limit cannot exceed 50 regardless of the total number of tokens. ` ,
)
} else if (
mintingDetails . numTokens >= 100 &&
Number ( config . per_address_limit ) > Math . ceil ( ( mintingDetails . numTokens / 100 ) * 3 )
) {
throw Error (
` Invalid limit for tokens per address ( ${ config . per_address_limit } tokens). Tokens per address limit cannot exceed 3% of the total number of tokens in the collection. ` ,
)
} else if ( mintingDetails . numTokens < 100 && Number ( config . per_address_limit ) > 3 ) {
throw Error (
` Invalid limit for tokens per address ( ${ config . per_address_limit } tokens). Tokens per address limit cannot exceed 3 for collections with less than 100 tokens in total. ` ,
)
}
}
2022-10-06 13:16:58 +00:00
}
2023-04-24 10:14:06 +00:00
} else if ( whitelistDetails . whitelistState === 'new' ) {
2022-08-04 09:16:42 +00:00
if ( whitelistDetails . members ? . length === 0 ) throw new Error ( 'Whitelist member list cannot be empty' )
2023-05-03 08:52:26 +00:00
if ( whitelistDetails . unitPrice === undefined ) throw new Error ( 'Whitelist unit price is required' )
2023-04-07 09:28:19 +00:00
if ( Number ( whitelistDetails . unitPrice ) < 0 )
throw new Error ( 'Invalid unit price: The unit price cannot be negative' )
2022-08-04 09:16:42 +00:00
if ( whitelistDetails . startTime === '' ) throw new Error ( 'Start time is required' )
if ( whitelistDetails . endTime === '' ) throw new Error ( 'End time is required' )
2023-04-27 17:19:42 +00:00
if (
whitelistDetails . whitelistType === 'standard' &&
( ! whitelistDetails . perAddressLimit || whitelistDetails . perAddressLimit === 0 )
)
2022-12-21 07:36:43 +00:00
throw new Error ( 'Per address limit is required' )
if ( ! whitelistDetails . memberLimit || whitelistDetails . memberLimit === 0 )
throw new Error ( 'Member limit is required' )
2023-03-18 08:38:44 +00:00
if ( Number ( whitelistDetails . startTime ) >= Number ( whitelistDetails . endTime ) )
throw new Error ( 'Whitelist start time cannot be equal to or later than the whitelist end time' )
2022-11-18 16:15:06 +00:00
if ( Number ( whitelistDetails . startTime ) !== Number ( mintingDetails ? . startTime ) )
throw new Error ( 'Whitelist start time must be the same as the minting start time' )
2023-03-04 09:43:04 +00:00
if ( whitelistDetails . perAddressLimit && mintingDetails ? . numTokens ) {
if ( mintingDetails . numTokens >= 100 && whitelistDetails . perAddressLimit > 50 ) {
throw Error (
` Invalid limit for tokens per address. Tokens per address limit cannot exceed 50 regardless of the total number of tokens. ` ,
)
} else if (
mintingDetails . numTokens >= 100 &&
whitelistDetails . perAddressLimit > Math . ceil ( ( mintingDetails . numTokens / 100 ) * 3 )
) {
throw Error (
` Invalid limit for tokens per address. Tokens per address limit cannot exceed 3% of the total number of tokens in the collection. ` ,
)
} else if ( mintingDetails . numTokens < 100 && whitelistDetails . perAddressLimit > 3 ) {
throw Error (
` Invalid limit for tokens per address. Tokens per address limit cannot exceed 3 for collections with less than 100 tokens in total. ` ,
)
}
}
2022-08-04 09:16:42 +00:00
}
2022-08-03 07:25:08 +00:00
}
2023-04-05 11:54:34 +00:00
const checkRoyaltyDetails = async ( ) = > {
2022-08-04 09:16:42 +00:00
if ( ! royaltyDetails ) throw new Error ( 'Please fill out the royalty details' )
2022-08-05 11:13:27 +00:00
if ( royaltyDetails . royaltyType === 'new' ) {
2022-09-01 06:27:23 +00:00
if ( royaltyDetails . share === 0 ) throw new Error ( 'Royalty share percentage is required' )
if ( royaltyDetails . share > 100 || royaltyDetails . share < 0 ) throw new Error ( 'Invalid royalty share percentage' )
2022-08-05 11:13:27 +00:00
if ( royaltyDetails . paymentAddress === '' ) throw new Error ( 'Royalty payment address is required' )
2023-04-05 13:46:18 +00:00
if ( ! isValidAddress ( royaltyDetails . paymentAddress . trim ( ) ) ) {
2023-01-12 10:01:11 +00:00
if ( royaltyDetails . paymentAddress . trim ( ) . endsWith ( '.stars' ) ) {
throw new Error ( 'Royalty payment address could not be resolved' )
}
throw new Error ( 'Invalid royalty payment address' )
}
2023-04-05 11:54:34 +00:00
const contractInfoResponse = await wallet . client
? . queryContractRaw (
2023-04-05 13:46:18 +00:00
royaltyDetails . paymentAddress . trim ( ) ,
2023-04-05 11:54:34 +00:00
toUtf8 ( Buffer . from ( Buffer . from ( 'contract_info' ) . toString ( 'hex' ) , 'hex' ) . toString ( ) ) ,
)
. catch ( ( e ) = > {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
if ( e . message . includes ( 'bech32' ) ) throw new Error ( 'Invalid royalty payment address.' )
console . log ( e . message )
} )
if ( contractInfoResponse !== undefined ) {
const contractInfo = JSON . parse ( new TextDecoder ( ) . decode ( contractInfoResponse as Uint8Array ) )
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
if ( contractInfo && ! contractInfo . contract . includes ( 'splits' ) )
throw new Error ( 'The provided royalty payment address does not belong to a splits contract.' )
else console . log ( contractInfo )
}
2022-08-05 11:13:27 +00:00
}
2022-08-03 07:25:08 +00:00
}
2022-12-21 07:36:43 +00:00
2023-07-31 09:25:57 +00:00
const fetchInitialFactoryParameters = async ( ) = > {
2023-04-01 13:45:49 +00:00
const client = wallet . client
if ( ! client ) return
if ( BASE_FACTORY_ADDRESS ) {
2023-05-26 11:50:35 +00:00
const baseFactoryParameters = await client
. queryContractSmart ( BASE_FACTORY_ADDRESS , { params : { } } )
. catch ( ( error ) = > {
toast . error ( ` ${ error . message } ` , { style : { maxWidth : 'none' } } )
addLogItem ( { id : uid ( ) , message : error.message , type : 'Error' , timestamp : new Date ( ) } )
} )
2023-04-01 13:45:49 +00:00
setBaseMinterCreationFee ( baseFactoryParameters ? . params ? . creation_fee ? . amount )
}
if ( BASE_FACTORY_UPDATABLE_ADDRESS ) {
2023-05-26 11:50:35 +00:00
const baseFactoryUpdatableParameters = await client
. queryContractSmart ( BASE_FACTORY_UPDATABLE_ADDRESS , {
params : { } ,
} )
. catch ( ( error ) = > {
toast . error ( ` ${ error . message } ` , { style : { maxWidth : 'none' } } )
addLogItem ( { id : uid ( ) , message : error.message , type : 'Error' , timestamp : new Date ( ) } )
} )
2023-04-01 13:45:49 +00:00
setBaseMinterUpdatableCreationFee ( baseFactoryUpdatableParameters ? . params ? . creation_fee ? . amount )
}
if ( VENDING_FACTORY_ADDRESS ) {
2023-05-26 11:50:35 +00:00
const vendingFactoryParameters = await client
. queryContractSmart ( VENDING_FACTORY_ADDRESS , { params : { } } )
. catch ( ( error ) = > {
toast . error ( ` ${ error . message } ` , { style : { maxWidth : 'none' } } )
addLogItem ( { id : uid ( ) , message : error.message , type : 'Error' , timestamp : new Date ( ) } )
} )
2023-04-01 13:45:49 +00:00
setVendingMinterCreationFee ( vendingFactoryParameters ? . params ? . creation_fee ? . amount )
2023-04-07 09:24:38 +00:00
setMinimumMintPrice ( vendingFactoryParameters ? . params ? . min_mint_price ? . amount )
2023-04-01 13:45:49 +00:00
}
if ( VENDING_FACTORY_UPDATABLE_ADDRESS ) {
2023-05-26 11:50:35 +00:00
const vendingFactoryUpdatableParameters = await client
. queryContractSmart ( VENDING_FACTORY_UPDATABLE_ADDRESS , {
params : { } ,
} )
. catch ( ( error ) = > {
toast . error ( ` ${ error . message } ` , { style : { maxWidth : 'none' } } )
addLogItem ( { id : uid ( ) , message : error.message , type : 'Error' , timestamp : new Date ( ) } )
} )
2023-04-01 13:45:49 +00:00
setVendingMinterUpdatableCreationFee ( vendingFactoryUpdatableParameters ? . params ? . creation_fee ? . amount )
2023-04-07 09:24:38 +00:00
setMinimumUpdatableMintPrice ( vendingFactoryUpdatableParameters ? . params ? . min_mint_price ? . amount )
2023-04-01 13:45:49 +00:00
}
2023-04-27 17:19:42 +00:00
if ( VENDING_FACTORY_FLEX_ADDRESS ) {
2023-05-26 11:50:35 +00:00
const vendingFactoryFlexParameters = await client
. queryContractSmart ( VENDING_FACTORY_FLEX_ADDRESS , {
params : { } ,
} )
. catch ( ( error ) = > {
toast . error ( ` ${ error . message } ` , { style : { maxWidth : 'none' } } )
addLogItem ( { id : uid ( ) , message : error.message , type : 'Error' , timestamp : new Date ( ) } )
} )
2023-04-27 17:19:42 +00:00
setVendingMinterFlexCreationFee ( vendingFactoryFlexParameters ? . params ? . creation_fee ? . amount )
setMinimumFlexMintPrice ( vendingFactoryFlexParameters ? . params ? . min_mint_price ? . amount )
}
2023-06-14 09:41:16 +00:00
if ( OPEN_EDITION_FACTORY_ADDRESS ) {
const openEditionFactoryParameters = await client
. queryContractSmart ( OPEN_EDITION_FACTORY_ADDRESS , { params : { } } )
. catch ( ( error ) = > {
toast . error ( ` ${ error . message } ` , { style : { maxWidth : 'none' } } )
addLogItem ( { id : uid ( ) , message : error.message , type : 'Error' , timestamp : new Date ( ) } )
} )
setOpenEditionMinterCreationFee ( openEditionFactoryParameters ? . params ? . creation_fee ? . amount )
setMinimumOpenEditionMintPrice ( openEditionFactoryParameters ? . params ? . min_mint_price ? . amount )
}
if ( OPEN_EDITION_UPDATABLE_FACTORY_ADDRESS ) {
const openEditionUpdatableFactoryParameters = await client
. queryContractSmart ( OPEN_EDITION_UPDATABLE_FACTORY_ADDRESS , { params : { } } )
. catch ( ( error ) = > {
toast . error ( ` ${ error . message } ` , { style : { maxWidth : 'none' } } )
addLogItem ( { id : uid ( ) , message : error.message , type : 'Error' , timestamp : new Date ( ) } )
} )
setOpenEditionMinterUpdatableCreationFee ( openEditionUpdatableFactoryParameters ? . params ? . creation_fee ? . amount )
2023-08-06 15:44:22 +00:00
setMinimumOpenEditionUpdatableMintPrice ( openEditionUpdatableFactoryParameters ? . params ? . min_mint_price ? . amount )
2023-06-14 09:41:16 +00:00
}
2023-08-15 17:07:51 +00:00
setInitialParametersFetched ( true )
2023-04-01 13:45:49 +00:00
}
2023-07-31 09:25:57 +00:00
const fetchOpenEditionFactoryParameters = useCallback ( async ( ) = > {
const client = wallet . client
if ( ! client ) return
const factoryForSelectedDenom = openEditionMinterList . find (
( minter ) = >
minter . supportedToken === openEditionMinterDetails ? . mintingDetails ? . selectedMintToken &&
minter . updatable === false ,
)
const updatableFactoryForSelectedDenom = openEditionMinterList . find (
( minter ) = >
minter . supportedToken === openEditionMinterDetails ? . mintingDetails ? . selectedMintToken &&
minter . updatable === true ,
)
if ( factoryForSelectedDenom ? . factoryAddress ) {
const openEditionFactoryParameters = await client
. queryContractSmart ( factoryForSelectedDenom . factoryAddress , { params : { } } )
. catch ( ( error ) = > {
toast . error ( ` ${ error . message } ` , { style : { maxWidth : 'none' } } )
addLogItem ( { id : uid ( ) , message : error.message , type : 'Error' , timestamp : new Date ( ) } )
} )
setOpenEditionMinterCreationFee ( openEditionFactoryParameters ? . params ? . creation_fee ? . amount )
if ( ! openEditionMinterDetails ? . collectionDetails ? . updatable ) {
setMinimumOpenEditionMintPrice ( openEditionFactoryParameters ? . params ? . min_mint_price ? . amount )
setMintTokenFromOpenEditionFactory (
tokensList . find ( ( token ) = > token . denom === openEditionFactoryParameters ? . params ? . min_mint_price ? . denom ) ,
)
}
}
if ( updatableFactoryForSelectedDenom ? . factoryAddress ) {
const openEditionUpdatableFactoryParameters = await client
. queryContractSmart ( updatableFactoryForSelectedDenom . factoryAddress , { params : { } } )
. catch ( ( error ) = > {
toast . error ( ` ${ error . message } ` , { style : { maxWidth : 'none' } } )
addLogItem ( { id : uid ( ) , message : error.message , type : 'Error' , timestamp : new Date ( ) } )
} )
setOpenEditionMinterUpdatableCreationFee ( openEditionUpdatableFactoryParameters ? . params ? . creation_fee ? . amount )
if ( openEditionMinterDetails ? . collectionDetails ? . updatable ) {
2023-08-15 17:07:51 +00:00
setMinimumOpenEditionUpdatableMintPrice ( openEditionUpdatableFactoryParameters ? . params ? . min_mint_price ? . amount )
2023-07-31 09:25:57 +00:00
setMintTokenFromOpenEditionFactory (
tokensList . find (
( token ) = > token . denom === openEditionUpdatableFactoryParameters ? . params ? . min_mint_price ? . denom ,
) ,
)
}
}
} , [
openEditionMinterDetails ? . mintingDetails ? . selectedMintToken ,
openEditionMinterDetails ? . collectionDetails ? . updatable ,
wallet . client ,
] )
2023-08-02 19:56:41 +00:00
const fetchVendingFactoryParameters = useCallback ( async ( ) = > {
const client = wallet . client
if ( ! client ) return
const vendingFactoryForSelectedDenom = vendingMinterList
. concat ( flexibleVendingMinterList )
. find (
( minter ) = >
minter . supportedToken === mintingDetails ? . selectedMintToken &&
minter . updatable === collectionDetails ? . updatable &&
minter . flexible === ( whitelistDetails ? . whitelistType === 'flex' ) ,
) ? . factoryAddress
if ( vendingFactoryForSelectedDenom ) {
2023-08-06 15:44:22 +00:00
setVendingFactoryAddress ( vendingFactoryForSelectedDenom )
2023-08-02 19:56:41 +00:00
const vendingFactoryParameters = await client
. queryContractSmart ( vendingFactoryForSelectedDenom , { params : { } } )
. catch ( ( error ) = > {
toast . error ( ` ${ error . message } ` , { style : { maxWidth : 'none' } } )
addLogItem ( { id : uid ( ) , message : error.message , type : 'Error' , timestamp : new Date ( ) } )
} )
2023-08-06 15:44:22 +00:00
if ( whitelistDetails ? . whitelistState !== 'none' && whitelistDetails ? . whitelistType === 'flex' ) {
setVendingMinterFlexCreationFee ( vendingFactoryParameters ? . params ? . creation_fee ? . amount )
setMinimumFlexMintPrice ( vendingFactoryParameters ? . params ? . min_mint_price ? . amount )
} else if ( collectionDetails ? . updatable ) {
setVendingMinterUpdatableCreationFee ( vendingFactoryParameters ? . params ? . creation_fee ? . amount )
setMinimumUpdatableMintPrice ( vendingFactoryParameters ? . params ? . min_mint_price ? . amount )
} else {
setVendingMinterCreationFee ( vendingFactoryParameters ? . params ? . creation_fee ? . amount )
2023-08-02 19:56:41 +00:00
setMinimumMintPrice ( vendingFactoryParameters ? . params ? . min_mint_price ? . amount )
}
2023-08-06 15:44:22 +00:00
setMintTokenFromVendingFactory (
tokensList . find ( ( token ) = > token . denom === vendingFactoryParameters ? . params ? . min_mint_price ? . denom ) ,
)
2023-08-02 19:56:41 +00:00
}
2023-08-06 15:44:22 +00:00
} , [
collectionDetails ? . updatable ,
mintingDetails ? . selectedMintToken ,
wallet . client ,
whitelistDetails ? . whitelistState ,
whitelistDetails ? . whitelistType ,
] )
2023-08-02 19:56:41 +00:00
2023-07-05 06:01:10 +00:00
const checkwalletBalance = async ( ) = > {
const walletBalance = await wallet . client ? . getBalance ( wallet . address , 'ustars' ) . then ( ( balance ) = > {
if ( minterType === 'vending' && whitelistDetails ? . whitelistState === 'new' && whitelistDetails . memberLimit ) {
const amountNeeded =
Math . ceil ( Number ( whitelistDetails . memberLimit ) / 1000 ) * 100000000 +
( whitelistDetails . whitelistType === 'flex'
2023-04-28 12:00:39 +00:00
? Number ( vendingMinterFlexCreationFee )
: collectionDetails ? . updatable
2023-04-01 13:45:49 +00:00
? Number ( vendingMinterUpdatableCreationFee )
2023-07-05 06:01:10 +00:00
: Number ( vendingMinterCreationFee ) )
if ( amountNeeded >= Number ( balance . amount ) )
throw new Error (
` Insufficient wallet balance to instantiate the required contracts. Needed amount: ${ (
amountNeeded / 1000000
) . toString ( ) } STARS ` ,
)
} else {
const amountNeeded =
minterType === 'vending'
? whitelistDetails ? . whitelistState === 'existing' && whitelistDetails . whitelistType === 'flex'
? Number ( vendingMinterFlexCreationFee )
: collectionDetails ? . updatable
? Number ( vendingMinterUpdatableCreationFee )
: Number ( vendingMinterCreationFee )
: collectionDetails ? . updatable
? Number ( baseMinterUpdatableCreationFee )
: Number ( baseMinterCreationFee )
if ( amountNeeded >= Number ( balance . amount ) )
throw new Error (
` Insufficient wallet balance to instantiate the required contracts. Needed amount: ${ (
amountNeeded / 1000000
) . toString ( ) } STARS ` ,
)
}
} )
2022-12-21 07:36:43 +00:00
}
2023-06-29 19:26:09 +00:00
2023-07-25 19:24:40 +00:00
const exportDetails = ( ) = > {
const details = {
minterType ,
collectionDetails ,
uploadDetails ,
mintingDetails ,
whitelistDetails ,
royaltyDetails ,
baseMinterDetails ,
openEditionMinterDetails ,
2023-08-15 15:24:27 +00:00
vendingMinterContractAddress ,
2023-08-21 16:45:23 +00:00
baseTokenUri : ` ${ baseTokenUri ? . startsWith ( 'ipfs://' ) ? baseTokenUri : ` ipfs:// ${ baseTokenUri } ` } ` ,
2023-08-15 15:24:27 +00:00
coverImageUrl :
uploadDetails ? . uploadMethod === 'new'
2023-08-16 14:48:33 +00:00
? ` ipfs:// ${ coverImageUrl } / ${ collectionDetails ? . imageFile [ 0 ] ? . name as string } `
2023-08-15 15:24:27 +00:00
: ` ${ coverImageUrl } ` ,
2023-07-25 19:24:40 +00:00
}
const element = document . createElement ( 'a' )
const file = new Blob ( [ JSON . stringify ( details ) ] , { type : 'text/plain' } )
element . href = URL . createObjectURL ( file )
2023-08-21 11:59:12 +00:00
element . download = ` ${
minterType === 'vending'
? collectionDetails ? . name
? ` ${ collectionDetails . name } - `
: ''
: openEditionMinterDetails ? . collectionDetails
? ` ${ openEditionMinterDetails . collectionDetails . name } - `
: ''
} configuration - $ { new Date ( ) . toLocaleString ( ) . replaceAll ( ',' , '_' ) } . json `
2023-07-25 19:24:40 +00:00
document . body . appendChild ( element ) // Required for this to work in FireFox
element . click ( )
}
const importDetails = ( event : ChangeEvent < HTMLInputElement > ) = > {
2023-08-21 11:59:12 +00:00
if ( event . target . files === null || event . target . files . length === 0 ) return toast . error ( 'No files selected.' )
2023-07-25 19:24:40 +00:00
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 )
2023-08-15 15:24:27 +00:00
if ( details . vendingMinterContractAddress ) {
details . uploadDetails . uploadMethod = 'existing'
details . uploadDetails . baseTokenURI = details . baseTokenUri
details . uploadDetails . imageUrl = details . coverImageUrl
}
2023-08-21 09:40:54 +00:00
if ( details . openEditionMinterDetails ? . openEditionMinterContractAddress ) {
2023-08-16 14:48:33 +00:00
details . openEditionMinterDetails . offChainMetadataUploadDetails . uploadMethod = 'existing'
details . openEditionMinterDetails . offChainMetadataUploadDetails . tokenURI =
details . openEditionMinterDetails . tokenUri
details . openEditionMinterDetails . offChainMetadataUploadDetails . imageUrl =
details . openEditionMinterDetails . coverImageUrl
}
2023-09-21 05:57:43 +00:00
if ( NETWORK === 'mainnet' ) {
details . collectionDetails . updatable = false
details . openEditionMinterDetails . collectionDetails . updatable = false
}
2023-08-16 14:48:33 +00:00
2023-07-25 19:24:40 +00:00
setImportedDetails ( details )
}
reader . readAsText ( file )
}
2023-06-29 19:26:09 +00:00
const syncCollections = useCallback ( async ( ) = > {
const collectionAddress =
2023-07-31 09:25:57 +00:00
minterType === 'openEdition' ? openEditionMinterCreatorData?.sg721ContractAddress : sg721ContractAddress
2023-06-29 20:37:11 +00:00
if ( collectionAddress && SYNC_COLLECTIONS_API_URL ) {
2023-06-29 19:26:09 +00:00
await axios . get ( ` ${ SYNC_COLLECTIONS_API_URL } / ${ collectionAddress } ` ) . catch ( ( error ) = > {
console . error ( 'Sync collections: ' , error )
} )
}
2023-07-31 09:25:57 +00:00
} , [ minterType , openEditionMinterCreatorData ? . sg721ContractAddress , sg721ContractAddress ] )
2023-06-29 19:26:09 +00:00
2022-08-10 12:04:18 +00:00
useEffect ( ( ) = > {
2023-06-17 13:23:55 +00:00
if (
vendingMinterContractAddress !== null ||
2023-07-31 09:25:57 +00:00
openEditionMinterCreatorData ? . openEditionMinterContractAddress ||
2023-06-17 13:23:55 +00:00
isMintingComplete
2023-06-28 15:24:43 +00:00
) {
2023-04-04 12:30:05 +00:00
scrollRef . current ? . scrollIntoView ( { behavior : 'smooth' } )
2023-06-28 15:24:43 +00:00
}
2023-06-28 18:01:12 +00:00
if (
( minterType === 'vending' && vendingMinterContractAddress !== null ) ||
2023-07-31 09:25:57 +00:00
( minterType === 'openEdition' && openEditionMinterCreatorData ? . openEditionMinterContractAddress ) ||
2023-06-28 18:01:12 +00:00
( minterType === 'base' && vendingMinterContractAddress !== null && isMintingComplete )
) {
2023-06-29 19:26:09 +00:00
void syncCollections ( )
2023-06-28 18:01:12 +00:00
if ( sidetabRef . current ) {
setTimeout ( ( ) = > {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
sidetabRef . current . open ( )
} , 3000 )
}
}
} , [
vendingMinterContractAddress ,
2023-07-31 09:25:57 +00:00
openEditionMinterCreatorData ? . openEditionMinterContractAddress ,
2023-06-28 18:01:12 +00:00
isMintingComplete ,
minterType ,
2023-06-29 19:26:09 +00:00
syncCollections ,
2023-06-28 18:01:12 +00:00
] )
2022-08-03 07:25:08 +00:00
2022-08-16 07:04:33 +00:00
useEffect ( ( ) = > {
setBaseTokenUri ( uploadDetails ? . baseTokenURI as string )
setCoverImageUrl ( uploadDetails ? . imageUrl as string )
} , [ uploadDetails ? . baseTokenURI , uploadDetails ? . imageUrl ] )
2022-12-13 18:50:42 +00:00
useEffect ( ( ) = > {
resetReadyFlags ( )
setVendingMinterContractAddress ( null )
2022-12-26 13:17:09 +00:00
setIsMintingComplete ( false )
} , [ minterType , baseMinterDetails ? . baseMinterAcquisitionMethod , uploadDetails ? . uploadMethod ] )
2022-12-13 18:50:42 +00:00
2023-04-01 13:45:49 +00:00
useEffect ( ( ) = > {
2023-08-15 17:07:51 +00:00
if ( ! initialParametersFetched ) {
void fetchInitialFactoryParameters ( )
}
2023-04-01 13:45:49 +00:00
} , [ wallet . client ] )
2023-07-31 09:25:57 +00:00
useEffect ( ( ) = > {
void fetchOpenEditionFactoryParameters ( )
} , [ fetchOpenEditionFactoryParameters ] )
2023-08-06 15:44:22 +00:00
useEffect ( ( ) = > {
void fetchVendingFactoryParameters ( )
} , [ fetchVendingFactoryParameters ] )
2022-07-27 06:49:36 +00:00
return (
< div >
2022-12-13 18:50:42 +00:00
< NextSeo
title = {
2022-12-26 13:17:09 +00:00
minterType === 'base' && baseMinterDetails ? . baseMinterAcquisitionMethod === 'existing'
2023-03-31 16:25:32 +00:00
? 'Add Token'
2022-12-13 18:50:42 +00:00
: 'Create Collection'
}
/ >
2022-07-27 06:49:36 +00:00
2022-08-04 11:19:25 +00:00
< div className = "mt-5 space-y-5 text-center" >
2022-12-13 18:50:42 +00:00
< h1 className = "font-heading text-4xl font-bold" >
2022-12-26 13:17:09 +00:00
{ minterType === 'base' && baseMinterDetails ? . baseMinterAcquisitionMethod === 'existing'
2023-03-31 16:25:32 +00:00
? 'Add Token'
2022-12-13 18:50:42 +00:00
: 'Create Collection' }
< / h1 >
2022-07-27 06:49:36 +00:00
2022-08-10 09:07:05 +00:00
< Conditional test = { uploading } >
< LoadingModal / >
< / Conditional >
2022-07-27 06:49:36 +00:00
< p >
Make sure you check our { ' ' }
2022-08-10 12:04:18 +00:00
< Anchor className = "font-bold text-plumbus hover:underline" external href = { links [ 'Docs' ] } >
2022-07-27 06:49:36 +00:00
documentation
< / Anchor > { ' ' }
on how to create your collection
< / p >
< / div >
2023-08-21 11:59:12 +00:00
2022-08-10 12:04:18 +00:00
< div className = "mx-10" ref = { scrollRef } >
2023-06-17 13:23:55 +00:00
< Conditional
2023-07-31 09:25:57 +00:00
test = { minterType === 'openEdition' && openEditionMinterCreatorData ? . openEditionMinterContractAddress !== null }
2023-06-17 13:23:55 +00:00
>
< Alert className = "mt-5" type = "info" >
< div >
Open Edition Minter Contract Address : { ' ' }
< Anchor
className = "text-stargaze hover:underline"
external
href = { ` /contracts/openEditionMinter/query/?contractAddress= ${
2023-07-31 09:25:57 +00:00
openEditionMinterCreatorData ? . openEditionMinterContractAddress as string
2023-06-17 13:23:55 +00:00
} ` }
>
2023-07-31 09:25:57 +00:00
{ openEditionMinterCreatorData ? . openEditionMinterContractAddress as string }
2023-06-17 13:23:55 +00:00
< / Anchor >
< br / >
SG721 Contract Address : { ' ' }
< Anchor
className = "text-stargaze hover:underline"
external
href = { ` /contracts/sg721/query/?contractAddress= ${
2023-07-31 09:25:57 +00:00
openEditionMinterCreatorData ? . sg721ContractAddress as string
2023-06-17 13:23:55 +00:00
} ` }
>
2023-07-31 09:25:57 +00:00
{ openEditionMinterCreatorData ? . sg721ContractAddress as string }
2023-06-17 13:23:55 +00:00
< / Anchor >
< br / >
Transaction Hash : { ' ' }
< Conditional test = { NETWORK === 'testnet' } >
< Anchor
className = "text-stargaze hover:underline"
external
2023-07-31 09:25:57 +00:00
href = { ` ${ BLOCK_EXPLORER_URL } /tx/ ${ openEditionMinterCreatorData ? . transactionHash as string } ` }
2023-06-17 13:23:55 +00:00
>
2023-07-31 09:25:57 +00:00
{ openEditionMinterCreatorData ? . transactionHash }
2023-06-17 13:23:55 +00:00
< / Anchor >
< / Conditional >
< Conditional test = { NETWORK === 'mainnet' } >
< Anchor
className = "text-stargaze hover:underline"
external
2023-07-31 09:25:57 +00:00
href = { ` ${ BLOCK_EXPLORER_URL } /txs/ ${ openEditionMinterCreatorData ? . transactionHash as string } ` }
2023-06-17 13:23:55 +00:00
>
2023-07-31 09:25:57 +00:00
{ openEditionMinterCreatorData ? . transactionHash }
2023-06-17 13:23:55 +00:00
< / Anchor >
< / Conditional >
< br / >
< Button className = "mt-2" >
< Anchor
className = "text-white"
external
href = { ` ${ STARGAZE_URL } /launchpad/ ${
2023-07-31 09:25:57 +00:00
openEditionMinterCreatorData ? . openEditionMinterContractAddress as string
2023-06-17 13:23:55 +00:00
} ` }
>
View on Launchpad
< / Anchor >
< / Button >
< / div >
< / Alert >
< / Conditional >
2023-04-04 12:30:05 +00:00
< Conditional test = { vendingMinterContractAddress !== null || isMintingComplete } >
2022-08-10 12:04:18 +00:00
< Alert className = "mt-5" type = "info" >
< div >
2022-12-26 13:17:09 +00:00
< Conditional test = { minterType === 'vending' || isMintingComplete } >
{ minterType === 'vending' ? 'Base Token URI: ' : 'Token URI: ' } { ' ' }
{ uploadDetails ? . uploadMethod === 'new' && (
< Anchor
className = "text-stargaze hover:underline"
external
2023-04-01 13:45:49 +00:00
href = { ` https://ipfs-gw.stargaze-apis.com/ipfs/ ${ baseTokenUri as string } ` }
2022-12-26 13:17:09 +00:00
>
ipfs : //{baseTokenUri as string}
< / Anchor >
) }
{ uploadDetails ? . uploadMethod === 'existing' && (
< Anchor
className = "text-stargaze hover:underline"
external
2023-04-01 13:45:49 +00:00
href = { ` https://ipfs-gw.stargaze-apis.com/ipfs/ ${ baseTokenUri ? . substring (
2022-12-26 13:17:09 +00:00
baseTokenUri . lastIndexOf ( 'ipfs://' ) + 7 ,
) } / ` }
>
ipfs : //{baseTokenUri?.substring(baseTokenUri.lastIndexOf('ipfs://') + 7)}
< / Anchor >
) }
< br / >
2023-04-04 12:30:05 +00:00
< 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 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 >
2022-12-26 13:17:09 +00:00
< / Conditional >
2023-04-04 12:30:05 +00:00
< Conditional test = { vendingMinterContractAddress !== null } >
Minter Contract Address : { ' ' }
2022-09-11 17:54:28 +00:00
< Anchor
className = "text-stargaze hover:underline"
external
2023-04-04 12:30:05 +00:00
href = {
minterType === 'vending'
? ` /contracts/vendingMinter/query/?contractAddress= ${ vendingMinterContractAddress as string } `
: ` /contracts/baseMinter/query/?contractAddress= ${ vendingMinterContractAddress as string } `
}
2022-09-11 17:54:28 +00:00
>
2023-04-04 12:30:05 +00:00
{ vendingMinterContractAddress }
2022-09-11 17:54:28 +00:00
< / Anchor >
< br / >
2023-04-04 12:30:05 +00:00
SG721 Contract Address : { ' ' }
2022-09-23 17:36:34 +00:00
< Anchor
className = "text-stargaze hover:underline"
external
2023-04-04 12:30:05 +00:00
href = { ` /contracts/sg721/query/?contractAddress= ${ sg721ContractAddress as string } ` }
2022-09-23 17:36:34 +00:00
>
2023-04-04 12:30:05 +00:00
{ sg721ContractAddress }
2022-09-23 17:36:34 +00:00
< / Anchor >
2023-04-04 12:30:05 +00:00
< br / >
< Conditional test = { whitelistContractAddress !== null && whitelistContractAddress !== undefined } >
Whitelist Contract Address : { ' ' }
2023-04-03 09:40:33 +00:00
< Anchor
2023-04-04 12:30:05 +00:00
className = "text-stargaze hover:underline"
2023-04-03 09:40:33 +00:00
external
2023-04-04 12:30:05 +00:00
href = { ` /contracts/whitelist/query/?contractAddress= ${ whitelistContractAddress as string } ` }
2023-04-03 09:40:33 +00:00
>
2023-04-04 12:30:05 +00:00
{ whitelistContractAddress }
2023-04-03 09:40:33 +00:00
< / Anchor >
2023-04-04 12:30:05 +00:00
< br / >
< / Conditional >
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 test = { NETWORK === 'mainnet' } >
2023-04-03 09:40:33 +00:00
< Anchor
2023-04-04 12:30:05 +00:00
className = "text-stargaze hover:underline"
2023-04-03 09:40:33 +00:00
external
2023-04-04 12:30:05 +00:00
href = { ` ${ BLOCK_EXPLORER_URL } /txs/ ${ transactionHash as string } ` }
2023-04-03 09:40:33 +00:00
>
2023-04-04 12:30:05 +00:00
{ transactionHash }
2023-04-03 09:40:33 +00:00
< / Anchor >
2023-04-04 12:30:05 +00:00
< / Conditional >
< Conditional test = { minterType === 'vending' } >
< Button className = "mt-2" >
< Anchor
className = "text-white"
external
href = { ` ${ STARGAZE_URL } /launchpad/ ${ vendingMinterContractAddress as string } ` }
>
View on Launchpad
< / Anchor >
< / Button >
< / Conditional >
< Conditional test = { minterType === 'base' } >
< 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 } ${
! isMintingComplete ? ` ?sort=price_asc ` : ` /1 `
} ` }
>
View the Collection on Marketplace
< / AnchorButton >
< / div >
< / Conditional >
2023-04-03 09:40:33 +00:00
< / Conditional >
2022-08-10 12:04:18 +00:00
< / div >
< / Alert >
< / Conditional >
< / div >
2022-12-19 14:38:51 +00:00
2023-06-13 09:04:08 +00:00
< div >
< div
className = { clsx (
'mx-10 mt-5' ,
'grid before:absolute relative grid-cols-3 grid-flow-col items-stretch rounded' ,
2023-08-21 11:59:12 +00:00
'before:inset-x-0 before:bottom-0 before:border-white/25' ,
minterType !== 'base' ? 'rounded-none border-b-2 border-white/25' : 'border-0' ,
2023-06-13 09:04:08 +00:00
) }
>
2022-12-13 12:52:43 +00:00
< div
className = { clsx (
2023-06-13 09:04:08 +00:00
'isolate space-y-1 border-2' ,
'first-of-type:rounded-tl-md last-of-type:rounded-tr-md' ,
minterType === 'vending' ? 'border-stargaze' : 'border-transparent' ,
minterType !== 'vending' ? 'bg-stargaze/5 hover:bg-stargaze/80' : 'hover:bg-white/5' ,
2022-12-13 12:52:43 +00:00
) }
>
2023-06-13 09:04:08 +00:00
< button
className = "p-4 w-full h-full text-left bg-transparent"
onClick = { ( ) = > {
setMinterType ( 'vending' )
resetReadyFlags ( )
} }
type = "button"
2022-12-13 12:52:43 +00:00
>
2023-06-13 09:04:08 +00:00
< h4 className = "font-bold" > Standard Collection < / h4 >
< span className = "text-sm text-white/80 line-clamp-2" >
A non - appendable collection that facilitates primary market vending machine style minting
< / span >
< / button >
< / div >
< div
className = { clsx (
'isolate space-y-1 border-2' ,
'first-of-type:rounded-tl-md last-of-type:rounded-tr-md' ,
minterType === 'base' ? 'border-stargaze' : 'border-transparent' ,
minterType !== 'base' ? 'bg-stargaze/5 hover:bg-stargaze/80' : 'hover:bg-white/5' ,
) }
>
< button
className = "p-4 w-full h-full text-left bg-transparent"
onClick = { ( ) = > {
setMinterType ( 'base' )
resetReadyFlags ( )
} }
type = "button"
>
< h4 className = "font-bold" > 1 / 1 Collection < / h4 >
< span className = "text-sm text-white/80 line-clamp-2" >
An appendable collection that only allows for direct secondary market listing of tokens
< / span >
< / button >
< / div >
2023-06-15 13:13:08 +00:00
< div
className = { clsx (
'isolate space-y-1 border-2' ,
'first-of-type:rounded-tl-md last-of-type:rounded-tr-md' ,
minterType === 'openEdition' ? 'border-stargaze' : 'border-transparent' ,
minterType !== 'openEdition' ? 'bg-stargaze/5 hover:bg-stargaze/80' : 'hover:bg-white/5' ,
OPEN_EDITION_FACTORY_ADDRESS === undefined ? 'hover:bg-zinc-500 opacity-50 hover:opacity-70' : '' ,
) }
>
< button
className = "p-4 w-full h-full text-left bg-transparent"
disabled = { OPEN_EDITION_FACTORY_ADDRESS === undefined }
onClick = { ( ) = > {
setMinterType ( 'openEdition' )
resetReadyFlags ( )
} }
type = "button"
2022-12-13 12:52:43 +00:00
>
2023-06-15 13:13:08 +00:00
< h4 className = "font-bold" > Open Edition Collection < / h4 >
< span className = "text-sm text-white/80 line-clamp-2" >
2023-06-16 10:39:24 +00:00
Allows multiple copies of a single NFT to be minted for a given time interval
2023-06-15 13:13:08 +00:00
< / span >
< / button >
< / div >
2022-12-13 12:52:43 +00:00
< / div >
2023-06-13 09:04:08 +00:00
< / div >
2022-12-13 12:52:43 +00:00
2023-08-21 11:59:12 +00:00
< Conditional test = { minterType !== 'base' } >
< FormControl className = { clsx ( 'py-4 px-10 w-full' ) } title = "Import Creation Configuration" >
< div className = "flex flex-row justify-between mt-5 space-x-2" >
< input
accept = "application/json"
className = "py-4 px-4 w-1/3 rounded-sm border-[1px] border-zinc-500 border-dashed"
onChange = { ( e ) = > importDetails ( e ) }
type = "file"
/ >
< Button className = "mt-3 h-1/2 w-1/8" onClick = { ( ) = > exportDetails ( ) } >
Export Creation Configuration
< / Button >
< / div >
< / FormControl >
< / Conditional >
2022-12-13 12:52:43 +00:00
{ minterType === 'base' && (
< div >
2022-12-26 13:17:09 +00:00
< BaseMinterDetails minterType = { minterType } onChange = { setBaseMinterDetails } / >
2022-12-13 12:52:43 +00:00
< / div >
) }
2023-06-14 09:41:16 +00:00
< Conditional test = { minterType === 'openEdition' } >
< OpenEditionMinterCreator
2023-08-16 14:48:33 +00:00
importedOpenEditionMinterDetails = { importedDetails ? . openEditionMinterDetails }
2023-06-14 09:41:16 +00:00
minimumMintPrice = { minimumOpenEditionMintPrice as string }
minimumUpdatableMintPrice = { minimumOpenEditionUpdatableMintPrice as string }
2023-07-31 09:25:57 +00:00
mintTokenFromFactory = { mintTokenFromOpenEditionFactory }
2023-06-17 13:23:55 +00:00
minterType = { minterType }
2023-07-31 09:25:57 +00:00
onChange = { setOpenEditionMinterCreatorData }
onDetailsChange = { setOpenEditionMinterDetails }
2023-06-14 09:41:16 +00:00
openEditionMinterCreationFee = { openEditionMinterCreationFee as string }
openEditionMinterUpdatableCreationFee = { openEditionMinterUpdatableCreationFee as string }
2022-12-13 18:50:42 +00:00
/ >
2023-06-14 09:41:16 +00:00
< / Conditional >
< div className = "mx-10" >
< Conditional test = { minterType === 'vending' || minterType === 'base' } >
< UploadDetails
baseMinterAcquisitionMethod = { baseMinterDetails ? . baseMinterAcquisitionMethod }
2023-07-25 19:24:40 +00:00
importedUploadDetails = { importedDetails ? . uploadDetails }
2023-06-14 09:41:16 +00:00
minterType = { minterType }
onChange = { setUploadDetails }
/ >
< / Conditional >
2022-08-05 11:13:27 +00:00
2022-12-13 12:52:43 +00:00
< Conditional
2022-12-26 13:17:09 +00:00
test = {
minterType === 'vending' ||
( minterType === 'base' && baseMinterDetails ? . baseMinterAcquisitionMethod === 'new' )
}
2022-12-13 12:52:43 +00:00
>
< div className = "flex justify-between py-3 px-8 rounded border-2 border-white/20 grid-col-2" >
< Conditional
test = {
2022-12-26 13:17:09 +00:00
minterType === 'vending' ||
( minterType === 'base' && baseMinterDetails ? . baseMinterAcquisitionMethod === 'new' )
2022-12-13 12:52:43 +00:00
}
>
< CollectionDetails
coverImageUrl = { coverImageUrl as string }
2023-07-25 19:24:40 +00:00
importedCollectionDetails = { importedDetails ? . collectionDetails }
2022-12-26 13:17:09 +00:00
minterType = { minterType }
2022-12-13 12:52:43 +00:00
onChange = { setCollectionDetails }
uploadMethod = { uploadDetails ? . uploadMethod as UploadMethod }
/ >
< / Conditional >
< Conditional test = { minterType === 'vending' } >
< MintingDetails
2023-07-25 19:24:40 +00:00
importedMintingDetails = { importedDetails ? . mintingDetails }
2023-04-07 09:24:38 +00:00
minimumMintPrice = {
2023-08-06 15:44:22 +00:00
whitelistDetails ? . whitelistState !== 'none' && whitelistDetails ? . whitelistType === 'flex'
? Number ( minimumFlexMintPrice ) / 1000000
: collectionDetails ? . updatable
2023-04-07 09:24:38 +00:00
? Number ( minimumUpdatableMintPrice ) / 1000000
: Number ( minimumMintPrice ) / 1000000
}
2023-08-06 18:09:43 +00:00
mintingTokenFromFactory = { mintTokenFromVendingFactory }
2022-12-13 12:52:43 +00:00
numberOfTokens = { uploadDetails ? . assetFiles . length }
onChange = { setMintingDetails }
uploadMethod = { uploadDetails ? . uploadMethod as UploadMethod }
/ >
< / Conditional >
< / div >
2023-05-04 09:57:45 +00:00
< Conditional
test = {
mintingDetails ? . numTokens !== undefined &&
mintingDetails . numTokens > 0 &&
mintingDetails . unitPrice === '0'
}
>
< Alert className = "mt-4" type = "info" >
2023-05-04 10:37:18 +00:00
Setting the unit price as 0 for public minting may render the collection vulnerable for bot attacks .
Please consider creating a whitelist of addresses that can mint for free instead .
2023-05-04 09:57:45 +00:00
< / Alert >
< / Conditional >
2022-12-13 12:52:43 +00:00
< / Conditional >
< Conditional
2022-12-26 13:17:09 +00:00
test = {
minterType === 'vending' ||
( minterType === 'base' && baseMinterDetails ? . baseMinterAcquisitionMethod === 'new' )
}
2022-12-13 12:52:43 +00:00
>
< div className = "my-6" >
< Conditional test = { minterType === 'vending' } >
2023-07-25 19:24:40 +00:00
< WhitelistDetails
importedWhitelistDetails = { importedDetails ? . whitelistDetails }
2023-08-08 11:35:46 +00:00
mintingTokenFromFactory = { mintTokenFromVendingFactory }
2023-07-25 19:24:40 +00:00
onChange = { setWhitelistDetails }
/ >
2022-12-13 12:52:43 +00:00
< div className = "my-6" / >
< / Conditional >
2023-07-25 19:24:40 +00:00
< RoyaltyDetails importedRoyaltyDetails = { importedDetails ? . royaltyDetails } onChange = { setRoyaltyDetails } / >
2022-12-13 12:52:43 +00:00
< / div >
< / Conditional >
< Conditional test = { readyToCreateVm && minterType === 'vending' } >
< ConfirmationModal confirm = { createVendingMinterCollection } / >
< / Conditional >
< Conditional
2022-12-26 13:17:09 +00:00
test = { readyToCreateBm && minterType === 'base' && baseMinterDetails ? . baseMinterAcquisitionMethod === 'new' }
2022-12-13 12:52:43 +00:00
>
< ConfirmationModal confirm = { createBaseMinterCollection } / >
< / Conditional >
< Conditional
2022-12-26 13:17:09 +00:00
test = {
readyToUploadAndMint &&
minterType === 'base' &&
baseMinterDetails ? . baseMinterAcquisitionMethod === 'existing'
}
2022-12-13 12:52:43 +00:00
>
< ConfirmationModal confirm = { uploadAndMint } / >
< / Conditional >
2022-09-01 06:27:23 +00:00
< div className = "flex justify-end w-full" >
2022-12-13 12:52:43 +00:00
< Conditional test = { minterType === 'vending' } >
< Button
className = "relative justify-center p-2 mb-6 max-h-12 text-white bg-plumbus hover:bg-plumbus-light border-0"
isLoading = { creatingCollection }
onClick = { performVendingMinterChecks }
variant = "solid"
>
Create Collection
< / Button >
< / Conditional >
2022-12-26 13:17:09 +00:00
< Conditional test = { minterType === 'base' && baseMinterDetails ? . baseMinterAcquisitionMethod === 'new' } >
2022-12-13 12:52:43 +00:00
< Button
className = "relative justify-center p-2 mb-6 max-h-12 text-white bg-plumbus hover:bg-plumbus-light border-0"
isLoading = { creatingCollection }
onClick = { performBaseMinterChecks }
variant = "solid"
>
2022-12-13 18:50:42 +00:00
Create Collection
2022-12-13 12:52:43 +00:00
< / Button >
< / Conditional >
2022-12-26 13:17:09 +00:00
< Conditional test = { minterType === 'base' && baseMinterDetails ? . baseMinterAcquisitionMethod === 'existing' } >
2022-12-13 12:52:43 +00:00
< Button
className = "relative justify-center p-2 mb-6 max-h-12 text-white bg-plumbus hover:bg-plumbus-light border-0"
isLoading = { creatingCollection }
onClick = { performUploadAndMintChecks }
variant = "solid"
>
2023-03-31 16:25:32 +00:00
Mint & Add Token ( s )
2022-12-13 12:52:43 +00:00
< / Button >
< / Conditional >
2023-06-28 15:24:43 +00:00
< Sidetab
buttonColor = "#455CF9"
buttonText = "Studio Survey"
height = { 600 }
id = "yJnL8fXk"
ref = { sidetabRef }
width = { 800 }
/ >
2022-09-01 06:27:23 +00:00
< / div >
2022-08-03 07:25:08 +00:00
< / div >
2022-07-27 06:49:36 +00:00
< / div >
)
}
2022-08-04 09:16:42 +00:00
export default withMetadata ( CollectionCreationPage , { center : false } )