import { coin } from '@cosmjs/proto-signing' import { Alert } from 'components/Alert' import { Button } from 'components/Button' import { Conditional } from 'components/Conditional' import { ContractPageHeader } from 'components/ContractPageHeader' import { FormControl } from 'components/FormControl' import { FormGroup } from 'components/FormGroup' import { NumberInput, TextInput } from 'components/forms/FormInput' import { useInputState, useNumberInputState } from 'components/forms/FormInput.hooks' import { FormTextArea } from 'components/forms/FormTextArea' import { InputDateTime } from 'components/InputDateTime' import { JsonPreview } from 'components/JsonPreview' import { LinkTabs } from 'components/LinkTabs' import { baseMinterLinkTabs } from 'components/LinkTabs.data' import { useContracts } from 'contexts/contracts' import { useWallet } from 'contexts/wallet' import type { NextPage } from 'next' import { NextSeo } from 'next-seo' import type { FormEvent } from 'react' import { useEffect, useState } from 'react' import { toast } from 'react-hot-toast' import { FaAsterisk } from 'react-icons/fa' import { useMutation } from 'react-query' import { BASE_FACTORY_ADDRESS } from 'utils/constants' import { withMetadata } from 'utils/layout' import { links } from 'utils/links' import type { CreateBaseMinterResponse } from '../../../contracts/baseFactory/contract' import { SG721_CODE_ID } from '../../../utils/constants' import { resolveAddress } from '../../../utils/resolveAddress' const BaseMinterInstantiatePage: NextPage = () => { const wallet = useWallet() const contract = useContracts().baseFactory const [timestamp, setTimestamp] = useState() const [explicit, setExplicit] = useState(false) const nameState = useInputState({ id: 'name', name: 'name', title: 'Name', placeholder: 'My Awesome SG721 Contract', subtitle: 'Name of the sg721 contract', }) const symbolState = useInputState({ id: 'symbol', name: 'symbol', title: 'Symbol', placeholder: 'AWSM', subtitle: 'Symbol of the sg721 contract', }) const codeIdState = useNumberInputState({ id: 'code-id', name: 'code-id', title: 'Code ID', subtitle: 'Code ID for the sg721 contract', placeholder: '1', defaultValue: SG721_CODE_ID, }) const creatorState = useInputState({ id: 'creator-address', name: 'creatorAddress', title: 'Creator Address', placeholder: 'stars1234567890abcdefghijklmnopqrstuvwxyz...', subtitle: 'Address of the collection creator', defaultValue: wallet.address, }) const descriptionState = useInputState({ id: 'description', name: 'description', title: 'Description', subtitle: 'Description of the collection', }) const imageState = useInputState({ id: 'image', name: 'image', title: 'Image', subtitle: 'Image of the collection', placeholder: 'ipfs://bafybe....', }) const externalLinkState = useInputState({ id: 'external-link', name: 'externalLink', title: 'External Link (optional)', subtitle: 'External link to the collection', }) const royaltyPaymentAddressState = useInputState({ id: 'royalty-payment-address', name: 'royaltyPaymentAddress', title: 'Payment Address', subtitle: 'Address to receive royalties', placeholder: 'stars1234567890abcdefghijklmnopqrstuvwxyz...', }) const royaltyShareState = useInputState({ id: 'royalty-share', name: 'royaltyShare', title: 'Share Percentage', subtitle: 'Percentage of royalties to be paid', placeholder: '8%', }) const { data, isLoading, mutate } = useMutation( async (event: FormEvent): Promise => { event.preventDefault() if (!contract) { throw new Error('Smart contract connection failed') } let royaltyInfo = null if (royaltyPaymentAddressState.value && royaltyShareState.value) { royaltyInfo = { payment_address: royaltyPaymentAddressState.value, share: (Number(royaltyShareState.value) / 100).toString(), } } const msg = { create_minter: { collection_params: { code_id: codeIdState.value, name: nameState.value, symbol: symbolState.value, info: { creator: creatorState.value, description: descriptionState.value, image: imageState.value, external_link: externalLinkState.value || null, explicit_content: explicit, start_trading_time: timestamp ? (timestamp.getTime() * 1_000_000).toString() : null, royalty_info: royaltyInfo, }, }, }, } return toast.promise( contract .use(BASE_FACTORY_ADDRESS) ?.createBaseMinter(wallet.address, msg, [coin('1000000000', 'ustars')]) as Promise, { loading: 'Instantiating contract...', error: 'Instantiation failed!', success: 'Instantiation success!', }, ) }, { onError: (error) => { toast.error(String(error), { style: { maxWidth: 'none' } }) }, }, ) const txHash = data?.transactionHash useEffect(() => { void resolveAddress(creatorState.value, wallet).then((resolvedAddress) => { creatorState.onChange(resolvedAddress) }) }, [creatorState.value]) useEffect(() => { void resolveAddress(royaltyPaymentAddressState.value, wallet).then((resolvedAddress) => { royaltyPaymentAddressState.onChange(resolvedAddress) }) }, [royaltyPaymentAddressState.value]) return (
Instantiate success! Here is the transaction result containing the contract address and the transaction hash.
setTimestamp(date)} value={timestamp} />
Does the collection contain explicit content?
{ setExplicit(true) }} type="radio" />
{ setExplicit(false) }} type="radio" />
) } export default withMetadata(BaseMinterInstantiatePage, { center: false })