-
+
{showAddressField &&
}
{showTokenIdField &&
}
diff --git a/components/collections/queries/query.ts b/components/collections/queries/query.ts
index e9454db..37b041b 100644
--- a/components/collections/queries/query.ts
+++ b/components/collections/queries/query.ts
@@ -1,5 +1,6 @@
-import type { MinterInstance } from 'contracts/minter'
+import type { BaseMinterInstance } from 'contracts/baseMinter'
import type { SG721Instance } from 'contracts/sg721'
+import type { VendingMinterInstance } from 'contracts/vendingMinter'
export type QueryType = typeof QUERY_TYPES[number]
@@ -10,6 +11,8 @@ export const QUERY_TYPES = [
'tokens_minted_to_user',
// 'token_owners',
'token_info',
+ 'config',
+ 'status',
] as const
export interface QueryListItem {
@@ -18,7 +21,7 @@ export interface QueryListItem {
description?: string
}
-export const QUERY_LIST: QueryListItem[] = [
+export const VENDING_QUERY_LIST: QueryListItem[] = [
{
id: 'collection_info',
name: 'Collection Info',
@@ -49,6 +52,43 @@ export const QUERY_LIST: QueryListItem[] = [
name: 'Token Info',
description: `Get information about a token in the collection.`,
},
+ {
+ id: 'config',
+ name: 'Minter Config',
+ description: `Query Minter Config`,
+ },
+ {
+ id: 'status',
+ name: 'Minter Status',
+ description: `Query Minter Status`,
+ },
+]
+export const BASE_QUERY_LIST: QueryListItem[] = [
+ {
+ id: 'collection_info',
+ name: 'Collection Info',
+ description: `Get information about the collection.`,
+ },
+ {
+ id: 'tokens_minted_to_user',
+ name: 'Tokens Minted to User',
+ description: `Get the number of tokens minted in the collection to a user.`,
+ },
+ {
+ id: 'token_info',
+ name: 'Token Info',
+ description: `Get information about a token in the collection.`,
+ },
+ {
+ id: 'config',
+ name: 'Minter Config',
+ description: `Query Minter Config`,
+ },
+ {
+ id: 'status',
+ name: 'Minter Status',
+ description: `Query Minter Status`,
+ },
]
export interface DispatchExecuteProps {
@@ -59,7 +99,8 @@ export interface DispatchExecuteProps {
type Select
= T
export type DispatchQueryArgs = {
- minterMessages?: MinterInstance
+ baseMinterMessages?: BaseMinterInstance
+ vendingMinterMessages?: VendingMinterInstance
sg721Messages?: SG721Instance
} & (
| { type: undefined }
@@ -69,11 +110,13 @@ export type DispatchQueryArgs = {
| { type: Select<'tokens_minted_to_user'>; address: string }
// | { type: Select<'token_owners'> }
| { type: Select<'token_info'>; tokenId: string }
+ | { type: Select<'config'> }
+ | { type: Select<'status'> }
)
export const dispatchQuery = async (args: DispatchQueryArgs) => {
- const { minterMessages, sg721Messages } = args
- if (!minterMessages || !sg721Messages) {
+ const { baseMinterMessages, vendingMinterMessages, sg721Messages } = args
+ if (!baseMinterMessages || !vendingMinterMessages || !sg721Messages) {
throw new Error('Cannot execute actions')
}
switch (args.type) {
@@ -81,21 +124,27 @@ export const dispatchQuery = async (args: DispatchQueryArgs) => {
return sg721Messages.collectionInfo()
}
case 'mint_price': {
- return minterMessages.getMintPrice()
+ return vendingMinterMessages.getMintPrice()
}
case 'num_tokens': {
- return minterMessages.getMintableNumTokens()
+ return vendingMinterMessages.getMintableNumTokens()
}
case 'tokens_minted_to_user': {
- return minterMessages.getMintCount(args.address)
+ return vendingMinterMessages.getMintCount(args.address)
}
// case 'token_owners': {
- // return minterMessages.updateStartTime(txSigner, args.startTime)
+ // return vendingMinterMessages.updateStartTime(txSigner, args.startTime)
// }
case 'token_info': {
if (!args.tokenId) return
return sg721Messages.allNftInfo(args.tokenId)
}
+ case 'config': {
+ return baseMinterMessages.getConfig()
+ }
+ case 'status': {
+ return baseMinterMessages.getStatus()
+ }
default: {
throw new Error('Unknown action')
}
diff --git a/components/contracts/minter/ExecuteCombobox.hooks.ts b/components/contracts/baseMinter/ExecuteCombobox.hooks.ts
similarity index 74%
rename from components/contracts/minter/ExecuteCombobox.hooks.ts
rename to components/contracts/baseMinter/ExecuteCombobox.hooks.ts
index 19830ab..2c9ee59 100644
--- a/components/contracts/minter/ExecuteCombobox.hooks.ts
+++ b/components/contracts/baseMinter/ExecuteCombobox.hooks.ts
@@ -1,4 +1,4 @@
-import type { ExecuteListItem } from 'contracts/minter/messages/execute'
+import type { ExecuteListItem } from 'contracts/baseMinter/messages/execute'
import { useState } from 'react'
export const useExecuteComboboxState = () => {
diff --git a/components/contracts/minter/ExecuteCombobox.tsx b/components/contracts/baseMinter/ExecuteCombobox.tsx
similarity index 94%
rename from components/contracts/minter/ExecuteCombobox.tsx
rename to components/contracts/baseMinter/ExecuteCombobox.tsx
index e327c6d..9905148 100644
--- a/components/contracts/minter/ExecuteCombobox.tsx
+++ b/components/contracts/baseMinter/ExecuteCombobox.tsx
@@ -1,8 +1,8 @@
import { Combobox, Transition } from '@headlessui/react'
import clsx from 'clsx'
import { FormControl } from 'components/FormControl'
-import type { ExecuteListItem } from 'contracts/minter/messages/execute'
-import { EXECUTE_LIST } from 'contracts/minter/messages/execute'
+import type { ExecuteListItem } from 'contracts/baseMinter/messages/execute'
+import { EXECUTE_LIST } from 'contracts/baseMinter/messages/execute'
import { matchSorter } from 'match-sorter'
import { Fragment, useState } from 'react'
import { FaChevronDown, FaInfoCircle } from 'react-icons/fa'
@@ -67,7 +67,7 @@ export const ExecuteCombobox = ({ value, onChange }: ExecuteComboboxProps) => {
- clsx('flex relative flex-col py-2 px-4 space-y-1 cursor-pointer', { 'bg-plumbus-70': active })
+ clsx('flex relative flex-col py-2 px-4 space-y-1 cursor-pointer', { 'bg-stargaze-80': active })
}
value={entry}
>
diff --git a/components/contracts/sg721/ExecuteCombobox.tsx b/components/contracts/sg721/ExecuteCombobox.tsx
index aa67719..926a136 100644
--- a/components/contracts/sg721/ExecuteCombobox.tsx
+++ b/components/contracts/sg721/ExecuteCombobox.tsx
@@ -67,7 +67,7 @@ export const ExecuteCombobox = ({ value, onChange }: ExecuteComboboxProps) => {
- clsx('flex relative flex-col py-2 px-4 space-y-1 cursor-pointer', { 'bg-plumbus-70': active })
+ clsx('flex relative flex-col py-2 px-4 space-y-1 cursor-pointer', { 'bg-stargaze-80': active })
}
value={entry}
>
diff --git a/components/contracts/vendingMinter/ExecuteCombobox.hooks.ts b/components/contracts/vendingMinter/ExecuteCombobox.hooks.ts
new file mode 100644
index 0000000..09ef184
--- /dev/null
+++ b/components/contracts/vendingMinter/ExecuteCombobox.hooks.ts
@@ -0,0 +1,7 @@
+import type { ExecuteListItem } from 'contracts/vendingMinter/messages/execute'
+import { useState } from 'react'
+
+export const useExecuteComboboxState = () => {
+ const [value, setValue] = useState(null)
+ return { value, onChange: (item: ExecuteListItem) => setValue(item) }
+}
diff --git a/components/contracts/vendingMinter/ExecuteCombobox.tsx b/components/contracts/vendingMinter/ExecuteCombobox.tsx
new file mode 100644
index 0000000..3b9a6d4
--- /dev/null
+++ b/components/contracts/vendingMinter/ExecuteCombobox.tsx
@@ -0,0 +1,92 @@
+import { Combobox, Transition } from '@headlessui/react'
+import clsx from 'clsx'
+import { FormControl } from 'components/FormControl'
+import type { ExecuteListItem } from 'contracts/vendingMinter/messages/execute'
+import { EXECUTE_LIST } from 'contracts/vendingMinter/messages/execute'
+import { matchSorter } from 'match-sorter'
+import { Fragment, useState } from 'react'
+import { FaChevronDown, FaInfoCircle } from 'react-icons/fa'
+
+export interface ExecuteComboboxProps {
+ value: ExecuteListItem | null
+ onChange: (item: ExecuteListItem) => void
+}
+
+export const ExecuteCombobox = ({ value, onChange }: ExecuteComboboxProps) => {
+ const [search, setSearch] = useState('')
+
+ const filtered =
+ search === '' ? EXECUTE_LIST : matchSorter(EXECUTE_LIST, search, { keys: ['id', 'name', 'description'] })
+
+ return (
+
+
+ val?.name ?? ''}
+ id="message-type"
+ onChange={(event) => setSearch(event.target.value)}
+ placeholder="Select message type"
+ />
+
+
+ {({ open }) => }
+
+
+ setSearch('')} as={Fragment}>
+
+ {filtered.length < 1 && (
+
+ Message type not found.
+
+ )}
+ {filtered.map((entry) => (
+
+ clsx('flex relative flex-col py-2 px-4 space-y-1 cursor-pointer', { 'bg-stargaze-80': active })
+ }
+ value={entry}
+ >
+ {entry.name}
+ {entry.description}
+
+ ))}
+
+
+
+
+ {value && (
+
+
+
+
+
{value.description}
+
+ )}
+
+ )
+}
diff --git a/components/contracts/whitelist/ExecuteCombobox.tsx b/components/contracts/whitelist/ExecuteCombobox.tsx
index 7dce2a9..2db88e8 100644
--- a/components/contracts/whitelist/ExecuteCombobox.tsx
+++ b/components/contracts/whitelist/ExecuteCombobox.tsx
@@ -67,7 +67,7 @@ export const ExecuteCombobox = ({ value, onChange }: ExecuteComboboxProps) => {
- clsx('flex relative flex-col py-2 px-4 space-y-1 cursor-pointer', { 'bg-plumbus-70': active })
+ clsx('flex relative flex-col py-2 px-4 space-y-1 cursor-pointer', { 'bg-stargaze-80': active })
}
value={entry}
>
diff --git a/contexts/contracts.tsx b/contexts/contracts.tsx
index 5094c4a..b0fbd06 100644
--- a/contexts/contracts.tsx
+++ b/contexts/contracts.tsx
@@ -1,9 +1,13 @@
-import type { UseMinterContractProps } from 'contracts/minter'
-import { useMinterContract } from 'contracts/minter'
+import type { UseBaseFactoryContractProps } from 'contracts/baseFactory'
+import { useBaseFactoryContract } from 'contracts/baseFactory'
+import type { UseBaseMinterContractProps } from 'contracts/baseMinter'
+import { useBaseMinterContract } from 'contracts/baseMinter'
import type { UseSG721ContractProps } from 'contracts/sg721'
import { useSG721Contract } from 'contracts/sg721'
import type { UseVendingFactoryContractProps } from 'contracts/vendingFactory'
import { useVendingFactoryContract } from 'contracts/vendingFactory'
+import type { UseVendingMinterContractProps } from 'contracts/vendingMinter'
+import { useVendingMinterContract } from 'contracts/vendingMinter'
import type { UseWhiteListContractProps } from 'contracts/whitelist'
import { useWhiteListContract } from 'contracts/whitelist'
import type { ReactNode, VFC } from 'react'
@@ -16,9 +20,11 @@ import create from 'zustand'
*/
export interface ContractsStore extends State {
sg721: UseSG721ContractProps | null
- minter: UseMinterContractProps | null
+ vendingMinter: UseVendingMinterContractProps | null
+ baseMinter: UseBaseMinterContractProps | null
whitelist: UseWhiteListContractProps | null
vendingFactory: UseVendingFactoryContractProps | null
+ baseFactory: UseBaseFactoryContractProps | null
}
/**
@@ -26,9 +32,11 @@ export interface ContractsStore extends State {
*/
export const defaultValues: ContractsStore = {
sg721: null,
- minter: null,
+ vendingMinter: null,
+ baseMinter: null,
whitelist: null,
vendingFactory: null,
+ baseFactory: null,
}
/**
@@ -53,18 +61,22 @@ export const ContractsProvider = ({ children }: { children: ReactNode }) => {
const ContractsSubscription: VFC = () => {
const sg721 = useSG721Contract()
- const minter = useMinterContract()
+ const vendingMinter = useVendingMinterContract()
+ const baseMinter = useBaseMinterContract()
const whitelist = useWhiteListContract()
const vendingFactory = useVendingFactoryContract()
+ const baseFactory = useBaseFactoryContract()
useEffect(() => {
useContracts.setState({
sg721,
- minter,
+ vendingMinter,
+ baseMinter,
whitelist,
vendingFactory,
+ baseFactory,
})
- }, [sg721, minter, whitelist, vendingFactory])
+ }, [sg721, vendingMinter, baseMinter, whitelist, vendingFactory, baseFactory])
return null
}
diff --git a/contracts/baseFactory/contract.ts b/contracts/baseFactory/contract.ts
new file mode 100644
index 0000000..20fd166
--- /dev/null
+++ b/contracts/baseFactory/contract.ts
@@ -0,0 +1,93 @@
+import type { SigningCosmWasmClient } from '@cosmjs/cosmwasm-stargate'
+import type { Coin } from '@cosmjs/proto-signing'
+import { coin } from '@cosmjs/proto-signing'
+import type { logs } from '@cosmjs/stargate'
+import { BASE_FACTORY_ADDRESS } from 'utils/constants'
+
+export interface CreateBaseMinterResponse {
+ readonly baseMinterAddress: string
+ readonly sg721Address: string
+ readonly transactionHash: string
+ readonly logs: readonly logs.Log[]
+}
+
+export interface BaseFactoryInstance {
+ readonly contractAddress: string
+
+ //Query
+ getParams: () => Promise
+ //Execute
+ createBaseMinter: (
+ senderAddress: string,
+ msg: Record,
+ funds: Coin[],
+ ) => Promise
+}
+
+export interface BaseFactoryMessages {
+ createBaseMinter: (msg: Record) => CreateBaseMinterMessage
+}
+
+export interface CreateBaseMinterMessage {
+ sender: string
+ contract: string
+ msg: Record
+ funds: Coin[]
+}
+
+export interface BaseFactoryContract {
+ use: (contractAddress: string) => BaseFactoryInstance
+
+ messages: (contractAddress: string) => BaseFactoryMessages
+}
+
+export const baseFactory = (client: SigningCosmWasmClient, txSigner: string): BaseFactoryContract => {
+ const use = (contractAddress: string): BaseFactoryInstance => {
+ //Query
+ const getParams = async (): Promise => {
+ const res = await client.queryContractSmart(contractAddress, {
+ params: {},
+ })
+ return res
+ }
+
+ //Execute
+ const createBaseMinter = async (
+ senderAddress: string,
+ msg: Record,
+ funds: Coin[],
+ ): Promise => {
+ const result = await client.execute(senderAddress, BASE_FACTORY_ADDRESS, msg, 'auto', '', funds)
+
+ return {
+ baseMinterAddress: result.logs[0].events[5].attributes[0].value,
+ sg721Address: result.logs[0].events[5].attributes[2].value,
+ transactionHash: result.transactionHash,
+ logs: result.logs,
+ }
+ }
+
+ return {
+ contractAddress,
+ getParams,
+ createBaseMinter,
+ }
+ }
+
+ const messages = (contractAddress: string) => {
+ const createBaseMinter = (msg: Record): CreateBaseMinterMessage => {
+ return {
+ sender: txSigner,
+ contract: contractAddress,
+ msg,
+ funds: [coin('1000000000', 'ustars')],
+ }
+ }
+
+ return {
+ createBaseMinter,
+ }
+ }
+
+ return { use, messages }
+}
diff --git a/contracts/minter/index.ts b/contracts/baseFactory/index.ts
similarity index 100%
rename from contracts/minter/index.ts
rename to contracts/baseFactory/index.ts
diff --git a/contracts/baseFactory/messages/execute.ts b/contracts/baseFactory/messages/execute.ts
new file mode 100644
index 0000000..374aba9
--- /dev/null
+++ b/contracts/baseFactory/messages/execute.ts
@@ -0,0 +1,28 @@
+import type { Coin } from '@cosmjs/proto-signing'
+
+import type { BaseFactoryInstance } from '../index'
+import { useBaseFactoryContract } from '../index'
+
+/** @see {@link VendingFactoryInstance} */
+export interface DispatchExecuteArgs {
+ contract: string
+ messages?: BaseFactoryInstance
+ txSigner: string
+ msg: Record
+ funds: Coin[]
+}
+
+export const dispatchExecute = async (args: DispatchExecuteArgs) => {
+ const { messages, txSigner } = args
+ if (!messages) {
+ throw new Error('cannot dispatch execute, messages is not defined')
+ }
+ return messages.createBaseMinter(txSigner, args.msg, args.funds)
+}
+
+export const previewExecutePayload = (args: DispatchExecuteArgs) => {
+ // eslint-disable-next-line react-hooks/rules-of-hooks
+ const { messages } = useBaseFactoryContract()
+ const { contract } = args
+ return messages(contract)?.createBaseMinter(args.msg)
+}
diff --git a/contracts/baseFactory/useContract.ts b/contracts/baseFactory/useContract.ts
new file mode 100644
index 0000000..d03ff09
--- /dev/null
+++ b/contracts/baseFactory/useContract.ts
@@ -0,0 +1,57 @@
+import { useWallet } from 'contexts/wallet'
+import { useCallback, useEffect, useState } from 'react'
+
+import type { BaseFactoryContract, BaseFactoryInstance, BaseFactoryMessages } from './contract'
+import { baseFactory as initContract } from './contract'
+
+export interface UseBaseFactoryContractProps {
+ use: (customAddress: string) => BaseFactoryInstance | undefined
+ updateContractAddress: (contractAddress: string) => void
+ getContractAddress: () => string | undefined
+ messages: (contractAddress: string) => BaseFactoryMessages | undefined
+}
+
+export function useBaseFactoryContract(): UseBaseFactoryContractProps {
+ const wallet = useWallet()
+
+ const [address, setAddress] = useState('')
+ const [baseFactory, setBaseFactory] = useState()
+
+ useEffect(() => {
+ setAddress(localStorage.getItem('contract_address') || '')
+ }, [])
+
+ useEffect(() => {
+ const BaseFactoryBaseContract = initContract(wallet.getClient(), wallet.address)
+ setBaseFactory(BaseFactoryBaseContract)
+ }, [wallet])
+
+ const updateContractAddress = (contractAddress: string) => {
+ setAddress(contractAddress)
+ }
+
+ const use = useCallback(
+ (customAddress = ''): BaseFactoryInstance | undefined => {
+ return baseFactory?.use(address || customAddress)
+ },
+ [baseFactory, address],
+ )
+
+ const getContractAddress = (): string | undefined => {
+ return address
+ }
+
+ const messages = useCallback(
+ (customAddress = ''): BaseFactoryMessages | undefined => {
+ return baseFactory?.messages(address || customAddress)
+ },
+ [baseFactory, address],
+ )
+
+ return {
+ use,
+ updateContractAddress,
+ getContractAddress,
+ messages,
+ }
+}
diff --git a/contracts/baseMinter/contract.ts b/contracts/baseMinter/contract.ts
new file mode 100644
index 0000000..7ebfcd4
--- /dev/null
+++ b/contracts/baseMinter/contract.ts
@@ -0,0 +1,243 @@
+import type { SigningCosmWasmClient } from '@cosmjs/cosmwasm-stargate'
+import type { Coin } from '@cosmjs/proto-signing'
+import { coin } from '@cosmjs/proto-signing'
+import type { logs } from '@cosmjs/stargate'
+import type { Timestamp } from '@stargazezone/types/contracts/minter/shared-types'
+import toast from 'react-hot-toast'
+import { BASE_FACTORY_ADDRESS } from 'utils/constants'
+
+export interface InstantiateResponse {
+ readonly contractAddress: string
+ readonly transactionHash: string
+ readonly logs: readonly logs.Log[]
+}
+
+export interface MigrateResponse {
+ readonly transactionHash: string
+ readonly logs: readonly logs.Log[]
+}
+
+export interface RoyaltyInfo {
+ payment_address: string
+ share: string
+}
+
+export interface BaseMinterInstance {
+ readonly contractAddress: string
+
+ //Query
+ getConfig: () => Promise
+ getStatus: () => Promise
+
+ //Execute
+ mint: (senderAddress: string, tokenUri: string) => Promise
+ updateStartTradingTime: (senderAddress: string, time?: Timestamp) => Promise
+}
+
+export interface BaseMinterMessages {
+ mint: (tokenUri: string) => MintMessage
+ updateStartTradingTime: (time: Timestamp) => UpdateStartTradingTimeMessage
+}
+
+export interface MintMessage {
+ sender: string
+ contract: string
+ msg: {
+ mint: {
+ token_uri: string
+ }
+ }
+ funds: Coin[]
+}
+
+export interface UpdateStartTradingTimeMessage {
+ sender: string
+ contract: string
+ msg: {
+ update_start_trading_time: string
+ }
+ funds: Coin[]
+}
+
+export interface CustomMessage {
+ sender: string
+ contract: string
+ msg: Record[]
+ funds: Coin[]
+}
+
+export interface MintPriceMessage {
+ public_price: {
+ denom: string
+ amount: string
+ }
+ airdrop_price: {
+ denom: string
+ amount: string
+ }
+ whitelist_price?: {
+ denom: string
+ amount: string
+ }
+ current_price: {
+ denom: string
+ amount: string
+ }
+}
+
+export interface BaseMinterContract {
+ instantiate: (
+ senderAddress: string,
+ codeId: number,
+ initMsg: Record,
+ label: string,
+ admin?: string,
+ funds?: Coin[],
+ ) => Promise
+
+ migrate: (
+ senderAddress: string,
+ contractAddress: string,
+ codeId: number,
+ migrateMsg: Record,
+ ) => Promise
+
+ use: (contractAddress: string) => BaseMinterInstance
+
+ messages: (contractAddress: string) => BaseMinterMessages
+}
+
+export const baseMinter = (client: SigningCosmWasmClient, txSigner: string): BaseMinterContract => {
+ const use = (contractAddress: string): BaseMinterInstance => {
+ //Query
+ const getFactoryParameters = async (): Promise => {
+ const res = await client.queryContractSmart(BASE_FACTORY_ADDRESS, { params: {} })
+ return res
+ console.log(res)
+ }
+
+ const getConfig = async (): Promise => {
+ const res = await client.queryContractSmart(contractAddress, {
+ config: {},
+ })
+ return res
+ }
+
+ const getStatus = async (): Promise => {
+ const res = await client.queryContractSmart(contractAddress, {
+ status: {},
+ })
+ return res
+ }
+
+ //Execute
+ const mint = async (senderAddress: string, tokenUri: string): Promise => {
+ //const factoryParameters = await baseFactory?.use(BASE_FACTORY_ADDRESS)?.getParams()
+
+ const factoryParameters = await toast.promise(getFactoryParameters(), {
+ loading: 'Querying Factory Parameters...',
+ error: 'Querying Factory Parameters failed!',
+ success: 'Query successful! Minting...',
+ })
+ console.log(factoryParameters.params.mint_fee_bps)
+
+ const price = (await getConfig()).config.mint_price.amount
+ console.log(price)
+ console.log((Number(price) * Number(factoryParameters.params.mint_fee_bps)) / 100)
+ const res = await client.execute(
+ senderAddress,
+ contractAddress,
+ {
+ mint: { token_uri: tokenUri },
+ },
+ 'auto',
+ '',
+ [coin((Number(price) * Number(factoryParameters.params.mint_fee_bps)) / 100 / 100, 'ustars')],
+ )
+
+ return res.transactionHash
+ }
+
+ const updateStartTradingTime = async (senderAddress: string, time?: Timestamp): Promise => {
+ const res = await client.execute(
+ senderAddress,
+ contractAddress,
+ {
+ update_start_trading_time: time || null,
+ },
+ 'auto',
+ '',
+ )
+
+ return res.transactionHash
+ }
+
+ return {
+ contractAddress,
+ getConfig,
+ getStatus,
+ mint,
+ updateStartTradingTime,
+ }
+ }
+
+ const migrate = async (
+ senderAddress: string,
+ contractAddress: string,
+ codeId: number,
+ migrateMsg: Record,
+ ): Promise => {
+ const result = await client.migrate(senderAddress, contractAddress, codeId, migrateMsg, 'auto')
+ return {
+ transactionHash: result.transactionHash,
+ logs: result.logs,
+ }
+ }
+
+ const instantiate = async (
+ senderAddress: string,
+ codeId: number,
+ initMsg: Record,
+ label: string,
+ ): Promise => {
+ const result = await client.instantiate(senderAddress, codeId, initMsg, label, 'auto', {
+ funds: [coin('1000000000', 'ustars')],
+ })
+ return {
+ contractAddress: result.contractAddress,
+ transactionHash: result.transactionHash,
+ logs: result.logs,
+ }
+ }
+
+ const messages = (contractAddress: string) => {
+ const mint = (tokenUri: string): MintMessage => {
+ return {
+ sender: txSigner,
+ contract: contractAddress,
+ msg: {
+ mint: { token_uri: tokenUri },
+ },
+ funds: [],
+ }
+ }
+
+ const updateStartTradingTime = (startTime: string): UpdateStartTradingTimeMessage => {
+ return {
+ sender: txSigner,
+ contract: contractAddress,
+ msg: {
+ update_start_trading_time: startTime,
+ },
+ funds: [],
+ }
+ }
+
+ return {
+ mint,
+ updateStartTradingTime,
+ }
+ }
+
+ return { use, instantiate, migrate, messages }
+}
diff --git a/contracts/baseMinter/index.ts b/contracts/baseMinter/index.ts
new file mode 100644
index 0000000..6dc6461
--- /dev/null
+++ b/contracts/baseMinter/index.ts
@@ -0,0 +1,2 @@
+export * from './contract'
+export * from './useContract'
diff --git a/contracts/baseMinter/messages/execute.ts b/contracts/baseMinter/messages/execute.ts
new file mode 100644
index 0000000..dc29129
--- /dev/null
+++ b/contracts/baseMinter/messages/execute.ts
@@ -0,0 +1,82 @@
+import type { BaseMinterInstance } from '../index'
+import { useBaseMinterContract } from '../index'
+
+export type ExecuteType = typeof EXECUTE_TYPES[number]
+
+export const EXECUTE_TYPES = ['mint', 'update_start_trading_time'] as const
+
+export interface ExecuteListItem {
+ id: ExecuteType
+ name: string
+ description?: string
+}
+
+export const EXECUTE_LIST: ExecuteListItem[] = [
+ {
+ id: 'mint',
+ name: 'Mint',
+ description: `Mint a token with the given token URI`,
+ },
+ {
+ id: 'update_start_trading_time',
+ name: 'Update Start Trading Time',
+ description: `Update start trading time for minting`,
+ },
+]
+
+export interface DispatchExecuteProps {
+ type: ExecuteType
+ [k: string]: unknown
+}
+
+type Select = T
+
+/** @see {@link BaseMinterInstance} */
+export type DispatchExecuteArgs = {
+ contract: string
+ messages?: BaseMinterInstance
+ txSigner: string
+} & (
+ | { type: undefined }
+ | { type: Select<'mint'>; tokenUri: string }
+ | { type: Select<'update_start_trading_time'>; startTime?: string }
+)
+
+export const dispatchExecute = async (args: DispatchExecuteArgs) => {
+ const { messages, txSigner } = args
+ if (!messages) {
+ throw new Error('cannot dispatch execute, messages is not defined')
+ }
+ switch (args.type) {
+ case 'mint': {
+ return messages.mint(txSigner, args.tokenUri)
+ }
+ case 'update_start_trading_time': {
+ return messages.updateStartTradingTime(txSigner, args.startTime)
+ }
+ default: {
+ throw new Error('unknown execute type')
+ }
+ }
+}
+
+export const previewExecutePayload = (args: DispatchExecuteArgs) => {
+ // eslint-disable-next-line react-hooks/rules-of-hooks
+ const { messages } = useBaseMinterContract()
+ const { contract } = args
+ switch (args.type) {
+ case 'mint': {
+ return messages(contract)?.mint(args.tokenUri)
+ }
+ case 'update_start_trading_time': {
+ return messages(contract)?.updateStartTradingTime(args.startTime as string)
+ }
+ default: {
+ return {}
+ }
+ }
+}
+
+export const isEitherType = (type: unknown, arr: T[]): type is T => {
+ return arr.some((val) => type === val)
+}
diff --git a/contracts/baseMinter/messages/query.ts b/contracts/baseMinter/messages/query.ts
new file mode 100644
index 0000000..6f92b26
--- /dev/null
+++ b/contracts/baseMinter/messages/query.ts
@@ -0,0 +1,37 @@
+import type { BaseMinterInstance } from '../contract'
+
+export type QueryType = typeof QUERY_TYPES[number]
+
+export const QUERY_TYPES = ['config', 'status'] as const
+
+export interface QueryListItem {
+ id: QueryType
+ name: string
+ description?: string
+}
+
+export const QUERY_LIST: QueryListItem[] = [
+ { id: 'config', name: 'Config', description: 'Query current contract config' },
+ { id: 'status', name: 'Status', description: 'Query current contract status' },
+]
+
+export interface DispatchQueryProps {
+ address: string
+ messages: BaseMinterInstance | undefined
+ type: QueryType
+}
+
+export const dispatchQuery = (props: DispatchQueryProps) => {
+ const { address, messages, type } = props
+ switch (type) {
+ case 'config': {
+ return messages?.getConfig()
+ }
+ case 'status': {
+ return messages?.getStatus()
+ }
+ default: {
+ throw new Error('unknown query type')
+ }
+ }
+}
diff --git a/contracts/baseMinter/useContract.ts b/contracts/baseMinter/useContract.ts
new file mode 100644
index 0000000..35d54fe
--- /dev/null
+++ b/contracts/baseMinter/useContract.ts
@@ -0,0 +1,102 @@
+import type { Coin } from '@cosmjs/proto-signing'
+import type { logs } from '@cosmjs/stargate'
+import { useWallet } from 'contexts/wallet'
+import { useCallback, useEffect, useState } from 'react'
+
+import type { BaseMinterContract, BaseMinterInstance, BaseMinterMessages, MigrateResponse } from './contract'
+import { baseMinter as initContract } from './contract'
+
+interface InstantiateResponse {
+ readonly contractAddress: string
+ readonly transactionHash: string
+ readonly logs: readonly logs.Log[]
+}
+
+export interface UseBaseMinterContractProps {
+ instantiate: (
+ codeId: number,
+ initMsg: Record,
+ label: string,
+ admin?: string,
+ funds?: Coin[],
+ ) => Promise
+ migrate: (contractAddress: string, codeId: number, migrateMsg: Record) => Promise
+ use: (customAddress: string) => BaseMinterInstance | undefined
+ updateContractAddress: (contractAddress: string) => void
+ getContractAddress: () => string | undefined
+ messages: (contractAddress: string) => BaseMinterMessages | undefined
+}
+
+export function useBaseMinterContract(): UseBaseMinterContractProps {
+ const wallet = useWallet()
+
+ const [address, setAddress] = useState('')
+ const [baseMinter, setBaseMinter] = useState()
+
+ useEffect(() => {
+ setAddress(localStorage.getItem('contract_address') || '')
+ }, [])
+
+ useEffect(() => {
+ const BaseMinterBaseContract = initContract(wallet.getClient(), wallet.address)
+ setBaseMinter(BaseMinterBaseContract)
+ }, [wallet])
+
+ const updateContractAddress = (contractAddress: string) => {
+ setAddress(contractAddress)
+ }
+
+ const instantiate = useCallback(
+ (codeId: number, initMsg: Record, label: string, admin?: string): Promise => {
+ return new Promise((resolve, reject) => {
+ if (!baseMinter) {
+ reject(new Error('Contract is not initialized.'))
+ return
+ }
+ baseMinter.instantiate(wallet.address, codeId, initMsg, label, admin).then(resolve).catch(reject)
+ })
+ },
+ [baseMinter, wallet],
+ )
+
+ const migrate = useCallback(
+ (contractAddress: string, codeId: number, migrateMsg: Record): Promise => {
+ return new Promise((resolve, reject) => {
+ if (!baseMinter) {
+ reject(new Error('Contract is not initialized.'))
+ return
+ }
+ console.log(wallet.address, contractAddress, codeId)
+ baseMinter.migrate(wallet.address, contractAddress, codeId, migrateMsg).then(resolve).catch(reject)
+ })
+ },
+ [baseMinter, wallet],
+ )
+
+ const use = useCallback(
+ (customAddress = ''): BaseMinterInstance | undefined => {
+ return baseMinter?.use(address || customAddress)
+ },
+ [baseMinter, address],
+ )
+
+ const getContractAddress = (): string | undefined => {
+ return address
+ }
+
+ const messages = useCallback(
+ (customAddress = ''): BaseMinterMessages | undefined => {
+ return baseMinter?.messages(address || customAddress)
+ },
+ [baseMinter, address],
+ )
+
+ return {
+ instantiate,
+ use,
+ updateContractAddress,
+ getContractAddress,
+ messages,
+ migrate,
+ }
+}
diff --git a/contracts/sg721/contract.ts b/contracts/sg721/contract.ts
index 7183816..dbefd57 100644
--- a/contracts/sg721/contract.ts
+++ b/contracts/sg721/contract.ts
@@ -4,7 +4,7 @@ import type { Coin, logs } from '@cosmjs/stargate'
import { coin } from '@cosmjs/stargate'
import { MsgExecuteContract } from 'cosmjs-types/cosmwasm/wasm/v1/tx'
-import type { RoyaltyInfo } from '../minter/contract'
+import type { RoyaltyInfo } from '../vendingMinter/contract'
export interface InstantiateResponse {
readonly contractAddress: string
diff --git a/contracts/vendingFactory/contract.ts b/contracts/vendingFactory/contract.ts
index a172157..6082804 100644
--- a/contracts/vendingFactory/contract.ts
+++ b/contracts/vendingFactory/contract.ts
@@ -4,8 +4,8 @@ import { coin } from '@cosmjs/proto-signing'
import type { logs } from '@cosmjs/stargate'
import { VENDING_FACTORY_ADDRESS } from 'utils/constants'
-export interface CreateMinterResponse {
- readonly minterAddress: string
+export interface CreateVendingMinterResponse {
+ readonly vendingMinterAddress: string
readonly sg721Address: string
readonly transactionHash: string
readonly logs: readonly logs.Log[]
@@ -17,14 +17,18 @@ export interface VendingFactoryInstance {
//Query
//Execute
- createMinter: (senderAddress: string, msg: Record, funds: Coin[]) => Promise
+ createVendingMinter: (
+ senderAddress: string,
+ msg: Record,
+ funds: Coin[],
+ ) => Promise
}
export interface VendingFactoryMessages {
- createMinter: (msg: Record) => CreateMinterMessage
+ createVendingMinter: (msg: Record) => CreateVendingMinterMessage
}
-export interface CreateMinterMessage {
+export interface CreateVendingMinterMessage {
sender: string
contract: string
msg: Record
@@ -42,15 +46,15 @@ export const vendingFactory = (client: SigningCosmWasmClient, txSigner: string):
//Query
//Execute
- const createMinter = async (
+ const createVendingMinter = async (
senderAddress: string,
msg: Record,
funds: Coin[],
- ): Promise => {
+ ): Promise => {
const result = await client.execute(senderAddress, VENDING_FACTORY_ADDRESS, msg, 'auto', '', funds)
return {
- minterAddress: result.logs[0].events[5].attributes[0].value,
+ vendingMinterAddress: result.logs[0].events[5].attributes[0].value,
sg721Address: result.logs[0].events[5].attributes[2].value,
transactionHash: result.transactionHash,
logs: result.logs,
@@ -59,12 +63,12 @@ export const vendingFactory = (client: SigningCosmWasmClient, txSigner: string):
return {
contractAddress,
- createMinter,
+ createVendingMinter,
}
}
const messages = (contractAddress: string) => {
- const createMinter = (msg: Record): CreateMinterMessage => {
+ const createVendingMinter = (msg: Record): CreateVendingMinterMessage => {
return {
sender: txSigner,
contract: contractAddress,
@@ -74,7 +78,7 @@ export const vendingFactory = (client: SigningCosmWasmClient, txSigner: string):
}
return {
- createMinter,
+ createVendingMinter,
}
}
diff --git a/contracts/vendingFactory/messages/execute.ts b/contracts/vendingFactory/messages/execute.ts
index fedf1f2..7939a7f 100644
--- a/contracts/vendingFactory/messages/execute.ts
+++ b/contracts/vendingFactory/messages/execute.ts
@@ -17,12 +17,12 @@ export const dispatchExecute = async (args: DispatchExecuteArgs) => {
if (!messages) {
throw new Error('cannot dispatch execute, messages is not defined')
}
- return messages.createMinter(txSigner, args.msg, args.funds)
+ return messages.createVendingMinter(txSigner, args.msg, args.funds)
}
export const previewExecutePayload = (args: DispatchExecuteArgs) => {
// eslint-disable-next-line react-hooks/rules-of-hooks
const { messages } = useVendingFactoryContract()
const { contract } = args
- return messages(contract)?.createMinter(args.msg)
+ return messages(contract)?.createVendingMinter(args.msg)
}
diff --git a/contracts/minter/contract.ts b/contracts/vendingMinter/contract.ts
similarity index 97%
rename from contracts/minter/contract.ts
rename to contracts/vendingMinter/contract.ts
index ca9b9e5..e462cfb 100644
--- a/contracts/minter/contract.ts
+++ b/contracts/vendingMinter/contract.ts
@@ -22,7 +22,7 @@ export interface RoyaltyInfo {
share: string
}
-export interface MinterInstance {
+export interface VendingMinterInstance {
readonly contractAddress: string
//Query
@@ -50,7 +50,7 @@ export interface MinterInstance {
burnRemaining: (senderAddress: string) => Promise
}
-export interface MinterMessages {
+export interface VendingMinterMessages {
mint: () => MintMessage
purge: () => PurgeMessage
updateMintPrice: (price: string) => UpdateMintPriceMessage
@@ -219,7 +219,7 @@ export interface MintPriceMessage {
}
}
-export interface MinterContract {
+export interface VendingMinterContract {
instantiate: (
senderAddress: string,
codeId: number,
@@ -236,13 +236,13 @@ export interface MinterContract {
migrateMsg: Record,
) => Promise
- use: (contractAddress: string) => MinterInstance
+ use: (contractAddress: string) => VendingMinterInstance
- messages: (contractAddress: string) => MinterMessages
+ messages: (contractAddress: string) => VendingMinterMessages
}
-export const minter = (client: SigningCosmWasmClient, txSigner: string): MinterContract => {
- const use = (contractAddress: string): MinterInstance => {
+export const vendingMinter = (client: SigningCosmWasmClient, txSigner: string): VendingMinterContract => {
+ const use = (contractAddress: string): VendingMinterInstance => {
//Query
const getConfig = async (): Promise => {
const res = await client.queryContractSmart(contractAddress, {
diff --git a/contracts/vendingMinter/index.ts b/contracts/vendingMinter/index.ts
new file mode 100644
index 0000000..6dc6461
--- /dev/null
+++ b/contracts/vendingMinter/index.ts
@@ -0,0 +1,2 @@
+export * from './contract'
+export * from './useContract'
diff --git a/contracts/minter/messages/execute.ts b/contracts/vendingMinter/messages/execute.ts
similarity index 95%
rename from contracts/minter/messages/execute.ts
rename to contracts/vendingMinter/messages/execute.ts
index f2f072f..058ae73 100644
--- a/contracts/minter/messages/execute.ts
+++ b/contracts/vendingMinter/messages/execute.ts
@@ -1,5 +1,5 @@
-import type { MinterInstance } from '../index'
-import { useMinterContract } from '../index'
+import type { VendingMinterInstance } from '../index'
+import { useVendingMinterContract } from '../index'
export type ExecuteType = typeof EXECUTE_TYPES[number]
@@ -89,10 +89,10 @@ export interface DispatchExecuteProps {
type Select = T
-/** @see {@link MinterInstance} */
+/** @see {@link VendingMinterInstance} */
export type DispatchExecuteArgs = {
contract: string
- messages?: MinterInstance
+ messages?: VendingMinterInstance
txSigner: string
} & (
| { type: undefined }
@@ -160,7 +160,7 @@ export const dispatchExecute = async (args: DispatchExecuteArgs) => {
export const previewExecutePayload = (args: DispatchExecuteArgs) => {
// eslint-disable-next-line react-hooks/rules-of-hooks
- const { messages } = useMinterContract()
+ const { messages } = useVendingMinterContract()
const { contract } = args
switch (args.type) {
case 'mint': {
diff --git a/contracts/minter/messages/query.ts b/contracts/vendingMinter/messages/query.ts
similarity index 93%
rename from contracts/minter/messages/query.ts
rename to contracts/vendingMinter/messages/query.ts
index 496ca5e..f5673ed 100644
--- a/contracts/minter/messages/query.ts
+++ b/contracts/vendingMinter/messages/query.ts
@@ -1,4 +1,4 @@
-import type { MinterInstance } from '../contract'
+import type { VendingMinterInstance } from '../contract'
export type QueryType = typeof QUERY_TYPES[number]
@@ -24,7 +24,7 @@ export const QUERY_LIST: QueryListItem[] = [
export interface DispatchQueryProps {
address: string
- messages: MinterInstance | undefined
+ messages: VendingMinterInstance | undefined
type: QueryType
}
diff --git a/contracts/minter/useContract.ts b/contracts/vendingMinter/useContract.ts
similarity index 65%
rename from contracts/minter/useContract.ts
rename to contracts/vendingMinter/useContract.ts
index 1121ea2..d118f04 100644
--- a/contracts/minter/useContract.ts
+++ b/contracts/vendingMinter/useContract.ts
@@ -3,8 +3,8 @@ import type { logs } from '@cosmjs/stargate'
import { useWallet } from 'contexts/wallet'
import { useCallback, useEffect, useState } from 'react'
-import type { MigrateResponse, MinterContract, MinterInstance, MinterMessages } from './contract'
-import { minter as initContract } from './contract'
+import type { MigrateResponse, VendingMinterContract, VendingMinterInstance, VendingMinterMessages } from './contract'
+import { vendingMinter as initContract } from './contract'
/*export interface InstantiateResponse {
/** The address of the newly instantiated contract *-/
@@ -24,7 +24,7 @@ interface InstantiateResponse {
readonly logs: readonly logs.Log[]
}
-export interface UseMinterContractProps {
+export interface UseVendingMinterContractProps {
instantiate: (
codeId: number,
initMsg: Record,
@@ -33,25 +33,25 @@ export interface UseMinterContractProps {
funds?: Coin[],
) => Promise
migrate: (contractAddress: string, codeId: number, migrateMsg: Record) => Promise
- use: (customAddress: string) => MinterInstance | undefined
+ use: (customAddress: string) => VendingMinterInstance | undefined
updateContractAddress: (contractAddress: string) => void
getContractAddress: () => string | undefined
- messages: (contractAddress: string) => MinterMessages | undefined
+ messages: (contractAddress: string) => VendingMinterMessages | undefined
}
-export function useMinterContract(): UseMinterContractProps {
+export function useVendingMinterContract(): UseVendingMinterContractProps {
const wallet = useWallet()
const [address, setAddress] = useState('')
- const [minter, setMinter] = useState()
+ const [vendingMinter, setVendingMinter] = useState()
useEffect(() => {
setAddress(localStorage.getItem('contract_address') || '')
}, [])
useEffect(() => {
- const MinterBaseContract = initContract(wallet.getClient(), wallet.address)
- setMinter(MinterBaseContract)
+ const VendingMinterBaseContract = initContract(wallet.getClient(), wallet.address)
+ setVendingMinter(VendingMinterBaseContract)
}, [wallet])
const updateContractAddress = (contractAddress: string) => {
@@ -61,35 +61,35 @@ export function useMinterContract(): UseMinterContractProps {
const instantiate = useCallback(
(codeId: number, initMsg: Record, label: string, admin?: string): Promise => {
return new Promise((resolve, reject) => {
- if (!minter) {
+ if (!vendingMinter) {
reject(new Error('Contract is not initialized.'))
return
}
- minter.instantiate(wallet.address, codeId, initMsg, label, admin).then(resolve).catch(reject)
+ vendingMinter.instantiate(wallet.address, codeId, initMsg, label, admin).then(resolve).catch(reject)
})
},
- [minter, wallet],
+ [vendingMinter, wallet],
)
const migrate = useCallback(
(contractAddress: string, codeId: number, migrateMsg: Record): Promise => {
return new Promise((resolve, reject) => {
- if (!minter) {
+ if (!vendingMinter) {
reject(new Error('Contract is not initialized.'))
return
}
console.log(wallet.address, contractAddress, codeId)
- minter.migrate(wallet.address, contractAddress, codeId, migrateMsg).then(resolve).catch(reject)
+ vendingMinter.migrate(wallet.address, contractAddress, codeId, migrateMsg).then(resolve).catch(reject)
})
},
- [minter, wallet],
+ [vendingMinter, wallet],
)
const use = useCallback(
- (customAddress = ''): MinterInstance | undefined => {
- return minter?.use(address || customAddress)
+ (customAddress = ''): VendingMinterInstance | undefined => {
+ return vendingMinter?.use(address || customAddress)
},
- [minter, address],
+ [vendingMinter, address],
)
const getContractAddress = (): string | undefined => {
@@ -97,10 +97,10 @@ export function useMinterContract(): UseMinterContractProps {
}
const messages = useCallback(
- (customAddress = ''): MinterMessages | undefined => {
- return minter?.messages(address || customAddress)
+ (customAddress = ''): VendingMinterMessages | undefined => {
+ return vendingMinter?.messages(address || customAddress)
},
- [minter, address],
+ [vendingMinter, address],
)
return {
diff --git a/env.d.ts b/env.d.ts
index 51d0974..bc8526b 100644
--- a/env.d.ts
+++ b/env.d.ts
@@ -18,6 +18,8 @@ declare namespace NodeJS {
readonly NEXT_PUBLIC_WHITELIST_CODE_ID: string
readonly NEXT_PUBLIC_VENDING_MINTER_CODE_ID: string
readonly NEXT_PUBLIC_VENDING_FACTORY_ADDRESS: string
+ readonly NEXT_PUBLIC_BASE_FACTORY_ADDRESS: string
+ readonly NEXT_PUBLIC_BASE_MINTER_CODE_ID: string
readonly NEXT_PUBLIC_PINATA_ENDPOINT_URL: string
readonly NEXT_PUBLIC_API_URL: string
diff --git a/next.config.js b/next.config.js
index 8896752..81a4daf 100644
--- a/next.config.js
+++ b/next.config.js
@@ -14,7 +14,7 @@ const nextConfig = {
NEXT_PUBLIC_WEBSITE_URL:
process.env.NODE_ENV === 'development' ? LOCALHOST_URL : process.env.NEXT_PUBLIC_WEBSITE_URL,
},
- reactStrictMode: true,
+ reactStrictMode: false,
trailingSlash: true,
webpack(config, { dev, webpack }) {
// svgr integration
diff --git a/package.json b/package.json
index 1912e63..9252f0f 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "stargaze-studio",
- "version": "0.2.9",
+ "version": "0.3.0",
"workspaces": [
"packages/*"
],
diff --git a/pages/collections/actions.tsx b/pages/collections/actions.tsx
index 8757da5..cf529bf 100644
--- a/pages/collections/actions.tsx
+++ b/pages/collections/actions.tsx
@@ -1,3 +1,4 @@
+import { toUtf8 } from '@cosmjs/encoding'
import { CollectionActions } from 'components/collections/actions/Action'
import { CollectionQueries } from 'components/collections/queries/Queries'
import { ContractPageHeader } from 'components/ContractPageHeader'
@@ -9,14 +10,19 @@ import type { NextPage } from 'next'
import { useRouter } from 'next/router'
import { NextSeo } from 'next-seo'
import { useEffect, useMemo, useState } from 'react'
+import toast from 'react-hot-toast'
+import { useDebounce } from 'utils/debounce'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
+import type { MinterType } from '../../components/collections/actions/Combobox'
+
const CollectionActionsPage: NextPage = () => {
- const { minter: minterContract, sg721: sg721Contract } = useContracts()
+ const { baseMinter: baseMinterContract, vendingMinter: vendingMinterContract, sg721: sg721Contract } = useContracts()
const wallet = useWallet()
const [action, setAction] = useState(false)
+ const [minterType, setMinterType] = useState('vending')
const sg721ContractState = useInputState({
id: 'sg721-contract-address',
@@ -32,9 +38,15 @@ const CollectionActionsPage: NextPage = () => {
subtitle: 'Address of the Minter contract',
})
- const minterMessages = useMemo(
- () => minterContract?.use(minterContractState.value),
- [minterContract, minterContractState.value],
+ const debouncedMinterContractState = useDebounce(minterContractState.value, 300)
+
+ const vendingMinterMessages = useMemo(
+ () => vendingMinterContract?.use(minterContractState.value),
+ [vendingMinterContract, minterContractState.value],
+ )
+ const baseMinterMessages = useMemo(
+ () => baseMinterContract?.use(minterContractState.value),
+ [baseMinterContract, minterContractState.value],
)
const sg721Messages = useMemo(
() => sg721Contract?.use(sg721ContractState.value),
@@ -66,6 +78,41 @@ const CollectionActionsPage: NextPage = () => {
if (initialSg721 && initialSg721.length > 0) sg721ContractState.onChange(initialSg721)
}, [])
+ useEffect(() => {
+ async function getMinterContractType() {
+ if (wallet.client && debouncedMinterContractState.length > 0) {
+ const client = wallet.client
+ const data = await toast.promise(
+ client.queryContractRaw(
+ debouncedMinterContractState,
+ toUtf8(Buffer.from(Buffer.from('contract_info').toString('hex'), 'hex').toString()),
+ ),
+ {
+ loading: 'Retrieving Minter type...',
+ error: 'Minter type retrieval failed.',
+ success: 'Minter type retrieved.',
+ },
+ )
+ const contract: string = JSON.parse(new TextDecoder().decode(data as Uint8Array)).contract
+ console.log(contract)
+ return contract
+ }
+ }
+ void getMinterContractType()
+ .then((contract) => {
+ if (contract?.includes('sg-base-minter')) {
+ setMinterType('base')
+ } else {
+ setMinterType('vending')
+ }
+ })
+ .catch((err) => {
+ console.log(err)
+ setMinterType('vending')
+ console.log('Unable to retrieve contract version')
+ })
+ }, [debouncedMinterContractState, wallet.client])
+
return (
@@ -124,18 +171,23 @@ const CollectionActionsPage: NextPage = () => {
{(action && (
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
)) || (
)}
diff --git a/pages/collections/create.tsx b/pages/collections/create.tsx
index f09b4c2..baa0154 100644
--- a/pages/collections/create.tsx
+++ b/pages/collections/create.tsx
@@ -4,6 +4,7 @@
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
import { coin } from '@cosmjs/proto-signing'
+import clsx from 'clsx'
import { Alert } from 'components/Alert'
import { Anchor } from 'components/Anchor'
import { Button } from 'components/Button'
@@ -15,6 +16,8 @@ import {
WhitelistDetails,
} from 'components/collections/creation'
import type { CollectionDetailsDataProps } from 'components/collections/creation/CollectionDetails'
+import type { MinterDetailsDataProps } from 'components/collections/creation/MinterDetails'
+import { MinterDetails } from 'components/collections/creation/MinterDetails'
import type { MintingDetailsDataProps } from 'components/collections/creation/MintingDetails'
import type { RoyaltyDetailsDataProps } from 'components/collections/creation/RoyaltyDetails'
import type { UploadDetailsDataProps } from 'components/collections/creation/UploadDetails'
@@ -23,8 +26,10 @@ import { Conditional } from 'components/Conditional'
import { LoadingModal } from 'components/LoadingModal'
import { useContracts } from 'contexts/contracts'
import { useWallet } from 'contexts/wallet'
-import type { DispatchExecuteArgs } from 'contracts/vendingFactory/messages/execute'
-import { dispatchExecute } from 'contracts/vendingFactory/messages/execute'
+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'
import type { NextPage } from 'next'
import { NextSeo } from 'next-seo'
import { useEffect, useMemo, useRef, useState } from 'react'
@@ -32,6 +37,7 @@ import { toast } from 'react-hot-toast'
import { upload } from 'services/upload'
import { compareFileArrays } from 'utils/compareFileArrays'
import {
+ BASE_FACTORY_ADDRESS,
BLOCK_EXPLORER_URL,
NETWORK,
SG721_CODE_ID,
@@ -42,6 +48,7 @@ import {
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
+import type { MinterType } from '../../components/collections/actions/Combobox'
import type { UploadMethod } from '../../components/collections/creation/UploadDetails'
import { ConfirmationModal } from '../../components/ConfirmationModal'
import { getAssetType } from '../../utils/getAssetType'
@@ -49,47 +56,58 @@ import { getAssetType } from '../../utils/getAssetType'
const CollectionCreationPage: NextPage = () => {
const wallet = useWallet()
const {
- minter: minterContract,
+ baseMinter: baseMinterContract,
+ vendingMinter: vendingMinterContract,
whitelist: whitelistContract,
vendingFactory: vendingFactoryContract,
+ baseFactory: baseFactoryContract,
} = useContracts()
const scrollRef = useRef