Merge pull request #116 from public-awesome/v2.1-updates

Launchpad v2.1 - Vending Minter updates
This commit is contained in:
Adnan Deniz corlu 2023-03-03 18:15:30 +03:00 committed by GitHub
commit 91e4b6893c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 161 additions and 22 deletions

View File

@ -1,4 +1,4 @@
APP_VERSION=0.4.6 APP_VERSION=0.4.7
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=793 NEXT_PUBLIC_SG721_CODE_ID=793

View File

@ -114,8 +114,8 @@ export const CollectionActions = ({
const priceState = useNumberInputState({ const priceState = useNumberInputState({
id: 'update-mint-price', id: 'update-mint-price',
name: 'updateMintPrice', name: 'updateMintPrice',
title: 'Update Mint Price', title: type === 'update_discount_price' ? 'Discount Price' : 'Update Mint Price',
subtitle: 'New minting price in STARS', subtitle: type === 'update_discount_price' ? 'New discount price in STARS' : 'New minting price in STARS',
}) })
const descriptionState = useInputState({ const descriptionState = useInputState({
@ -170,7 +170,7 @@ export const CollectionActions = ({
'batch_mint_for', 'batch_mint_for',
]) ])
const showAirdropFileField = type === 'airdrop' const showAirdropFileField = type === 'airdrop'
const showPriceField = type === 'update_mint_price' const showPriceField = isEitherType(type, ['update_mint_price', 'update_discount_price'])
const showDescriptionField = type === 'update_collection_info' const showDescriptionField = type === 'update_collection_info'
const showImageField = type === 'update_collection_info' const showImageField = type === 'update_collection_info'
const showExternalLinkField = type === 'update_collection_info' const showExternalLinkField = type === 'update_collection_info'
@ -357,8 +357,8 @@ export const CollectionActions = ({
{showLimitField && <NumberInput {...limitState} />} {showLimitField && <NumberInput {...limitState} />}
{showTokenIdField && <NumberInput {...tokenIdState} />} {showTokenIdField && <NumberInput {...tokenIdState} />}
{showTokenIdListField && <TextInput className="mt-2" {...tokenIdListState} />} {showTokenIdListField && <TextInput className="mt-2" {...tokenIdListState} />}
{showNumberOfTokensField && <NumberInput {...batchNumberState} />} {showNumberOfTokensField && <NumberInput className="mt-2" {...batchNumberState} />}
{showPriceField && <NumberInput {...priceState} />} {showPriceField && <NumberInput className="mt-2" {...priceState} />}
{showDescriptionField && <TextInput className="my-2" {...descriptionState} />} {showDescriptionField && <TextInput className="my-2" {...descriptionState} />}
{showImageField && <TextInput className="mb-2" {...imageState} />} {showImageField && <TextInput className="mb-2" {...imageState} />}
{showExternalLinkField && <TextInput className="mb-2" {...externalLinkState} />} {showExternalLinkField && <TextInput className="mb-2" {...externalLinkState} />}

View File

@ -13,6 +13,8 @@ export const ACTION_TYPES = [
'mint_token_uri', 'mint_token_uri',
'purge', 'purge',
'update_mint_price', 'update_mint_price',
'update_discount_price',
'remove_discount_price',
'mint_to', 'mint_to',
'mint_for', 'mint_for',
'batch_mint', 'batch_mint',
@ -87,16 +89,21 @@ export const VENDING_ACTION_LIST: ActionListItem[] = [
name: 'Mint', name: 'Mint',
description: `Mint a token`, description: `Mint a token`,
}, },
{
id: 'purge',
name: 'Purge',
description: `Purge`,
},
{ {
id: 'update_mint_price', id: 'update_mint_price',
name: 'Update Mint Price', name: 'Update Mint Price',
description: `Update mint price`, description: `Update mint price`,
}, },
{
id: 'update_discount_price',
name: 'Update Discount Price',
description: `Update discount price`,
},
{
id: 'remove_discount_price',
name: 'Remove Discount Price',
description: `Remove discount price`,
},
{ {
id: 'mint_to', id: 'mint_to',
name: 'Mint To', name: 'Mint To',
@ -182,6 +189,11 @@ export const VENDING_ACTION_LIST: ActionListItem[] = [
name: 'Burn Remaining Tokens', name: 'Burn Remaining Tokens',
description: 'Burn remaining tokens', description: 'Burn remaining tokens',
}, },
{
id: 'purge',
name: 'Purge',
description: `Purge`,
},
] ]
export interface DispatchExecuteProps { export interface DispatchExecuteProps {
@ -205,6 +217,8 @@ export type DispatchExecuteArgs = {
| { type: Select<'mint_token_uri'>; tokenUri: string } | { type: Select<'mint_token_uri'>; tokenUri: string }
| { type: Select<'purge'> } | { type: Select<'purge'> }
| { type: Select<'update_mint_price'>; price: string } | { type: Select<'update_mint_price'>; price: string }
| { type: Select<'update_discount_price'>; price: string }
| { type: Select<'remove_discount_price'> }
| { type: Select<'mint_to'>; recipient: string } | { type: Select<'mint_to'>; recipient: string }
| { type: Select<'mint_for'>; recipient: string; tokenId: number } | { type: Select<'mint_for'>; recipient: string; tokenId: number }
| { type: Select<'batch_mint'>; recipient: string; batchNumber: number } | { type: Select<'batch_mint'>; recipient: string; batchNumber: number }
@ -242,6 +256,12 @@ export const dispatchExecute = async (args: DispatchExecuteArgs) => {
case 'update_mint_price': { case 'update_mint_price': {
return vendingMinterMessages.updateMintPrice(txSigner, args.price) return vendingMinterMessages.updateMintPrice(txSigner, args.price)
} }
case 'update_discount_price': {
return vendingMinterMessages.updateDiscountPrice(txSigner, args.price)
}
case 'remove_discount_price': {
return vendingMinterMessages.removeDiscountPrice(txSigner)
}
case 'mint_to': { case 'mint_to': {
return vendingMinterMessages.mintTo(txSigner, args.recipient) return vendingMinterMessages.mintTo(txSigner, args.recipient)
} }
@ -320,6 +340,12 @@ export const previewExecutePayload = (args: DispatchExecuteArgs) => {
case 'update_mint_price': { case 'update_mint_price': {
return vendingMinterMessages(minterContract)?.updateMintPrice(args.price) return vendingMinterMessages(minterContract)?.updateMintPrice(args.price)
} }
case 'update_discount_price': {
return vendingMinterMessages(minterContract)?.updateDiscountPrice(args.price)
}
case 'remove_discount_price': {
return vendingMinterMessages(minterContract)?.removeDiscountPrice()
}
case 'mint_to': { case 'mint_to': {
return vendingMinterMessages(minterContract)?.mintTo(args.recipient) return vendingMinterMessages(minterContract)?.mintTo(args.recipient)
} }

View File

@ -2,7 +2,7 @@
"path": "/assets/", "path": "/assets/",
"appName": "StargazeStudio", "appName": "StargazeStudio",
"appShortName": "StargazeStudio", "appShortName": "StargazeStudio",
"appDescription": "Stargaze Studio is built to provide useful smart contract interfaces that helps you build and deploy your own NFT collection in no time.", "appDescription": "Stargaze Studio is built to provide useful smart contract interfaces that help you build and deploy your own NFT collection in no time.",
"developerName": "StargazeStudio", "developerName": "StargazeStudio",
"developerURL": "https://", "developerURL": "https://",
"background": "#FFC27D", "background": "#FFC27D",

View File

@ -48,6 +48,8 @@ export interface VendingMinterInstance {
withdraw: (senderAddress: string) => Promise<string> withdraw: (senderAddress: string) => Promise<string>
airdrop: (senderAddress: string, recipients: string[]) => Promise<string> airdrop: (senderAddress: string, recipients: string[]) => Promise<string>
burnRemaining: (senderAddress: string) => Promise<string> burnRemaining: (senderAddress: string) => Promise<string>
updateDiscountPrice: (senderAddress: string, price: string) => Promise<string>
removeDiscountPrice: (senderAddress: string) => Promise<string>
} }
export interface VendingMinterMessages { export interface VendingMinterMessages {
@ -66,6 +68,8 @@ export interface VendingMinterMessages {
withdraw: () => WithdrawMessage withdraw: () => WithdrawMessage
airdrop: (recipients: string[]) => CustomMessage airdrop: (recipients: string[]) => CustomMessage
burnRemaining: () => BurnRemainingMessage burnRemaining: () => BurnRemainingMessage
updateDiscountPrice: (price: string) => UpdateDiscountPriceMessage
removeDiscountPrice: () => RemoveDiscountPriceMessage
} }
export interface MintMessage { export interface MintMessage {
@ -97,6 +101,26 @@ export interface UpdateMintPriceMessage {
funds: Coin[] funds: Coin[]
} }
export interface UpdateDiscountPriceMessage {
sender: string
contract: string
msg: {
update_discount_price: {
price: string
}
}
funds: Coin[]
}
export interface RemoveDiscountPriceMessage {
sender: string
contract: string
msg: {
remove_discount_price: Record<string, never>
}
funds: Coin[]
}
export interface SetWhitelistMessage { export interface SetWhitelistMessage {
sender: string sender: string
contract: string contract: string
@ -326,6 +350,36 @@ export const vendingMinter = (client: SigningCosmWasmClient, txSigner: string):
return res.transactionHash return res.transactionHash
} }
const updateDiscountPrice = async (senderAddress: string, price: string): Promise<string> => {
const res = await client.execute(
senderAddress,
contractAddress,
{
update_discount_price: {
price: (Number(price) * 1000000).toString(),
},
},
'auto',
'',
)
return res.transactionHash
}
const removeDiscountPrice = async (senderAddress: string): Promise<string> => {
const res = await client.execute(
senderAddress,
contractAddress,
{
remove_discount_price: {},
},
'auto',
'',
)
return res.transactionHash
}
const setWhitelist = async (senderAddress: string, whitelist: string): Promise<string> => { const setWhitelist = async (senderAddress: string, whitelist: string): Promise<string> => {
const res = await client.execute( const res = await client.execute(
senderAddress, senderAddress,
@ -552,6 +606,8 @@ export const vendingMinter = (client: SigningCosmWasmClient, txSigner: string):
mint, mint,
purge, purge,
updateMintPrice, updateMintPrice,
updateDiscountPrice,
removeDiscountPrice,
setWhitelist, setWhitelist,
updateStartTime, updateStartTime,
updateStartTradingTime, updateStartTradingTime,
@ -633,6 +689,30 @@ export const vendingMinter = (client: SigningCosmWasmClient, txSigner: string):
} }
} }
const updateDiscountPrice = (price: string): UpdateDiscountPriceMessage => {
return {
sender: txSigner,
contract: contractAddress,
msg: {
update_discount_price: {
price: (Number(price) * 1000000).toString(),
},
},
funds: [],
}
}
const removeDiscountPrice = (): RemoveDiscountPriceMessage => {
return {
sender: txSigner,
contract: contractAddress,
msg: {
remove_discount_price: {},
},
funds: [],
}
}
const setWhitelist = (whitelist: string): SetWhitelistMessage => { const setWhitelist = (whitelist: string): SetWhitelistMessage => {
return { return {
sender: txSigner, sender: txSigner,
@ -795,6 +875,8 @@ export const vendingMinter = (client: SigningCosmWasmClient, txSigner: string):
mint, mint,
purge, purge,
updateMintPrice, updateMintPrice,
updateDiscountPrice,
removeDiscountPrice,
setWhitelist, setWhitelist,
updateStartTime, updateStartTime,
updateStartTradingTime, updateStartTradingTime,

View File

@ -7,6 +7,8 @@ export const EXECUTE_TYPES = [
'mint', 'mint',
'purge', 'purge',
'update_mint_price', 'update_mint_price',
'update_discount_price',
'remove_discount_price',
'set_whitelist', 'set_whitelist',
'update_start_time', 'update_start_time',
'update_start_trading_time', 'update_start_trading_time',
@ -39,6 +41,16 @@ export const EXECUTE_LIST: ExecuteListItem[] = [
name: 'Update Mint Price', name: 'Update Mint Price',
description: `Update mint price`, description: `Update mint price`,
}, },
{
id: 'update_discount_price',
name: 'Update Discount Price',
description: `Update discount price`,
},
{
id: 'remove_discount_price',
name: 'Remove Discount Price',
description: `Remove discount price`,
},
{ {
id: 'set_whitelist', id: 'set_whitelist',
name: 'Set Whitelist', name: 'Set Whitelist',
@ -98,6 +110,8 @@ export type DispatchExecuteArgs = {
| { type: Select<'mint'> } | { type: Select<'mint'> }
| { type: Select<'purge'> } | { type: Select<'purge'> }
| { type: Select<'update_mint_price'>; price: string } | { type: Select<'update_mint_price'>; price: string }
| { type: Select<'update_discount_price'>; price: string }
| { type: Select<'remove_discount_price'> }
| { type: Select<'set_whitelist'>; whitelist: string } | { type: Select<'set_whitelist'>; whitelist: string }
| { type: Select<'update_start_time'>; startTime: string } | { type: Select<'update_start_time'>; startTime: string }
| { type: Select<'update_start_trading_time'>; startTime?: string } | { type: Select<'update_start_trading_time'>; startTime?: string }
@ -123,6 +137,12 @@ export const dispatchExecute = async (args: DispatchExecuteArgs) => {
case 'update_mint_price': { case 'update_mint_price': {
return messages.updateMintPrice(txSigner, args.price) return messages.updateMintPrice(txSigner, args.price)
} }
case 'update_discount_price': {
return messages.updateDiscountPrice(txSigner, args.price)
}
case 'remove_discount_price': {
return messages.removeDiscountPrice(txSigner)
}
case 'set_whitelist': { case 'set_whitelist': {
return messages.setWhitelist(txSigner, args.whitelist) return messages.setWhitelist(txSigner, args.whitelist)
} }
@ -167,6 +187,12 @@ export const previewExecutePayload = (args: DispatchExecuteArgs) => {
case 'update_mint_price': { case 'update_mint_price': {
return messages(contract)?.updateMintPrice(args.price) return messages(contract)?.updateMintPrice(args.price)
} }
case 'update_discount_price': {
return messages(contract)?.updateDiscountPrice(args.price)
}
case 'remove_discount_price': {
return messages(contract)?.removeDiscountPrice()
}
case 'set_whitelist': { case 'set_whitelist': {
return messages(contract)?.setWhitelist(args.whitelist) return messages(contract)?.setWhitelist(args.whitelist)
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "stargaze-studio", "name": "stargaze-studio",
"version": "0.4.6", "version": "0.4.7",
"workspaces": [ "workspaces": [
"packages/*" "packages/*"
], ],

View File

@ -748,12 +748,17 @@ const CollectionCreationPage: NextPage = () => {
mintingDetails.perAddressLimit > mintingDetails.numTokens mintingDetails.perAddressLimit > mintingDetails.numTokens
) )
throw new Error('Invalid limit for tokens per address') throw new Error('Invalid limit for tokens per address')
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.',
)
if ( if (
mintingDetails.numTokens > 100 && mintingDetails.numTokens >= 100 &&
mintingDetails.numTokens < 100 * mintingDetails.perAddressLimit && mintingDetails.perAddressLimit > Math.ceil((mintingDetails.numTokens / 100) * 3)
mintingDetails.perAddressLimit > mintingDetails.numTokens / 100
) )
throw new Error('Invalid limit for tokens per address. The limit cannot exceed 1% of the total number of tokens.') 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.',
)
if (mintingDetails.startTime === '') throw new Error('Start time is required') if (mintingDetails.startTime === '') throw new Error('Start time is required')
if (Number(mintingDetails.startTime) < new Date().getTime() * 1000000) throw new Error('Invalid start time') if (Number(mintingDetails.startTime) < new Date().getTime() * 1000000) throw new Error('Invalid start time')
} }

View File

@ -55,8 +55,8 @@ const VendingMinterExecutePage: NextPage = () => {
const priceState = useNumberInputState({ const priceState = useNumberInputState({
id: 'price', id: 'price',
name: 'price', name: 'price',
title: 'Price', title: type === 'update_discount_price' ? 'Discount Price' : 'Price',
subtitle: 'Enter the token price', subtitle: type === 'update_discount_price' ? 'New discount price in STARS' : 'Enter the token price',
}) })
const contractState = useInputState({ const contractState = useInputState({
@ -86,7 +86,7 @@ const VendingMinterExecutePage: NextPage = () => {
const showLimitField = type === 'update_per_address_limit' const showLimitField = type === 'update_per_address_limit'
const showTokenIdField = type === 'mint_for' const showTokenIdField = type === 'mint_for'
const showRecipientField = isEitherType(type, ['mint_to', 'mint_for']) const showRecipientField = isEitherType(type, ['mint_to', 'mint_for'])
const showPriceField = type === 'update_mint_price' const showPriceField = isEitherType(type, ['update_mint_price', 'update_discount_price'])
const messages = useMemo(() => contract?.use(contractState.value), [contract, wallet.address, contractState.value]) const messages = useMemo(() => contract?.use(contractState.value), [contract, wallet.address, contractState.value])
const payload: DispatchExecuteArgs = { const payload: DispatchExecuteArgs = {

View File

@ -15,8 +15,8 @@ const HomePage: NextPage = () => {
Looking for a fast and efficient way to build an NFT collection? Stargaze Studio is the solution. Looking for a fast and efficient way to build an NFT collection? Stargaze Studio is the solution.
<br /> <br />
<br /> <br />
Stargaze Studio is built to provide useful smart contract interfaces that helps you build and deploy your own Stargaze Studio is built to provide useful smart contract interfaces that help you build and deploy your own NFT
NFT collections in no time. collections in no time.
</p> </p>
<br /> <br />