From b6fc6ab37c57cd66bc8e50e74827e67076d14ec3 Mon Sep 17 00:00:00 2001 From: jason-c-child Date: Fri, 9 Feb 2024 19:08:26 -0900 Subject: [PATCH 01/13] Add a function to return renewal price for multiple names --- contracts/marketplace/src/query.rs | 205 ++++++++++++++--------------- 1 file changed, 96 insertions(+), 109 deletions(-) diff --git a/contracts/marketplace/src/query.rs b/contracts/marketplace/src/query.rs index 448504a9..f95c4744 100644 --- a/contracts/marketplace/src/query.rs +++ b/contracts/marketplace/src/query.rs @@ -1,16 +1,42 @@ use crate::helpers::get_renewal_price_and_bid; -use crate::msg::{BidOffset, Bidder, ConfigResponse, QueryMsg}; +use crate::msg::{ BidOffset, Bidder, ConfigResponse, QueryMsg }; use crate::state::{ - ask_key, asks, bid_key, bids, legacy_bids, Ask, AskKey, Bid, Id, SudoParams, TokenId, - ASK_COUNT, ASK_HOOKS, BID_HOOKS, NAME_COLLECTION, NAME_MINTER, RENEWAL_QUEUE, SALE_HOOKS, + ask_key, + asks, + bid_key, + bids, + legacy_bids, + Ask, + AskKey, + Bid, + Id, + SudoParams, + TokenId, + ASK_COUNT, + ASK_HOOKS, + BID_HOOKS, + NAME_COLLECTION, + NAME_MINTER, + RENEWAL_QUEUE, + SALE_HOOKS, SUDO_PARAMS, }; use cosmwasm_std::{ - coin, to_binary, Addr, Binary, Coin, Deps, Env, Order, StdError, StdResult, Timestamp, + coin, + to_binary, + Addr, + Binary, + Coin, + Deps, + Env, + Order, + StdError, + StdResult, + Timestamp, }; use cw_storage_plus::Bound; -use sg_name_minter::{SgNameMinterQueryMsg, SudoParams as NameMinterParams}; +use sg_name_minter::{ SgNameMinterQueryMsg, SudoParams as NameMinterParams }; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; @@ -27,73 +53,38 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { QueryMsg::Ask { token_id } => to_binary(&query_ask(deps, token_id)?), QueryMsg::Asks { start_after, limit } => to_binary(&query_asks(deps, start_after, limit)?), - QueryMsg::AsksBySeller { - seller, - start_after, - limit, - } => to_binary(&query_asks_by_seller( - deps, - api.addr_validate(&seller)?, - start_after, - limit, - )?), - QueryMsg::AsksByRenewTime { - max_time, - start_after, - limit, - } => to_binary(&query_asks_by_renew_time( - deps, - max_time, - start_after, - limit, - )?), - QueryMsg::AskRenewPrice { - current_time, - token_id, - } => to_binary(&query_ask_renew_price(deps, current_time, token_id)?), + QueryMsg::AsksBySeller { seller, start_after, limit } => + to_binary( + &query_asks_by_seller(deps, api.addr_validate(&seller)?, start_after, limit)? + ), + QueryMsg::AsksByRenewTime { max_time, start_after, limit } => + to_binary(&query_asks_by_renew_time(deps, max_time, start_after, limit)?), + QueryMsg::AskRenewPrice { current_time, token_id } => + to_binary(&query_ask_renew_price(deps, current_time, token_id)?), + QueryMsg::AskRenewalPrices { current_time, token_ids } => + to_binary(&query_ask_renew_prices(deps, current_time, token_ids)?), QueryMsg::AskCount {} => to_binary(&query_ask_count(deps)?), QueryMsg::Bid { token_id, bidder } => { to_binary(&query_bid(deps, token_id, api.addr_validate(&bidder)?)?) } - QueryMsg::Bids { - token_id, - start_after, - limit, - } => to_binary(&query_bids(deps, token_id, start_after, limit)?), + QueryMsg::Bids { token_id, start_after, limit } => + to_binary(&query_bids(deps, token_id, start_after, limit)?), QueryMsg::LegacyBids { start_after, limit } => { to_binary(&query_legacy_bids(deps, start_after, limit)?) } - QueryMsg::BidsByBidder { - bidder, - start_after, - limit, - } => to_binary(&query_bids_by_bidder( - deps, - api.addr_validate(&bidder)?, - start_after, - limit, - )?), + QueryMsg::BidsByBidder { bidder, start_after, limit } => + to_binary( + &query_bids_by_bidder(deps, api.addr_validate(&bidder)?, start_after, limit)? + ), QueryMsg::BidsSortedByPrice { start_after, limit } => { to_binary(&query_bids_sorted_by_price(deps, start_after, limit)?) } - QueryMsg::ReverseBidsSortedByPrice { - start_before, - limit, - } => to_binary(&reverse_query_bids_sorted_by_price( - deps, - start_before, - limit, - )?), - QueryMsg::BidsForSeller { - seller, - start_after, - limit, - } => to_binary(&query_bids_for_seller( - deps, - api.addr_validate(&seller)?, - start_after, - limit, - )?), + QueryMsg::ReverseBidsSortedByPrice { start_before, limit } => + to_binary(&reverse_query_bids_sorted_by_price(deps, start_before, limit)?), + QueryMsg::BidsForSeller { seller, start_after, limit } => + to_binary( + &query_bids_for_seller(deps, api.addr_validate(&seller)?, start_after, limit)? + ), QueryMsg::HighestBid { token_id } => to_binary(&query_highest_bid(deps, token_id)?), QueryMsg::Params {} => to_binary(&query_params(deps)?), QueryMsg::AskHooks {} => to_binary(&ASK_HOOKS.query_hooks(deps)?), @@ -112,8 +103,7 @@ pub fn query_config(deps: Deps) -> StdResult { } pub fn query_renewal_queue(deps: Deps, time: Timestamp) -> StdResult> { - let names = RENEWAL_QUEUE - .prefix(time.seconds()) + let names = RENEWAL_QUEUE.prefix(time.seconds()) .range(deps.storage, None, None, Order::Ascending) .map(|item| item.map(|item| item.1)) .collect::>>()?; @@ -128,13 +118,11 @@ pub fn query_asks(deps: Deps, start_after: Option, limit: Option) -> St let limit = limit.unwrap_or(DEFAULT_QUERY_LIMIT).min(MAX_QUERY_LIMIT) as usize; asks() - .idx - .id - .range( + .idx.id.range( deps.storage, Some(Bound::exclusive(start_after.unwrap_or_default())), None, - Order::Ascending, + Order::Ascending ) .take(limit) .map(|res| res.map(|item| item.1)) @@ -150,16 +138,14 @@ pub fn query_asks_by_seller( deps: Deps, seller: Addr, 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.map(|start| Bound::exclusive(ask_key(&start))); asks() - .idx - .seller - .prefix(seller) + .idx.seller.prefix(seller) .range(deps.storage, start, None, Order::Ascending) .take(limit) .map(|res| res.map(|item| item.1)) @@ -170,18 +156,16 @@ pub fn query_asks_by_renew_time( deps: Deps, max_time: Timestamp, start_after: Option, - limit: Option, + limit: Option ) -> StdResult> { let limit = limit.unwrap_or(DEFAULT_QUERY_LIMIT) as usize; let renewable_asks = asks() - .idx - .renewal_time - .range( + .idx.renewal_time.range( deps.storage, start_after.map(|start| Bound::inclusive((start.seconds() + 1, "".to_string()))), Some(Bound::exclusive((max_time.seconds() + 1, "".to_string()))), - Order::Ascending, + Order::Ascending ) .take(limit) .map(|item| item.map(|(_, v)| v)) @@ -193,7 +177,7 @@ pub fn query_asks_by_renew_time( pub fn query_ask_renew_price( deps: Deps, current_time: Timestamp, - token_id: String, + token_id: String ) -> StdResult<(Option, Option)> { let ask = asks().load(deps.storage, ask_key(&token_id))?; let sudo_params = SUDO_PARAMS.load(deps.storage)?; @@ -205,22 +189,33 @@ pub fn query_ask_renew_price( } let name_minter = NAME_MINTER.load(deps.storage)?; - let name_minter_params = deps - .querier - .query_wasm_smart::(name_minter, &SgNameMinterQueryMsg::Params {})?; + let name_minter_params = deps.querier.query_wasm_smart::( + name_minter, + &(SgNameMinterQueryMsg::Params {}) + )?; let (renewal_price, valid_bid) = get_renewal_price_and_bid( deps, ¤t_time, &sudo_params, &ask.token_id, - name_minter_params.base_price.u128(), - ) - .map_err(|_| StdError::generic_err("failed to fetch renewal price".to_string()))?; + name_minter_params.base_price.u128() + ).map_err(|_| StdError::generic_err("failed to fetch renewal price".to_string()))?; Ok((Some(coin(renewal_price.u128(), NATIVE_DENOM)), valid_bid)) } +pub fn query_ask_renew_prices( + deps: Deps, + current_time: Timestamp, + token_ids: Vec +) -> StdResult, Option)>> { + token_ids + .iter() + .map(|token_id| query_ask_renew_price(deps, current_time, token_id.to_string())) + .collect::>>() +} + pub fn query_ask(deps: Deps, token_id: TokenId) -> StdResult> { asks().may_load(deps.storage, ask_key(&token_id)) } @@ -233,16 +228,14 @@ pub fn query_bids_by_bidder( deps: Deps, bidder: Addr, 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.map(|start| Bound::exclusive((start, bidder.clone()))); bids() - .idx - .bidder - .prefix(bidder) + .idx.bidder.prefix(bidder) .range(deps.storage, start, None, Order::Ascending) .take(limit) .map(|item| item.map(|(_, b)| b)) @@ -253,19 +246,18 @@ pub fn query_bids_for_seller( deps: Deps, seller: Addr, start_after: Option, - limit: Option, + limit: Option ) -> StdResult> { let limit = limit.unwrap_or(DEFAULT_QUERY_LIMIT).min(MAX_QUERY_LIMIT) as usize; // Query seller asks, then collect bids starting after token_id // Limitation: Can not collect bids in the middle using `start_after: token_id` pattern // This leads to imprecise pagination based on token id and not bid count - let start_token_id = - start_after.map(|start| Bound::::exclusive(ask_key(&start.token_id))); + let start_token_id = start_after.map(|start| + Bound::::exclusive(ask_key(&start.token_id)) + ); let bids = asks() - .idx - .seller - .prefix(seller) + .idx.seller.prefix(seller) .range(deps.storage, start_token_id, None, Order::Ascending) .take(limit) .map(|res| res.map(|item| item.0).unwrap()) @@ -285,7 +277,7 @@ pub fn query_bids( deps: Deps, token_id: TokenId, 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.map(|s| Bound::ExclusiveRaw(s.into())); @@ -301,12 +293,13 @@ pub fn query_bids( pub fn query_legacy_bids( deps: Deps, 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.map(|offset| Bound::exclusive(bid_key(&offset.token_id, &offset.bidder))); + let start = start_after.map(|offset| + Bound::exclusive(bid_key(&offset.token_id, &offset.bidder)) + ); legacy_bids() .range(deps.storage, start, None, Order::Ascending) @@ -317,9 +310,7 @@ pub fn query_legacy_bids( pub fn query_highest_bid(deps: Deps, token_id: TokenId) -> StdResult> { let bid = bids() - .idx - .price - .range(deps.storage, None, None, Order::Descending) + .idx.price.range(deps.storage, None, None, Order::Descending) .filter_map(|item| { let (key, bid) = item.unwrap(); if key.0 == token_id { @@ -339,7 +330,7 @@ pub fn query_highest_bid(deps: Deps, token_id: TokenId) -> StdResult pub fn query_bids_sorted_by_price( deps: Deps, start_after: Option, - limit: Option, + limit: Option ) -> StdResult> { let limit = limit.unwrap_or(DEFAULT_QUERY_LIMIT).min(MAX_QUERY_LIMIT) as usize; @@ -351,9 +342,7 @@ pub fn query_bids_sorted_by_price( }); bids() - .idx - .price - .range(deps.storage, start, None, Order::Ascending) + .idx.price.range(deps.storage, start, None, Order::Ascending) .take(limit) .map(|item| item.map(|(_, b)| b)) .collect::>>() @@ -362,7 +351,7 @@ pub fn query_bids_sorted_by_price( pub fn reverse_query_bids_sorted_by_price( deps: Deps, start_before: Option, - limit: Option, + limit: Option ) -> StdResult> { let limit = limit.unwrap_or(DEFAULT_QUERY_LIMIT).min(MAX_QUERY_LIMIT) as usize; @@ -374,9 +363,7 @@ pub fn reverse_query_bids_sorted_by_price( }); bids() - .idx - .price - .range(deps.storage, None, end, Order::Descending) + .idx.price.range(deps.storage, None, end, Order::Descending) .take(limit) .map(|item| item.map(|(_, b)| b)) .collect::>>() From 5b6b4fb035b96e4d3b9cb8070e643b5f5b6578a4 Mon Sep 17 00:00:00 2001 From: jason-c-child Date: Fri, 9 Feb 2024 19:13:14 -0900 Subject: [PATCH 02/13] linting --- contracts/marketplace/src/query.rs | 200 ++++++++++++++++------------- 1 file changed, 114 insertions(+), 86 deletions(-) diff --git a/contracts/marketplace/src/query.rs b/contracts/marketplace/src/query.rs index f95c4744..16246ec6 100644 --- a/contracts/marketplace/src/query.rs +++ b/contracts/marketplace/src/query.rs @@ -1,42 +1,16 @@ use crate::helpers::get_renewal_price_and_bid; -use crate::msg::{ BidOffset, Bidder, ConfigResponse, QueryMsg }; +use crate::msg::{BidOffset, Bidder, ConfigResponse, QueryMsg}; use crate::state::{ - ask_key, - asks, - bid_key, - bids, - legacy_bids, - Ask, - AskKey, - Bid, - Id, - SudoParams, - TokenId, - ASK_COUNT, - ASK_HOOKS, - BID_HOOKS, - NAME_COLLECTION, - NAME_MINTER, - RENEWAL_QUEUE, - SALE_HOOKS, + ask_key, asks, bid_key, bids, legacy_bids, Ask, AskKey, Bid, Id, SudoParams, TokenId, + ASK_COUNT, ASK_HOOKS, BID_HOOKS, NAME_COLLECTION, NAME_MINTER, RENEWAL_QUEUE, SALE_HOOKS, SUDO_PARAMS, }; use cosmwasm_std::{ - coin, - to_binary, - Addr, - Binary, - Coin, - Deps, - Env, - Order, - StdError, - StdResult, - Timestamp, + coin, to_binary, Addr, Binary, Coin, Deps, Env, Order, StdError, StdResult, Timestamp, }; use cw_storage_plus::Bound; -use sg_name_minter::{ SgNameMinterQueryMsg, SudoParams as NameMinterParams }; +use sg_name_minter::{SgNameMinterQueryMsg, SudoParams as NameMinterParams}; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; @@ -53,38 +27,77 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { QueryMsg::Ask { token_id } => to_binary(&query_ask(deps, token_id)?), QueryMsg::Asks { start_after, limit } => to_binary(&query_asks(deps, start_after, limit)?), - QueryMsg::AsksBySeller { seller, start_after, limit } => - to_binary( - &query_asks_by_seller(deps, api.addr_validate(&seller)?, start_after, limit)? - ), - QueryMsg::AsksByRenewTime { max_time, start_after, limit } => - to_binary(&query_asks_by_renew_time(deps, max_time, start_after, limit)?), - QueryMsg::AskRenewPrice { current_time, token_id } => - to_binary(&query_ask_renew_price(deps, current_time, token_id)?), - QueryMsg::AskRenewalPrices { current_time, token_ids } => - to_binary(&query_ask_renew_prices(deps, current_time, token_ids)?), + QueryMsg::AsksBySeller { + seller, + start_after, + limit, + } => to_binary(&query_asks_by_seller( + deps, + api.addr_validate(&seller)?, + start_after, + limit, + )?), + QueryMsg::AsksByRenewTime { + max_time, + start_after, + limit, + } => to_binary(&query_asks_by_renew_time( + deps, + max_time, + start_after, + limit, + )?), + QueryMsg::AskRenewPrice { + current_time, + token_id, + } => to_binary(&query_ask_renew_price(deps, current_time, token_id)?), + QueryMsg::AskRenewalPrices { + current_time, + token_ids, + } => to_binary(&query_ask_renew_prices(deps, current_time, token_ids)?), QueryMsg::AskCount {} => to_binary(&query_ask_count(deps)?), QueryMsg::Bid { token_id, bidder } => { to_binary(&query_bid(deps, token_id, api.addr_validate(&bidder)?)?) } - QueryMsg::Bids { token_id, start_after, limit } => - to_binary(&query_bids(deps, token_id, start_after, limit)?), + QueryMsg::Bids { + token_id, + start_after, + limit, + } => to_binary(&query_bids(deps, token_id, start_after, limit)?), QueryMsg::LegacyBids { start_after, limit } => { to_binary(&query_legacy_bids(deps, start_after, limit)?) } - QueryMsg::BidsByBidder { bidder, start_after, limit } => - to_binary( - &query_bids_by_bidder(deps, api.addr_validate(&bidder)?, start_after, limit)? - ), + QueryMsg::BidsByBidder { + bidder, + start_after, + limit, + } => to_binary(&query_bids_by_bidder( + deps, + api.addr_validate(&bidder)?, + start_after, + limit, + )?), QueryMsg::BidsSortedByPrice { start_after, limit } => { to_binary(&query_bids_sorted_by_price(deps, start_after, limit)?) } - QueryMsg::ReverseBidsSortedByPrice { start_before, limit } => - to_binary(&reverse_query_bids_sorted_by_price(deps, start_before, limit)?), - QueryMsg::BidsForSeller { seller, start_after, limit } => - to_binary( - &query_bids_for_seller(deps, api.addr_validate(&seller)?, start_after, limit)? - ), + QueryMsg::ReverseBidsSortedByPrice { + start_before, + limit, + } => to_binary(&reverse_query_bids_sorted_by_price( + deps, + start_before, + limit, + )?), + QueryMsg::BidsForSeller { + seller, + start_after, + limit, + } => to_binary(&query_bids_for_seller( + deps, + api.addr_validate(&seller)?, + start_after, + limit, + )?), QueryMsg::HighestBid { token_id } => to_binary(&query_highest_bid(deps, token_id)?), QueryMsg::Params {} => to_binary(&query_params(deps)?), QueryMsg::AskHooks {} => to_binary(&ASK_HOOKS.query_hooks(deps)?), @@ -103,7 +116,8 @@ pub fn query_config(deps: Deps) -> StdResult { } pub fn query_renewal_queue(deps: Deps, time: Timestamp) -> StdResult> { - let names = RENEWAL_QUEUE.prefix(time.seconds()) + let names = RENEWAL_QUEUE + .prefix(time.seconds()) .range(deps.storage, None, None, Order::Ascending) .map(|item| item.map(|item| item.1)) .collect::>>()?; @@ -118,11 +132,13 @@ pub fn query_asks(deps: Deps, start_after: Option, limit: Option) -> St let limit = limit.unwrap_or(DEFAULT_QUERY_LIMIT).min(MAX_QUERY_LIMIT) as usize; asks() - .idx.id.range( + .idx + .id + .range( deps.storage, Some(Bound::exclusive(start_after.unwrap_or_default())), None, - Order::Ascending + Order::Ascending, ) .take(limit) .map(|res| res.map(|item| item.1)) @@ -138,14 +154,16 @@ pub fn query_asks_by_seller( deps: Deps, seller: Addr, 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.map(|start| Bound::exclusive(ask_key(&start))); asks() - .idx.seller.prefix(seller) + .idx + .seller + .prefix(seller) .range(deps.storage, start, None, Order::Ascending) .take(limit) .map(|res| res.map(|item| item.1)) @@ -156,16 +174,18 @@ pub fn query_asks_by_renew_time( deps: Deps, max_time: Timestamp, start_after: Option, - limit: Option + limit: Option, ) -> StdResult> { let limit = limit.unwrap_or(DEFAULT_QUERY_LIMIT) as usize; let renewable_asks = asks() - .idx.renewal_time.range( + .idx + .renewal_time + .range( deps.storage, start_after.map(|start| Bound::inclusive((start.seconds() + 1, "".to_string()))), Some(Bound::exclusive((max_time.seconds() + 1, "".to_string()))), - Order::Ascending + Order::Ascending, ) .take(limit) .map(|item| item.map(|(_, v)| v)) @@ -177,7 +197,7 @@ pub fn query_asks_by_renew_time( pub fn query_ask_renew_price( deps: Deps, current_time: Timestamp, - token_id: String + token_id: String, ) -> StdResult<(Option, Option)> { let ask = asks().load(deps.storage, ask_key(&token_id))?; let sudo_params = SUDO_PARAMS.load(deps.storage)?; @@ -189,18 +209,18 @@ pub fn query_ask_renew_price( } let name_minter = NAME_MINTER.load(deps.storage)?; - let name_minter_params = deps.querier.query_wasm_smart::( - name_minter, - &(SgNameMinterQueryMsg::Params {}) - )?; + let name_minter_params = deps + .querier + .query_wasm_smart::(name_minter, &(SgNameMinterQueryMsg::Params {}))?; let (renewal_price, valid_bid) = get_renewal_price_and_bid( deps, ¤t_time, &sudo_params, &ask.token_id, - name_minter_params.base_price.u128() - ).map_err(|_| StdError::generic_err("failed to fetch renewal price".to_string()))?; + name_minter_params.base_price.u128(), + ) + .map_err(|_| StdError::generic_err("failed to fetch renewal price".to_string()))?; Ok((Some(coin(renewal_price.u128(), NATIVE_DENOM)), valid_bid)) } @@ -208,7 +228,7 @@ pub fn query_ask_renew_price( pub fn query_ask_renew_prices( deps: Deps, current_time: Timestamp, - token_ids: Vec + token_ids: Vec, ) -> StdResult, Option)>> { token_ids .iter() @@ -228,14 +248,16 @@ pub fn query_bids_by_bidder( deps: Deps, bidder: Addr, 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.map(|start| Bound::exclusive((start, bidder.clone()))); bids() - .idx.bidder.prefix(bidder) + .idx + .bidder + .prefix(bidder) .range(deps.storage, start, None, Order::Ascending) .take(limit) .map(|item| item.map(|(_, b)| b)) @@ -246,18 +268,19 @@ pub fn query_bids_for_seller( deps: Deps, seller: Addr, start_after: Option, - limit: Option + limit: Option, ) -> StdResult> { let limit = limit.unwrap_or(DEFAULT_QUERY_LIMIT).min(MAX_QUERY_LIMIT) as usize; // Query seller asks, then collect bids starting after token_id // Limitation: Can not collect bids in the middle using `start_after: token_id` pattern // This leads to imprecise pagination based on token id and not bid count - let start_token_id = start_after.map(|start| - Bound::::exclusive(ask_key(&start.token_id)) - ); + let start_token_id = + start_after.map(|start| Bound::::exclusive(ask_key(&start.token_id))); let bids = asks() - .idx.seller.prefix(seller) + .idx + .seller + .prefix(seller) .range(deps.storage, start_token_id, None, Order::Ascending) .take(limit) .map(|res| res.map(|item| item.0).unwrap()) @@ -277,7 +300,7 @@ pub fn query_bids( deps: Deps, token_id: TokenId, 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.map(|s| Bound::ExclusiveRaw(s.into())); @@ -293,13 +316,12 @@ pub fn query_bids( pub fn query_legacy_bids( deps: Deps, 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.map(|offset| - Bound::exclusive(bid_key(&offset.token_id, &offset.bidder)) - ); + let start = + start_after.map(|offset| Bound::exclusive(bid_key(&offset.token_id, &offset.bidder))); legacy_bids() .range(deps.storage, start, None, Order::Ascending) @@ -310,7 +332,9 @@ pub fn query_legacy_bids( pub fn query_highest_bid(deps: Deps, token_id: TokenId) -> StdResult> { let bid = bids() - .idx.price.range(deps.storage, None, None, Order::Descending) + .idx + .price + .range(deps.storage, None, None, Order::Descending) .filter_map(|item| { let (key, bid) = item.unwrap(); if key.0 == token_id { @@ -330,7 +354,7 @@ pub fn query_highest_bid(deps: Deps, token_id: TokenId) -> StdResult pub fn query_bids_sorted_by_price( deps: Deps, start_after: Option, - limit: Option + limit: Option, ) -> StdResult> { let limit = limit.unwrap_or(DEFAULT_QUERY_LIMIT).min(MAX_QUERY_LIMIT) as usize; @@ -342,7 +366,9 @@ pub fn query_bids_sorted_by_price( }); bids() - .idx.price.range(deps.storage, start, None, Order::Ascending) + .idx + .price + .range(deps.storage, start, None, Order::Ascending) .take(limit) .map(|item| item.map(|(_, b)| b)) .collect::>>() @@ -351,7 +377,7 @@ pub fn query_bids_sorted_by_price( pub fn reverse_query_bids_sorted_by_price( deps: Deps, start_before: Option, - limit: Option + limit: Option, ) -> StdResult> { let limit = limit.unwrap_or(DEFAULT_QUERY_LIMIT).min(MAX_QUERY_LIMIT) as usize; @@ -363,7 +389,9 @@ pub fn reverse_query_bids_sorted_by_price( }); bids() - .idx.price.range(deps.storage, None, end, Order::Descending) + .idx + .price + .range(deps.storage, None, end, Order::Descending) .take(limit) .map(|item| item.map(|(_, b)| b)) .collect::>>() From 9172e555c7f1c736d2c7eacf91069e919088e33b Mon Sep 17 00:00:00 2001 From: jason-c-child Date: Sat, 10 Feb 2024 11:30:15 -0900 Subject: [PATCH 03/13] add missing query info and fix test --- contracts/marketplace/src/msg.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/contracts/marketplace/src/msg.rs b/contracts/marketplace/src/msg.rs index 30008069..acf5a5f8 100644 --- a/contracts/marketplace/src/msg.rs +++ b/contracts/marketplace/src/msg.rs @@ -159,6 +159,12 @@ pub enum QueryMsg { current_time: Timestamp, token_id: TokenId, }, + /// Get renewal price for multiple names + #[returns(Vec<(TokenId, Coin, Option)>)] + AskRenewalPrices { + current_time: Timestamp, + token_ids: Vec, + }, /// Get data for a specific bid #[returns(Option)] Bid { token_id: TokenId, bidder: Bidder }, From ce0d3583368dea586930f11fbc44d4c5856d4f4e Mon Sep 17 00:00:00 2001 From: jason-c-child Date: Sat, 10 Feb 2024 11:43:52 -0900 Subject: [PATCH 04/13] genreate schemas --- ts/src/NameMarketplace.client.ts | 24 +++++++++++++++++++++- ts/src/NameMarketplace.message-composer.ts | 2 +- ts/src/NameMarketplace.types.ts | 6 ++++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/ts/src/NameMarketplace.client.ts b/ts/src/NameMarketplace.client.ts index 951bfe0a..27bb0c20 100644 --- a/ts/src/NameMarketplace.client.ts +++ b/ts/src/NameMarketplace.client.ts @@ -6,7 +6,7 @@ import { CosmWasmClient, SigningCosmWasmClient, ExecuteResult } from "@cosmjs/cosmwasm-stargate"; import { StdFee } from "@cosmjs/amino"; -import { Uint128, Decimal, InstantiateMsg, ExecuteMsg, QueryMsg, Timestamp, Uint64, Addr, BidOffset, NullableAsk, Ask, HooksResponse, TupleOfNullable_CoinAndNullable_Bid, Coin, Bid, ArrayOfAsk, NullableBid, ArrayOfBid, ConfigResponse, SudoParams } from "./NameMarketplace.types"; +import { Uint128, Decimal, InstantiateMsg, ExecuteMsg, QueryMsg, Timestamp, Uint64, Addr, BidOffset, NullableAsk, Ask, HooksResponse, TupleOfNullable_CoinAndNullable_Bid, Coin, Bid, ArrayOfTupleOfStringAndCoinAndNullable_Bid, ArrayOfAsk, NullableBid, ArrayOfBid, ConfigResponse, SudoParams } from "./NameMarketplace.types"; export interface NameMarketplaceReadOnlyInterface { contractAddress: string; ask: ({ @@ -47,6 +47,13 @@ export interface NameMarketplaceReadOnlyInterface { currentTime: Timestamp; tokenId: string; }) => Promise; + askRenewalPrices: ({ + currentTime, + tokenIds + }: { + currentTime: Timestamp; + tokenIds: string[]; + }) => Promise; bid: ({ bidder, tokenId @@ -131,6 +138,7 @@ export class NameMarketplaceQueryClient implements NameMarketplaceReadOnlyInterf this.asksBySeller = this.asksBySeller.bind(this); this.asksByRenewTime = this.asksByRenewTime.bind(this); this.askRenewPrice = this.askRenewPrice.bind(this); + this.askRenewalPrices = this.askRenewalPrices.bind(this); this.bid = this.bid.bind(this); this.bidsByBidder = this.bidsByBidder.bind(this); this.bids = this.bids.bind(this); @@ -225,6 +233,20 @@ export class NameMarketplaceQueryClient implements NameMarketplaceReadOnlyInterf } }); }; + askRenewalPrices = async ({ + currentTime, + tokenIds + }: { + currentTime: Timestamp; + tokenIds: string[]; + }): Promise => { + return this.client.queryContractSmart(this.contractAddress, { + ask_renewal_prices: { + current_time: currentTime, + token_ids: tokenIds + } + }); + }; bid = async ({ bidder, tokenId diff --git a/ts/src/NameMarketplace.message-composer.ts b/ts/src/NameMarketplace.message-composer.ts index 6e745ec7..8b89c934 100644 --- a/ts/src/NameMarketplace.message-composer.ts +++ b/ts/src/NameMarketplace.message-composer.ts @@ -7,7 +7,7 @@ import { MsgExecuteContractEncodeObject } from "cosmwasm"; import { MsgExecuteContract } from "cosmjs-types/cosmwasm/wasm/v1/tx"; import { toUtf8 } from "@cosmjs/encoding"; -import { Uint128, Decimal, InstantiateMsg, ExecuteMsg, QueryMsg, Timestamp, Uint64, Addr, BidOffset, NullableAsk, Ask, HooksResponse, TupleOfNullable_CoinAndNullable_Bid, Coin, Bid, ArrayOfAsk, NullableBid, ArrayOfBid, ConfigResponse, SudoParams } from "./NameMarketplace.types"; +import { Uint128, Decimal, InstantiateMsg, ExecuteMsg, QueryMsg, Timestamp, Uint64, Addr, BidOffset, NullableAsk, Ask, HooksResponse, TupleOfNullable_CoinAndNullable_Bid, Coin, Bid, ArrayOfTupleOfStringAndCoinAndNullable_Bid, ArrayOfAsk, NullableBid, ArrayOfBid, ConfigResponse, SudoParams } from "./NameMarketplace.types"; export interface NameMarketplaceMessage { contractAddress: string; sender: string; diff --git a/ts/src/NameMarketplace.types.ts b/ts/src/NameMarketplace.types.ts index 1145bc90..392e9893 100644 --- a/ts/src/NameMarketplace.types.ts +++ b/ts/src/NameMarketplace.types.ts @@ -97,6 +97,11 @@ export type QueryMsg = { current_time: Timestamp; token_id: string; }; +} | { + ask_renewal_prices: { + current_time: Timestamp; + token_ids: string[]; + }; } | { bid: { bidder: string; @@ -185,6 +190,7 @@ export interface Bid { created_time: Timestamp; token_id: string; } +export type ArrayOfTupleOfStringAndCoinAndNullable_Bid = [string, Coin, Bid | null][]; export type ArrayOfAsk = Ask[]; export type NullableBid = Bid | null; export type ArrayOfBid = Bid[]; From 015eafe6a0020756f675633a54bd80cb3f2eece2 Mon Sep 17 00:00:00 2001 From: jason-c-child Date: Sat, 10 Feb 2024 11:47:09 -0900 Subject: [PATCH 05/13] check in file --- .../marketplace/schema/name-marketplace.json | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/contracts/marketplace/schema/name-marketplace.json b/contracts/marketplace/schema/name-marketplace.json index eab0cf02..7c052d22 100644 --- a/contracts/marketplace/schema/name-marketplace.json +++ b/contracts/marketplace/schema/name-marketplace.json @@ -544,6 +544,35 @@ }, "additionalProperties": false }, + { + "description": "Get renewal price for multiple names", + "type": "object", + "required": [ + "ask_renewal_prices" + ], + "properties": { + "ask_renewal_prices": { + "type": "object", + "required": [ + "current_time", + "token_ids" + ], + "properties": { + "current_time": { + "$ref": "#/definitions/Timestamp" + }, + "token_ids": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, { "description": "Get data for a specific bid", "type": "object", @@ -1126,6 +1155,96 @@ } } }, + "ask_renewal_prices": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Array_of_Tuple_of_String_and_Coin_and_Nullable_Bid", + "type": "array", + "items": { + "type": "array", + "items": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/Coin" + }, + { + "anyOf": [ + { + "$ref": "#/definitions/Bid" + }, + { + "type": "null" + } + ] + } + ], + "maxItems": 3, + "minItems": 3 + }, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Bid": { + "description": "Represents a bid (offer) on the marketplace", + "type": "object", + "required": [ + "amount", + "bidder", + "created_time", + "token_id" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "bidder": { + "$ref": "#/definitions/Addr" + }, + "created_time": { + "$ref": "#/definitions/Timestamp" + }, + "token_id": { + "type": "string" + } + }, + "additionalProperties": false + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + } + } + }, "asks": { "$schema": "http://json-schema.org/draft-07/schema#", "title": "Array_of_Ask", From 295acbfd5e4b760a904b70bfa6fa28bdb137c63e Mon Sep 17 00:00:00 2001 From: jason-c-child Date: Sat, 10 Feb 2024 12:53:57 -0900 Subject: [PATCH 06/13] handle bad returns and update test --- contracts/marketplace/src/query.rs | 21 +++++++++++-- .../name-minter/src/integration_tests.rs | 30 +++++++++++++++++++ 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/contracts/marketplace/src/query.rs b/contracts/marketplace/src/query.rs index 16246ec6..6b0b0e74 100644 --- a/contracts/marketplace/src/query.rs +++ b/contracts/marketplace/src/query.rs @@ -7,7 +7,7 @@ use crate::state::{ }; use cosmwasm_std::{ - coin, to_binary, Addr, Binary, Coin, Deps, Env, Order, StdError, StdResult, Timestamp, + coin, to_binary, Addr, Binary, Coin, Deps, Env, Order, StdError, StdResult, Timestamp, Uint128 }; use cw_storage_plus::Bound; use sg_name_minter::{SgNameMinterQueryMsg, SudoParams as NameMinterParams}; @@ -229,10 +229,25 @@ pub fn query_ask_renew_prices( deps: Deps, current_time: Timestamp, token_ids: Vec, -) -> StdResult, Option)>> { +) -> StdResult> { token_ids .iter() - .map(|token_id| query_ask_renew_price(deps, current_time, token_id.to_string())) + .map(|token_id| { + let (coin_option, bid_option) = query_ask_renew_price(deps, current_time, token_id.to_string()) + .map_err(|e| StdError::generic_err(format!("Failed to query ask renew price for token_id {}: {}", token_id, e)))?; + let coin = coin_option.unwrap_or(Coin { + denom: "".to_string(), + amount: Uint128::zero(), + }); + let bid = bid_option.unwrap_or(Bid { + // Fill in the fields of Bid with default values + token_id: "".to_string(), + bidder: Addr::unchecked(""), + amount: Uint128::zero(), + created_time: Timestamp::from_seconds(0), + }); + Ok((coin, bid)) + }) .collect::>>() } diff --git a/contracts/name-minter/src/integration_tests.rs b/contracts/name-minter/src/integration_tests.rs index df133cb2..03ac81ea 100644 --- a/contracts/name-minter/src/integration_tests.rs +++ b/contracts/name-minter/src/integration_tests.rs @@ -81,6 +81,7 @@ const BIDDER2: &str = "bidder2"; const ADMIN: &str = "admin"; const ADMIN2: &str = "admin2"; const NAME: &str = "bobo"; +const NAME2: &str = "mccool"; const VERIFIER: &str = "verifier"; const OPERATOR: &str = "operator"; @@ -1191,6 +1192,35 @@ mod query { assert_eq!(renewal_price.unwrap().amount, expect_price); } + #[test] + fn multiple_renew_prices() { + // test that QueryRenewPrices returns multiple entires + let mut app = instantiate_contracts(None, None, None); + + mint_and_list(&mut app, NAME, USER, None).unwrap(); + mint_and_list(&mut app, NAME2, USER, None).unwrap(); + + // Amount to make it just above the char price + let bid_amount = 1_000_000_000u128 * 201u128; + + update_block_time(&mut app, SECONDS_PER_YEAR - (60 * 60 * 24 * 31)); + + bid(&mut app, NAME, BIDDER, bid_amount); + bid(&mut app, NAME2, BIDDER, bid_amount); + + update_block_time(&mut app, 60 * 60 * 24 * 31); + + let result = app.wrap().query_wasm_smart::>( + MKT, + &MarketplaceQueryMsg::AskRenewalPrices { + current_time: app.block_info().time, + token_ids: vec![NAME.to_string(), NAME2.to_string()], + }, + ); + println!("{:?}", result); + assert!(result.is_ok()); + } + #[test] fn renew_execute_msg() { let mut app = instantiate_contracts(None, None, None); From 136e2a2557beb6abd40213453566e22fdcf6c018 Mon Sep 17 00:00:00 2001 From: jason-c-child Date: Sat, 10 Feb 2024 12:56:25 -0900 Subject: [PATCH 07/13] linter --- contracts/marketplace/src/query.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/contracts/marketplace/src/query.rs b/contracts/marketplace/src/query.rs index 6b0b0e74..9cb05561 100644 --- a/contracts/marketplace/src/query.rs +++ b/contracts/marketplace/src/query.rs @@ -7,7 +7,7 @@ use crate::state::{ }; use cosmwasm_std::{ - coin, to_binary, Addr, Binary, Coin, Deps, Env, Order, StdError, StdResult, Timestamp, Uint128 + coin, to_binary, Addr, Binary, Coin, Deps, Env, Order, StdError, StdResult, Timestamp, Uint128, }; use cw_storage_plus::Bound; use sg_name_minter::{SgNameMinterQueryMsg, SudoParams as NameMinterParams}; @@ -233,8 +233,13 @@ pub fn query_ask_renew_prices( token_ids .iter() .map(|token_id| { - let (coin_option, bid_option) = query_ask_renew_price(deps, current_time, token_id.to_string()) - .map_err(|e| StdError::generic_err(format!("Failed to query ask renew price for token_id {}: {}", token_id, e)))?; + let (coin_option, bid_option) = + query_ask_renew_price(deps, current_time, token_id.to_string()).map_err(|e| { + StdError::generic_err(format!( + "Failed to query ask renew price for token_id {}: {}", + token_id, e + )) + })?; let coin = coin_option.unwrap_or(Coin { denom: "".to_string(), amount: Uint128::zero(), @@ -244,7 +249,7 @@ pub fn query_ask_renew_prices( token_id: "".to_string(), bidder: Addr::unchecked(""), amount: Uint128::zero(), - created_time: Timestamp::from_seconds(0), + created_time: Timestamp::from_seconds(0), }); Ok((coin, bid)) }) From e4acca70c62a2dda0630fe332d3d54a2401bb160 Mon Sep 17 00:00:00 2001 From: jason-c-child Date: Mon, 19 Feb 2024 20:37:09 -0900 Subject: [PATCH 08/13] Convert ask renew price response to struct --- contracts/marketplace/src/msg.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/contracts/marketplace/src/msg.rs b/contracts/marketplace/src/msg.rs index acf5a5f8..3f4065a8 100644 --- a/contracts/marketplace/src/msg.rs +++ b/contracts/marketplace/src/msg.rs @@ -124,6 +124,13 @@ impl BidOffset { } } +#[cw_serde] +pub struct AskRenewPriceResponse { + pub token_id: TokenId, + pub price: Coin, + pub bid: Option, +} + #[cw_serde] #[derive(QueryResponses)] pub enum QueryMsg { @@ -160,7 +167,7 @@ pub enum QueryMsg { token_id: TokenId, }, /// Get renewal price for multiple names - #[returns(Vec<(TokenId, Coin, Option)>)] + #[returns(Vec)] AskRenewalPrices { current_time: Timestamp, token_ids: Vec, From 05e9014fb68e6fe8f1cfe1bed2db979500b9b3c6 Mon Sep 17 00:00:00 2001 From: jason-c-child Date: Mon, 19 Feb 2024 20:43:33 -0900 Subject: [PATCH 09/13] return vect of struct; remove explicit error return --- contracts/marketplace/src/query.rs | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/contracts/marketplace/src/query.rs b/contracts/marketplace/src/query.rs index 9cb05561..c4c5b0da 100644 --- a/contracts/marketplace/src/query.rs +++ b/contracts/marketplace/src/query.rs @@ -1,10 +1,11 @@ use crate::helpers::get_renewal_price_and_bid; -use crate::msg::{BidOffset, Bidder, ConfigResponse, QueryMsg}; +use crate::msg::{AskRenewPriceResponse, BidOffset, Bidder, ConfigResponse, QueryMsg}; use crate::state::{ ask_key, asks, bid_key, bids, legacy_bids, Ask, AskKey, Bid, Id, SudoParams, TokenId, ASK_COUNT, ASK_HOOKS, BID_HOOKS, NAME_COLLECTION, NAME_MINTER, RENEWAL_QUEUE, SALE_HOOKS, SUDO_PARAMS, }; +use crate::ContractError; use cosmwasm_std::{ coin, to_binary, Addr, Binary, Coin, Deps, Env, Order, StdError, StdResult, Timestamp, Uint128, @@ -229,29 +230,17 @@ pub fn query_ask_renew_prices( deps: Deps, current_time: Timestamp, token_ids: Vec, -) -> StdResult> { +) -> StdResult> { token_ids .iter() .map(|token_id| { let (coin_option, bid_option) = - query_ask_renew_price(deps, current_time, token_id.to_string()).map_err(|e| { - StdError::generic_err(format!( - "Failed to query ask renew price for token_id {}: {}", - token_id, e - )) - })?; - let coin = coin_option.unwrap_or(Coin { - denom: "".to_string(), - amount: Uint128::zero(), - }); - let bid = bid_option.unwrap_or(Bid { - // Fill in the fields of Bid with default values - token_id: "".to_string(), - bidder: Addr::unchecked(""), - amount: Uint128::zero(), - created_time: Timestamp::from_seconds(0), - }); - Ok((coin, bid)) + query_ask_renew_price(deps, current_time, token_id.to_string())?; + Ok(AskRenewPriceResponse { + token_id: token_id.to_string(), + price: coin_option.unwrap_or_default(), + bid: bid_option, + }) }) .collect::>>() } From 2b341ba151589f90802984ed528ca3bb5d9ca980 Mon Sep 17 00:00:00 2001 From: jason-c-child Date: Mon, 19 Feb 2024 20:46:05 -0900 Subject: [PATCH 10/13] fix test --- contracts/name-minter/src/integration_tests.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contracts/name-minter/src/integration_tests.rs b/contracts/name-minter/src/integration_tests.rs index 03ac81ea..2823e5f3 100644 --- a/contracts/name-minter/src/integration_tests.rs +++ b/contracts/name-minter/src/integration_tests.rs @@ -862,6 +862,7 @@ mod query { use cosmwasm_std::coin; use cosmwasm_std::Coin; use cosmwasm_std::StdResult; + use name_marketplace::msg::AskRenewPriceResponse; use name_marketplace::msg::BidOffset; use name_marketplace::state::Ask; use sg721_base::msg::CollectionInfoResponse; @@ -1210,7 +1211,7 @@ mod query { update_block_time(&mut app, 60 * 60 * 24 * 31); - let result = app.wrap().query_wasm_smart::>( + let result = app.wrap().query_wasm_smart::>( MKT, &MarketplaceQueryMsg::AskRenewalPrices { current_time: app.block_info().time, From 93c37f78e32bbde56c4410049b95beca02ed4d17 Mon Sep 17 00:00:00 2001 From: jason-c-child Date: Mon, 19 Feb 2024 20:49:04 -0900 Subject: [PATCH 11/13] fix linter error --- contracts/marketplace/src/query.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/contracts/marketplace/src/query.rs b/contracts/marketplace/src/query.rs index c4c5b0da..be6d50b9 100644 --- a/contracts/marketplace/src/query.rs +++ b/contracts/marketplace/src/query.rs @@ -5,10 +5,9 @@ use crate::state::{ ASK_COUNT, ASK_HOOKS, BID_HOOKS, NAME_COLLECTION, NAME_MINTER, RENEWAL_QUEUE, SALE_HOOKS, SUDO_PARAMS, }; -use crate::ContractError; use cosmwasm_std::{ - coin, to_binary, Addr, Binary, Coin, Deps, Env, Order, StdError, StdResult, Timestamp, Uint128, + coin, to_binary, Addr, Binary, Coin, Deps, Env, Order, StdError, StdResult, Timestamp, }; use cw_storage_plus::Bound; use sg_name_minter::{SgNameMinterQueryMsg, SudoParams as NameMinterParams}; From 69532346cdeebd93f62768e88e1feeaa83afb356 Mon Sep 17 00:00:00 2001 From: jason-c-child Date: Mon, 19 Feb 2024 20:51:50 -0900 Subject: [PATCH 12/13] update schemas --- ts/src/NameMarketplace.client.ts | 6 +++--- ts/src/NameMarketplace.message-composer.ts | 2 +- ts/src/NameMarketplace.types.ts | 7 ++++++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/ts/src/NameMarketplace.client.ts b/ts/src/NameMarketplace.client.ts index 27bb0c20..375ff7d6 100644 --- a/ts/src/NameMarketplace.client.ts +++ b/ts/src/NameMarketplace.client.ts @@ -6,7 +6,7 @@ import { CosmWasmClient, SigningCosmWasmClient, ExecuteResult } from "@cosmjs/cosmwasm-stargate"; import { StdFee } from "@cosmjs/amino"; -import { Uint128, Decimal, InstantiateMsg, ExecuteMsg, QueryMsg, Timestamp, Uint64, Addr, BidOffset, NullableAsk, Ask, HooksResponse, TupleOfNullable_CoinAndNullable_Bid, Coin, Bid, ArrayOfTupleOfStringAndCoinAndNullable_Bid, ArrayOfAsk, NullableBid, ArrayOfBid, ConfigResponse, SudoParams } from "./NameMarketplace.types"; +import { Uint128, Decimal, InstantiateMsg, ExecuteMsg, QueryMsg, Timestamp, Uint64, Addr, BidOffset, NullableAsk, Ask, HooksResponse, TupleOfNullable_CoinAndNullable_Bid, Coin, Bid, ArrayOfAskRenewPriceResponse, AskRenewPriceResponse, ArrayOfAsk, NullableBid, ArrayOfBid, ConfigResponse, SudoParams } from "./NameMarketplace.types"; export interface NameMarketplaceReadOnlyInterface { contractAddress: string; ask: ({ @@ -53,7 +53,7 @@ export interface NameMarketplaceReadOnlyInterface { }: { currentTime: Timestamp; tokenIds: string[]; - }) => Promise; + }) => Promise; bid: ({ bidder, tokenId @@ -239,7 +239,7 @@ export class NameMarketplaceQueryClient implements NameMarketplaceReadOnlyInterf }: { currentTime: Timestamp; tokenIds: string[]; - }): Promise => { + }): Promise => { return this.client.queryContractSmart(this.contractAddress, { ask_renewal_prices: { current_time: currentTime, diff --git a/ts/src/NameMarketplace.message-composer.ts b/ts/src/NameMarketplace.message-composer.ts index 8b89c934..4e68677f 100644 --- a/ts/src/NameMarketplace.message-composer.ts +++ b/ts/src/NameMarketplace.message-composer.ts @@ -7,7 +7,7 @@ import { MsgExecuteContractEncodeObject } from "cosmwasm"; import { MsgExecuteContract } from "cosmjs-types/cosmwasm/wasm/v1/tx"; import { toUtf8 } from "@cosmjs/encoding"; -import { Uint128, Decimal, InstantiateMsg, ExecuteMsg, QueryMsg, Timestamp, Uint64, Addr, BidOffset, NullableAsk, Ask, HooksResponse, TupleOfNullable_CoinAndNullable_Bid, Coin, Bid, ArrayOfTupleOfStringAndCoinAndNullable_Bid, ArrayOfAsk, NullableBid, ArrayOfBid, ConfigResponse, SudoParams } from "./NameMarketplace.types"; +import { Uint128, Decimal, InstantiateMsg, ExecuteMsg, QueryMsg, Timestamp, Uint64, Addr, BidOffset, NullableAsk, Ask, HooksResponse, TupleOfNullable_CoinAndNullable_Bid, Coin, Bid, ArrayOfAskRenewPriceResponse, AskRenewPriceResponse, ArrayOfAsk, NullableBid, ArrayOfBid, ConfigResponse, SudoParams } from "./NameMarketplace.types"; export interface NameMarketplaceMessage { contractAddress: string; sender: string; diff --git a/ts/src/NameMarketplace.types.ts b/ts/src/NameMarketplace.types.ts index 392e9893..767e3607 100644 --- a/ts/src/NameMarketplace.types.ts +++ b/ts/src/NameMarketplace.types.ts @@ -190,7 +190,12 @@ export interface Bid { created_time: Timestamp; token_id: string; } -export type ArrayOfTupleOfStringAndCoinAndNullable_Bid = [string, Coin, Bid | null][]; +export type ArrayOfAskRenewPriceResponse = AskRenewPriceResponse[]; +export interface AskRenewPriceResponse { + bid?: Bid | null; + price: Coin; + token_id: string; +} export type ArrayOfAsk = Ask[]; export type NullableBid = Bid | null; export type ArrayOfBid = Bid[]; From f908a672567f00f69379a49cc999ffc69d0b6f9b Mon Sep 17 00:00:00 2001 From: jason-c-child Date: Mon, 19 Feb 2024 20:53:23 -0900 Subject: [PATCH 13/13] update def --- .../marketplace/schema/name-marketplace.json | 50 +++++++++++-------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/contracts/marketplace/schema/name-marketplace.json b/contracts/marketplace/schema/name-marketplace.json index 7c052d22..42cf07ec 100644 --- a/contracts/marketplace/schema/name-marketplace.json +++ b/contracts/marketplace/schema/name-marketplace.json @@ -1157,36 +1157,42 @@ }, "ask_renewal_prices": { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_Tuple_of_String_and_Coin_and_Nullable_Bid", + "title": "Array_of_AskRenewPriceResponse", "type": "array", "items": { - "type": "array", - "items": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/Coin" - }, - { - "anyOf": [ - { - "$ref": "#/definitions/Bid" - }, - { - "type": "null" - } - ] - } - ], - "maxItems": 3, - "minItems": 3 + "$ref": "#/definitions/AskRenewPriceResponse" }, "definitions": { "Addr": { "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", "type": "string" }, + "AskRenewPriceResponse": { + "type": "object", + "required": [ + "price", + "token_id" + ], + "properties": { + "bid": { + "anyOf": [ + { + "$ref": "#/definitions/Bid" + }, + { + "type": "null" + } + ] + }, + "price": { + "$ref": "#/definitions/Coin" + }, + "token_id": { + "type": "string" + } + }, + "additionalProperties": false + }, "Bid": { "description": "Represents a bid (offer) on the marketplace", "type": "object",