From 2def96407fb0c38f95fb49d87dae8171586d8d9c Mon Sep 17 00:00:00 2001 From: Serkan Reis Date: Fri, 23 Jun 2023 00:20:23 +0300 Subject: [PATCH 1/4] Update open edition minter contract helpers --- contracts/openEditionMinter/contract.ts | 159 +++++++++++++++++------- 1 file changed, 117 insertions(+), 42 deletions(-) diff --git a/contracts/openEditionMinter/contract.ts b/contracts/openEditionMinter/contract.ts index 9db36b6..8088abc 100644 --- a/contracts/openEditionMinter/contract.ts +++ b/contracts/openEditionMinter/contract.ts @@ -1,3 +1,6 @@ +/* eslint-disable eslint-comments/disable-enable-pair */ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ import type { MsgExecuteContractEncodeObject, SigningCosmWasmClient } from '@cosmjs/cosmwasm-stargate' import { toUtf8 } from '@cosmjs/encoding' import type { Coin } from '@cosmjs/proto-signing' @@ -5,6 +8,7 @@ import { coin } from '@cosmjs/proto-signing' import type { logs } from '@cosmjs/stargate' import type { Timestamp } from '@stargazezone/types/contracts/minter/shared-types' import { MsgExecuteContract } from 'cosmjs-types/cosmwasm/wasm/v1/tx' +import toast from 'react-hot-toast' export interface InstantiateResponse { readonly contractAddress: string @@ -185,6 +189,11 @@ export interface OpenEditionMinterContract { export const openEditionMinter = (client: SigningCosmWasmClient, txSigner: string): OpenEditionMinterContract => { const use = (contractAddress: string): OpenEditionMinterInstance => { //Query + const getFactoryParameters = async (factoryAddress: string): Promise => { + const res = await client.queryContractSmart(factoryAddress, { params: {} }) + return res + } + const getConfig = async (): Promise => { const res = await client.queryContractSmart(contractAddress, { config: {}, @@ -338,63 +347,129 @@ export const openEditionMinter = (client: SigningCosmWasmClient, txSigner: strin } const mintTo = async (senderAddress: string, recipient: string): Promise => { - const res = await client.execute( - senderAddress, - contractAddress, - { - mint_to: { recipient }, - }, - 'auto', - '', - ) + const txHash = await getConfig().then(async (response) => { + const factoryParameters = await toast.promise(getFactoryParameters(response.factory), { + loading: 'Querying Factory Parameters...', + error: 'Querying Factory Parameters failed!', + success: 'Query successful! Minting...', + }) + console.log(factoryParameters?.params?.extension?.airdrop_mint_fee_bps) - return res.transactionHash + const price = factoryParameters?.params?.extension?.airdrop_mint_price.amount + if (!price) { + throw new Error( + 'Unable to retrieve a valid airdrop mint price. It may be that the given contract address does not belong to a Open Edition Factory.', + ) + } + console.log((Number(price) * Number(factoryParameters.params.extension?.airdrop_mint_fee_bps)) / 100) + const res = await client.execute( + senderAddress, + contractAddress, + { + mint_to: { recipient }, + }, + 'auto', + '', + [ + coin( + (Number(price) * Number(factoryParameters.params.extension?.airdrop_mint_fee_bps)) / 100 / 100, + 'ustars', + ), + ], + ) + return res.transactionHash + }) + return txHash } const batchMint = async (senderAddress: string, recipient: string, batchNumber: number): Promise => { - const executeContractMsgs: MsgExecuteContractEncodeObject[] = [] - for (let i = 0; i < batchNumber; i++) { - const msg = { - mint_to: { recipient }, - } - const executeContractMsg: MsgExecuteContractEncodeObject = { - typeUrl: '/cosmwasm.wasm.v1.MsgExecuteContract', - value: MsgExecuteContract.fromPartial({ - sender: senderAddress, - contract: contractAddress, - msg: toUtf8(JSON.stringify(msg)), - }), + const txHash = await getConfig().then(async (response) => { + const factoryParameters = await toast.promise(getFactoryParameters(response?.factory), { + loading: 'Querying Factory Parameters...', + error: 'Querying Factory Parameters failed!', + success: 'Query successful! Minting...', + }) + + const price = factoryParameters?.params?.extension?.airdrop_mint_price.amount + if (!price) { + throw new Error( + 'Unable to retrieve a valid airdrop mint price. It may be that the given contract address does not belong to a Open Edition Factory.', + ) } - executeContractMsgs.push(executeContractMsg) - } + const executeContractMsgs: MsgExecuteContractEncodeObject[] = [] + for (let i = 0; i < batchNumber; i++) { + const msg = { + mint_to: { recipient }, + } + const executeContractMsg: MsgExecuteContractEncodeObject = { + typeUrl: '/cosmwasm.wasm.v1.MsgExecuteContract', + value: MsgExecuteContract.fromPartial({ + sender: senderAddress, + contract: contractAddress, + msg: toUtf8(JSON.stringify(msg)), + funds: [ + coin( + (Number(price) * Number(factoryParameters.params.extension?.airdrop_mint_fee_bps)) / 100 / 100, + 'ustars', + ), + ], + }), + } - const res = await client.signAndBroadcast(senderAddress, executeContractMsgs, 'auto', 'batch mint') + executeContractMsgs.push(executeContractMsg) + } - return res.transactionHash + const res = await client.signAndBroadcast(senderAddress, executeContractMsgs, 'auto', 'batch mint') + + return res.transactionHash + }) + return txHash } const airdrop = async (senderAddress: string, recipients: string[]): Promise => { - const executeContractMsgs: MsgExecuteContractEncodeObject[] = [] - for (let i = 0; i < recipients.length; i++) { - const msg = { - mint_to: { recipient: recipients[i] }, - } - const executeContractMsg: MsgExecuteContractEncodeObject = { - typeUrl: '/cosmwasm.wasm.v1.MsgExecuteContract', - value: MsgExecuteContract.fromPartial({ - sender: senderAddress, - contract: contractAddress, - msg: toUtf8(JSON.stringify(msg)), - }), + const txHash = await getConfig().then(async (response) => { + const factoryParameters = await toast.promise(getFactoryParameters(response?.factory), { + loading: 'Querying Factory Parameters...', + error: 'Querying Factory Parameters failed!', + success: 'Query successful! Minting...', + }) + + const price = factoryParameters?.params?.extension?.airdrop_mint_price.amount + if (!price) { + throw new Error( + 'Unable to retrieve a valid airdrop mint price. It may be that the given contract address does not belong to a Open Edition Factory.', + ) } - executeContractMsgs.push(executeContractMsg) - } + const executeContractMsgs: MsgExecuteContractEncodeObject[] = [] + for (let i = 0; i < recipients.length; i++) { + const msg = { + mint_to: { recipient: recipients[i] }, + } + const executeContractMsg: MsgExecuteContractEncodeObject = { + typeUrl: '/cosmwasm.wasm.v1.MsgExecuteContract', + value: MsgExecuteContract.fromPartial({ + sender: senderAddress, + contract: contractAddress, + msg: toUtf8(JSON.stringify(msg)), + funds: [ + coin( + (Number(price) * Number(factoryParameters.params.extension?.airdrop_mint_fee_bps)) / 100 / 100, + 'ustars', + ), + ], + }), + } - const res = await client.signAndBroadcast(senderAddress, executeContractMsgs, 'auto', 'airdrop') + executeContractMsgs.push(executeContractMsg) + } - return res.transactionHash + const res = await client.signAndBroadcast(senderAddress, executeContractMsgs, 'auto', 'airdrop') + + return res.transactionHash + }) + return txHash } return { From edb93c0bbf583d532bad634f05f781da9991fb0a Mon Sep 17 00:00:00 2001 From: Serkan Reis Date: Fri, 23 Jun 2023 00:20:51 +0300 Subject: [PATCH 2/4] Update Collection Actions > Actions for open edition collections --- components/collections/actions/Action.tsx | 6 +++-- components/collections/actions/actions.ts | 27 ++++++++++++++++++++--- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/components/collections/actions/Action.tsx b/components/collections/actions/Action.tsx index 5f38fb5..9e91783 100644 --- a/components/collections/actions/Action.tsx +++ b/components/collections/actions/Action.tsx @@ -175,7 +175,7 @@ export const CollectionActions = ({ const showEndDateField = type === 'update_end_time' const showLimitField = type === 'update_per_address_limit' const showTokenIdField = isEitherType(type, ['transfer', 'mint_for', 'burn', 'update_token_metadata']) - const showNumberOfTokensField = type === 'batch_mint' + const showNumberOfTokensField = isEitherType(type, ['batch_mint', 'batch_mint_open_edition']) const showTokenIdListField = isEitherType(type, [ 'batch_burn', 'batch_transfer', @@ -185,12 +185,14 @@ export const CollectionActions = ({ const showRecipientField = isEitherType(type, [ 'transfer', 'mint_to', + 'mint_to_open_edition', 'mint_for', 'batch_mint', + 'batch_mint_open_edition', 'batch_transfer', 'batch_mint_for', ]) - const showAirdropFileField = isEitherType(type, ['airdrop', 'airdrop_specific']) + const showAirdropFileField = isEitherType(type, ['airdrop', 'airdrop_open_edition', 'airdrop_specific']) const showPriceField = isEitherType(type, ['update_mint_price', 'update_discount_price']) const showDescriptionField = type === 'update_collection_info' const showImageField = type === 'update_collection_info' diff --git a/components/collections/actions/actions.ts b/components/collections/actions/actions.ts index c5cfc54..a1803c8 100644 --- a/components/collections/actions/actions.ts +++ b/components/collections/actions/actions.ts @@ -18,8 +18,10 @@ export const ACTION_TYPES = [ 'update_discount_price', 'remove_discount_price', 'mint_to', + 'mint_to_open_edition', 'mint_for', 'batch_mint', + 'batch_mint_open_edition', 'set_whitelist', 'update_start_time', 'update_end_time', @@ -34,6 +36,7 @@ export const ACTION_TYPES = [ 'batch_mint_for', 'shuffle', 'airdrop', + 'airdrop_open_edition', 'airdrop_specific', 'burn_remaining', 'update_token_metadata', @@ -206,12 +209,12 @@ export const OPEN_EDITION_ACTION_LIST: ActionListItem[] = [ description: `Update mint price`, }, { - id: 'mint_to', + id: 'mint_to_open_edition', name: 'Mint To', description: `Mint a token to a user`, }, { - id: 'batch_mint', + id: 'batch_mint_open_edition', name: 'Batch Mint To', description: `Mint multiple tokens to a user`, }, @@ -266,7 +269,7 @@ export const OPEN_EDITION_ACTION_LIST: ActionListItem[] = [ description: `Burn a list of tokens from the collection`, }, { - id: 'airdrop', + id: 'airdrop_open_edition', name: 'Airdrop Tokens', description: 'Airdrop tokens to given addresses', }, @@ -347,12 +350,18 @@ export const dispatchExecute = async (args: DispatchExecuteArgs) => { case 'mint_to': { return vendingMinterMessages.mintTo(txSigner, args.recipient) } + case 'mint_to_open_edition': { + return openEditionMinterMessages.mintTo(txSigner, args.recipient) + } case 'mint_for': { return vendingMinterMessages.mintFor(txSigner, args.recipient, args.tokenId) } case 'batch_mint': { return vendingMinterMessages.batchMint(txSigner, args.recipient, args.batchNumber) } + case 'batch_mint_open_edition': { + return openEditionMinterMessages.batchMint(txSigner, args.recipient, args.batchNumber) + } case 'set_whitelist': { return vendingMinterMessages.setWhitelist(txSigner, args.whitelist) } @@ -407,6 +416,9 @@ export const dispatchExecute = async (args: DispatchExecuteArgs) => { case 'airdrop': { return vendingMinterMessages.airdrop(txSigner, args.recipients) } + case 'airdrop_open_edition': { + return openEditionMinterMessages.airdrop(txSigner, args.recipients) + } case 'airdrop_specific': { return vendingMinterMessages.airdropSpecificTokens(txSigner, args.tokenRecipients) } @@ -445,12 +457,18 @@ export const previewExecutePayload = (args: DispatchExecuteArgs) => { case 'mint_to': { return vendingMinterMessages(minterContract)?.mintTo(args.recipient) } + case 'mint_to_open_edition': { + return openEditionMinterMessages(minterContract)?.mintTo(args.recipient) + } case 'mint_for': { return vendingMinterMessages(minterContract)?.mintFor(args.recipient, args.tokenId) } case 'batch_mint': { return vendingMinterMessages(minterContract)?.batchMint(args.recipient, args.batchNumber) } + case 'batch_mint_open_edition': { + return openEditionMinterMessages(minterContract)?.batchMint(args.recipient, args.batchNumber) + } case 'set_whitelist': { return vendingMinterMessages(minterContract)?.setWhitelist(args.whitelist) } @@ -505,6 +523,9 @@ export const previewExecutePayload = (args: DispatchExecuteArgs) => { case 'airdrop': { return vendingMinterMessages(minterContract)?.airdrop(args.recipients) } + case 'airdrop_open_edition': { + return openEditionMinterMessages(minterContract)?.airdrop(args.recipients) + } case 'airdrop_specific': { return vendingMinterMessages(minterContract)?.airdropSpecificTokens(args.tokenRecipients) } From b7628d036621bddf1135af323db5cfc39636adea Mon Sep 17 00:00:00 2001 From: Serkan Reis Date: Fri, 23 Jun 2023 00:21:40 +0300 Subject: [PATCH 3/4] Update Studio version --- .env.example | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.env.example b/.env.example index 201368a..a5e6a7b 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,4 @@ -APP_VERSION=0.6.7 +APP_VERSION=0.6.8 NEXT_PUBLIC_PINATA_ENDPOINT_URL=https://api.pinata.cloud/pinning/pinFileToIPFS NEXT_PUBLIC_SG721_CODE_ID=2595 diff --git a/package.json b/package.json index 64f344f..7ea8c9b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "stargaze-studio", - "version": "0.6.7", + "version": "0.6.8", "workspaces": [ "packages/*" ], From 06ce126b64664ba736f49538dd4aee109eeb9268 Mon Sep 17 00:00:00 2001 From: Serkan Reis Date: Fri, 23 Jun 2023 00:26:06 +0300 Subject: [PATCH 4/4] Update open edition factory addresses --- .env.example | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.env.example b/.env.example index a5e6a7b..90d63f5 100644 --- a/.env.example +++ b/.env.example @@ -13,8 +13,8 @@ NEXT_PUBLIC_VENDING_FACTORY_UPDATABLE_ADDRESS="stars1h65nms9gwg4vdktyqj84tu50gwl NEXT_PUBLIC_VENDING_FACTORY_FLEX_ADDRESS="stars1hvu2ghqkcnvhtj2fc6wuazxt4dqcftslp2rwkkkcxy269a35a9pq60ug2q" NEXT_PUBLIC_BASE_FACTORY_ADDRESS="stars1a45hcxty3spnmm2f0papl8v4dk5ew29s4syhn4efte8u5haex99qlkrtnx" NEXT_PUBLIC_BASE_FACTORY_UPDATABLE_ADDRESS="stars100xegx2syry4tclkmejjwxk4nfqahvcqhm9qxut5wxuzhj5d9qfsh5nmym" -NEXT_PUBLIC_OPEN_EDITION_FACTORY_ADDRESS="stars13r06dn4jc6mudvvkl9rclxjctywm4nhl045jn9f8mk6vc53eylusy4zxzj" -NEXT_PUBLIC_OPEN_EDITION_UPDATABLE_FACTORY_ADDRESS="stars1n7np7wdmm4ea8tapkz00j3jtxupne0g8v9jj02j96wfn9w9ukxgs6hcsv0" +NEXT_PUBLIC_OPEN_EDITION_FACTORY_ADDRESS="stars1sqweqcxlf2f7qhf27gn5naqusk5q52fkzewmy63c4sglvle3s7ls6k828e" +NEXT_PUBLIC_OPEN_EDITION_UPDATABLE_FACTORY_ADDRESS="stars1fk5dkzcylam8mcpqrn8y9spauvc3d4navtaqurcc49dc3p9f8d3qdkvymx" NEXT_PUBLIC_OPEN_EDITION_MINTER_CODE_ID=2579 NEXT_PUBLIC_SG721_NAME_ADDRESS="stars1fx74nkqkw2748av8j7ew7r3xt9cgjqduwn8m0ur5lhe49uhlsasszc5fhr"