commit
8d70edd6c0
@ -1,10 +1,10 @@
|
|||||||
APP_VERSION=0.1.0
|
APP_VERSION=0.1.0
|
||||||
|
|
||||||
NEXT_PUBLIC_PINATA_ENDPOINT_URL=https://api.pinata.cloud/pinning/pinFileToIPFS
|
NEXT_PUBLIC_PINATA_ENDPOINT_URL=https://api.pinata.cloud/pinning/pinFileToIPFS
|
||||||
NEXT_PUBLIC_SG721_CODE_ID=256
|
NEXT_PUBLIC_SG721_CODE_ID=274
|
||||||
NEXT_PUBLIC_VENDING_MINTER_CODE_ID=257
|
NEXT_PUBLIC_VENDING_MINTER_CODE_ID=275
|
||||||
NEXT_PUBLIC_VENDING_FACTORY_ADDRESS="stars1qdcxmc82uh8tqf56kprjddkfy7p4ft4z46kh9f6lhnjxtgekra5qjj5r6c"
|
NEXT_PUBLIC_VENDING_FACTORY_ADDRESS="stars1j4qn9krchp5xs8nued4j4vcr4j654wxkhf7acy76734xe5fsz08sku28s2"
|
||||||
NEXT_PUBLIC_WHITELIST_CODE_ID=267
|
NEXT_PUBLIC_WHITELIST_CODE_ID=277
|
||||||
|
|
||||||
NEXT_PUBLIC_API_URL=https://
|
NEXT_PUBLIC_API_URL=https://
|
||||||
NEXT_PUBLIC_BLOCK_EXPLORER_URL=https://testnet-explorer.publicawesome.dev/stargaze
|
NEXT_PUBLIC_BLOCK_EXPLORER_URL=https://testnet-explorer.publicawesome.dev/stargaze
|
||||||
|
@ -1,19 +1,45 @@
|
|||||||
|
import { useState } from 'react'
|
||||||
|
|
||||||
import { Button } from './Button'
|
import { Button } from './Button'
|
||||||
|
|
||||||
export interface ConfirmationModalProps {
|
export interface ConfirmationModalProps {
|
||||||
confirm: () => void
|
confirm: () => void
|
||||||
}
|
}
|
||||||
export const ConfirmationModal = (props: ConfirmationModalProps) => {
|
export const ConfirmationModal = (props: ConfirmationModalProps) => {
|
||||||
|
const [isChecked, setIsChecked] = useState(false)
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<input className="modal-toggle" defaultChecked id="my-modal-2" type="checkbox" />
|
<input className="modal-toggle" defaultChecked id="my-modal-2" type="checkbox" />
|
||||||
<label className="cursor-pointer modal" htmlFor="my-modal-2">
|
<label className="cursor-pointer modal" htmlFor="my-modal-2">
|
||||||
<label
|
<label
|
||||||
className="absolute top-[40%] bottom-5 left-1/3 max-w-xl max-h-40 border-2 no-scrollbar modal-box"
|
className="absolute top-[25%] bottom-5 left-1/3 max-w-[600px] max-h-[400px] border-2 no-scrollbar modal-box"
|
||||||
htmlFor="temp"
|
htmlFor="temp"
|
||||||
>
|
>
|
||||||
{/* <Alert type="warning"></Alert> */}
|
{/* <Alert type="warning"></Alert> */}
|
||||||
<div className="text-xl font-bold">
|
<div className="text-xl font-bold">
|
||||||
|
<div className="text-sm font-thin">
|
||||||
|
You represent and warrant that you have, or have obtained, all rights, licenses, consents, permissions,
|
||||||
|
power and/or authority necessary to grant the rights granted herein for any content that you create,
|
||||||
|
submit, post, promote, or display on or through the Service. You represent and warrant that such contain
|
||||||
|
material subject to copyright, trademark, publicity rights, or other intellectual property rights, unless
|
||||||
|
you have necessary permission or are otherwise legally entitled to post the material and to grant Stargaze
|
||||||
|
Parties the license described above, and that the content does not violate any laws.
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<div className="flex flex-row pb-4">
|
||||||
|
<label className="flex flex-col space-y-1" htmlFor="terms">
|
||||||
|
<span className="text-sm font-light text-white">I agree with the terms above.</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
checked={isChecked}
|
||||||
|
className="p-2 mb-1 ml-2"
|
||||||
|
id="terms"
|
||||||
|
name="terms"
|
||||||
|
onClick={() => setIsChecked(!isChecked)}
|
||||||
|
type="checkbox"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
Are you sure to create a collection with the specified assets, metadata and parameters?
|
Are you sure to create a collection with the specified assets, metadata and parameters?
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-end w-full">
|
<div className="flex justify-end w-full">
|
||||||
@ -25,9 +51,9 @@ export const ConfirmationModal = (props: ConfirmationModalProps) => {
|
|||||||
Go Back
|
Go Back
|
||||||
</label>
|
</label>
|
||||||
</Button>
|
</Button>
|
||||||
<Button className="px-0 mt-4 mb-4 max-h-12" onClick={props.confirm}>
|
<Button className="px-0 mt-4 mb-4 max-h-12" isDisabled={!isChecked} onClick={props.confirm}>
|
||||||
<label
|
<label
|
||||||
className="w-full h-full text-white bg-plumbus-light hover:bg-plumbus-light border-0 btn modal-button"
|
className="w-full h-full text-white bg-plumbus hover:bg-plumbus-light border-0 btn modal-button"
|
||||||
htmlFor="my-modal-2"
|
htmlFor="my-modal-2"
|
||||||
>
|
>
|
||||||
Confirm
|
Confirm
|
||||||
|
@ -22,6 +22,7 @@ import { FaArrowRight } from 'react-icons/fa'
|
|||||||
import { useMutation } from 'react-query'
|
import { useMutation } from 'react-query'
|
||||||
import type { AirdropAllocation } from 'utils/isValidAccountsFile'
|
import type { AirdropAllocation } from 'utils/isValidAccountsFile'
|
||||||
|
|
||||||
|
import type { CollectionInfo } from '../../../contracts/sg721/contract'
|
||||||
import { TextInput } from '../../forms/FormInput'
|
import { TextInput } from '../../forms/FormInput'
|
||||||
|
|
||||||
interface CollectionActionsProps {
|
interface CollectionActionsProps {
|
||||||
@ -31,6 +32,8 @@ interface CollectionActionsProps {
|
|||||||
minterMessages: MinterInstance | undefined
|
minterMessages: MinterInstance | undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ExplicitContentType = true | false | undefined
|
||||||
|
|
||||||
export const CollectionActions = ({
|
export const CollectionActions = ({
|
||||||
sg721ContractAddress,
|
sg721ContractAddress,
|
||||||
sg721Messages,
|
sg721Messages,
|
||||||
@ -43,12 +46,14 @@ export const CollectionActions = ({
|
|||||||
const [timestamp, setTimestamp] = useState<Date | undefined>(undefined)
|
const [timestamp, setTimestamp] = useState<Date | undefined>(undefined)
|
||||||
const [airdropAllocationArray, setAirdropAllocationArray] = useState<AirdropAllocation[]>([])
|
const [airdropAllocationArray, setAirdropAllocationArray] = useState<AirdropAllocation[]>([])
|
||||||
const [airdropArray, setAirdropArray] = useState<string[]>([])
|
const [airdropArray, setAirdropArray] = useState<string[]>([])
|
||||||
|
const [collectionInfo, setCollectionInfo] = useState<CollectionInfo>()
|
||||||
|
const [explicitContent, setExplicitContent] = useState<ExplicitContentType>(undefined)
|
||||||
|
|
||||||
const actionComboboxState = useActionsComboboxState()
|
const actionComboboxState = useActionsComboboxState()
|
||||||
const type = actionComboboxState.value?.id
|
const type = actionComboboxState.value?.id
|
||||||
|
|
||||||
const limitState = useNumberInputState({
|
const limitState = useNumberInputState({
|
||||||
id: 'per-address-limi',
|
id: 'per-address-limit',
|
||||||
name: 'perAddressLimit',
|
name: 'perAddressLimit',
|
||||||
title: 'Per Address Limit',
|
title: 'Per Address Limit',
|
||||||
subtitle: 'Enter the per address limit',
|
subtitle: 'Enter the per address limit',
|
||||||
@ -97,6 +102,42 @@ export const CollectionActions = ({
|
|||||||
subtitle: 'New minting price in STARS',
|
subtitle: 'New minting price in STARS',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const descriptionState = useInputState({
|
||||||
|
id: 'collection-description',
|
||||||
|
name: 'description',
|
||||||
|
title: 'Collection Description',
|
||||||
|
})
|
||||||
|
|
||||||
|
const imageState = useInputState({
|
||||||
|
id: 'collection-cover-image',
|
||||||
|
name: 'cover_image',
|
||||||
|
title: 'Collection Cover Image',
|
||||||
|
subtitle: 'URL for collection cover image.',
|
||||||
|
})
|
||||||
|
|
||||||
|
const externalLinkState = useInputState({
|
||||||
|
id: 'collection-ext-link',
|
||||||
|
name: 'external_link',
|
||||||
|
title: 'External Link',
|
||||||
|
subtitle: 'External URL for the collection.',
|
||||||
|
})
|
||||||
|
|
||||||
|
const royaltyPaymentAddressState = useInputState({
|
||||||
|
id: 'royalty-payment-address',
|
||||||
|
name: 'royaltyPaymentAddress',
|
||||||
|
title: 'Royalty 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 showWhitelistField = type === 'set_whitelist'
|
const showWhitelistField = type === 'set_whitelist'
|
||||||
const showDateField = isEitherType(type, ['update_start_time', 'update_start_trading_time'])
|
const showDateField = isEitherType(type, ['update_start_time', 'update_start_trading_time'])
|
||||||
const showLimitField = type === 'update_per_address_limit'
|
const showLimitField = type === 'update_per_address_limit'
|
||||||
@ -106,6 +147,11 @@ export const CollectionActions = ({
|
|||||||
const showRecipientField = isEitherType(type, ['transfer', 'mint_to', 'mint_for', 'batch_mint', 'batch_transfer'])
|
const showRecipientField = isEitherType(type, ['transfer', 'mint_to', 'mint_for', 'batch_mint', 'batch_transfer'])
|
||||||
const showAirdropFileField = type === 'airdrop'
|
const showAirdropFileField = type === 'airdrop'
|
||||||
const showPriceField = type === 'update_mint_price'
|
const showPriceField = type === 'update_mint_price'
|
||||||
|
const showDescriptionField = type === 'update_collection_info'
|
||||||
|
const showImageField = type === 'update_collection_info'
|
||||||
|
const showExternalLinkField = type === 'update_collection_info'
|
||||||
|
const showRoyaltyRelatedFields = type === 'update_collection_info'
|
||||||
|
const showExplicitContentField = type === 'update_collection_info'
|
||||||
|
|
||||||
const payload: DispatchExecuteArgs = {
|
const payload: DispatchExecuteArgs = {
|
||||||
whitelist: whitelistState.value,
|
whitelist: whitelistState.value,
|
||||||
@ -123,8 +169,32 @@ export const CollectionActions = ({
|
|||||||
txSigner: wallet.address,
|
txSigner: wallet.address,
|
||||||
type,
|
type,
|
||||||
price: priceState.value.toString(),
|
price: priceState.value.toString(),
|
||||||
|
collectionInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setCollectionInfo({
|
||||||
|
description: descriptionState.value || undefined,
|
||||||
|
image: imageState.value || undefined,
|
||||||
|
explicit_content: explicitContent,
|
||||||
|
external_link: externalLinkState.value || undefined,
|
||||||
|
royalty_info:
|
||||||
|
royaltyPaymentAddressState.value && royaltyShareState.value
|
||||||
|
? {
|
||||||
|
payment_address: royaltyPaymentAddressState.value,
|
||||||
|
share: (Number(royaltyShareState.value) / 100).toString(),
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
|
})
|
||||||
|
}, [
|
||||||
|
descriptionState.value,
|
||||||
|
imageState.value,
|
||||||
|
explicitContent,
|
||||||
|
externalLinkState.value,
|
||||||
|
royaltyPaymentAddressState.value,
|
||||||
|
royaltyShareState.value,
|
||||||
|
])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const addresses: string[] = []
|
const addresses: string[] = []
|
||||||
airdropAllocationArray.forEach((allocation) => {
|
airdropAllocationArray.forEach((allocation) => {
|
||||||
@ -150,10 +220,16 @@ export const CollectionActions = ({
|
|||||||
throw new Error('Please enter minter and sg721 contract addresses!')
|
throw new Error('Please enter minter and sg721 contract addresses!')
|
||||||
}
|
}
|
||||||
if (type === 'update_mint_price' && priceState.value < 50) {
|
if (type === 'update_mint_price' && priceState.value < 50) {
|
||||||
console.log('here')
|
|
||||||
throw new Error('Mint price must be at least 50 STARS')
|
throw new Error('Mint price must be at least 50 STARS')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
type === 'update_collection_info' &&
|
||||||
|
(royaltyShareState.value ? !royaltyPaymentAddressState.value : royaltyPaymentAddressState.value)
|
||||||
|
) {
|
||||||
|
throw new Error('Royalty payment address and share percentage are both required')
|
||||||
|
}
|
||||||
|
|
||||||
const txHash = await toast.promise(dispatchExecute(payload), {
|
const txHash = await toast.promise(dispatchExecute(payload), {
|
||||||
error: `${type.charAt(0).toUpperCase() + type.slice(1)} execute failed!`,
|
error: `${type.charAt(0).toUpperCase() + type.slice(1)} execute failed!`,
|
||||||
loading: 'Executing message...',
|
loading: 'Executing message...',
|
||||||
@ -172,7 +248,6 @@ export const CollectionActions = ({
|
|||||||
|
|
||||||
const airdropFileOnChange = (data: AirdropAllocation[]) => {
|
const airdropFileOnChange = (data: AirdropAllocation[]) => {
|
||||||
setAirdropAllocationArray(data)
|
setAirdropAllocationArray(data)
|
||||||
console.log(data)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -187,6 +262,62 @@ export const CollectionActions = ({
|
|||||||
{showTokenIdListField && <TextInput {...tokenIdListState} />}
|
{showTokenIdListField && <TextInput {...tokenIdListState} />}
|
||||||
{showNumberOfTokensField && <NumberInput {...batchNumberState} />}
|
{showNumberOfTokensField && <NumberInput {...batchNumberState} />}
|
||||||
{showPriceField && <NumberInput {...priceState} />}
|
{showPriceField && <NumberInput {...priceState} />}
|
||||||
|
{showDescriptionField && <TextInput className="mb-2" {...descriptionState} />}
|
||||||
|
{showImageField && <TextInput className="mb-2" {...imageState} />}
|
||||||
|
{showExternalLinkField && <TextInput className="mb-2" {...externalLinkState} />}
|
||||||
|
{showRoyaltyRelatedFields && (
|
||||||
|
<div className="p-2 my-4 rounded border-2 border-gray-500/50">
|
||||||
|
<TextInput className="mb-2" {...royaltyPaymentAddressState} />
|
||||||
|
<NumberInput className="mb-2" {...royaltyShareState} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{showExplicitContentField && (
|
||||||
|
<div className="flex flex-col space-y-2">
|
||||||
|
<div>
|
||||||
|
<div className="flex">
|
||||||
|
<span className="mt-1 text-sm first-letter:capitalize">
|
||||||
|
Does the collection contain explicit content?
|
||||||
|
</span>
|
||||||
|
<div className="ml-2 font-bold form-check form-check-inline">
|
||||||
|
<input
|
||||||
|
checked={explicitContent === true}
|
||||||
|
className="peer sr-only"
|
||||||
|
id="explicitRadio1"
|
||||||
|
name="explicitRadioOptions1"
|
||||||
|
onClick={() => {
|
||||||
|
setExplicitContent(true)
|
||||||
|
}}
|
||||||
|
type="radio"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
className="inline-block py-1 px-2 text-sm text-gray peer-checked:text-white hover:text-white peer-checked:bg-black hover:rounded-sm peer-checked:border-b-2 hover:border-b-2 peer-checked:border-plumbus hover:border-plumbus cursor-pointer form-check-label"
|
||||||
|
htmlFor="explicitRadio1"
|
||||||
|
>
|
||||||
|
YES
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div className="ml-2 font-bold form-check form-check-inline">
|
||||||
|
<input
|
||||||
|
checked={explicitContent === false}
|
||||||
|
className="peer sr-only"
|
||||||
|
id="explicitRadio2"
|
||||||
|
name="explicitRadioOptions2"
|
||||||
|
onClick={() => {
|
||||||
|
setExplicitContent(false)
|
||||||
|
}}
|
||||||
|
type="radio"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
className="inline-block py-1 px-2 text-sm text-gray peer-checked:text-white hover:text-white peer-checked:bg-black hover:rounded-sm peer-checked:border-b-2 hover:border-b-2 peer-checked:border-plumbus hover:border-plumbus cursor-pointer form-check-label"
|
||||||
|
htmlFor="explicitRadio2"
|
||||||
|
>
|
||||||
|
NO
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
{showAirdropFileField && (
|
{showAirdropFileField && (
|
||||||
<FormGroup
|
<FormGroup
|
||||||
subtitle="CSV file that contains the airdrop addresses and the amount of tokens allocated for each address. Should start with the following header row: address,amount"
|
subtitle="CSV file that contains the airdrop addresses and the amount of tokens allocated for each address. Should start with the following header row: address,amount"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import type { MinterInstance } from 'contracts/minter'
|
import type { MinterInstance } from 'contracts/minter'
|
||||||
import { useMinterContract } from 'contracts/minter'
|
import { useMinterContract } from 'contracts/minter'
|
||||||
import type { SG721Instance } from 'contracts/sg721'
|
import type { CollectionInfo, SG721Instance } from 'contracts/sg721'
|
||||||
import { useSG721Contract } from 'contracts/sg721'
|
import { useSG721Contract } from 'contracts/sg721'
|
||||||
|
|
||||||
export type ActionType = typeof ACTION_TYPES[number]
|
export type ActionType = typeof ACTION_TYPES[number]
|
||||||
@ -16,6 +16,8 @@ export const ACTION_TYPES = [
|
|||||||
'update_start_time',
|
'update_start_time',
|
||||||
'update_start_trading_time',
|
'update_start_trading_time',
|
||||||
'update_per_address_limit',
|
'update_per_address_limit',
|
||||||
|
'update_collection_info',
|
||||||
|
'freeze_collection_info',
|
||||||
'withdraw',
|
'withdraw',
|
||||||
'transfer',
|
'transfer',
|
||||||
'batch_transfer',
|
'batch_transfer',
|
||||||
@ -83,6 +85,16 @@ export const ACTION_LIST: ActionListItem[] = [
|
|||||||
name: 'Update Tokens Per Address Limit',
|
name: 'Update Tokens Per Address Limit',
|
||||||
description: `Update token per address limit`,
|
description: `Update token per address limit`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'update_collection_info',
|
||||||
|
name: 'Update Collection Info',
|
||||||
|
description: `Update Collection Info`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'freeze_collection_info',
|
||||||
|
name: 'Freeze Collection Info',
|
||||||
|
description: `Freeze collection info to prevent further updates`,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'withdraw',
|
id: 'withdraw',
|
||||||
name: 'Withdraw Tokens',
|
name: 'Withdraw Tokens',
|
||||||
@ -159,6 +171,8 @@ export type DispatchExecuteArgs = {
|
|||||||
| { type: Select<'batch_burn'>; tokenIds: string }
|
| { type: Select<'batch_burn'>; tokenIds: string }
|
||||||
| { type: Select<'airdrop'>; recipients: string[] }
|
| { type: Select<'airdrop'>; recipients: string[] }
|
||||||
| { type: Select<'burn_remaining'> }
|
| { type: Select<'burn_remaining'> }
|
||||||
|
| { type: Select<'update_collection_info'>; collectionInfo: CollectionInfo | undefined }
|
||||||
|
| { type: Select<'freeze_collection_info'> }
|
||||||
)
|
)
|
||||||
|
|
||||||
export const dispatchExecute = async (args: DispatchExecuteArgs) => {
|
export const dispatchExecute = async (args: DispatchExecuteArgs) => {
|
||||||
@ -197,6 +211,12 @@ export const dispatchExecute = async (args: DispatchExecuteArgs) => {
|
|||||||
case 'update_per_address_limit': {
|
case 'update_per_address_limit': {
|
||||||
return minterMessages.updatePerAddressLimit(txSigner, args.limit)
|
return minterMessages.updatePerAddressLimit(txSigner, args.limit)
|
||||||
}
|
}
|
||||||
|
case 'update_collection_info': {
|
||||||
|
return sg721Messages.updateCollectionInfo(args.collectionInfo as CollectionInfo)
|
||||||
|
}
|
||||||
|
case 'freeze_collection_info': {
|
||||||
|
return sg721Messages.freezeCollectionInfo()
|
||||||
|
}
|
||||||
case 'shuffle': {
|
case 'shuffle': {
|
||||||
return minterMessages.shuffle(txSigner)
|
return minterMessages.shuffle(txSigner)
|
||||||
}
|
}
|
||||||
@ -264,6 +284,12 @@ export const previewExecutePayload = (args: DispatchExecuteArgs) => {
|
|||||||
case 'update_per_address_limit': {
|
case 'update_per_address_limit': {
|
||||||
return minterMessages(minterContract)?.updatePerAddressLimit(args.limit)
|
return minterMessages(minterContract)?.updatePerAddressLimit(args.limit)
|
||||||
}
|
}
|
||||||
|
case 'update_collection_info': {
|
||||||
|
return sg721Messages(sg721Contract)?.updateCollectionInfo(args.collectionInfo as CollectionInfo)
|
||||||
|
}
|
||||||
|
case 'freeze_collection_info': {
|
||||||
|
return sg721Messages(sg721Contract)?.freezeCollectionInfo()
|
||||||
|
}
|
||||||
case 'shuffle': {
|
case 'shuffle': {
|
||||||
return minterMessages(minterContract)?.shuffle()
|
return minterMessages(minterContract)?.shuffle()
|
||||||
}
|
}
|
||||||
|
@ -107,10 +107,6 @@ export const CollectionDetails = ({ onChange, uploadMethod, coverImageUrl }: Col
|
|||||||
reader.readAsArrayBuffer(event.target.files[0])
|
reader.readAsArrayBuffer(event.target.files[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
console.log(explicit)
|
|
||||||
}, [explicit])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<FormGroup subtitle="Information about your collection" title="Collection Details">
|
<FormGroup subtitle="Information about your collection" title="Collection Details">
|
||||||
@ -118,7 +114,11 @@ export const CollectionDetails = ({ onChange, uploadMethod, coverImageUrl }: Col
|
|||||||
<TextInput {...descriptionState} isRequired />
|
<TextInput {...descriptionState} isRequired />
|
||||||
<TextInput {...symbolState} isRequired />
|
<TextInput {...symbolState} isRequired />
|
||||||
<TextInput {...externalLinkState} />
|
<TextInput {...externalLinkState} />
|
||||||
<FormControl htmlId="timestamp" subtitle="Trading start time (local)" title="Trading Start Time (optional)">
|
<FormControl
|
||||||
|
htmlId="timestamp"
|
||||||
|
subtitle="Trading start time offset will be set as 2 weeks by default."
|
||||||
|
title="Trading Start Time (optional)"
|
||||||
|
>
|
||||||
<InputDateTime minDate={new Date()} onChange={(date) => setTimestamp(date)} value={timestamp} />
|
<InputDateTime minDate={new Date()} onChange={(date) => setTimestamp(date)} value={timestamp} />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ export interface InstantiateResponse {
|
|||||||
readonly logs: readonly logs.Log[]
|
readonly logs: readonly logs.Log[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RoyalityInfo {
|
export interface RoyaltyInfo {
|
||||||
payment_address: string
|
payment_address: string
|
||||||
share: string
|
share: string
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,8 @@ import type { Coin } from '@cosmjs/stargate'
|
|||||||
import { coin } from '@cosmjs/stargate'
|
import { coin } from '@cosmjs/stargate'
|
||||||
import { MsgExecuteContract } from 'cosmjs-types/cosmwasm/wasm/v1/tx'
|
import { MsgExecuteContract } from 'cosmjs-types/cosmwasm/wasm/v1/tx'
|
||||||
|
|
||||||
|
import type { RoyaltyInfo } from '../minter/contract'
|
||||||
|
|
||||||
export interface InstantiateResponse {
|
export interface InstantiateResponse {
|
||||||
readonly contractAddress: string
|
readonly contractAddress: string
|
||||||
readonly transactionHash: string
|
readonly transactionHash: string
|
||||||
@ -11,6 +13,14 @@ export interface InstantiateResponse {
|
|||||||
|
|
||||||
export type Expiration = { at_height: number } | { at_time: string } | { never: Record<string, never> }
|
export type Expiration = { at_height: number } | { at_time: string } | { never: Record<string, never> }
|
||||||
|
|
||||||
|
export interface CollectionInfo {
|
||||||
|
description?: string
|
||||||
|
image?: string
|
||||||
|
external_link?: string
|
||||||
|
explicit_content?: boolean
|
||||||
|
royalty_info?: RoyaltyInfo | undefined
|
||||||
|
}
|
||||||
|
|
||||||
export interface SG721Instance {
|
export interface SG721Instance {
|
||||||
readonly contractAddress: string
|
readonly contractAddress: string
|
||||||
|
|
||||||
@ -65,7 +75,8 @@ export interface SG721Instance {
|
|||||||
revokeAll: (operator: string) => Promise<string>
|
revokeAll: (operator: string) => Promise<string>
|
||||||
/// Mint a new NFT, can only be called by the contract minter
|
/// Mint a new NFT, can only be called by the contract minter
|
||||||
mint: (tokenId: string, owner: string, tokenURI?: string) => Promise<string> //MintMsg<T>
|
mint: (tokenId: string, owner: string, tokenURI?: string) => Promise<string> //MintMsg<T>
|
||||||
|
updateCollectionInfo: (collectionInfo: CollectionInfo) => Promise<string>
|
||||||
|
freezeCollectionInfo: () => Promise<string>
|
||||||
/// Burn an NFT the sender has access to
|
/// Burn an NFT the sender has access to
|
||||||
burn: (tokenId: string) => Promise<string>
|
burn: (tokenId: string) => Promise<string>
|
||||||
batchBurn: (tokenIds: string) => Promise<string>
|
batchBurn: (tokenIds: string) => Promise<string>
|
||||||
@ -83,6 +94,8 @@ export interface Sg721Messages {
|
|||||||
burn: (tokenId: string) => BurnMessage
|
burn: (tokenId: string) => BurnMessage
|
||||||
batchBurn: (tokenIds: string) => BatchBurnMessage
|
batchBurn: (tokenIds: string) => BatchBurnMessage
|
||||||
batchTransfer: (recipient: string, tokenIds: string) => BatchTransferMessage
|
batchTransfer: (recipient: string, tokenIds: string) => BatchTransferMessage
|
||||||
|
updateCollectionInfo: (collectionInfo: CollectionInfo) => UpdateCollectionInfoMessage
|
||||||
|
freezeCollectionInfo: () => FreezeCollectionInfoMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TransferNFTMessage {
|
export interface TransferNFTMessage {
|
||||||
@ -197,6 +210,24 @@ export interface BatchTransferMessage {
|
|||||||
funds: Coin[]
|
funds: Coin[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface UpdateCollectionInfoMessage {
|
||||||
|
sender: string
|
||||||
|
contract: string
|
||||||
|
msg: {
|
||||||
|
update_collection_info: {
|
||||||
|
collection_info: CollectionInfo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
funds: Coin[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FreezeCollectionInfoMessage {
|
||||||
|
sender: string
|
||||||
|
contract: string
|
||||||
|
msg: { freeze_collection_info: Record<string, never> }
|
||||||
|
funds: Coin[]
|
||||||
|
}
|
||||||
|
|
||||||
export interface SG721Contract {
|
export interface SG721Contract {
|
||||||
instantiate: (
|
instantiate: (
|
||||||
senderAddress: string,
|
senderAddress: string,
|
||||||
@ -513,6 +544,33 @@ export const SG721 = (client: SigningCosmWasmClient, txSigner: string): SG721Con
|
|||||||
return res.transactionHash
|
return res.transactionHash
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-shadow
|
||||||
|
const updateCollectionInfo = async (collectionInfo: CollectionInfo): Promise<string> => {
|
||||||
|
const res = await client.execute(
|
||||||
|
txSigner,
|
||||||
|
contractAddress,
|
||||||
|
{
|
||||||
|
update_collection_info: { collection_info: collectionInfo },
|
||||||
|
},
|
||||||
|
'auto',
|
||||||
|
'',
|
||||||
|
)
|
||||||
|
return res.transactionHash
|
||||||
|
}
|
||||||
|
|
||||||
|
const freezeCollectionInfo = async (): Promise<string> => {
|
||||||
|
const res = await client.execute(
|
||||||
|
txSigner,
|
||||||
|
contractAddress,
|
||||||
|
{
|
||||||
|
freeze_collection_info: {},
|
||||||
|
},
|
||||||
|
'auto',
|
||||||
|
'',
|
||||||
|
)
|
||||||
|
return res.transactionHash
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
contractAddress,
|
contractAddress,
|
||||||
ownerOf,
|
ownerOf,
|
||||||
@ -537,6 +595,8 @@ export const SG721 = (client: SigningCosmWasmClient, txSigner: string): SG721Con
|
|||||||
burn,
|
burn,
|
||||||
batchBurn,
|
batchBurn,
|
||||||
batchTransfer,
|
batchTransfer,
|
||||||
|
updateCollectionInfo,
|
||||||
|
freezeCollectionInfo,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -719,6 +779,26 @@ export const SG721 = (client: SigningCosmWasmClient, txSigner: string): SG721Con
|
|||||||
funds: [],
|
funds: [],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const updateCollectionInfo = (collectionInfo: CollectionInfo) => {
|
||||||
|
return {
|
||||||
|
sender: txSigner,
|
||||||
|
contract: contractAddress,
|
||||||
|
msg: {
|
||||||
|
update_collection_info: { collection_info: collectionInfo },
|
||||||
|
},
|
||||||
|
funds: [],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const freezeCollectionInfo = () => {
|
||||||
|
return {
|
||||||
|
sender: txSigner,
|
||||||
|
contract: contractAddress,
|
||||||
|
msg: {
|
||||||
|
freeze_collection_info: {},
|
||||||
|
},
|
||||||
|
funds: [],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
transferNft,
|
transferNft,
|
||||||
@ -731,6 +811,8 @@ export const SG721 = (client: SigningCosmWasmClient, txSigner: string): SG721Con
|
|||||||
burn,
|
burn,
|
||||||
batchBurn,
|
batchBurn,
|
||||||
batchTransfer,
|
batchTransfer,
|
||||||
|
updateCollectionInfo,
|
||||||
|
freezeCollectionInfo,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +189,7 @@ const CollectionCreationPage: NextPage = () => {
|
|||||||
const msg = {
|
const msg = {
|
||||||
create_minter: {
|
create_minter: {
|
||||||
init_msg: {
|
init_msg: {
|
||||||
base_token_uri: `${uploadDetails?.uploadMethod === 'new' ? `ipfs://${baseUri}/` : `${baseUri}`}`,
|
base_token_uri: `${uploadDetails?.uploadMethod === 'new' ? `ipfs://${baseUri}` : `${baseUri}`}`,
|
||||||
start_time: mintingDetails?.startTime,
|
start_time: mintingDetails?.startTime,
|
||||||
num_tokens: mintingDetails?.numTokens,
|
num_tokens: mintingDetails?.numTokens,
|
||||||
mint_price: {
|
mint_price: {
|
||||||
@ -431,9 +431,9 @@ const CollectionCreationPage: NextPage = () => {
|
|||||||
<Anchor
|
<Anchor
|
||||||
className="text-stargaze hover:underline"
|
className="text-stargaze hover:underline"
|
||||||
external
|
external
|
||||||
href={`https://ipfs.stargaze.zone/ipfs/${baseTokenUri as string}/`}
|
href={`https://ipfs.stargaze.zone/ipfs/${baseTokenUri as string}`}
|
||||||
>
|
>
|
||||||
ipfs://{baseTokenUri as string}/
|
ipfs://{baseTokenUri as string}
|
||||||
</Anchor>
|
</Anchor>
|
||||||
)}
|
)}
|
||||||
{uploadDetails?.uploadMethod === 'existing' && (
|
{uploadDetails?.uploadMethod === 'existing' && (
|
||||||
|
@ -37,7 +37,7 @@ const MinterExecutePage: NextPage = () => {
|
|||||||
const type = comboboxState.value?.id
|
const type = comboboxState.value?.id
|
||||||
|
|
||||||
const limitState = useNumberInputState({
|
const limitState = useNumberInputState({
|
||||||
id: 'per-address-limi',
|
id: 'per-address-limit',
|
||||||
name: 'perAddressLimit',
|
name: 'perAddressLimit',
|
||||||
title: 'Per Address Limit',
|
title: 'Per Address Limit',
|
||||||
subtitle: 'Enter the per address limit',
|
subtitle: 'Enter the per address limit',
|
||||||
|
Loading…
Reference in New Issue
Block a user