diff --git a/README.md b/README.md index fc0ff36..a3ce747 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ Passage smart contracts written in CosmWasm and deployed to Juno. | pg721-metadata-onchain | 1486 | v0.2.0-alpha | 9587d0722d6a3ad19aa6623632ddc4b92592b70f7c6869fa754a3eeedbcad900 | 0.560861ujuno | | | minter-metadata-onchain | 1489 | v0.2.0-alpha | 598cc1f1a102e121d785bc3c58075892ef8f3f781c6084b5bf97ff628a888353 | 0.269856ujuno | | | royalty-group | 1988 | v0.2.0-alpha | 6e7dd43e8463f81d91bcbb83d175a1531cab72e4011fce5b4b5ea311ec87ebdc | | | +| minter-metadata-onchain | 1989 | v0.2.0-alpha | fc87cdd93c2ba1a3a417cf361245d4ab952662b4fc507cc0dc22d9b9fde9e30b | | | ### Testnet (uni-6) diff --git a/artifacts/checksums.txt b/artifacts/checksums.txt index f1a0cf3..6746a66 100644 --- a/artifacts/checksums.txt +++ b/artifacts/checksums.txt @@ -4,7 +4,7 @@ d7ac0e7b68abd1b3b4ed8612ccce373b066fba044e8fda2186047a438073112a friend.wasm 61820208f932ac3e771cfbcc7115ca624e555e466b98ab6c17e134a5d6237399 marketplace_legacy.wasm 995fbd52328256930296561c8a486272cd7998761fe0cf99cf087ed923178193 marketplace_v2.wasm aa8d7ca456732db687f93a859a882e57814a5f78c8836066a8454c22e657d522 minter.wasm -d82a4bcc8ef51dca7005851d0c059e548e1a1e1b7357158428d868b23f391138 minter_metadata_onchain.wasm +fc87cdd93c2ba1a3a417cf361245d4ab952662b4fc507cc0dc22d9b9fde9e30b minter_metadata_onchain.wasm 287715682a760726656e8366e6123077ee279048cad1b2a60ac17da1e7d539c0 nft_vault.wasm 0b4543555b4f053fa49e0a8d37a2f5fe0f18a2ca29c6b2243d8d3da8b9967f6b pg721.wasm b8a55d471bd2713e2594a15077a58326b935c43ae75e4eddb8167da0c0163c41 pg721_legacy.wasm diff --git a/artifacts/checksums_intermediate.txt b/artifacts/checksums_intermediate.txt index bc00531..69df993 100644 --- a/artifacts/checksums_intermediate.txt +++ b/artifacts/checksums_intermediate.txt @@ -4,7 +4,7 @@ f1e2847148b2a634a40b57fabdfcbd5e752c1c742921743cf8598d9f5b44a0a3 target/wasm32- 8541049c3e169da495d0cdaa6da5aa1fc2430b4a32e4795099a3106686b79949 target/wasm32-unknown-unknown/release/marketplace_legacy.wasm 13d870b87cc2582a3323d1dd44780ff79c17550e5951f31409637703ab5fe1ba target/wasm32-unknown-unknown/release/marketplace_v2.wasm d31e544b669e61af2ae1942b0ac5e94c6d51472a69c7b80f92365aa8004c9436 target/wasm32-unknown-unknown/release/minter.wasm -ca2003c7fdadc10be1bdbe2164dcddcee4f13c5f43e0678dafc72e7a66747375 target/wasm32-unknown-unknown/release/minter_metadata_onchain.wasm +f0eeb9d68fbfdf4718419bebd78bc84e5c6a72fb5688d5ebcb947f30bc7d80d0 target/wasm32-unknown-unknown/release/minter_metadata_onchain.wasm fb8de512291ddda27e24a222d698ac3b15e778261d50d8479c741d43e740f47c target/wasm32-unknown-unknown/release/nft_vault.wasm 06108ce86ec17b8debedcac200b1e8d1be025037883269ff39107cc1c5998b80 target/wasm32-unknown-unknown/release/pg721.wasm 6635fc111eae087bb33610bb14aed0bfe7e347567442030eabb45209f3928e4f target/wasm32-unknown-unknown/release/pg721_legacy.wasm diff --git a/artifacts/minter_metadata_onchain.wasm b/artifacts/minter_metadata_onchain.wasm index a4b22eb..8c10885 100644 Binary files a/artifacts/minter_metadata_onchain.wasm and b/artifacts/minter_metadata_onchain.wasm differ diff --git a/contracts/nft/minter-metadata-onchain/src/contract.rs b/contracts/nft/minter-metadata-onchain/src/contract.rs index 2f11265..c1f4344 100644 --- a/contracts/nft/minter-metadata-onchain/src/contract.rs +++ b/contracts/nft/minter-metadata-onchain/src/contract.rs @@ -1,27 +1,26 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - coin, to_binary, Addr, BankMsg, Binary, Coin, CosmosMsg, Deps, DepsMut, Env, - MessageInfo, Order, Reply, ReplyOn, StdError, StdResult, Timestamp, WasmMsg, - Response, SubMsg, Event + coin, to_binary, Addr, BankMsg, Binary, Coin, CosmosMsg, Deps, DepsMut, Env, Event, + MessageInfo, Order, Reply, ReplyOn, Response, StdError, StdResult, SubMsg, Timestamp, WasmMsg, }; -use cw_storage_plus::{Bound}; -use cw2::{set_contract_version, get_contract_version}; +use cw2::{get_contract_version, set_contract_version}; use cw721_base::MintMsg; +use cw_storage_plus::Bound; use cw_utils::{may_pay, parse_reply_instantiate_data}; use pg721_metadata_onchain::msg::{ - InstantiateMsg as Pg721InstantiateMsg, ExecuteMsg as Pg721ExecuteMsg, Metadata + ExecuteMsg as Pg721ExecuteMsg, InstantiateMsg as Pg721InstantiateMsg, Metadata, }; use crate::error::ContractError; use crate::msg::{ - ConfigResponse, ExecuteMsg, InstantiateMsg, MintCountResponse, MintPriceResponse, - QueryMsg, StartTimeResponse, TokenMetadata, TokenMintResponse, TokenMintsResponse, - NumMintedResponse, NumRemainingResponse, MigrateMsg + ConfigResponse, ExecuteMsg, InstantiateMsg, MigrateMsg, MintCountResponse, MintPriceResponse, + NumMintedResponse, NumRemainingResponse, QueryMsg, StartTimeResponse, TokenMetadata, + TokenMintResponse, TokenMintsResponse, }; use crate::state::{ - CONFIG, MINTER_ADDRS, CW721_ADDRESS, MINTABLE_TOKEN_IDS, - Config, TokenMint, token_mints, + token_mints, Config, TokenMint, CONFIG, CW721_ADDRESS, MINTABLE_TOKEN_IDS, MINTER_ADDRS, + NUM_MINTED, }; use whitelist::msg::{ ConfigResponse as WhitelistConfigResponse, HasMemberResponse, QueryMsg as WhitelistQueryMsg, @@ -43,8 +42,9 @@ pub fn instantiate( info: MessageInfo, msg: InstantiateMsg, ) -> Result { - if msg.cw721_instantiate_msg.is_none() && msg.cw721_address.is_none() || - msg.cw721_instantiate_msg.is_some() && msg.cw721_address.is_some() { + if msg.cw721_instantiate_msg.is_none() && msg.cw721_address.is_none() + || msg.cw721_instantiate_msg.is_some() && msg.cw721_address.is_some() + { return Err(ContractError::InvalidInstantiateMsg {}); } @@ -52,9 +52,7 @@ pub fn instantiate( // Check the number of tokens is more than zero if msg.max_num_tokens == 0 { - return Err(ContractError::InvalidNumTokens { - min: 1, - }); + return Err(ContractError::InvalidNumTokens { min: 1 }); } // Check per address limit is valid @@ -95,7 +93,7 @@ pub fn instantiate( let cw721_address = deps.api.addr_validate(&_addr)?; CW721_ADDRESS.save(deps.storage, &cw721_address)?; Response::new() - }, + } None => { let cw721_instantiate_msg = msg.cw721_instantiate_msg.unwrap(); // Submessage to instantiate cw721 contract @@ -138,13 +136,17 @@ pub fn execute( let api = deps.api; match msg { - ExecuteMsg::UpsertTokenMetadatas { token_metadatas } => execute_upsert_token_metadatas(deps, info, token_metadatas ), + ExecuteMsg::UpsertTokenMetadatas { token_metadatas } => { + execute_upsert_token_metadatas(deps, info, token_metadatas) + } ExecuteMsg::Mint {} => execute_mint_sender(deps, env, info), ExecuteMsg::UpdateStartTime(time) => execute_update_start_time(deps, env, info, time), ExecuteMsg::UpdatePerAddressLimit { per_address_limit } => { execute_update_per_address_limit(deps, env, info, per_address_limit) } - ExecuteMsg::UpdateUnitPrice { unit_price } => execute_update_unit_price(deps, env, info, unit_price), + ExecuteMsg::UpdateUnitPrice { unit_price } => { + execute_update_unit_price(deps, env, info, unit_price) + } ExecuteMsg::MintTo { recipient } => execute_mint_to(deps, env, info, recipient), ExecuteMsg::MintFor { token_id, @@ -154,14 +156,16 @@ pub fn execute( ExecuteMsg::SetWhitelist { whitelist } => { execute_set_whitelist(deps, env, info, &whitelist) } - ExecuteMsg::Withdraw { recipient } => execute_withdraw(deps, env, info, api.addr_validate(&recipient)?), + ExecuteMsg::Withdraw { recipient } => { + execute_withdraw(deps, env, info, api.addr_validate(&recipient)?) + } } } pub fn execute_upsert_token_metadatas( deps: DepsMut, info: MessageInfo, - token_metadatas: Vec + token_metadatas: Vec, ) -> Result { let config = CONFIG.load(deps.storage)?; if config.admin != info.sender { @@ -181,7 +185,9 @@ pub fn execute_upsert_token_metadatas( |existing_token_mint| -> Result { if let Some(_existing_token_mint) = existing_token_mint { if let true = _existing_token_mint.is_minted { - return Err(ContractError::TokenAlreadyMinted { token_id: _existing_token_mint.token_id }); + return Err(ContractError::TokenAlreadyMinted { + token_id: _existing_token_mint.token_id, + }); } }; Ok(TokenMint { @@ -189,18 +195,22 @@ pub fn execute_upsert_token_metadatas( metadata: token_metadata.clone().metadata, is_minted: false, }) - } + }, )?; append_token_ids.push(token_metadata.token_id); } let mut mintable_token_ids = MINTABLE_TOKEN_IDS.load(deps.storage)?; mintable_token_ids.append(&mut append_token_ids.clone()); + mintable_token_ids.sort_unstable(); + mintable_token_ids.dedup(); MINTABLE_TOKEN_IDS.save(deps.storage, &mintable_token_ids)?; let mut response = Response::new(); let append_token_ids_fmt: Vec = append_token_ids - .into_iter().map(|token_id| token_id.to_string()).collect(); + .into_iter() + .map(|token_id| token_id.to_string()) + .collect(); let event = Event::new("upsert-metadata") .add_attribute("append-token-ids", append_token_ids_fmt.join(", ")); response.events.push(event); @@ -376,7 +386,16 @@ pub fn execute_mint_to( )); } - _execute_mint(deps, env, info, &config, action, true, Some(recipient), None) + _execute_mint( + deps, + env, + info, + &config, + action, + true, + Some(recipient), + None, + ) } pub fn execute_mint_for( @@ -397,7 +416,16 @@ pub fn execute_mint_for( )); } - _execute_mint(deps, env, info, &config, action, true, Some(recipient), Some(token_id)) + _execute_mint( + deps, + env, + info, + &config, + action, + true, + Some(recipient), + Some(token_id), + ) } // Generalize checks and mint message creation @@ -443,18 +471,18 @@ fn _execute_mint( } match mintable_token_ids.iter().position(|_id| *_id == token_id) { Some(position) => position, - None => return Err(ContractError::TokenAlreadyMinted { token_id }) + None => return Err(ContractError::TokenAlreadyMinted { token_id }), } } - None => { - env.block.time.nanos() as usize % mintable_token_ids.len() - } + None => env.block.time.nanos() as usize % mintable_token_ids.len(), }; let mintable_token_id = mintable_token_ids[mintable_token_position]; let token_mint = token_mints().load(deps.storage, mintable_token_id)?; if token_mint.is_minted { - return Err(ContractError::TokenAlreadyMinted { token_id: mintable_token_id }); + return Err(ContractError::TokenAlreadyMinted { + token_id: mintable_token_id, + }); } // Create mint msgs @@ -478,7 +506,7 @@ fn _execute_mint( let mut updated_token_mint = token_mint.unwrap(); updated_token_mint.is_minted = true; Ok(updated_token_mint) - } + }, )?; // Remove mintable token id @@ -489,6 +517,10 @@ fn _execute_mint( let new_mint_count = mint_count(deps.as_ref(), &info)? + 1; MINTER_ADDRS.save(deps.storage, info.clone().sender, &new_mint_count)?; + // Increment NUM_MINTED + let num_minted = NUM_MINTED.load(deps.storage)?; + NUM_MINTED.save(deps.storage, &(num_minted + 1))?; + Ok(Response::default() .add_attribute("action", action) .add_attribute("sender", info.sender) @@ -619,8 +651,18 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { QueryMsg::MintPrice {} => to_binary(&query_mint_price(deps)?), QueryMsg::MintCount { address } => to_binary(&query_mint_count(deps, address)?), QueryMsg::TokenMint { token_id } => to_binary(&query_token_mint(deps, token_id)?), - QueryMsg::TokenMints { descending, filter_minted, start_after, limit } => - to_binary(&query_token_mints(deps, descending, filter_minted, start_after, limit)?), + QueryMsg::TokenMints { + descending, + filter_minted, + start_after, + limit, + } => to_binary(&query_token_mints( + deps, + descending, + filter_minted, + start_after, + limit, + )?), } } @@ -657,15 +699,15 @@ fn query_start_time(deps: Deps) -> StdResult { } fn query_num_minted(deps: Deps) -> StdResult { - let config = CONFIG.load(deps.storage)?; - let mintable_token_ids = MINTABLE_TOKEN_IDS.load(deps.storage)?; - let num_minted: u32 = config.max_num_tokens - mintable_token_ids.len() as u32; + let num_minted: u32 = NUM_MINTED.load(deps.storage)?; return Ok(NumMintedResponse { num_minted }); } fn query_num_remaining(deps: Deps) -> StdResult { let mintable_token_ids = MINTABLE_TOKEN_IDS.load(deps.storage)?; - Ok(NumRemainingResponse { num_remaining: mintable_token_ids.len() as u32 }) + Ok(NumRemainingResponse { + num_remaining: mintable_token_ids.len() as u32, + }) } fn query_mint_price(deps: Deps) -> StdResult { @@ -697,15 +739,19 @@ fn query_token_mints( descending: Option, filter_minted: Option, start_after: Option, - limit: Option + limit: Option, ) -> StdResult { let limit = limit.unwrap_or(DEFAULT_QUERY_LIMIT).min(MAX_QUERY_LIMIT) as usize; - let start = start_after.as_ref().map(|offset| { - Bound::exclusive(*offset) - }); + let start = start_after.as_ref().map(|offset| Bound::exclusive(*offset)); let order = match descending { - Some(_descending) => if _descending { Order::Descending } else { Order::Ascending }, - _ => Order::Ascending + Some(_descending) => { + if _descending { + Order::Descending + } else { + Order::Ascending + } + } + _ => Order::Ascending, }; let token_mints = token_mints() @@ -748,6 +794,8 @@ pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result, filter_minted: Option, start_after: Option, - limit: Option - }, + limit: Option, + }, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct MigrateMsg { -} +pub struct MigrateMsg {} #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] pub struct ConfigResponse { @@ -96,16 +99,16 @@ pub struct MintCountResponse { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] pub struct TokenMintResponse { - pub token_mint: Option + pub token_mint: Option, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] pub struct TokenMintsResponse { - pub token_mints: Vec + pub token_mints: Vec, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] pub struct TokenMetadata { pub token_id: u32, - pub metadata: Metadata + pub metadata: Metadata, } diff --git a/contracts/nft/minter-metadata-onchain/src/state.rs b/contracts/nft/minter-metadata-onchain/src/state.rs index 1a3bb69..6814afe 100644 --- a/contracts/nft/minter-metadata-onchain/src/state.rs +++ b/contracts/nft/minter-metadata-onchain/src/state.rs @@ -1,9 +1,8 @@ - -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; use cosmwasm_std::{Addr, Coin, Timestamp}; -use cw_storage_plus::{Item, Map, Index, IndexList, IndexedMap, MultiIndex}; +use cw_storage_plus::{Index, IndexList, IndexedMap, Item, Map, MultiIndex}; use pg721_metadata_onchain::msg::Metadata; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] pub struct Config { @@ -20,6 +19,7 @@ pub const CONFIG: Item = Item::new("config"); pub const CW721_ADDRESS: Item = Item::new("cw721_address"); pub const MINTER_ADDRS: Map = Map::new("minter_address"); pub const MINTABLE_TOKEN_IDS: Item> = Item::new("mintable_token_ids"); +pub const NUM_MINTED: Item = Item::new("num-minted"); pub type TokenId = u32; @@ -45,7 +45,11 @@ impl<'a> IndexList for TokenMintIndices<'a> { pub fn token_mints<'a>() -> IndexedMap<'a, TokenId, TokenMint, TokenMintIndices<'a>> { let indexes = TokenMintIndices { - is_minted: MultiIndex::new(|_, d: &TokenMint| d.is_minted as u8, "token_mint", "token_mint__is_minted"), + is_minted: MultiIndex::new( + |_, d: &TokenMint| d.is_minted as u8, + "token_mint", + "token_mint__is_minted", + ), }; IndexedMap::new("token_mint", indexes) -} \ No newline at end of file +}