From f86be40cc346c4a137f49d7f64f1003ed1f86adb Mon Sep 17 00:00:00 2001 From: Serkan Reis Date: Fri, 28 Oct 2022 13:05:02 +0300 Subject: [PATCH] Add batch mint_for() functionality to Collection Actions --- components/collections/actions/Action.tsx | 13 +++- components/collections/actions/actions.ts | 25 ++++++-- contracts/minter/contract.ts | 77 +++++++++++++++++++++++ pages/collections/create.tsx | 2 +- 4 files changed, 107 insertions(+), 10 deletions(-) diff --git a/components/collections/actions/Action.tsx b/components/collections/actions/Action.tsx index b8f8b3e..660f1ae 100644 --- a/components/collections/actions/Action.tsx +++ b/components/collections/actions/Action.tsx @@ -143,8 +143,15 @@ export const CollectionActions = ({ const showLimitField = type === 'update_per_address_limit' const showTokenIdField = isEitherType(type, ['transfer', 'mint_for', 'burn']) const showNumberOfTokensField = type === 'batch_mint' - const showTokenIdListField = isEitherType(type, ['batch_burn', 'batch_transfer']) - const showRecipientField = isEitherType(type, ['transfer', 'mint_to', 'mint_for', 'batch_mint', 'batch_transfer']) + const showTokenIdListField = isEitherType(type, ['batch_burn', 'batch_transfer', 'batch_mint_for']) + const showRecipientField = isEitherType(type, [ + 'transfer', + 'mint_to', + 'mint_for', + 'batch_mint', + 'batch_transfer', + 'batch_mint_for', + ]) const showAirdropFileField = type === 'airdrop' const showPriceField = type === 'update_mint_price' const showDescriptionField = type === 'update_collection_info' @@ -259,7 +266,7 @@ export const CollectionActions = ({ {showWhitelistField && } {showLimitField && } {showTokenIdField && } - {showTokenIdListField && } + {showTokenIdListField && } {showNumberOfTokensField && } {showPriceField && } {showDescriptionField && } diff --git a/components/collections/actions/actions.ts b/components/collections/actions/actions.ts index c5d9597..86700f4 100644 --- a/components/collections/actions/actions.ts +++ b/components/collections/actions/actions.ts @@ -23,6 +23,7 @@ export const ACTION_TYPES = [ 'batch_transfer', 'burn', 'batch_burn', + 'batch_mint_for', 'shuffle', 'airdrop', 'burn_remaining', @@ -55,15 +56,20 @@ export const ACTION_LIST: ActionListItem[] = [ name: 'Mint To', description: `Mint a token to a user`, }, - { - id: 'mint_for', - name: 'Mint For', - description: `Mint a token for a user with given token ID`, - }, { id: 'batch_mint', name: 'Batch Mint', - description: `Mint multiple tokens to a user with given token amount`, + description: `Mint multiple tokens to a user`, + }, + { + id: 'mint_for', + name: 'Mint For', + description: `Mint a token for a user with the given token ID`, + }, + { + id: 'batch_mint_for', + name: 'Batch Mint For', + description: `Mint a specific range of tokens from the collection to a specific address`, }, { id: 'set_whitelist', @@ -169,6 +175,7 @@ export type DispatchExecuteArgs = { | { type: Select<'batch_transfer'>; recipient: string; tokenIds: string } | { type: Select<'burn'>; tokenId: number } | { type: Select<'batch_burn'>; tokenIds: string } + | { type: Select<'batch_mint_for'>; recipient: string; tokenIds: string } | { type: Select<'airdrop'>; recipients: string[] } | { type: Select<'burn_remaining'> } | { type: Select<'update_collection_info'>; collectionInfo: CollectionInfo | undefined } @@ -235,6 +242,9 @@ export const dispatchExecute = async (args: DispatchExecuteArgs) => { case 'batch_burn': { return sg721Messages.batchBurn(args.tokenIds) } + case 'batch_mint_for': { + return minterMessages.batchMintFor(txSigner, args.recipient, args.tokenIds) + } case 'airdrop': { return minterMessages.airdrop(txSigner, args.recipients) } @@ -308,6 +318,9 @@ export const previewExecutePayload = (args: DispatchExecuteArgs) => { case 'batch_burn': { return sg721Messages(sg721Contract)?.batchBurn(args.tokenIds) } + case 'batch_mint_for': { + return minterMessages(minterContract)?.batchMintFor(args.recipient, args.tokenIds) + } case 'airdrop': { return minterMessages(minterContract)?.airdrop(args.recipients) } diff --git a/contracts/minter/contract.ts b/contracts/minter/contract.ts index 3303dc1..a69fca8 100644 --- a/contracts/minter/contract.ts +++ b/contracts/minter/contract.ts @@ -37,6 +37,7 @@ export interface MinterInstance { updatePerAddressLimit: (senderAddress: string, perAddressLimit: number) => Promise mintTo: (senderAddress: string, recipient: string) => Promise mintFor: (senderAddress: string, recipient: string, tokenId: number) => Promise + batchMintFor: (senderAddress: string, recipient: string, tokenIds: string) => Promise batchMint: (senderAddress: string, recipient: string, batchNumber: number) => Promise shuffle: (senderAddress: string) => Promise withdraw: (senderAddress: string) => Promise @@ -54,6 +55,7 @@ export interface MinterMessages { updatePerAddressLimit: (perAddressLimit: number) => UpdatePerAddressLimitMessage mintTo: (recipient: string) => MintToMessage mintFor: (recipient: string, tokenId: number) => MintForMessage + batchMintFor: (recipient: string, tokenIds: string) => BatchMintForMessage batchMint: (recipient: string, batchNumber: number) => CustomMessage shuffle: () => ShuffleMessage withdraw: () => WithdrawMessage @@ -152,6 +154,12 @@ export interface MintForMessage { } funds: Coin[] } +export interface BatchMintForMessage { + sender: string + contract: string + msg: Record[] + funds: Coin[] +} export interface CustomMessage { sender: string @@ -390,6 +398,49 @@ export const minter = (client: SigningCosmWasmClient, txSigner: string): MinterC return res.transactionHash } + const batchMintFor = async (senderAddress: string, recipient: string, tokenIds: string): Promise => { + const executeContractMsgs: MsgExecuteContractEncodeObject[] = [] + if (tokenIds.includes(':')) { + const [start, end] = tokenIds.split(':').map(Number) + for (let i = start; i <= end; i++) { + const msg = { + mint_for: { token_id: i, recipient }, + } + const executeContractMsg: MsgExecuteContractEncodeObject = { + typeUrl: '/cosmwasm.wasm.v1.MsgExecuteContract', + value: MsgExecuteContract.fromPartial({ + sender: txSigner, + contract: contractAddress, + msg: toUtf8(JSON.stringify(msg)), + }), + } + + executeContractMsgs.push(executeContractMsg) + } + } else { + const tokenNumbers = tokenIds.split(',').map(Number) + for (let i = 0; i < tokenNumbers.length; i++) { + const msg = { + mint_for: { token_id: tokenNumbers[i], recipient }, + } + const executeContractMsg: MsgExecuteContractEncodeObject = { + typeUrl: '/cosmwasm.wasm.v1.MsgExecuteContract', + value: MsgExecuteContract.fromPartial({ + sender: txSigner, + contract: contractAddress, + msg: toUtf8(JSON.stringify(msg)), + }), + } + + executeContractMsgs.push(executeContractMsg) + } + } + + const res = await client.signAndBroadcast(txSigner, executeContractMsgs, 'auto', 'batch mint for') + + return res.transactionHash + } + const batchMint = async (senderAddress: string, recipient: string, batchNumber: number): Promise => { const executeContractMsgs: MsgExecuteContractEncodeObject[] = [] for (let i = 0; i < batchNumber; i++) { @@ -495,6 +546,7 @@ export const minter = (client: SigningCosmWasmClient, txSigner: string): MinterC updatePerAddressLimit, mintTo, mintFor, + batchMintFor, batchMint, airdrop, shuffle, @@ -631,6 +683,30 @@ export const minter = (client: SigningCosmWasmClient, txSigner: string): MinterC } } + const batchMintFor = (recipient: string, tokenIds: string): BatchMintForMessage => { + const msg: Record[] = [] + if (tokenIds.includes(':')) { + const [start, end] = tokenIds.split(':').map(Number) + for (let i = start; i <= end; i++) { + msg.push({ + mint_for: { token_id: i.toString(), recipient }, + }) + } + } else { + const tokenNumbers = tokenIds.split(',').map(Number) + for (let i = 0; i < tokenNumbers.length; i++) { + msg.push({ mint_for: { token_id: tokenNumbers[i].toString(), recipient } }) + } + } + + return { + sender: txSigner, + contract: contractAddress, + msg, + funds: [], + } + } + const batchMint = (recipient: string, batchNumber: number): CustomMessage => { const msg: Record[] = [] for (let i = 0; i < batchNumber; i++) { @@ -700,6 +776,7 @@ export const minter = (client: SigningCosmWasmClient, txSigner: string): MinterC updatePerAddressLimit, mintTo, mintFor, + batchMintFor, batchMint, airdrop, shuffle, diff --git a/pages/collections/create.tsx b/pages/collections/create.tsx index 8b1dd09..57f2327 100644 --- a/pages/collections/create.tsx +++ b/pages/collections/create.tsx @@ -444,7 +444,7 @@ const CollectionCreationPage: NextPage = () => { baseTokenUri.lastIndexOf('ipfs://') + 7, )}/`} > - ipfs://{baseTokenUri?.substring(baseTokenUri.lastIndexOf('ipfs://') + 7)}/ + ipfs://{baseTokenUri?.substring(baseTokenUri.lastIndexOf('ipfs://') + 7)} )}