use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use cosmwasm_std::{to_binary, Binary, Coin, CosmosMsg, StdResult, Uint128, WasmMsg};
use crate::expiration::Expiration;
use crate::metadata::Metadata;
use secret_toolkit_utils::space_pad;
#[derive(Serialize, Deserialize, JsonSchema, Clone, PartialEq, Eq, Debug)]
#[serde(rename_all = "snake_case")]
pub enum AccessLevel {
ApproveToken,
All,
RevokeToken,
None,
}
#[derive(Serialize, Deserialize, JsonSchema, Clone, PartialEq, Eq, Debug)]
pub struct Mint {
pub token_id: Option<String>,
pub owner: Option<String>,
pub public_metadata: Option<Metadata>,
pub private_metadata: Option<Metadata>,
pub memo: Option<String>,
}
#[derive(Serialize, Deserialize, JsonSchema, Clone, PartialEq, Eq, Debug)]
pub struct Burn {
pub token_ids: Vec<String>,
pub memo: Option<String>,
}
#[derive(Serialize, Deserialize, JsonSchema, Clone, PartialEq, Eq, Debug)]
pub struct Transfer {
pub recipient: String,
pub token_ids: Vec<String>,
pub memo: Option<String>,
}
#[derive(Serialize, Deserialize, JsonSchema, Clone, PartialEq, Eq, Debug)]
pub struct Send {
pub contract: String,
pub token_ids: Vec<String>,
pub msg: Option<Binary>,
pub memo: Option<String>,
}
#[derive(Serialize, Clone, Debug, Eq, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum HandleMsg {
TransferNft {
recipient: String,
token_id: String,
memo: Option<String>,
padding: Option<String>,
},
SendNft {
contract: String,
token_id: String,
msg: Option<Binary>,
memo: Option<String>,
padding: Option<String>,
},
Approve {
spender: String,
token_id: String,
expires: Option<Expiration>,
padding: Option<String>,
},
Revoke {
spender: String,
token_id: String,
padding: Option<String>,
},
ApproveAll {
operator: String,
expires: Option<Expiration>,
padding: Option<String>,
},
RevokeAll {
operator: String,
padding: Option<String>,
},
SetWhitelistedApproval {
address: String,
token_id: Option<String>,
view_owner: Option<AccessLevel>,
view_private_metadata: Option<AccessLevel>,
transfer: Option<AccessLevel>,
expires: Option<Expiration>,
padding: Option<String>,
},
RegisterReceiveNft {
code_hash: String,
also_implements_batch_receive_nft: Option<bool>,
padding: Option<String>,
},
SetViewingKey {
key: String,
padding: Option<String>,
},
MintNft {
token_id: Option<String>,
owner: Option<String>,
public_metadata: Option<Metadata>,
private_metadata: Option<Metadata>,
memo: Option<String>,
padding: Option<String>,
},
AddMinters {
minters: Vec<String>,
padding: Option<String>,
},
RemoveMinters {
minters: Vec<String>,
padding: Option<String>,
},
SetMinters {
minters: Vec<String>,
padding: Option<String>,
},
SetMetadata {
token_id: String,
public_metadata: Option<Metadata>,
private_metadata: Option<Metadata>,
padding: Option<String>,
},
BatchMintNft {
mints: Vec<Mint>,
padding: Option<String>,
},
BatchTransferNft {
transfers: Vec<Transfer>,
padding: Option<String>,
},
BatchSendNft {
sends: Vec<Send>,
padding: Option<String>,
},
BurnNft {
token_id: String,
memo: Option<String>,
padding: Option<String>,
},
BatchBurnNft {
burns: Vec<Burn>,
padding: Option<String>,
},
SetGlobalApproval {
token_id: Option<String>,
view_owner: Option<AccessLevel>,
view_private_metadata: Option<AccessLevel>,
expires: Option<Expiration>,
padding: Option<String>,
},
Reveal {
token_id: String,
padding: Option<String>,
},
}
impl HandleMsg {
pub fn to_cosmos_msg(
&self,
mut block_size: usize,
code_hash: String,
contract_addr: String,
send_amount: Option<Uint128>,
) -> StdResult<CosmosMsg> {
if block_size == 0 {
block_size = 1;
}
let mut msg = to_binary(self)?;
space_pad(&mut msg.0, block_size);
let mut funds = Vec::new();
if let Some(amount) = send_amount {
funds.push(Coin {
amount,
denom: String::from("uscrt"),
});
}
let execute = WasmMsg::Execute {
msg,
contract_addr,
code_hash,
funds,
};
Ok(execute.into())
}
}
pub fn transfer_nft_msg(
recipient: String,
token_id: String,
memo: Option<String>,
padding: Option<String>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<CosmosMsg> {
HandleMsg::TransferNft {
recipient,
token_id,
memo,
padding,
}
.to_cosmos_msg(block_size, code_hash, contract_addr, None)
}
#[allow(clippy::too_many_arguments)]
pub fn send_nft_msg(
contract: String,
token_id: String,
msg: Option<Binary>,
memo: Option<String>,
padding: Option<String>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<CosmosMsg> {
HandleMsg::SendNft {
contract,
token_id,
msg,
memo,
padding,
}
.to_cosmos_msg(block_size, code_hash, contract_addr, None)
}
pub fn approve_msg(
spender: String,
token_id: String,
expires: Option<Expiration>,
padding: Option<String>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<CosmosMsg> {
HandleMsg::Approve {
spender,
token_id,
expires,
padding,
}
.to_cosmos_msg(block_size, code_hash, contract_addr, None)
}
pub fn revoke_msg(
spender: String,
token_id: String,
padding: Option<String>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<CosmosMsg> {
HandleMsg::Revoke {
spender,
token_id,
padding,
}
.to_cosmos_msg(block_size, code_hash, contract_addr, None)
}
pub fn approve_all_msg(
operator: String,
expires: Option<Expiration>,
padding: Option<String>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<CosmosMsg> {
HandleMsg::ApproveAll {
operator,
expires,
padding,
}
.to_cosmos_msg(block_size, code_hash, contract_addr, None)
}
pub fn revoke_all_msg(
operator: String,
padding: Option<String>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<CosmosMsg> {
HandleMsg::RevokeAll { operator, padding }.to_cosmos_msg(
block_size,
code_hash,
contract_addr,
None,
)
}
#[allow(clippy::too_many_arguments)]
pub fn set_whitelisted_approval_msg(
address: String,
token_id: Option<String>,
view_owner: Option<AccessLevel>,
view_private_metadata: Option<AccessLevel>,
transfer: Option<AccessLevel>,
expires: Option<Expiration>,
padding: Option<String>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<CosmosMsg> {
HandleMsg::SetWhitelistedApproval {
address,
token_id,
view_owner,
view_private_metadata,
transfer,
expires,
padding,
}
.to_cosmos_msg(block_size, code_hash, contract_addr, None)
}
pub fn register_receive_nft_msg(
your_contracts_code_hash: String,
also_implements_batch_receive_nft: Option<bool>,
padding: Option<String>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<CosmosMsg> {
HandleMsg::RegisterReceiveNft {
code_hash: your_contracts_code_hash,
also_implements_batch_receive_nft,
padding,
}
.to_cosmos_msg(block_size, code_hash, contract_addr, None)
}
pub fn set_viewing_key_msg(
key: String,
padding: Option<String>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<CosmosMsg> {
HandleMsg::SetViewingKey { key, padding }.to_cosmos_msg(
block_size,
code_hash,
contract_addr,
None,
)
}
#[allow(clippy::too_many_arguments)]
pub fn mint_nft_msg(
token_id: Option<String>,
owner: Option<String>,
public_metadata: Option<Metadata>,
private_metadata: Option<Metadata>,
memo: Option<String>,
padding: Option<String>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<CosmosMsg> {
HandleMsg::MintNft {
token_id,
owner,
public_metadata,
private_metadata,
memo,
padding,
}
.to_cosmos_msg(block_size, code_hash, contract_addr, None)
}
pub fn add_minters_msg(
minters: Vec<String>,
padding: Option<String>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<CosmosMsg> {
HandleMsg::AddMinters { minters, padding }.to_cosmos_msg(
block_size,
code_hash,
contract_addr,
None,
)
}
pub fn remove_minters_msg(
minters: Vec<String>,
padding: Option<String>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<CosmosMsg> {
HandleMsg::RemoveMinters { minters, padding }.to_cosmos_msg(
block_size,
code_hash,
contract_addr,
None,
)
}
pub fn set_minters_msg(
minters: Vec<String>,
padding: Option<String>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<CosmosMsg> {
HandleMsg::SetMinters { minters, padding }.to_cosmos_msg(
block_size,
code_hash,
contract_addr,
None,
)
}
pub fn set_metadata_msg(
token_id: String,
public_metadata: Option<Metadata>,
private_metadata: Option<Metadata>,
padding: Option<String>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<CosmosMsg> {
HandleMsg::SetMetadata {
token_id,
public_metadata,
private_metadata,
padding,
}
.to_cosmos_msg(block_size, code_hash, contract_addr, None)
}
pub fn batch_mint_nft_msg(
mints: Vec<Mint>,
padding: Option<String>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<CosmosMsg> {
HandleMsg::BatchMintNft { mints, padding }.to_cosmos_msg(
block_size,
code_hash,
contract_addr,
None,
)
}
pub fn batch_transfer_nft_msg(
transfers: Vec<Transfer>,
padding: Option<String>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<CosmosMsg> {
HandleMsg::BatchTransferNft { transfers, padding }.to_cosmos_msg(
block_size,
code_hash,
contract_addr,
None,
)
}
pub fn batch_send_nft_msg(
sends: Vec<Send>,
padding: Option<String>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<CosmosMsg> {
HandleMsg::BatchSendNft { sends, padding }.to_cosmos_msg(
block_size,
code_hash,
contract_addr,
None,
)
}
pub fn burn_nft_msg(
token_id: String,
memo: Option<String>,
padding: Option<String>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<CosmosMsg> {
HandleMsg::BurnNft {
token_id,
memo,
padding,
}
.to_cosmos_msg(block_size, code_hash, contract_addr, None)
}
pub fn batch_burn_nft_msg(
burns: Vec<Burn>,
padding: Option<String>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<CosmosMsg> {
HandleMsg::BatchBurnNft { burns, padding }.to_cosmos_msg(
block_size,
code_hash,
contract_addr,
None,
)
}
#[allow(clippy::too_many_arguments)]
pub fn set_global_approval_msg(
token_id: Option<String>,
view_owner: Option<AccessLevel>,
view_private_metadata: Option<AccessLevel>,
expires: Option<Expiration>,
padding: Option<String>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<CosmosMsg> {
HandleMsg::SetGlobalApproval {
token_id,
view_owner,
view_private_metadata,
expires,
padding,
}
.to_cosmos_msg(block_size, code_hash, contract_addr, None)
}
pub fn reveal_msg(
token_id: String,
padding: Option<String>,
block_size: usize,
code_hash: String,
contract_addr: String,
) -> StdResult<CosmosMsg> {
HandleMsg::Reveal { token_id, padding }.to_cosmos_msg(
block_size,
code_hash,
contract_addr,
None,
)
}
#[cfg(test)]
mod tests {
use crate::{Extension, Trait};
use super::*;
#[test]
fn test_transfer_nft_msg() -> StdResult<()> {
let recipient = "alice".to_string();
let token_id = "NFT1".to_string();
let memo = Some("memo".to_string());
let padding = Some("padding".to_string());
let code_hash = "code hash".to_string();
let contract_addr = "contract".to_string();
let test_msg = transfer_nft_msg(
recipient.clone(),
token_id.clone(),
memo.clone(),
padding.clone(),
256usize,
code_hash.clone(),
contract_addr.clone(),
)?;
let mut msg = to_binary(&HandleMsg::TransferNft {
recipient,
token_id,
memo,
padding,
})?;
let msg = space_pad(&mut msg.0, 256usize);
let expected_msg = CosmosMsg::Wasm(WasmMsg::Execute {
msg: Binary(msg.to_vec()),
contract_addr,
code_hash,
funds: vec![],
});
assert_eq!(test_msg, expected_msg);
Ok(())
}
#[test]
fn test_send_nft_msg() -> StdResult<()> {
let contract = "alice".to_string();
let recipient = "bob".to_string();
let token_id = "NFT1".to_string();
let memo = Some("memo".to_string());
let padding = Some("padding".to_string());
let code_hash = "code hash".to_string();
let contract_addr = "contract".to_string();
let send_msg = Some(to_binary(&HandleMsg::TransferNft {
recipient,
token_id: token_id.clone(),
memo: memo.clone(),
padding: padding.clone(),
})?);
let test_msg = send_nft_msg(
contract.clone(),
token_id.clone(),
send_msg.clone(),
memo.clone(),
padding.clone(),
256usize,
code_hash.clone(),
contract_addr.clone(),
)?;
let mut msg = to_binary(&HandleMsg::SendNft {
contract,
token_id,
msg: send_msg,
memo,
padding,
})?;
let msg = space_pad(&mut msg.0, 256usize);
let expected_msg = CosmosMsg::Wasm(WasmMsg::Execute {
msg: Binary(msg.to_vec()),
contract_addr,
code_hash,
funds: vec![],
});
assert_eq!(test_msg, expected_msg);
Ok(())
}
#[test]
fn test_approve_msg() -> StdResult<()> {
let spender = "alice".to_string();
let token_id = "NFT1".to_string();
let expires = Some(Expiration::AtHeight(1000000));
let padding = Some("padding".to_string());
let code_hash = "code hash".to_string();
let contract_addr = "contract".to_string();
let test_msg = approve_msg(
spender.clone(),
token_id.clone(),
expires,
padding.clone(),
256usize,
code_hash.clone(),
contract_addr.clone(),
)?;
let mut msg = to_binary(&HandleMsg::Approve {
spender,
token_id,
expires,
padding,
})?;
let msg = space_pad(&mut msg.0, 256usize);
let expected_msg = CosmosMsg::Wasm(WasmMsg::Execute {
msg: Binary(msg.to_vec()),
contract_addr,
code_hash,
funds: vec![],
});
assert_eq!(test_msg, expected_msg);
Ok(())
}
#[test]
fn test_revoke_msg() -> StdResult<()> {
let spender = "alice".to_string();
let token_id = "NFT1".to_string();
let padding = Some("padding".to_string());
let code_hash = "code hash".to_string();
let contract_addr = "contract".to_string();
let test_msg = revoke_msg(
spender.clone(),
token_id.clone(),
padding.clone(),
256usize,
code_hash.clone(),
contract_addr.clone(),
)?;
let mut msg = to_binary(&HandleMsg::Revoke {
spender,
token_id,
padding,
})?;
let msg = space_pad(&mut msg.0, 256usize);
let expected_msg = CosmosMsg::Wasm(WasmMsg::Execute {
msg: Binary(msg.to_vec()),
contract_addr,
code_hash,
funds: vec![],
});
assert_eq!(test_msg, expected_msg);
Ok(())
}
#[test]
fn test_approve_all_msg() -> StdResult<()> {
let operator = "alice".to_string();
let expires = Some(Expiration::AtHeight(1000000));
let padding = Some("padding".to_string());
let code_hash = "code hash".to_string();
let contract_addr = "contract".to_string();
let test_msg = approve_all_msg(
operator.clone(),
expires,
padding.clone(),
256usize,
code_hash.clone(),
contract_addr.clone(),
)?;
let mut msg = to_binary(&HandleMsg::ApproveAll {
operator,
expires,
padding,
})?;
let msg = space_pad(&mut msg.0, 256usize);
let expected_msg = CosmosMsg::Wasm(WasmMsg::Execute {
msg: Binary(msg.to_vec()),
contract_addr,
code_hash,
funds: vec![],
});
assert_eq!(test_msg, expected_msg);
Ok(())
}
#[test]
fn test_revoke_all_msg() -> StdResult<()> {
let operator = "alice".to_string();
let padding = Some("padding".to_string());
let code_hash = "code hash".to_string();
let contract_addr = "contract".to_string();
let test_msg = revoke_all_msg(
operator.clone(),
padding.clone(),
256usize,
code_hash.clone(),
contract_addr.clone(),
)?;
let mut msg = to_binary(&HandleMsg::RevokeAll { operator, padding })?;
let msg = space_pad(&mut msg.0, 256usize);
let expected_msg = CosmosMsg::Wasm(WasmMsg::Execute {
msg: Binary(msg.to_vec()),
contract_addr,
code_hash,
funds: vec![],
});
assert_eq!(test_msg, expected_msg);
Ok(())
}
#[test]
fn test_set_whitelisted_approval_msg() -> StdResult<()> {
let address = "alice".to_string();
let token_id = Some("NFT1".to_string());
let view_owner = Some(AccessLevel::All);
let view_private_metadata = None;
let transfer = Some(AccessLevel::RevokeToken);
let expires = Some(Expiration::AtTime(1000000000));
let padding = Some("padding".to_string());
let code_hash = "code hash".to_string();
let contract_addr = "contract".to_string();
let test_msg = set_whitelisted_approval_msg(
address.clone(),
token_id.clone(),
view_owner.clone(),
view_private_metadata.clone(),
transfer.clone(),
expires,
padding.clone(),
256usize,
code_hash.clone(),
contract_addr.clone(),
)?;
let mut msg = to_binary(&HandleMsg::SetWhitelistedApproval {
address,
token_id,
view_owner,
view_private_metadata,
transfer,
expires,
padding,
})?;
let msg = space_pad(&mut msg.0, 256usize);
let expected_msg = CosmosMsg::Wasm(WasmMsg::Execute {
msg: Binary(msg.to_vec()),
contract_addr,
code_hash,
funds: vec![],
});
assert_eq!(test_msg, expected_msg);
Ok(())
}
#[test]
fn test_register_receive_nft_msg() -> StdResult<()> {
let code_hash = "receiver code hash".to_string();
let also_implements_batch_receive_nft = Some(true);
let padding = Some("padding".to_string());
let callback_code_hash = "code hash".to_string();
let contract_addr = "contract".to_string();
let test_msg = register_receive_nft_msg(
code_hash.clone(),
also_implements_batch_receive_nft,
padding.clone(),
256usize,
callback_code_hash.clone(),
contract_addr.clone(),
)?;
let mut msg = to_binary(&HandleMsg::RegisterReceiveNft {
code_hash,
also_implements_batch_receive_nft,
padding,
})?;
let msg = space_pad(&mut msg.0, 256usize);
let expected_msg = CosmosMsg::Wasm(WasmMsg::Execute {
msg: Binary(msg.to_vec()),
contract_addr,
code_hash: callback_code_hash,
funds: vec![],
});
assert_eq!(test_msg, expected_msg);
Ok(())
}
#[test]
fn test_set_viewing_key_msg() -> StdResult<()> {
let key = "key".to_string();
let padding = Some("padding".to_string());
let code_hash = "code hash".to_string();
let contract_addr = "contract".to_string();
let test_msg = set_viewing_key_msg(
key.clone(),
padding.clone(),
256usize,
code_hash.clone(),
contract_addr.clone(),
)?;
let mut msg = to_binary(&HandleMsg::SetViewingKey { key, padding })?;
let msg = space_pad(&mut msg.0, 256usize);
let expected_msg = CosmosMsg::Wasm(WasmMsg::Execute {
msg: Binary(msg.to_vec()),
contract_addr,
code_hash,
funds: vec![],
});
assert_eq!(test_msg, expected_msg);
Ok(())
}
#[test]
fn test_mint_nft_msg() -> StdResult<()> {
let owner = Some("alice".to_string());
let token_id = Some("NFT1".to_string());
let public_metadata = Some(Metadata {
token_uri: Some("token uri".to_string()),
extension: Some(Extension {
image: Some("public_image".to_string()),
image_data: None,
external_url: None,
description: None,
name: None,
attributes: Some(vec![Trait {
display_type: None,
trait_type: Some("public trait".to_string()),
value: "value".to_string(),
max_value: None,
}]),
background_color: None,
animation_url: None,
youtube_url: None,
media: None,
protected_attributes: None,
}),
});
let private_metadata = Some(Metadata {
token_uri: Some("token uri".to_string()),
extension: Some(Extension {
image: Some("private_image".to_string()),
image_data: None,
external_url: None,
description: None,
name: None,
attributes: Some(vec![Trait {
display_type: None,
trait_type: Some("private trait".to_string()),
value: "value".to_string(),
max_value: None,
}]),
background_color: None,
animation_url: None,
youtube_url: None,
media: None,
protected_attributes: None,
}),
});
let memo = Some("memo".to_string());
let padding = None;
let code_hash = "code hash".to_string();
let contract_addr = "contract".to_string();
let test_msg = mint_nft_msg(
token_id.clone(),
owner.clone(),
public_metadata.clone(),
private_metadata.clone(),
memo.clone(),
padding.clone(),
256usize,
code_hash.clone(),
contract_addr.clone(),
)?;
let mut msg = to_binary(&HandleMsg::MintNft {
token_id,
owner,
public_metadata,
private_metadata,
memo,
padding,
})?;
let msg = space_pad(&mut msg.0, 256usize);
let expected_msg = CosmosMsg::Wasm(WasmMsg::Execute {
msg: Binary(msg.to_vec()),
contract_addr,
code_hash,
funds: vec![],
});
assert_eq!(test_msg, expected_msg);
Ok(())
}
#[test]
fn test_add_minters_msg() -> StdResult<()> {
let minters = vec!["alice".to_string(), "bob".to_string()];
let padding = Some("padding".to_string());
let code_hash = "code hash".to_string();
let contract_addr = "contract".to_string();
let test_msg = add_minters_msg(
minters.clone(),
padding.clone(),
256usize,
code_hash.clone(),
contract_addr.clone(),
)?;
let mut msg = to_binary(&HandleMsg::AddMinters { minters, padding })?;
let msg = space_pad(&mut msg.0, 256usize);
let expected_msg = CosmosMsg::Wasm(WasmMsg::Execute {
msg: Binary(msg.to_vec()),
contract_addr,
code_hash,
funds: vec![],
});
assert_eq!(test_msg, expected_msg);
Ok(())
}
#[test]
fn test_remove_minters_msg() -> StdResult<()> {
let minters = vec![
"alice".to_string(),
"bob".to_string(),
"charlie".to_string(),
];
let padding = Some("padding".to_string());
let code_hash = "code hash".to_string();
let contract_addr = "contract".to_string();
let test_msg = remove_minters_msg(
minters.clone(),
padding.clone(),
256usize,
code_hash.clone(),
contract_addr.clone(),
)?;
let mut msg = to_binary(&HandleMsg::RemoveMinters { minters, padding })?;
let msg = space_pad(&mut msg.0, 256usize);
let expected_msg = CosmosMsg::Wasm(WasmMsg::Execute {
msg: Binary(msg.to_vec()),
contract_addr,
code_hash,
funds: vec![],
});
assert_eq!(test_msg, expected_msg);
Ok(())
}
#[test]
fn test_set_minters_msg() -> StdResult<()> {
let minters = vec![
"alice".to_string(),
"bob".to_string(),
"charlie".to_string(),
];
let padding = Some("padding".to_string());
let code_hash = "code hash".to_string();
let contract_addr = "contract".to_string();
let test_msg = set_minters_msg(
minters.clone(),
padding.clone(),
256usize,
code_hash.clone(),
contract_addr.clone(),
)?;
let mut msg = to_binary(&HandleMsg::SetMinters { minters, padding })?;
let msg = space_pad(&mut msg.0, 256usize);
let expected_msg = CosmosMsg::Wasm(WasmMsg::Execute {
msg: Binary(msg.to_vec()),
contract_addr,
code_hash,
funds: vec![],
});
assert_eq!(test_msg, expected_msg);
Ok(())
}
#[test]
fn test_set_metadata_msg() -> StdResult<()> {
let token_id = "NFT1".to_string();
let public_metadata = Some(Metadata {
token_uri: Some("token uri".to_string()),
extension: Some(Extension {
image: Some("public_image".to_string()),
image_data: None,
external_url: None,
description: None,
name: None,
attributes: Some(vec![Trait {
display_type: None,
trait_type: Some("public trait".to_string()),
value: "value".to_string(),
max_value: None,
}]),
background_color: None,
animation_url: None,
youtube_url: None,
media: None,
protected_attributes: None,
}),
});
let private_metadata = Some(Metadata {
token_uri: Some("token uri".to_string()),
extension: Some(Extension {
image: Some("private_image".to_string()),
image_data: None,
external_url: None,
description: None,
name: None,
attributes: Some(vec![Trait {
display_type: None,
trait_type: Some("private trait".to_string()),
value: "value".to_string(),
max_value: None,
}]),
background_color: None,
animation_url: None,
youtube_url: None,
media: None,
protected_attributes: None,
}),
});
let padding = None;
let code_hash = "code hash".to_string();
let contract_addr = "contract".to_string();
let test_msg = set_metadata_msg(
token_id.clone(),
public_metadata.clone(),
private_metadata.clone(),
padding.clone(),
256usize,
code_hash.clone(),
contract_addr.clone(),
)?;
let mut msg = to_binary(&HandleMsg::SetMetadata {
token_id,
public_metadata,
private_metadata,
padding,
})?;
let msg = space_pad(&mut msg.0, 256usize);
let expected_msg = CosmosMsg::Wasm(WasmMsg::Execute {
msg: Binary(msg.to_vec()),
contract_addr,
code_hash,
funds: vec![],
});
assert_eq!(test_msg, expected_msg);
Ok(())
}
#[test]
fn test_batch_mint_nft_msg() -> StdResult<()> {
let mints = vec![
Mint {
token_id: None,
owner: Some("alice".to_string()),
public_metadata: Some(Metadata {
token_uri: Some("token uri".to_string()),
extension: Some(Extension {
image: Some("public_image".to_string()),
image_data: None,
external_url: None,
description: None,
name: None,
attributes: Some(vec![Trait {
display_type: None,
trait_type: Some("public trait".to_string()),
value: "value".to_string(),
max_value: None,
}]),
background_color: None,
animation_url: None,
youtube_url: None,
media: None,
protected_attributes: None,
}),
}),
private_metadata: None,
memo: Some("memo 1".to_string()),
},
Mint {
token_id: Some("NFT2".to_string()),
owner: None,
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: Some(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,
}),
}),
memo: None,
},
Mint {
token_id: Some("NFT3".to_string()),
owner: Some("bob".to_string()),
public_metadata: None,
private_metadata: Some(Metadata {
token_uri: Some("token uri3".to_string()),
extension: Some(Extension {
image: Some("private_image3".to_string()),
image_data: None,
external_url: None,
description: None,
name: None,
attributes: Some(vec![Trait {
display_type: None,
trait_type: Some("private trait3".to_string()),
value: "value3".to_string(),
max_value: None,
}]),
background_color: None,
animation_url: None,
youtube_url: None,
media: None,
protected_attributes: None,
}),
}),
memo: Some("memo 3".to_string()),
},
];
let padding = None;
let code_hash = "code hash".to_string();
let contract_addr = "contract".to_string();
let test_msg = batch_mint_nft_msg(
mints.clone(),
padding.clone(),
256usize,
code_hash.clone(),
contract_addr.clone(),
)?;
let mut msg = to_binary(&HandleMsg::BatchMintNft { mints, padding })?;
let msg = space_pad(&mut msg.0, 256usize);
let expected_msg = CosmosMsg::Wasm(WasmMsg::Execute {
msg: Binary(msg.to_vec()),
contract_addr,
code_hash,
funds: vec![],
});
assert_eq!(test_msg, expected_msg);
Ok(())
}
#[test]
fn test_batch_transfer_nft_msg() -> StdResult<()> {
let transfers = vec![
Transfer {
recipient: "alice".to_string(),
token_ids: vec!["NFT1".to_string()],
memo: Some("memo 1".to_string()),
},
Transfer {
recipient: "bob".to_string(),
token_ids: vec!["NFT2".to_string(), "NFT3".to_string(), "NFT4".to_string()],
memo: None,
},
];
let padding = None;
let code_hash = "code hash".to_string();
let contract_addr = "contract".to_string();
let test_msg = batch_transfer_nft_msg(
transfers.clone(),
padding.clone(),
256usize,
code_hash.clone(),
contract_addr.clone(),
)?;
let mut msg = to_binary(&HandleMsg::BatchTransferNft { transfers, padding })?;
let msg = space_pad(&mut msg.0, 256usize);
let expected_msg = CosmosMsg::Wasm(WasmMsg::Execute {
msg: Binary(msg.to_vec()),
contract_addr,
code_hash,
funds: vec![],
});
assert_eq!(test_msg, expected_msg);
Ok(())
}
#[test]
fn test_batch_send_nft_msg() -> StdResult<()> {
let sends = vec![
Send {
contract: "alice".to_string(),
token_ids: vec!["NFT1".to_string()],
msg: Some(to_binary(&HandleMsg::TransferNft {
recipient: "bob".to_string(),
token_id: "NFT1".to_string(),
memo: Some("send msg memo".to_string()),
padding: None,
})?),
memo: Some("memo 1".to_string()),
},
Send {
contract: "bob".to_string(),
token_ids: vec!["NFT2".to_string(), "NFT3".to_string(), "NFT4".to_string()],
msg: None,
memo: None,
},
];
let padding = None;
let code_hash = "code hash".to_string();
let contract_addr = "contract".to_string();
let test_msg = batch_send_nft_msg(
sends.clone(),
padding.clone(),
256usize,
code_hash.clone(),
contract_addr.clone(),
)?;
let mut msg = to_binary(&HandleMsg::BatchSendNft { sends, padding })?;
let msg = space_pad(&mut msg.0, 256usize);
let expected_msg = CosmosMsg::Wasm(WasmMsg::Execute {
msg: Binary(msg.to_vec()),
contract_addr,
code_hash,
funds: vec![],
});
assert_eq!(test_msg, expected_msg);
Ok(())
}
#[test]
fn test_burn_nft_msg() -> StdResult<()> {
let token_id = "NFT1".to_string();
let memo = Some("memo".to_string());
let padding = Some("padding".to_string());
let code_hash = "code hash".to_string();
let contract_addr = "contract".to_string();
let test_msg = burn_nft_msg(
token_id.clone(),
memo.clone(),
padding.clone(),
256usize,
code_hash.clone(),
contract_addr.clone(),
)?;
let mut msg = to_binary(&HandleMsg::BurnNft {
token_id,
memo,
padding,
})?;
let msg = space_pad(&mut msg.0, 256usize);
let expected_msg = CosmosMsg::Wasm(WasmMsg::Execute {
msg: Binary(msg.to_vec()),
contract_addr,
code_hash,
funds: vec![],
});
assert_eq!(test_msg, expected_msg);
Ok(())
}
#[test]
fn test_batch_burn_nft_msg() -> StdResult<()> {
let burns = vec![
Burn {
token_ids: vec!["NFT1".to_string()],
memo: Some("memo 1".to_string()),
},
Burn {
token_ids: vec!["NFT2".to_string(), "NFT3".to_string(), "NFT4".to_string()],
memo: None,
},
];
let padding = None;
let code_hash = "code hash".to_string();
let contract_addr = "contract".to_string();
let test_msg = batch_burn_nft_msg(
burns.clone(),
padding.clone(),
256usize,
code_hash.clone(),
contract_addr.clone(),
)?;
let mut msg = to_binary(&HandleMsg::BatchBurnNft { burns, padding })?;
let msg = space_pad(&mut msg.0, 256usize);
let expected_msg = CosmosMsg::Wasm(WasmMsg::Execute {
msg: Binary(msg.to_vec()),
contract_addr,
code_hash,
funds: vec![],
});
assert_eq!(test_msg, expected_msg);
Ok(())
}
#[test]
fn test_set_global_approval_msg() -> StdResult<()> {
let token_id = Some("NFT1".to_string());
let view_owner = Some(AccessLevel::All);
let view_private_metadata = None;
let expires = Some(Expiration::AtTime(1000000000));
let padding = Some("padding".to_string());
let code_hash = "code hash".to_string();
let contract_addr = "contract".to_string();
let test_msg = set_global_approval_msg(
token_id.clone(),
view_owner.clone(),
view_private_metadata.clone(),
expires,
padding.clone(),
256usize,
code_hash.clone(),
contract_addr.clone(),
)?;
let mut msg = to_binary(&HandleMsg::SetGlobalApproval {
token_id,
view_owner,
view_private_metadata,
expires,
padding,
})?;
let msg = space_pad(&mut msg.0, 256usize);
let expected_msg = CosmosMsg::Wasm(WasmMsg::Execute {
msg: Binary(msg.to_vec()),
contract_addr,
code_hash,
funds: vec![],
});
assert_eq!(test_msg, expected_msg);
Ok(())
}
#[test]
fn test_reveal_msg() -> StdResult<()> {
let token_id = "NFT1".to_string();
let padding = Some("padding".to_string());
let code_hash = "code hash".to_string();
let contract_addr = "contract".to_string();
let test_msg = reveal_msg(
token_id.clone(),
padding.clone(),
256usize,
code_hash.clone(),
contract_addr.clone(),
)?;
let mut msg = to_binary(&HandleMsg::Reveal { token_id, padding })?;
let msg = space_pad(&mut msg.0, 256usize);
let expected_msg = CosmosMsg::Wasm(WasmMsg::Execute {
msg: Binary(msg.to_vec()),
contract_addr,
code_hash,
funds: vec![],
});
assert_eq!(test_msg, expected_msg);
Ok(())
}
}