From 280cdf5b19149907cc07be1977f29e9723e77d47 Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Sun, 3 Dec 2023 19:22:18 -0500 Subject: [PATCH 1/8] Add mint hooks to vending minter --- Cargo.lock | 1 + contracts/minters/vending-minter/Cargo.toml | 3 ++- contracts/minters/vending-minter/src/contract.rs | 10 ++++++++++ contracts/minters/vending-minter/src/error.rs | 5 +++++ contracts/minters/vending-minter/src/msg.rs | 2 ++ 5 files changed, 20 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index b1e8bc301..3a4d8c862 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4428,6 +4428,7 @@ dependencies = [ "schemars", "semver", "serde", + "sg-mint-hooks", "sg-std", "sg-whitelist", "sg1", diff --git a/contracts/minters/vending-minter/Cargo.toml b/contracts/minters/vending-minter/Cargo.toml index f6058766a..e93a32d88 100644 --- a/contracts/minters/vending-minter/Cargo.toml +++ b/contracts/minters/vending-minter/Cargo.toml @@ -51,4 +51,5 @@ sg-whitelist = { workspace = true, features = ["library"] } thiserror = { workspace = true } url = { workspace = true } vending-factory = { workspace = true, features = ["library"] } -semver = {workspace = true } +semver = { workspace = true } +sg-mint-hooks = { workspace = true } diff --git a/contracts/minters/vending-minter/src/contract.rs b/contracts/minters/vending-minter/src/contract.rs index da484f29d..371385f00 100644 --- a/contracts/minters/vending-minter/src/contract.rs +++ b/contracts/minters/vending-minter/src/contract.rs @@ -25,6 +25,8 @@ use sg1::{checked_fair_burn, ibc_denom_fair_burn}; use sg2::query::Sg2QueryMsg; use sg4::{MinterConfig, Status, StatusResponse, SudoMsg}; use sg721::{ExecuteMsg as Sg721ExecuteMsg, InstantiateMsg as Sg721InstantiateMsg}; +use sg_mint_hooks::post::add_postmint_hook; +use sg_mint_hooks::pre::add_premint_hook; use sg_std::{StargazeMsgWrapper, GENESIS_MINT_START_TIME, NATIVE_DENOM}; use sg_whitelist::msg::{ ConfigResponse as WhitelistConfigResponse, HasMemberResponse, QueryMsg as WhitelistQueryMsg, @@ -240,6 +242,14 @@ pub fn execute( execute_update_discount_price(deps, env, info, price) } ExecuteMsg::RemoveDiscountPrice {} => execute_remove_discount_price(deps, info), + ExecuteMsg::AddPreMintHook { hook } => { + // TODO: need to admin gate.. + add_premint_hook(deps, hook).map_err(ContractError::from) + } + ExecuteMsg::AddPostMintHook { hook } => { + // TODO: need to admin gate.. + add_postmint_hook(deps, hook).map_err(ContractError::from) + } } } diff --git a/contracts/minters/vending-minter/src/error.rs b/contracts/minters/vending-minter/src/error.rs index 5defd6e75..19f77c26a 100644 --- a/contracts/minters/vending-minter/src/error.rs +++ b/contracts/minters/vending-minter/src/error.rs @@ -1,8 +1,10 @@ use cosmwasm_std::{Coin, StdError, Timestamp}; use cw_utils::PaymentError; use sg1::FeeError; +use sg_mint_hooks::MintHookError; use thiserror::Error; use url::ParseError; + #[derive(Error, Debug, PartialEq)] pub enum ContractError { #[error("{0}")] @@ -17,6 +19,9 @@ pub enum ContractError { #[error("{0}")] Fee(#[from] FeeError), + #[error("{0}")] + MintHook(#[from] MintHookError), + #[error("Unauthorized: {0}")] Unauthorized(String), diff --git a/contracts/minters/vending-minter/src/msg.rs b/contracts/minters/vending-minter/src/msg.rs index d4d9f0358..958e8dc64 100644 --- a/contracts/minters/vending-minter/src/msg.rs +++ b/contracts/minters/vending-minter/src/msg.rs @@ -1,5 +1,6 @@ use cosmwasm_schema::cw_serde; use cosmwasm_std::{Coin, Timestamp}; +use sg_mint_hooks::sg_mint_hooks_execute; use vending_factory::{msg::VendingMinterCreateMsg, state::VendingMinterParams}; #[cw_serde] @@ -8,6 +9,7 @@ pub struct InstantiateMsg { pub params: VendingMinterParams, } +#[sg_mint_hooks_execute] #[cw_serde] pub enum ExecuteMsg { Mint {}, From 9213c4bacdbf17659152b03a034bd2027ea6c435 Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Sun, 3 Dec 2023 19:49:01 -0500 Subject: [PATCH 2/8] Refactor admin check --- .../minters/vending-minter/src/contract.rs | 91 ++++++------------- 1 file changed, 30 insertions(+), 61 deletions(-) diff --git a/contracts/minters/vending-minter/src/contract.rs b/contracts/minters/vending-minter/src/contract.rs index 371385f00..dbac4c28c 100644 --- a/contracts/minters/vending-minter/src/contract.rs +++ b/contracts/minters/vending-minter/src/contract.rs @@ -243,11 +243,11 @@ pub fn execute( } ExecuteMsg::RemoveDiscountPrice {} => execute_remove_discount_price(deps, info), ExecuteMsg::AddPreMintHook { hook } => { - // TODO: need to admin gate.. + only_admin(deps.as_ref(), &info)?; add_premint_hook(deps, hook).map_err(ContractError::from) } ExecuteMsg::AddPostMintHook { hook } => { - // TODO: need to admin gate.. + only_admin(deps.as_ref(), &info)?; add_postmint_hook(deps, hook).map_err(ContractError::from) } } @@ -260,12 +260,10 @@ pub fn execute_update_discount_price( price: u128, ) -> Result { nonpayable(&info)?; + only_admin(deps.as_ref(), &info)?; + let mut config = CONFIG.load(deps.storage)?; - if info.sender != config.extension.admin { - return Err(ContractError::Unauthorized( - "Sender is not an admin".to_owned(), - )); - } + if env.block.time < config.extension.start_time { return Err(ContractError::BeforeMintStartTime {}); } @@ -304,12 +302,9 @@ pub fn execute_remove_discount_price( info: MessageInfo, ) -> Result { nonpayable(&info)?; + only_admin(deps.as_ref(), &info)?; + let mut config = CONFIG.load(deps.storage)?; - if info.sender != config.extension.admin { - return Err(ContractError::Unauthorized( - "Sender is not an admin".to_owned(), - )); - } config.extension.discount_price = None; CONFIG.save(deps.storage, &config)?; @@ -401,22 +396,19 @@ pub fn execute_set_whitelist( whitelist: &str, ) -> Result { nonpayable(&info)?; + only_admin(deps.as_ref(), &info)?; + let mut config = CONFIG.load(deps.storage)?; let MinterConfig { factory, extension: ConfigExtension { whitelist: existing_whitelist, - admin, start_time, .. }, .. } = config.clone(); - ensure!( - admin == info.sender, - ContractError::Unauthorized("Sender is not an admin".to_owned()) - ); ensure!( env.block.time < start_time, @@ -557,17 +549,11 @@ pub fn execute_mint_to( info: MessageInfo, recipient: String, ) -> Result { + only_admin(deps.as_ref(), &info)?; + let recipient = deps.api.addr_validate(&recipient)?; - let config = CONFIG.load(deps.storage)?; let action = "mint_to"; - // Check only admin - if info.sender != config.extension.admin { - return Err(ContractError::Unauthorized( - "Sender is not an admin".to_owned(), - )); - } - _execute_mint(deps, env, info, action, true, Some(recipient), None) } @@ -578,17 +564,11 @@ pub fn execute_mint_for( token_id: u32, recipient: String, ) -> Result { + only_admin(deps.as_ref(), &info)?; + let recipient = deps.api.addr_validate(&recipient)?; - let config = CONFIG.load(deps.storage)?; let action = "mint_for"; - // Check only admin - if info.sender != config.extension.admin { - return Err(ContractError::Unauthorized( - "Sender is not an admin".to_owned(), - )); - } - _execute_mint( deps, env, @@ -824,12 +804,9 @@ pub fn execute_update_mint_price( price: u128, ) -> Result { nonpayable(&info)?; + only_admin(deps.as_ref(), &info)?; + let mut config = CONFIG.load(deps.storage)?; - if info.sender != config.extension.admin { - return Err(ContractError::Unauthorized( - "Sender is not an admin".to_owned(), - )); - } // If current time is after the stored start time, only allow lowering price if env.block.time >= config.extension.start_time && price >= config.mint_price.amount.u128() { return Err(ContractError::UpdatedMintPriceTooHigh { @@ -865,12 +842,9 @@ pub fn execute_update_start_time( start_time: Timestamp, ) -> Result { nonpayable(&info)?; + only_admin(deps.as_ref(), &info)?; + let mut config = CONFIG.load(deps.storage)?; - if info.sender != config.extension.admin { - return Err(ContractError::Unauthorized( - "Sender is not an admin".to_owned(), - )); - } // If current time is after the stored start time return error if env.block.time >= config.extension.start_time { return Err(ContractError::AlreadyStarted {}); @@ -902,15 +876,11 @@ pub fn execute_update_start_trading_time( start_time: Option, ) -> Result { nonpayable(&info)?; + only_admin(deps.as_ref(), &info)?; + let config = CONFIG.load(deps.storage)?; let sg721_contract_addr = SG721_ADDRESS.load(deps.storage)?; - if info.sender != config.extension.admin { - return Err(ContractError::Unauthorized( - "Sender is not an admin".to_owned(), - )); - } - // add custom rules here let factory_params: ParamsResponse = deps .querier @@ -958,12 +928,9 @@ pub fn execute_update_per_address_limit( per_address_limit: u32, ) -> Result { nonpayable(&info)?; + only_admin(deps.as_ref(), &info)?; + let mut config = CONFIG.load(deps.storage)?; - if info.sender != config.extension.admin { - return Err(ContractError::Unauthorized( - "Sender is not an admin".to_owned(), - )); - } let factory: ParamsResponse = deps .querier @@ -1009,13 +976,7 @@ pub fn execute_burn_remaining( info: MessageInfo, ) -> Result { nonpayable(&info)?; - let config = CONFIG.load(deps.storage)?; - // Check only admin - if info.sender != config.extension.admin { - return Err(ContractError::Unauthorized( - "Sender is not an admin".to_owned(), - )); - } + only_admin(deps.as_ref(), &info)?; // check mint not sold out let mintable_num_tokens = MINTABLE_NUM_TOKENS.load(deps.storage)?; @@ -1098,6 +1059,14 @@ pub fn display_max_mintable_tokens( Ok(three_percent as u32) } +fn only_admin(deps: Deps, info: &MessageInfo) -> Result<(), ContractError> { + ensure!( + CONFIG.load(deps.storage)?.extension.admin == info.sender, + ContractError::Unauthorized("Sender is not an admin".to_owned()) + ); + Ok(()) +} + #[cfg_attr(not(feature = "library"), entry_point)] pub fn sudo(deps: DepsMut, _env: Env, msg: SudoMsg) -> Result { match msg { From a1c0eccb11de3abe58b0f1aa155d1edf0b333055 Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Sun, 3 Dec 2023 20:10:16 -0500 Subject: [PATCH 3/8] Finish adding premint hooks --- contracts/minters/vending-minter/src/contract.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/contracts/minters/vending-minter/src/contract.rs b/contracts/minters/vending-minter/src/contract.rs index dbac4c28c..efe9ab8c4 100644 --- a/contracts/minters/vending-minter/src/contract.rs +++ b/contracts/minters/vending-minter/src/contract.rs @@ -25,8 +25,8 @@ use sg1::{checked_fair_burn, ibc_denom_fair_burn}; use sg2::query::Sg2QueryMsg; use sg4::{MinterConfig, Status, StatusResponse, SudoMsg}; use sg721::{ExecuteMsg as Sg721ExecuteMsg, InstantiateMsg as Sg721InstantiateMsg}; -use sg_mint_hooks::post::add_postmint_hook; -use sg_mint_hooks::pre::add_premint_hook; +use sg_mint_hooks::post::{add_postmint_hook, prepare_postmint_hooks}; +use sg_mint_hooks::pre::{add_premint_hook, prepare_premint_hooks}; use sg_std::{StargazeMsgWrapper, GENESIS_MINT_START_TIME, NATIVE_DENOM}; use sg_whitelist::msg::{ ConfigResponse as WhitelistConfigResponse, HasMemberResponse, QueryMsg as WhitelistQueryMsg, @@ -674,6 +674,14 @@ fn _execute_mint( None => random_mintable_token_mapping(deps.as_ref(), env, info.sender.clone())?, }; + let premint_hooks = prepare_premint_hooks( + deps.as_ref(), + sg721_address.clone(), + Some(mintable_token_mapping.token_id.to_string()), + info.sender.to_string(), + )?; + res = res.add_submessages(premint_hooks); + // Create mint msgs let mint_msg = Sg721ExecuteMsg::::Mint { token_id: mintable_token_mapping.token_id.to_string(), @@ -1189,6 +1197,8 @@ fn query_mint_price(deps: Deps) -> StdResult { // Reply callback triggered from cw721 contract instantiation #[cfg_attr(not(feature = "library"), entry_point)] pub fn reply(deps: DepsMut, _env: Env, msg: Reply) -> Result { + sg_mint_hooks::handle_reply(msg.id)?; + if msg.id != INSTANTIATE_SG721_REPLY_ID { return Err(ContractError::InvalidReplyID {}); } From 599bec790abf134de2ed4cd6ad913ce14becf3f1 Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Sun, 3 Dec 2023 21:57:18 -0500 Subject: [PATCH 4/8] Add post mint hooks --- contracts/minters/vending-minter/src/contract.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/contracts/minters/vending-minter/src/contract.rs b/contracts/minters/vending-minter/src/contract.rs index efe9ab8c4..c3827b8a0 100644 --- a/contracts/minters/vending-minter/src/contract.rs +++ b/contracts/minters/vending-minter/src/contract.rs @@ -699,6 +699,14 @@ fn _execute_mint( }); res = res.add_message(msg); + let postmint_hooks = prepare_postmint_hooks( + deps.as_ref(), + sg721_address.clone(), + Some(mintable_token_mapping.token_id.to_string()), + info.sender.to_string(), + )?; + res = res.add_submessages(postmint_hooks); + // Remove mintable token position from map MINTABLE_TOKEN_POSITIONS.remove(deps.storage, mintable_token_mapping.position); let mintable_num_tokens = MINTABLE_NUM_TOKENS.load(deps.storage)?; From a65e30821f787d6974aa20fb6743c193f81c1a25 Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Sun, 3 Dec 2023 22:06:38 -0500 Subject: [PATCH 5/8] Add mint hook queries --- contracts/minters/vending-minter/src/contract.rs | 2 ++ contracts/minters/vending-minter/src/msg.rs | 13 +++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/contracts/minters/vending-minter/src/contract.rs b/contracts/minters/vending-minter/src/contract.rs index c3827b8a0..e29017f48 100644 --- a/contracts/minters/vending-minter/src/contract.rs +++ b/contracts/minters/vending-minter/src/contract.rs @@ -1120,6 +1120,8 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { QueryMsg::MintableNumTokens {} => to_binary(&query_mintable_num_tokens(deps)?), QueryMsg::MintPrice {} => to_binary(&query_mint_price(deps)?), QueryMsg::MintCount { address } => to_binary(&query_mint_count(deps, address)?), + QueryMsg::PreMintHooks {} => to_binary(&sg_mint_hooks::pre::query_premint_hooks(deps)?), + QueryMsg::PostMintHooks {} => to_binary(&sg_mint_hooks::post::query_postmint_hooks(deps)?), } } diff --git a/contracts/minters/vending-minter/src/msg.rs b/contracts/minters/vending-minter/src/msg.rs index 958e8dc64..edb627cc0 100644 --- a/contracts/minters/vending-minter/src/msg.rs +++ b/contracts/minters/vending-minter/src/msg.rs @@ -1,6 +1,7 @@ -use cosmwasm_schema::cw_serde; +use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{Coin, Timestamp}; -use sg_mint_hooks::sg_mint_hooks_execute; +use sg4::StatusResponse; +use sg_mint_hooks::{sg_mint_hooks_execute, sg_mint_hooks_query, HooksResponse}; use vending_factory::{msg::VendingMinterCreateMsg, state::VendingMinterParams}; #[cw_serde] @@ -41,13 +42,21 @@ pub enum ExecuteMsg { RemoveDiscountPrice {}, } +#[sg_mint_hooks_query] #[cw_serde] +#[derive(QueryResponses)] pub enum QueryMsg { + #[returns(ConfigResponse)] Config {}, + #[returns(MintableNumTokensResponse)] MintableNumTokens {}, + #[returns(StartTimeResponse)] StartTime {}, + #[returns(MintPriceResponse)] MintPrice {}, + #[returns(MintCountResponse)] MintCount { address: String }, + #[returns(StatusResponse)] Status {}, } From 0f82bf2bb716c26681777a8b874db1b8d73bdcc7 Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Sun, 3 Dec 2023 23:04:03 -0500 Subject: [PATCH 6/8] Fix HooksResponse --- Cargo.lock | 1 + contracts/minters/vending-minter/Cargo.toml | 1 + contracts/minters/vending-minter/src/msg.rs | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 3a4d8c862..1fc5a21e8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4428,6 +4428,7 @@ dependencies = [ "schemars", "semver", "serde", + "sg-controllers", "sg-mint-hooks", "sg-std", "sg-whitelist", diff --git a/contracts/minters/vending-minter/Cargo.toml b/contracts/minters/vending-minter/Cargo.toml index e93a32d88..c06e2e66e 100644 --- a/contracts/minters/vending-minter/Cargo.toml +++ b/contracts/minters/vending-minter/Cargo.toml @@ -53,3 +53,4 @@ url = { workspace = true } vending-factory = { workspace = true, features = ["library"] } semver = { workspace = true } sg-mint-hooks = { workspace = true } +sg-controllers = { workspace = true } diff --git a/contracts/minters/vending-minter/src/msg.rs b/contracts/minters/vending-minter/src/msg.rs index edb627cc0..26c92163e 100644 --- a/contracts/minters/vending-minter/src/msg.rs +++ b/contracts/minters/vending-minter/src/msg.rs @@ -1,7 +1,8 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{Coin, Timestamp}; use sg4::StatusResponse; -use sg_mint_hooks::{sg_mint_hooks_execute, sg_mint_hooks_query, HooksResponse}; +use sg_controllers::HooksResponse; +use sg_mint_hooks::{sg_mint_hooks_execute, sg_mint_hooks_query}; use vending_factory::{msg::VendingMinterCreateMsg, state::VendingMinterParams}; #[cw_serde] From 9ce08da9a58325e5899590076510c6a84de90127 Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Sun, 3 Dec 2023 23:09:37 -0500 Subject: [PATCH 7/8] Fix lint issue --- packages/mint-hooks/derive/src/lib.rs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/packages/mint-hooks/derive/src/lib.rs b/packages/mint-hooks/derive/src/lib.rs index 68213e8d2..e02bda1e5 100644 --- a/packages/mint-hooks/derive/src/lib.rs +++ b/packages/mint-hooks/derive/src/lib.rs @@ -19,10 +19,7 @@ fn merge_variants(metadata: TokenStream, left: TokenStream, right: TokenStream) // parse the left enum let mut left: DeriveInput = parse_macro_input!(left); - let Enum(DataEnum { - variants, - .. - }) = &mut left.data else { + let Enum(DataEnum { variants, .. }) = &mut left.data else { return syn::Error::new(left.ident.span(), "only enums can accept variants") .to_compile_error() .into(); @@ -31,16 +28,16 @@ fn merge_variants(metadata: TokenStream, left: TokenStream, right: TokenStream) // parse the right enum let right: DeriveInput = parse_macro_input!(right); let Enum(DataEnum { - variants: to_add, - .. - }) = right.data else { + variants: to_add, .. + }) = right.data + else { return syn::Error::new(left.ident.span(), "only enums can provide variants") .to_compile_error() .into(); }; // insert variants from the right to the left - variants.extend(to_add.into_iter()); + variants.extend(to_add); quote! { #left }.into() } From 8adccf044f2acac4d4ee85481fe0e318e1213e3d Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Sun, 3 Dec 2023 23:17:35 -0500 Subject: [PATCH 8/8] Update schema --- .../vending-minter/schema/execute_msg.json | 42 ++++++++++++++++ .../vending-minter/schema/query_msg.json | 26 ++++++++++ .../minters/vending-minter/src/contract.rs | 2 +- ts/src/VendingMinter.client.ts | 48 ++++++++++++++++++ ts/src/VendingMinter.message-composer.ts | 50 +++++++++++++++++++ ts/src/VendingMinter.types.ts | 12 +++++ 6 files changed, 179 insertions(+), 1 deletion(-) diff --git a/contracts/minters/vending-minter/schema/execute_msg.json b/contracts/minters/vending-minter/schema/execute_msg.json index a6044d1ab..5263ecb5e 100644 --- a/contracts/minters/vending-minter/schema/execute_msg.json +++ b/contracts/minters/vending-minter/schema/execute_msg.json @@ -236,6 +236,48 @@ } }, "additionalProperties": false + }, + { + "type": "object", + "required": [ + "add_pre_mint_hook" + ], + "properties": { + "add_pre_mint_hook": { + "type": "object", + "required": [ + "hook" + ], + "properties": { + "hook": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "add_post_mint_hook" + ], + "properties": { + "add_post_mint_hook": { + "type": "object", + "required": [ + "hook" + ], + "properties": { + "hook": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false } ], "definitions": { diff --git a/contracts/minters/vending-minter/schema/query_msg.json b/contracts/minters/vending-minter/schema/query_msg.json index 56821a1c8..f6169c471 100644 --- a/contracts/minters/vending-minter/schema/query_msg.json +++ b/contracts/minters/vending-minter/schema/query_msg.json @@ -87,6 +87,32 @@ } }, "additionalProperties": false + }, + { + "type": "object", + "required": [ + "pre_mint_hooks" + ], + "properties": { + "pre_mint_hooks": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "post_mint_hooks" + ], + "properties": { + "post_mint_hooks": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false } ] } diff --git a/contracts/minters/vending-minter/src/contract.rs b/contracts/minters/vending-minter/src/contract.rs index e29017f48..1ad47b802 100644 --- a/contracts/minters/vending-minter/src/contract.rs +++ b/contracts/minters/vending-minter/src/contract.rs @@ -701,7 +701,7 @@ fn _execute_mint( let postmint_hooks = prepare_postmint_hooks( deps.as_ref(), - sg721_address.clone(), + sg721_address, Some(mintable_token_mapping.token_id.to_string()), info.sender.to_string(), )?; diff --git a/ts/src/VendingMinter.client.ts b/ts/src/VendingMinter.client.ts index d35a6e592..726853380 100644 --- a/ts/src/VendingMinter.client.ts +++ b/ts/src/VendingMinter.client.ts @@ -19,6 +19,8 @@ export interface VendingMinterReadOnlyInterface { address: string; }) => Promise; status: () => Promise; + preMintHooks: () => Promise; + postMintHooks: () => Promise; } export class VendingMinterQueryClient implements VendingMinterReadOnlyInterface { client: CosmWasmClient; @@ -33,6 +35,8 @@ export class VendingMinterQueryClient implements VendingMinterReadOnlyInterface this.mintPrice = this.mintPrice.bind(this); this.mintCount = this.mintCount.bind(this); this.status = this.status.bind(this); + this.preMintHooks = this.preMintHooks.bind(this); + this.postMintHooks = this.postMintHooks.bind(this); } config = async (): Promise => { @@ -71,6 +75,16 @@ export class VendingMinterQueryClient implements VendingMinterReadOnlyInterface status: {} }); }; + preMintHooks = async (): Promise => { + return this.client.queryContractSmart(this.contractAddress, { + pre_mint_hooks: {} + }); + }; + postMintHooks = async (): Promise => { + return this.client.queryContractSmart(this.contractAddress, { + post_mint_hooks: {} + }); + }; } export interface VendingMinterInterface extends VendingMinterReadOnlyInterface { contractAddress: string; @@ -114,6 +128,16 @@ export interface VendingMinterInterface extends VendingMinterReadOnlyInterface { price: number; }, fee?: number | StdFee | "auto", memo?: string, funds?: Coin[]) => Promise; removeDiscountPrice: (fee?: number | StdFee | "auto", memo?: string, funds?: Coin[]) => Promise; + addPreMintHook: ({ + hook + }: { + hook: string; + }, fee?: number | StdFee | "auto", memo?: string, funds?: Coin[]) => Promise; + addPostMintHook: ({ + hook + }: { + hook: string; + }, fee?: number | StdFee | "auto", memo?: string, funds?: Coin[]) => Promise; } export class VendingMinterClient extends VendingMinterQueryClient implements VendingMinterInterface { client: SigningCosmWasmClient; @@ -138,6 +162,8 @@ export class VendingMinterClient extends VendingMinterQueryClient implements Ven this.burnRemaining = this.burnRemaining.bind(this); this.updateDiscountPrice = this.updateDiscountPrice.bind(this); this.removeDiscountPrice = this.removeDiscountPrice.bind(this); + this.addPreMintHook = this.addPreMintHook.bind(this); + this.addPostMintHook = this.addPostMintHook.bind(this); } mint = async (fee: number | StdFee | "auto" = "auto", memo?: string, funds?: Coin[]): Promise => { @@ -244,4 +270,26 @@ export class VendingMinterClient extends VendingMinterQueryClient implements Ven remove_discount_price: {} }, fee, memo, funds); }; + addPreMintHook = async ({ + hook + }: { + hook: string; + }, fee: number | StdFee | "auto" = "auto", memo?: string, funds?: Coin[]): Promise => { + return await this.client.execute(this.sender, this.contractAddress, { + add_pre_mint_hook: { + hook + } + }, fee, memo, funds); + }; + addPostMintHook = async ({ + hook + }: { + hook: string; + }, fee: number | StdFee | "auto" = "auto", memo?: string, funds?: Coin[]): Promise => { + return await this.client.execute(this.sender, this.contractAddress, { + add_post_mint_hook: { + hook + } + }, fee, memo, funds); + }; } \ No newline at end of file diff --git a/ts/src/VendingMinter.message-composer.ts b/ts/src/VendingMinter.message-composer.ts index aa02002ba..cc923ee68 100644 --- a/ts/src/VendingMinter.message-composer.ts +++ b/ts/src/VendingMinter.message-composer.ts @@ -50,6 +50,16 @@ export interface VendingMinterMessage { price: number; }, funds?: Coin[]) => MsgExecuteContractEncodeObject; removeDiscountPrice: (funds?: Coin[]) => MsgExecuteContractEncodeObject; + addPreMintHook: ({ + hook + }: { + hook: string; + }, funds?: Coin[]) => MsgExecuteContractEncodeObject; + addPostMintHook: ({ + hook + }: { + hook: string; + }, funds?: Coin[]) => MsgExecuteContractEncodeObject; } export class VendingMinterMessageComposer implements VendingMinterMessage { sender: string; @@ -71,6 +81,8 @@ export class VendingMinterMessageComposer implements VendingMinterMessage { this.burnRemaining = this.burnRemaining.bind(this); this.updateDiscountPrice = this.updateDiscountPrice.bind(this); this.removeDiscountPrice = this.removeDiscountPrice.bind(this); + this.addPreMintHook = this.addPreMintHook.bind(this); + this.addPostMintHook = this.addPostMintHook.bind(this); } mint = (funds?: Coin[]): MsgExecuteContractEncodeObject => { @@ -281,4 +293,42 @@ export class VendingMinterMessageComposer implements VendingMinterMessage { }) }; }; + addPreMintHook = ({ + hook + }: { + hook: string; + }, funds?: Coin[]): MsgExecuteContractEncodeObject => { + return { + typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract", + value: MsgExecuteContract.fromPartial({ + sender: this.sender, + contract: this.contractAddress, + msg: toUtf8(JSON.stringify({ + add_pre_mint_hook: { + hook + } + })), + funds + }) + }; + }; + addPostMintHook = ({ + hook + }: { + hook: string; + }, funds?: Coin[]): MsgExecuteContractEncodeObject => { + return { + typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract", + value: MsgExecuteContract.fromPartial({ + sender: this.sender, + contract: this.contractAddress, + msg: toUtf8(JSON.stringify({ + add_post_mint_hook: { + hook + } + })), + funds + }) + }; + }; } \ No newline at end of file diff --git a/ts/src/VendingMinter.types.ts b/ts/src/VendingMinter.types.ts index 37accbb0f..741908041 100644 --- a/ts/src/VendingMinter.types.ts +++ b/ts/src/VendingMinter.types.ts @@ -64,6 +64,14 @@ export type ExecuteMsg = { }; } | { remove_discount_price: {}; +} | { + add_pre_mint_hook: { + hook: string; + }; +} | { + add_post_mint_hook: { + hook: string; + }; }; export type Decimal = string; export interface InstantiateMsg { @@ -164,6 +172,10 @@ export type QueryMsg = { }; } | { status: {}; +} | { + pre_mint_hooks: {}; +} | { + post_mint_hooks: {}; }; export interface StartTimeResponse { start_time: string;