use core::fmt;
use schemars::JsonSchema;
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use cosmwasm_std::{
to_binary, CustomQuery, QuerierWrapper, QueryRequest, StdError, StdResult, WasmQuery,
};
use crate::expiration::Expiration;
use crate::metadata::Metadata;
use secret_toolkit_utils::space_pad;
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
pub struct ViewerInfo {
pub address: String,
pub viewing_key: String,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
pub struct ContractInfo {
pub name: String,
pub symbol: String,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
pub struct NumTokens {
pub count: u32,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
pub struct TokenList {
pub tokens: Vec<String>,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
pub struct Cw721Approval {
pub spender: String,
pub expires: Expiration,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
pub struct OwnerOf {
pub owner: Option<String>,
pub approvals: Vec<Cw721Approval>,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
pub struct AllNftInfo {
pub access: OwnerOf,
pub info: Option<Metadata>,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
pub struct Snip721Approval {
pub address: String,
pub view_owner_expiration: Option<Expiration>,
pub view_private_metadata_expiration: Option<Expiration>,
pub transfer_expiration: Option<Expiration>,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
pub struct NftDossier {
pub owner: Option<String>,
pub public_metadata: Option<Metadata>,
pub private_metadata: Option<Metadata>,
pub display_private_metadata_error: Option<String>,
pub owner_is_public: bool,
pub public_ownership_expiration: Option<Expiration>,
pub private_metadata_is_public: bool,
pub private_metadata_is_public_expiration: Option<Expiration>,
pub token_approvals: Option<Vec<Snip721Approval>>,
pub inventory_approvals: Option<Vec<Snip721Approval>>,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
pub struct TokenApprovals {
pub owner_is_public: bool,
pub public_ownership_expiration: Option<Expiration>,
pub private_metadata_is_public: bool,
pub private_metadata_is_public_expiration: Option<Expiration>,
pub token_approvals: Vec<Snip721Approval>,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
pub struct ApprovedForAll {
pub operators: Vec<Cw721Approval>,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
pub struct InventoryApprovals {
pub owner_is_public: bool,
pub public_ownership_expiration: Option<Expiration>,
pub private_metadata_is_public: bool,
pub private_metadata_is_public_expiration: Option<Expiration>,
pub inventory_approvals: Vec<Snip721Approval>,
}
#[derive(Serialize, Deserialize, JsonSchema, Clone, PartialEq, Eq, Debug)]
#[serde(rename_all = "snake_case")]
pub enum TxAction {
Transfer {
from: String,
sender: Option<String>,
recipient: String,
},
Mint {
minter: String,
recipient: String,
},
Burn {
owner: String,
burner: Option<String>,
},
}
#[derive(Serialize, Deserialize, JsonSchema, Clone, PartialEq, Eq, Debug)]
#[serde(rename_all = "snake_case")]
pub struct Tx {
pub tx_id: u64,
pub block_height: u64,
pub block_time: u64,
pub token_id: String,
pub action: TxAction,
pub memo: Option<String>,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
pub struct TransactionHistory {
pub total: u64,
pub txs: Vec<Tx>,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
pub struct Minters {
pub minters: Vec<String>,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
pub struct IsUnwrapped {
pub token_is_unwrapped: bool,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
pub struct VerifyTransferApproval {
pub approved_for_all: bool,
pub first_unapproved_token: Option<String>,
}
#[derive(Serialize, Clone, Debug, Eq, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum QueryMsg {
ContractInfo {},
NumTokens {
viewer: Option<ViewerInfo>,
},
AllTokens {
viewer: Option<ViewerInfo>,
start_after: Option<String>,
limit: Option<u32>,
},
OwnerOf {
token_id: String,
viewer: Option<ViewerInfo>,
include_expired: Option<bool>,
},
NftInfo { token_id: String },
AllNftInfo {
token_id: String,
viewer: Option<ViewerInfo>,
include_expired: Option<bool>,
},
PrivateMetadata {
token_id: String,
viewer: Option<ViewerInfo>,
},
NftDossier {
token_id: String,
viewer: Option<ViewerInfo>,
include_expired: Option<bool>,
},
TokenApprovals {
token_id: String,
viewing_key: String,
include_expired: Option<bool>,
},
ApprovedForAll {
owner: String,
viewing_key: Option<String>,
include_expired: Option<bool>,
},
InventoryApprovals {
address: String,
viewing_key: String,
include_expired: Option<bool>,
},
Tokens {
owner: String,
viewer: Option<String>,
viewing_key: Option<String>,
start_after: Option<String>,
limit: Option<u32>,
},
TransactionHistory {
address: String,
viewing_key: String,
page: Option<u32>,
page_size: Option<u32>,
},
Minters {},
IsUnwrapped { token_id: String },
VerifyTransferApproval {
token_ids: Vec<String>,
address: String,
viewing_key: String,
},
}
impl fmt::Display for QueryMsg {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
QueryMsg::ContractInfo { .. } => write!(f, "ContractInfo"),
QueryMsg::NumTokens { .. } => write!(f, "NumTokens"),
QueryMsg::AllTokens { .. } => write!(f, "AllTokens"),
QueryMsg::OwnerOf { .. } => write!(f, "OwnerOf"),
QueryMsg::NftInfo { .. } => write!(f, "NftInfo"),
QueryMsg::AllNftInfo { .. } => write!(f, "AllNftInfo"),
QueryMsg::PrivateMetadata { .. } => write!(f, "PrivateMetadata"),
QueryMsg::NftDossier { .. } => write!(f, "NftDossier"),
QueryMsg::TokenApprovals { .. } => write!(f, "TokenApprovals"),
QueryMsg::ApprovedForAll { .. } => write!(f, "ApprovedForAll"),
QueryMsg::InventoryApprovals { .. } => write!(f, "InventoryApprovals"),
QueryMsg::Tokens { .. } => write!(f, "Tokens"),
QueryMsg::TransactionHistory { .. } => write!(f, "TransactionHistory"),
QueryMsg::Minters { .. } => write!(f, "Minters"),
QueryMsg::IsUnwrapped { .. } => write!(f, "IsUnwrapped"),
QueryMsg::VerifyTransferApproval { .. } => write!(f, "VerifyTransferApproval"),
}
}
}
impl QueryMsg {
pub fn query<C: CustomQuery, T: DeserializeOwned>(
&self,
querier: QuerierWrapper<C>,
mut block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<T> {
if block_size == 0 {
block_size = 1;
}
let mut msg = to_binary(self)?;
space_pad(&mut msg.0, block_size);
querier
.query(&QueryRequest::Wasm(WasmQuery::Smart {
contract_addr,
code_hash,
msg,
}))
.map_err(|err| {
StdError::generic_err(format!("Error performing {self} query: {err}"))
})
}
}
#[derive(Serialize, Deserialize)]
pub struct ContractInfoResponse {
pub contract_info: ContractInfo,
}
#[derive(Serialize, Deserialize)]
pub struct NumTokensResponse {
pub num_tokens: NumTokens,
}
#[derive(Serialize, Deserialize)]
pub struct TokenListResponse {
pub token_list: TokenList,
}
#[derive(Serialize, Deserialize)]
pub struct OwnerOfResponse {
pub owner_of: OwnerOf,
}
#[derive(Serialize, Deserialize)]
pub struct NftInfoResponse {
pub nft_info: Metadata,
}
#[derive(Serialize, Deserialize)]
pub struct AllNftInfoResponse {
pub all_nft_info: AllNftInfo,
}
#[derive(Serialize, Deserialize)]
pub struct PrivateMetadataResponse {
pub private_metadata: Metadata,
}
#[derive(Serialize, Deserialize)]
pub struct NftDossierResponse {
pub nft_dossier: NftDossier,
}
#[derive(Serialize, Deserialize)]
pub struct TokenApprovalsResponse {
pub token_approvals: TokenApprovals,
}
#[derive(Serialize, Deserialize)]
pub struct ApprovedForAllResponse {
pub approved_for_all: ApprovedForAll,
}
#[derive(Serialize, Deserialize)]
pub struct InventoryApprovalsResponse {
pub inventory_approvals: InventoryApprovals,
}
#[derive(Serialize, Deserialize)]
pub struct TransactionHistoryResponse {
pub transaction_history: TransactionHistory,
}
#[derive(Serialize, Deserialize)]
pub struct MintersResponse {
pub minters: Minters,
}
#[derive(Serialize, Deserialize)]
pub struct IsUnwrappedResponse {
pub is_unwrapped: IsUnwrapped,
}
#[derive(Serialize, Deserialize)]
pub struct VerifyTransferApprovalResponse {
pub verify_transfer_approval: VerifyTransferApproval,
}
pub fn contract_info_query<C: CustomQuery>(
querier: QuerierWrapper<C>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<ContractInfo> {
let answer: ContractInfoResponse =
QueryMsg::ContractInfo {}.query(querier, block_size, code_hash, contract_addr)?;
Ok(answer.contract_info)
}
pub fn num_tokens_query<C: CustomQuery>(
querier: QuerierWrapper<C>,
viewer: Option<ViewerInfo>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<NumTokens> {
let answer: NumTokensResponse =
QueryMsg::NumTokens { viewer }.query(querier, block_size, code_hash, contract_addr)?;
Ok(answer.num_tokens)
}
pub fn all_tokens_query<C: CustomQuery>(
querier: QuerierWrapper<C>,
viewer: Option<ViewerInfo>,
start_after: Option<String>,
limit: Option<u32>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<TokenList> {
let answer: TokenListResponse = QueryMsg::AllTokens {
viewer,
start_after,
limit,
}
.query(querier, block_size, code_hash, contract_addr)?;
Ok(answer.token_list)
}
pub fn owner_of_query<C: CustomQuery>(
querier: QuerierWrapper<C>,
token_id: String,
viewer: Option<ViewerInfo>,
include_expired: Option<bool>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<OwnerOf> {
let answer: OwnerOfResponse = QueryMsg::OwnerOf {
token_id,
viewer,
include_expired,
}
.query(querier, block_size, code_hash, contract_addr)?;
Ok(answer.owner_of)
}
pub fn nft_info_query<C: CustomQuery>(
querier: QuerierWrapper<C>,
token_id: String,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<Metadata> {
let answer: NftInfoResponse =
QueryMsg::NftInfo { token_id }.query(querier, block_size, code_hash, contract_addr)?;
Ok(answer.nft_info)
}
pub fn all_nft_info_query<C: CustomQuery>(
querier: QuerierWrapper<C>,
token_id: String,
viewer: Option<ViewerInfo>,
include_expired: Option<bool>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<AllNftInfo> {
let answer: AllNftInfoResponse = QueryMsg::AllNftInfo {
token_id,
viewer,
include_expired,
}
.query(querier, block_size, code_hash, contract_addr)?;
Ok(answer.all_nft_info)
}
pub fn private_metadata_query<C: CustomQuery>(
querier: QuerierWrapper<C>,
token_id: String,
viewer: Option<ViewerInfo>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<Metadata> {
let answer: PrivateMetadataResponse = QueryMsg::PrivateMetadata { token_id, viewer }.query(
querier,
block_size,
code_hash,
contract_addr,
)?;
Ok(answer.private_metadata)
}
pub fn nft_dossier_query<C: CustomQuery>(
querier: QuerierWrapper<C>,
token_id: String,
viewer: Option<ViewerInfo>,
include_expired: Option<bool>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<NftDossier> {
let answer: NftDossierResponse = QueryMsg::NftDossier {
token_id,
viewer,
include_expired,
}
.query(querier, block_size, code_hash, contract_addr)?;
Ok(answer.nft_dossier)
}
pub fn token_approvals_query<C: CustomQuery>(
querier: QuerierWrapper<C>,
token_id: String,
viewing_key: String,
include_expired: Option<bool>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<TokenApprovals> {
let answer: TokenApprovalsResponse = QueryMsg::TokenApprovals {
token_id,
viewing_key,
include_expired,
}
.query(querier, block_size, code_hash, contract_addr)?;
Ok(answer.token_approvals)
}
pub fn approved_for_all_query<C: CustomQuery>(
querier: QuerierWrapper<C>,
owner: String,
viewing_key: Option<String>,
include_expired: Option<bool>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<ApprovedForAll> {
let answer: ApprovedForAllResponse = QueryMsg::ApprovedForAll {
owner,
viewing_key,
include_expired,
}
.query(querier, block_size, code_hash, contract_addr)?;
Ok(answer.approved_for_all)
}
pub fn inventory_approvals_query<C: CustomQuery>(
querier: QuerierWrapper<C>,
address: String,
viewing_key: String,
include_expired: Option<bool>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<InventoryApprovals> {
let answer: InventoryApprovalsResponse = QueryMsg::InventoryApprovals {
address,
viewing_key,
include_expired,
}
.query(querier, block_size, code_hash, contract_addr)?;
Ok(answer.inventory_approvals)
}
#[allow(clippy::too_many_arguments)]
pub fn tokens_query<C: CustomQuery>(
querier: QuerierWrapper<C>,
owner: String,
viewer: Option<String>,
viewing_key: Option<String>,
start_after: Option<String>,
limit: Option<u32>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<TokenList> {
let answer: TokenListResponse = QueryMsg::Tokens {
owner,
viewer,
viewing_key,
start_after,
limit,
}
.query(querier, block_size, code_hash, contract_addr)?;
Ok(answer.token_list)
}
#[allow(clippy::too_many_arguments)]
pub fn transaction_history_query<C: CustomQuery>(
querier: QuerierWrapper<C>,
address: String,
viewing_key: String,
page: Option<u32>,
page_size: Option<u32>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<TransactionHistory> {
let answer: TransactionHistoryResponse = QueryMsg::TransactionHistory {
address,
viewing_key,
page,
page_size,
}
.query(querier, block_size, code_hash, contract_addr)?;
Ok(answer.transaction_history)
}
pub fn minters_query<C: CustomQuery>(
querier: QuerierWrapper<C>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<Minters> {
let answer: MintersResponse =
QueryMsg::Minters {}.query(querier, block_size, code_hash, contract_addr)?;
Ok(answer.minters)
}
pub fn is_unwrapped_query<C: CustomQuery>(
querier: QuerierWrapper<C>,
token_id: String,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<IsUnwrapped> {
let answer: IsUnwrappedResponse =
QueryMsg::IsUnwrapped { token_id }.query(querier, block_size, code_hash, contract_addr)?;
Ok(answer.is_unwrapped)
}
pub fn verify_transfer_approval_query<C: CustomQuery>(
querier: QuerierWrapper<C>,
token_ids: Vec<String>,
address: String,
viewing_key: String,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<VerifyTransferApproval> {
let answer: VerifyTransferApprovalResponse = QueryMsg::VerifyTransferApproval {
token_ids,
address,
viewing_key,
}
.query(querier, block_size, code_hash, contract_addr)?;
Ok(answer.verify_transfer_approval)
}
#[cfg(test)]
mod tests {
use crate::{Extension, Trait};
use super::*;
use cosmwasm_std::{
to_vec, ContractResult, Empty, Querier, QuerierResult, SystemError, SystemResult,
};
macro_rules! try_querier_result {
($result: expr) => {
match $result {
std::result::Result::Ok(ok) => ok,
std::result::Result::Err(err) => return cosmwasm_std::QuerierResult::Err(err),
}
};
}
#[test]
fn test_contract_info_query() -> StdResult<()> {
struct MyMockQuerier {}
impl Querier for MyMockQuerier {
fn raw_query(&self, request: &[u8]) -> QuerierResult {
let mut expected_msg = try_querier_result!(
to_binary(&QueryMsg::ContractInfo {}).map_err(|_e| SystemError::Unknown {})
);
space_pad(&mut expected_msg.0, 256);
let expected_request: QueryRequest<QueryMsg> =
QueryRequest::Wasm(WasmQuery::Smart {
contract_addr: "contract".to_string(),
code_hash: "code hash".to_string(),
msg: expected_msg,
});
let test_req: &[u8] = &try_querier_result!(
to_vec(&expected_request).map_err(|_e| SystemError::Unknown {})
);
assert_eq!(request, test_req);
let response = ContractInfoResponse {
contract_info: ContractInfo {
name: "NFTs".to_string(),
symbol: "NFTS".to_string(),
},
};
let response =
try_querier_result!(to_binary(&response).map_err(|_e| SystemError::Unknown {}));
SystemResult::Ok(ContractResult::Ok(response))
}
}
let querier = QuerierWrapper::<Empty>::new(&MyMockQuerier {});
let address = "contract".to_string();
let hash = "code hash".to_string();
let expected_response = ContractInfo {
name: "NFTs".to_string(),
symbol: "NFTS".to_string(),
};
let response = contract_info_query(querier, 256usize, hash, address)?;
assert_eq!(response, expected_response);
Ok(())
}
#[test]
fn test_num_tokens_query() -> StdResult<()> {
struct MyMockQuerier {}
impl Querier for MyMockQuerier {
fn raw_query(&self, request: &[u8]) -> QuerierResult {
let viewer = Some(ViewerInfo {
address: "alice".to_string(),
viewing_key: "key".to_string(),
});
let mut expected_msg =
try_querier_result!(to_binary(&QueryMsg::NumTokens { viewer })
.map_err(|_e| SystemError::Unknown {}));
space_pad(&mut expected_msg.0, 256);
let expected_request: QueryRequest<QueryMsg> =
QueryRequest::Wasm(WasmQuery::Smart {
contract_addr: "contract".to_string(),
code_hash: "code hash".to_string(),
msg: expected_msg,
});
let test_req: &[u8] = &try_querier_result!(
to_vec(&expected_request).map_err(|_e| SystemError::Unknown {})
);
assert_eq!(request, test_req);
let response = NumTokensResponse {
num_tokens: NumTokens { count: 32 },
};
let response =
try_querier_result!(to_binary(&response).map_err(|_e| SystemError::Unknown {}));
SystemResult::Ok(ContractResult::Ok(response))
}
}
let querier = QuerierWrapper::<Empty>::new(&MyMockQuerier {});
let address = "contract".to_string();
let hash = "code hash".to_string();
let viewer = Some(ViewerInfo {
address: "alice".to_string(),
viewing_key: "key".to_string(),
});
let expected_response = NumTokens { count: 32 };
let response = num_tokens_query(querier, viewer, 256usize, hash, address)?;
assert_eq!(response, expected_response);
Ok(())
}
#[test]
fn test_all_tokens_query() -> StdResult<()> {
struct MyMockQuerier {}
impl Querier for MyMockQuerier {
fn raw_query(&self, request: &[u8]) -> QuerierResult {
let viewer = Some(ViewerInfo {
address: "alice".to_string(),
viewing_key: "key".to_string(),
});
let start_after = Some("NFT1".to_string());
let limit = None;
let mut expected_msg = try_querier_result!(to_binary(&QueryMsg::AllTokens {
viewer,
start_after,
limit,
})
.map_err(|_e| SystemError::Unknown {}));
space_pad(&mut expected_msg.0, 256);
let expected_request: QueryRequest<QueryMsg> =
QueryRequest::Wasm(WasmQuery::Smart {
contract_addr: "contract".to_string(),
code_hash: "code hash".to_string(),
msg: expected_msg,
});
let test_req: &[u8] = &try_querier_result!(
to_vec(&expected_request).map_err(|_e| SystemError::Unknown {})
);
assert_eq!(request, test_req);
let response = TokenListResponse {
token_list: TokenList {
tokens: vec!["NFT2".to_string(), "NFT3".to_string(), "NFT4".to_string()],
},
};
let response =
try_querier_result!(to_binary(&response).map_err(|_e| SystemError::Unknown {}));
SystemResult::Ok(ContractResult::Ok(response))
}
}
let querier = QuerierWrapper::<Empty>::new(&MyMockQuerier {});
let address = "contract".to_string();
let hash = "code hash".to_string();
let viewer = Some(ViewerInfo {
address: "alice".to_string(),
viewing_key: "key".to_string(),
});
let start_after = Some("NFT1".to_string());
let limit = None;
let expected_response = TokenList {
tokens: vec!["NFT2".to_string(), "NFT3".to_string(), "NFT4".to_string()],
};
let response =
all_tokens_query(querier, viewer, start_after, limit, 256usize, hash, address)?;
assert_eq!(response, expected_response);
Ok(())
}
#[test]
fn test_owner_of_query() -> StdResult<()> {
struct MyMockQuerier {}
impl Querier for MyMockQuerier {
fn raw_query(&self, request: &[u8]) -> QuerierResult {
let viewer = Some(ViewerInfo {
address: "alice".to_string(),
viewing_key: "key".to_string(),
});
let token_id = "NFT1".to_string();
let include_expired = Some(true);
let mut expected_msg = try_querier_result!(to_binary(&QueryMsg::OwnerOf {
token_id,
viewer,
include_expired,
})
.map_err(|_e| SystemError::Unknown {}));
space_pad(&mut expected_msg.0, 256);
let expected_request: QueryRequest<QueryMsg> =
QueryRequest::Wasm(WasmQuery::Smart {
contract_addr: "contract".to_string(),
code_hash: "code hash".to_string(),
msg: expected_msg,
});
let test_req: &[u8] = &try_querier_result!(
to_vec(&expected_request).map_err(|_e| SystemError::Unknown {})
);
assert_eq!(request, test_req);
let response = OwnerOfResponse {
owner_of: OwnerOf {
owner: Some("alice".to_string()),
approvals: vec![
Cw721Approval {
spender: "bob".to_string(),
expires: Expiration::Never,
},
Cw721Approval {
spender: "charlie".to_string(),
expires: Expiration::AtHeight(1000000),
},
],
},
};
let response =
try_querier_result!(to_binary(&response).map_err(|_e| SystemError::Unknown {}));
SystemResult::Ok(ContractResult::Ok(response))
}
}
let querier = QuerierWrapper::<Empty>::new(&MyMockQuerier {});
let address = "contract".to_string();
let hash = "code hash".to_string();
let viewer = Some(ViewerInfo {
address: "alice".to_string(),
viewing_key: "key".to_string(),
});
let token_id = "NFT1".to_string();
let include_expired = Some(true);
let expected_response = OwnerOf {
owner: Some("alice".to_string()),
approvals: vec![
Cw721Approval {
spender: "bob".to_string(),
expires: Expiration::Never,
},
Cw721Approval {
spender: "charlie".to_string(),
expires: Expiration::AtHeight(1000000),
},
],
};
let response = owner_of_query(
querier,
token_id,
viewer,
include_expired,
256usize,
hash,
address,
)?;
assert_eq!(response, expected_response);
Ok(())
}
#[test]
fn test_nft_info_query() -> StdResult<()> {
struct MyMockQuerier {}
impl Querier for MyMockQuerier {
fn raw_query(&self, request: &[u8]) -> QuerierResult {
let token_id = "NFT1".to_string();
let mut expected_msg =
try_querier_result!(to_binary(&QueryMsg::NftInfo { token_id })
.map_err(|_e| SystemError::Unknown {}));
space_pad(&mut expected_msg.0, 256);
let expected_request: QueryRequest<QueryMsg> =
QueryRequest::Wasm(WasmQuery::Smart {
contract_addr: "contract".to_string(),
code_hash: "code hash".to_string(),
msg: expected_msg,
});
let test_req: &[u8] = &try_querier_result!(
to_vec(&expected_request).map_err(|_e| SystemError::Unknown {})
);
assert_eq!(request, test_req);
let response = NftInfoResponse {
nft_info: Metadata {
token_uri: Some("token uri2".to_string()),
extension: Some(Extension {
image: Some("public_image2".to_string()),
image_data: None,
external_url: None,
description: None,
name: None,
attributes: Some(vec![Trait {
display_type: None,
trait_type: Some("public trait2".to_string()),
value: "value2".to_string(),
max_value: None,
}]),
background_color: None,
animation_url: None,
youtube_url: None,
media: None,
protected_attributes: None,
}),
},
};
let response =
try_querier_result!(to_binary(&response).map_err(|_e| SystemError::Unknown {}));
SystemResult::Ok(ContractResult::Ok(response))
}
}
let querier = QuerierWrapper::<Empty>::new(&MyMockQuerier {});
let address = "contract".to_string();
let hash = "code hash".to_string();
let token_id = "NFT1".to_string();
let expected_response = Metadata {
token_uri: Some("token uri2".to_string()),
extension: Some(Extension {
image: Some("public_image2".to_string()),
image_data: None,
external_url: None,
description: None,
name: None,
attributes: Some(vec![Trait {
display_type: None,
trait_type: Some("public trait2".to_string()),
value: "value2".to_string(),
max_value: None,
}]),
background_color: None,
animation_url: None,
youtube_url: None,
media: None,
protected_attributes: None,
}),
};
let response = nft_info_query(querier, token_id, 256usize, hash, address)?;
assert_eq!(response, expected_response);
Ok(())
}
#[test]
fn test_all_nft_info_query() -> StdResult<()> {
struct MyMockQuerier {}
impl Querier for MyMockQuerier {
fn raw_query(&self, request: &[u8]) -> QuerierResult {
let viewer = Some(ViewerInfo {
address: "alice".to_string(),
viewing_key: "key".to_string(),
});
let token_id = "NFT1".to_string();
let include_expired = Some(true);
let mut expected_msg = try_querier_result!(to_binary(&QueryMsg::AllNftInfo {
token_id,
viewer,
include_expired,
})
.map_err(|_e| SystemError::Unknown {}));
space_pad(&mut expected_msg.0, 256);
let expected_request: QueryRequest<QueryMsg> =
QueryRequest::Wasm(WasmQuery::Smart {
contract_addr: "contract".to_string(),
code_hash: "code hash".to_string(),
msg: expected_msg,
});
let test_req: &[u8] = &try_querier_result!(
to_vec(&expected_request).map_err(|_e| SystemError::Unknown {})
);
assert_eq!(request, test_req);
let response = AllNftInfoResponse {
all_nft_info: AllNftInfo {
access: OwnerOf {
owner: Some("alice".to_string()),
approvals: vec![
Cw721Approval {
spender: "bob".to_string(),
expires: Expiration::Never,
},
Cw721Approval {
spender: "charlie".to_string(),
expires: Expiration::AtHeight(1000000),
},
],
},
info: Some(Metadata {
token_uri: Some("token uri2".to_string()),
extension: Some(Extension {
image: Some("public_image2".to_string()),
image_data: None,
external_url: None,
description: None,
name: None,
attributes: Some(vec![Trait {
display_type: None,
trait_type: Some("public trait2".to_string()),
value: "value2".to_string(),
max_value: None,
}]),
background_color: None,
animation_url: None,
youtube_url: None,
media: None,
protected_attributes: None,
}),
}),
},
};
let response =
try_querier_result!(to_binary(&response).map_err(|_e| SystemError::Unknown {}));
SystemResult::Ok(ContractResult::Ok(response))
}
}
let querier = QuerierWrapper::<Empty>::new(&MyMockQuerier {});
let address = "contract".to_string();
let hash = "code hash".to_string();
let viewer = Some(ViewerInfo {
address: "alice".to_string(),
viewing_key: "key".to_string(),
});
let token_id = "NFT1".to_string();
let include_expired = Some(true);
let expected_response = AllNftInfo {
access: OwnerOf {
owner: Some("alice".to_string()),
approvals: vec![
Cw721Approval {
spender: "bob".to_string(),
expires: Expiration::Never,
},
Cw721Approval {
spender: "charlie".to_string(),
expires: Expiration::AtHeight(1000000),
},
],
},
info: Some(Metadata {
token_uri: Some("token uri2".to_string()),
extension: Some(Extension {
image: Some("public_image2".to_string()),
image_data: None,
external_url: None,
description: None,
name: None,
attributes: Some(vec![Trait {
display_type: None,
trait_type: Some("public trait2".to_string()),
value: "value2".to_string(),
max_value: None,
}]),
background_color: None,
animation_url: None,
youtube_url: None,
media: None,
protected_attributes: None,
}),
}),
};
let response = all_nft_info_query(
querier,
token_id,
viewer,
include_expired,
256usize,
hash,
address,
)?;
assert_eq!(response, expected_response);
Ok(())
}
#[test]
fn test_private_metadata_query() -> StdResult<()> {
struct MyMockQuerier {}
impl Querier for MyMockQuerier {
fn raw_query(&self, request: &[u8]) -> QuerierResult {
let token_id = "NFT1".to_string();
let viewer = Some(ViewerInfo {
address: "alice".to_string(),
viewing_key: "key".to_string(),
});
let mut expected_msg =
try_querier_result!(to_binary(&QueryMsg::PrivateMetadata { token_id, viewer })
.map_err(|_e| SystemError::Unknown {}));
space_pad(&mut expected_msg.0, 256);
let expected_request: QueryRequest<QueryMsg> =
QueryRequest::Wasm(WasmQuery::Smart {
contract_addr: "contract".to_string(),
code_hash: "code hash".to_string(),
msg: expected_msg,
});
let test_req: &[u8] = &try_querier_result!(
to_vec(&expected_request).map_err(|_e| SystemError::Unknown {})
);
assert_eq!(request, test_req);
let response = PrivateMetadataResponse {
private_metadata: Metadata {
token_uri: Some("token uri2".to_string()),
extension: Some(Extension {
image: Some("private_image2".to_string()),
image_data: None,
external_url: None,
description: None,
name: None,
attributes: Some(vec![Trait {
display_type: None,
trait_type: Some("private trait2".to_string()),
value: "value2".to_string(),
max_value: None,
}]),
background_color: None,
animation_url: None,
youtube_url: None,
media: None,
protected_attributes: None,
}),
},
};
let response =
try_querier_result!(to_binary(&response).map_err(|_e| SystemError::Unknown {}));
SystemResult::Ok(ContractResult::Ok(response))
}
}
let querier = QuerierWrapper::<Empty>::new(&MyMockQuerier {});
let address = "contract".to_string();
let hash = "code hash".to_string();
let token_id = "NFT1".to_string();
let viewer = Some(ViewerInfo {
address: "alice".to_string(),
viewing_key: "key".to_string(),
});
let expected_response = Metadata {
token_uri: Some("token uri2".to_string()),
extension: Some(Extension {
image: Some("private_image2".to_string()),
image_data: None,
external_url: None,
description: None,
name: None,
attributes: Some(vec![Trait {
display_type: None,
trait_type: Some("private trait2".to_string()),
value: "value2".to_string(),
max_value: None,
}]),
background_color: None,
animation_url: None,
youtube_url: None,
media: None,
protected_attributes: None,
}),
};
let response = private_metadata_query(querier, token_id, viewer, 256usize, hash, address)?;
assert_eq!(response, expected_response);
Ok(())
}
#[test]
fn test_nft_dossier_query() -> StdResult<()> {
struct MyMockQuerier {}
impl Querier for MyMockQuerier {
fn raw_query(&self, request: &[u8]) -> QuerierResult {
let viewer = Some(ViewerInfo {
address: "alice".to_string(),
viewing_key: "key".to_string(),
});
let token_id = "NFT1".to_string();
let include_expired = Some(true);
let mut expected_msg = try_querier_result!(to_binary(&QueryMsg::NftDossier {
token_id,
viewer,
include_expired,
})
.map_err(|_e| SystemError::Unknown {}));
space_pad(&mut expected_msg.0, 256);
let expected_request: QueryRequest<QueryMsg> =
QueryRequest::Wasm(WasmQuery::Smart {
contract_addr: "contract".to_string(),
code_hash: "code hash".to_string(),
msg: expected_msg,
});
let test_req: &[u8] = &try_querier_result!(
to_vec(&expected_request).map_err(|_e| SystemError::Unknown {})
);
assert_eq!(request, test_req);
let response = NftDossierResponse {
nft_dossier: NftDossier {
owner: Some("alice".to_string()),
public_metadata: Some(Metadata {
token_uri: Some("token uri2".to_string()),
extension: Some(Extension {
image: Some("public_image2".to_string()),
image_data: None,
external_url: None,
description: None,
name: None,
attributes: Some(vec![Trait {
display_type: None,
trait_type: Some("public trait2".to_string()),
value: "value2".to_string(),
max_value: None,
}]),
background_color: None,
animation_url: None,
youtube_url: None,
media: None,
protected_attributes: None,
}),
}),
private_metadata: None,
display_private_metadata_error: Some("pretend it is sealed".to_string()),
owner_is_public: true,
public_ownership_expiration: Some(Expiration::Never),
private_metadata_is_public: false,
private_metadata_is_public_expiration: None,
token_approvals: Some(vec![
Snip721Approval {
address: "bob".to_string(),
view_owner_expiration: None,
view_private_metadata_expiration: Some(Expiration::AtTime(1000000)),
transfer_expiration: Some(Expiration::AtHeight(10000)),
},
Snip721Approval {
address: "charlie".to_string(),
view_owner_expiration: Some(Expiration::Never),
view_private_metadata_expiration: None,
transfer_expiration: None,
},
]),
inventory_approvals: None,
},
};
let response =
try_querier_result!(to_binary(&response).map_err(|_e| SystemError::Unknown {}));
SystemResult::Ok(ContractResult::Ok(response))
}
}
let querier = QuerierWrapper::<Empty>::new(&MyMockQuerier {});
let address = "contract".to_string();
let hash = "code hash".to_string();
let viewer = Some(ViewerInfo {
address: "alice".to_string(),
viewing_key: "key".to_string(),
});
let token_id = "NFT1".to_string();
let include_expired = Some(true);
let expected_response = NftDossier {
owner: Some("alice".to_string()),
public_metadata: Some(Metadata {
token_uri: Some("token uri2".to_string()),
extension: Some(Extension {
image: Some("public_image2".to_string()),
image_data: None,
external_url: None,
description: None,
name: None,
attributes: Some(vec![Trait {
display_type: None,
trait_type: Some("public trait2".to_string()),
value: "value2".to_string(),
max_value: None,
}]),
background_color: None,
animation_url: None,
youtube_url: None,
media: None,
protected_attributes: None,
}),
}),
private_metadata: None,
display_private_metadata_error: Some("pretend it is sealed".to_string()),
owner_is_public: true,
public_ownership_expiration: Some(Expiration::Never),
private_metadata_is_public: false,
private_metadata_is_public_expiration: None,
token_approvals: Some(vec![
Snip721Approval {
address: "bob".to_string(),
view_owner_expiration: None,
view_private_metadata_expiration: Some(Expiration::AtTime(1000000)),
transfer_expiration: Some(Expiration::AtHeight(10000)),
},
Snip721Approval {
address: "charlie".to_string(),
view_owner_expiration: Some(Expiration::Never),
view_private_metadata_expiration: None,
transfer_expiration: None,
},
]),
inventory_approvals: None,
};
let response = nft_dossier_query(
querier,
token_id,
viewer,
include_expired,
256usize,
hash,
address,
)?;
assert_eq!(response, expected_response);
Ok(())
}
#[test]
fn test_token_approvals_query() -> StdResult<()> {
struct MyMockQuerier {}
impl Querier for MyMockQuerier {
fn raw_query(&self, request: &[u8]) -> QuerierResult {
let viewing_key = "key".to_string();
let token_id = "NFT1".to_string();
let include_expired = None;
let mut expected_msg = try_querier_result!(to_binary(&QueryMsg::TokenApprovals {
token_id,
viewing_key,
include_expired,
})
.map_err(|_e| SystemError::Unknown {}));
space_pad(&mut expected_msg.0, 256);
let expected_request: QueryRequest<QueryMsg> =
QueryRequest::Wasm(WasmQuery::Smart {
contract_addr: "contract".to_string(),
code_hash: "code hash".to_string(),
msg: expected_msg,
});
let test_req: &[u8] = &try_querier_result!(
to_vec(&expected_request).map_err(|_e| SystemError::Unknown {})
);
assert_eq!(request, test_req);
let response = TokenApprovalsResponse {
token_approvals: TokenApprovals {
owner_is_public: true,
public_ownership_expiration: Some(Expiration::Never),
private_metadata_is_public: false,
private_metadata_is_public_expiration: None,
token_approvals: vec![
Snip721Approval {
address: "bob".to_string(),
view_owner_expiration: None,
view_private_metadata_expiration: Some(Expiration::AtTime(1000000)),
transfer_expiration: Some(Expiration::AtHeight(10000)),
},
Snip721Approval {
address: "charlie".to_string(),
view_owner_expiration: Some(Expiration::Never),
view_private_metadata_expiration: None,
transfer_expiration: None,
},
],
},
};
let response =
try_querier_result!(to_binary(&response).map_err(|_e| SystemError::Unknown {}));
SystemResult::Ok(ContractResult::Ok(response))
}
}
let querier = QuerierWrapper::<Empty>::new(&MyMockQuerier {});
let address = "contract".to_string();
let hash = "code hash".to_string();
let viewing_key = "key".to_string();
let token_id = "NFT1".to_string();
let include_expired = None;
let expected_response = TokenApprovals {
owner_is_public: true,
public_ownership_expiration: Some(Expiration::Never),
private_metadata_is_public: false,
private_metadata_is_public_expiration: None,
token_approvals: vec![
Snip721Approval {
address: "bob".to_string(),
view_owner_expiration: None,
view_private_metadata_expiration: Some(Expiration::AtTime(1000000)),
transfer_expiration: Some(Expiration::AtHeight(10000)),
},
Snip721Approval {
address: "charlie".to_string(),
view_owner_expiration: Some(Expiration::Never),
view_private_metadata_expiration: None,
transfer_expiration: None,
},
],
};
let response = token_approvals_query(
querier,
token_id,
viewing_key,
include_expired,
256usize,
hash,
address,
)?;
assert_eq!(response, expected_response);
Ok(())
}
#[test]
fn test_approved_for_all_query() -> StdResult<()> {
struct MyMockQuerier {}
impl Querier for MyMockQuerier {
fn raw_query(&self, request: &[u8]) -> QuerierResult {
let viewing_key = Some("key".to_string());
let owner = "alice".to_string();
let include_expired = None;
let mut expected_msg = try_querier_result!(to_binary(&QueryMsg::ApprovedForAll {
owner,
viewing_key,
include_expired,
})
.map_err(|_e| SystemError::Unknown {}));
space_pad(&mut expected_msg.0, 256);
let expected_request: QueryRequest<QueryMsg> =
QueryRequest::Wasm(WasmQuery::Smart {
contract_addr: "contract".to_string(),
code_hash: "code hash".to_string(),
msg: expected_msg,
});
let test_req: &[u8] = &try_querier_result!(
to_vec(&expected_request).map_err(|_e| SystemError::Unknown {})
);
assert_eq!(request, test_req);
let response = ApprovedForAllResponse {
approved_for_all: ApprovedForAll {
operators: vec![
Cw721Approval {
spender: "bob".to_string(),
expires: Expiration::Never,
},
Cw721Approval {
spender: "charlie".to_string(),
expires: Expiration::AtHeight(1000000),
},
],
},
};
let response =
try_querier_result!(to_binary(&response).map_err(|_e| SystemError::Unknown {}));
SystemResult::Ok(ContractResult::Ok(response))
}
}
let querier = QuerierWrapper::<Empty>::new(&MyMockQuerier {});
let address = "contract".to_string();
let hash = "code hash".to_string();
let viewing_key = Some("key".to_string());
let owner = "alice".to_string();
let include_expired = None;
let expected_response = ApprovedForAll {
operators: vec![
Cw721Approval {
spender: "bob".to_string(),
expires: Expiration::Never,
},
Cw721Approval {
spender: "charlie".to_string(),
expires: Expiration::AtHeight(1000000),
},
],
};
let response = approved_for_all_query(
querier,
owner,
viewing_key,
include_expired,
256usize,
hash,
address,
)?;
assert_eq!(response, expected_response);
Ok(())
}
#[test]
fn test_inventory_approvals_query() -> StdResult<()> {
struct MyMockQuerier {}
impl Querier for MyMockQuerier {
fn raw_query(&self, request: &[u8]) -> QuerierResult {
let viewing_key = "key".to_string();
let address = "alice".to_string();
let include_expired = None;
let mut expected_msg =
try_querier_result!(to_binary(&QueryMsg::InventoryApprovals {
address,
viewing_key,
include_expired,
})
.map_err(|_e| SystemError::Unknown {}));
space_pad(&mut expected_msg.0, 256);
let expected_request: QueryRequest<QueryMsg> =
QueryRequest::Wasm(WasmQuery::Smart {
contract_addr: "contract".to_string(),
code_hash: "code hash".to_string(),
msg: expected_msg,
});
let test_req: &[u8] = &try_querier_result!(
to_vec(&expected_request).map_err(|_e| SystemError::Unknown {})
);
assert_eq!(request, test_req);
let response = InventoryApprovalsResponse {
inventory_approvals: InventoryApprovals {
owner_is_public: true,
public_ownership_expiration: Some(Expiration::Never),
private_metadata_is_public: false,
private_metadata_is_public_expiration: None,
inventory_approvals: vec![
Snip721Approval {
address: "bob".to_string(),
view_owner_expiration: None,
view_private_metadata_expiration: Some(Expiration::AtTime(1000000)),
transfer_expiration: Some(Expiration::AtHeight(10000)),
},
Snip721Approval {
address: "charlie".to_string(),
view_owner_expiration: Some(Expiration::Never),
view_private_metadata_expiration: None,
transfer_expiration: None,
},
],
},
};
let response =
try_querier_result!(to_binary(&response).map_err(|_e| SystemError::Unknown {}));
SystemResult::Ok(ContractResult::Ok(response))
}
}
let querier = QuerierWrapper::<Empty>::new(&MyMockQuerier {});
let contract_address = "contract".to_string();
let hash = "code hash".to_string();
let viewing_key = "key".to_string();
let address = "alice".to_string();
let include_expired = None;
let expected_response = InventoryApprovals {
owner_is_public: true,
public_ownership_expiration: Some(Expiration::Never),
private_metadata_is_public: false,
private_metadata_is_public_expiration: None,
inventory_approvals: vec![
Snip721Approval {
address: "bob".to_string(),
view_owner_expiration: None,
view_private_metadata_expiration: Some(Expiration::AtTime(1000000)),
transfer_expiration: Some(Expiration::AtHeight(10000)),
},
Snip721Approval {
address: "charlie".to_string(),
view_owner_expiration: Some(Expiration::Never),
view_private_metadata_expiration: None,
transfer_expiration: None,
},
],
};
let response = inventory_approvals_query(
querier,
address,
viewing_key,
include_expired,
256usize,
hash,
contract_address,
)?;
assert_eq!(response, expected_response);
Ok(())
}
#[test]
fn test_tokens_query() -> StdResult<()> {
struct MyMockQuerier {}
impl Querier for MyMockQuerier {
fn raw_query(&self, request: &[u8]) -> QuerierResult {
let owner = "alice".to_string();
let viewer = Some("bob".to_string());
let viewing_key = Some("key".to_string());
let start_after = Some("NFT1".to_string());
let limit = Some(33);
let mut expected_msg = try_querier_result!(to_binary(&QueryMsg::Tokens {
owner,
viewer,
viewing_key,
start_after,
limit,
})
.map_err(|_e| SystemError::Unknown {}));
space_pad(&mut expected_msg.0, 256);
let expected_request: QueryRequest<QueryMsg> =
QueryRequest::Wasm(WasmQuery::Smart {
contract_addr: "contract".to_string(),
code_hash: "code hash".to_string(),
msg: expected_msg,
});
let test_req: &[u8] = &try_querier_result!(
to_vec(&expected_request).map_err(|_e| SystemError::Unknown {})
);
assert_eq!(request, test_req);
let response = TokenListResponse {
token_list: TokenList {
tokens: vec!["NFT2".to_string(), "NFT3".to_string(), "NFT4".to_string()],
},
};
let response =
try_querier_result!(to_binary(&response).map_err(|_e| SystemError::Unknown {}));
SystemResult::Ok(ContractResult::Ok(response))
}
}
let querier = QuerierWrapper::<Empty>::new(&MyMockQuerier {});
let address = "contract".to_string();
let hash = "code hash".to_string();
let owner = "alice".to_string();
let viewer = Some("bob".to_string());
let viewing_key = Some("key".to_string());
let start_after = Some("NFT1".to_string());
let limit = Some(33);
let expected_response = TokenList {
tokens: vec!["NFT2".to_string(), "NFT3".to_string(), "NFT4".to_string()],
};
let response = tokens_query(
querier,
owner,
viewer,
viewing_key,
start_after,
limit,
256usize,
hash,
address,
)?;
assert_eq!(response, expected_response);
Ok(())
}
#[test]
fn test_transaction_history_query() -> StdResult<()> {
struct MyMockQuerier {}
impl Querier for MyMockQuerier {
fn raw_query(&self, request: &[u8]) -> QuerierResult {
let address = "alice".to_string();
let viewing_key = "key".to_string();
let page = Some(2);
let page_size = None;
let mut expected_msg =
try_querier_result!(to_binary(&QueryMsg::TransactionHistory {
address,
viewing_key,
page,
page_size,
})
.map_err(|_e| SystemError::Unknown {}));
space_pad(&mut expected_msg.0, 256);
let expected_request: QueryRequest<QueryMsg> =
QueryRequest::Wasm(WasmQuery::Smart {
contract_addr: "contract".to_string(),
code_hash: "code hash".to_string(),
msg: expected_msg,
});
let test_req: &[u8] = &try_querier_result!(
to_vec(&expected_request).map_err(|_e| SystemError::Unknown {})
);
assert_eq!(request, test_req);
let response = TransactionHistoryResponse {
transaction_history: TransactionHistory {
total: 3,
txs: vec![
Tx {
tx_id: 103,
block_height: 2000000,
block_time: 2000000000,
token_id: "NFT3".to_string(),
action: TxAction::Burn {
owner: "alice".to_string(),
burner: Some("bob".to_string()),
},
memo: None,
},
Tx {
tx_id: 99,
block_height: 1900000,
block_time: 1900000000,
token_id: "NFT2".to_string(),
action: TxAction::Transfer {
from: "alice".to_string(),
sender: None,
recipient: "bob".to_string(),
},
memo: Some("xfer memo".to_string()),
},
Tx {
tx_id: 93,
block_height: 1800000,
block_time: 1800000000,
token_id: "NFT1".to_string(),
action: TxAction::Mint {
minter: "admin".to_string(),
recipient: "alice".to_string(),
},
memo: None,
},
],
},
};
let response =
try_querier_result!(to_binary(&response).map_err(|_e| SystemError::Unknown {}));
SystemResult::Ok(ContractResult::Ok(response))
}
}
let querier = QuerierWrapper::<Empty>::new(&MyMockQuerier {});
let contract_address = "contract".to_string();
let hash = "code hash".to_string();
let address = "alice".to_string();
let viewing_key = "key".to_string();
let page = Some(2);
let page_size = None;
let expected_response = TransactionHistory {
total: 3,
txs: vec![
Tx {
tx_id: 103,
block_height: 2000000,
block_time: 2000000000,
token_id: "NFT3".to_string(),
action: TxAction::Burn {
owner: "alice".to_string(),
burner: Some("bob".to_string()),
},
memo: None,
},
Tx {
tx_id: 99,
block_height: 1900000,
block_time: 1900000000,
token_id: "NFT2".to_string(),
action: TxAction::Transfer {
from: "alice".to_string(),
sender: None,
recipient: "bob".to_string(),
},
memo: Some("xfer memo".to_string()),
},
Tx {
tx_id: 93,
block_height: 1800000,
block_time: 1800000000,
token_id: "NFT1".to_string(),
action: TxAction::Mint {
minter: "admin".to_string(),
recipient: "alice".to_string(),
},
memo: None,
},
],
};
let response = transaction_history_query(
querier,
address,
viewing_key,
page,
page_size,
256usize,
hash,
contract_address,
)?;
assert_eq!(response, expected_response);
Ok(())
}
#[test]
fn test_minters_query() -> StdResult<()> {
struct MyMockQuerier {}
impl Querier for MyMockQuerier {
fn raw_query(&self, request: &[u8]) -> QuerierResult {
let mut expected_msg = try_querier_result!(
to_binary(&QueryMsg::Minters {}).map_err(|_e| SystemError::Unknown {})
);
space_pad(&mut expected_msg.0, 256);
let expected_request: QueryRequest<QueryMsg> =
QueryRequest::Wasm(WasmQuery::Smart {
contract_addr: "contract".to_string(),
code_hash: "code hash".to_string(),
msg: expected_msg,
});
let test_req: &[u8] = &try_querier_result!(
to_vec(&expected_request).map_err(|_e| SystemError::Unknown {})
);
assert_eq!(request, test_req);
let response = MintersResponse {
minters: Minters {
minters: vec![
"alice".to_string(),
"bob".to_string(),
"charlie".to_string(),
],
},
};
let response =
try_querier_result!(to_binary(&response).map_err(|_e| SystemError::Unknown {}));
SystemResult::Ok(ContractResult::Ok(response))
}
}
let querier = QuerierWrapper::<Empty>::new(&MyMockQuerier {});
let address = "contract".to_string();
let hash = "code hash".to_string();
let expected_response = Minters {
minters: vec![
"alice".to_string(),
"bob".to_string(),
"charlie".to_string(),
],
};
let response = minters_query(querier, 256usize, hash, address)?;
assert_eq!(response, expected_response);
Ok(())
}
#[test]
fn test_is_unwrapped_query() -> StdResult<()> {
struct MyMockQuerier {}
impl Querier for MyMockQuerier {
fn raw_query(&self, request: &[u8]) -> QuerierResult {
let token_id = "NFT1".to_string();
let mut expected_msg =
try_querier_result!(to_binary(&QueryMsg::IsUnwrapped { token_id })
.map_err(|_e| SystemError::Unknown {}));
space_pad(&mut expected_msg.0, 256);
let expected_request: QueryRequest<QueryMsg> =
QueryRequest::Wasm(WasmQuery::Smart {
contract_addr: "contract".to_string(),
code_hash: "code hash".to_string(),
msg: expected_msg,
});
let test_req: &[u8] = &try_querier_result!(
to_vec(&expected_request).map_err(|_e| SystemError::Unknown {})
);
assert_eq!(request, test_req);
let response = IsUnwrappedResponse {
is_unwrapped: IsUnwrapped {
token_is_unwrapped: false,
},
};
let response =
try_querier_result!(to_binary(&response).map_err(|_e| SystemError::Unknown {}));
SystemResult::Ok(ContractResult::Ok(response))
}
}
let querier = QuerierWrapper::<Empty>::new(&MyMockQuerier {});
let address = "contract".to_string();
let hash = "code hash".to_string();
let token_id = "NFT1".to_string();
let expected_response = IsUnwrapped {
token_is_unwrapped: false,
};
let response = is_unwrapped_query(querier, token_id, 256usize, hash, address)?;
assert_eq!(response, expected_response);
Ok(())
}
#[test]
fn test_verify_transfer_approval_query() -> StdResult<()> {
struct MyMockQuerier {}
impl Querier for MyMockQuerier {
fn raw_query(&self, request: &[u8]) -> QuerierResult {
let token_ids = vec!["NFT1".to_string(), "NFT2".to_string(), "NFT3".to_string()];
let address = "alice".to_string();
let viewing_key = "key".to_string();
let mut expected_msg =
try_querier_result!(to_binary(&QueryMsg::VerifyTransferApproval {
token_ids,
address,
viewing_key,
})
.map_err(|_e| SystemError::Unknown {}));
space_pad(&mut expected_msg.0, 256);
let expected_request: QueryRequest<QueryMsg> =
QueryRequest::Wasm(WasmQuery::Smart {
contract_addr: "contract".to_string(),
code_hash: "code hash".to_string(),
msg: expected_msg,
});
let test_req: &[u8] = &try_querier_result!(
to_vec(&expected_request).map_err(|_e| SystemError::Unknown {})
);
assert_eq!(request, test_req);
let response = VerifyTransferApprovalResponse {
verify_transfer_approval: VerifyTransferApproval {
approved_for_all: false,
first_unapproved_token: Some("NFT3".to_string()),
},
};
let response =
try_querier_result!(to_binary(&response).map_err(|_e| SystemError::Unknown {}));
SystemResult::Ok(ContractResult::Ok(response))
}
}
let querier = QuerierWrapper::<Empty>::new(&MyMockQuerier {});
let contract_address = "contract".to_string();
let hash = "code hash".to_string();
let token_ids = vec!["NFT1".to_string(), "NFT2".to_string(), "NFT3".to_string()];
let address = "alice".to_string();
let viewing_key = "key".to_string();
let expected_response = VerifyTransferApproval {
approved_for_all: false,
first_unapproved_token: Some("NFT3".to_string()),
};
let response = verify_transfer_approval_query(
querier,
token_ids,
address,
viewing_key,
256usize,
hash,
contract_address,
)?;
assert_eq!(response, expected_response);
Ok(())
}
}