Skip to main content

cw721_base/
lib.rs

1pub mod error;
2pub mod msg;
3pub mod state;
4
5// expose so other libs dont need to import cw721
6// pub use cw721::*;
7
8// These types are re-exported so that contracts interacting with this
9// one don't need a direct dependency on cw_ownable to use the API.
10//
11// `Action` is used in `ExecuteMsg::UpdateMinterOwnership` and `ExecuteMsg::UpdateCreatorOwnership`, `Ownership` is
12// used in `QueryMsg::GetMinterOwnership`, `QueryMsg::GetCreatorOwnership`, and `OwnershipError` is used in
13// `ContractError::Ownership`.
14use cw721::{extension::Cw721BaseExtensions, EmptyOptionalNftExtension};
15pub use cw_ownable::{Action, Ownership, OwnershipError};
16
17// Version info for migration
18pub const CONTRACT_NAME: &str = "crates.io:cw721-base";
19pub const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");
20
21#[deprecated(
22    since = "0.19.0",
23    note = "Please use `EmptyOptionalNftExtension` instead"
24)]
25pub type Extension = EmptyOptionalNftExtension;
26
27pub type Cw721BaseContract<'a> = Cw721BaseExtensions<'a>;
28
29pub mod entry {
30
31    use super::*;
32
33    #[cfg(not(feature = "library"))]
34    use cosmwasm_std::entry_point;
35    use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response};
36    use cw721::traits::{Cw721Execute, Cw721Query};
37    use error::ContractError;
38    use msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg};
39
40    #[cfg_attr(not(feature = "library"), entry_point)]
41    pub fn instantiate(
42        deps: DepsMut,
43        env: Env,
44        info: MessageInfo,
45        msg: InstantiateMsg,
46    ) -> Result<Response, ContractError> {
47        let contract = Cw721BaseContract::default();
48        contract.instantiate_with_version(deps, &env, &info, msg, CONTRACT_NAME, CONTRACT_VERSION)
49    }
50
51    #[cfg_attr(not(feature = "library"), entry_point)]
52    pub fn execute(
53        deps: DepsMut,
54        env: Env,
55        info: MessageInfo,
56        msg: ExecuteMsg,
57    ) -> Result<Response, ContractError> {
58        let contract = Cw721BaseContract::default();
59        contract.execute(deps, &env, &info, msg)
60    }
61
62    #[cfg_attr(not(feature = "library"), entry_point)]
63    pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result<Binary, ContractError> {
64        let contract = Cw721BaseContract::default();
65        contract.query(deps, &env, msg)
66    }
67
68    #[cfg_attr(not(feature = "library"), entry_point)]
69    pub fn migrate(deps: DepsMut, env: Env, msg: MigrateMsg) -> Result<Response, ContractError> {
70        let contract = Cw721BaseContract::default();
71        contract.migrate(deps, env, msg, CONTRACT_NAME, CONTRACT_VERSION)
72    }
73}
74
75#[cfg(test)]
76mod tests {
77    use super::*;
78
79    use cosmwasm_std::{
80        testing::{message_info, mock_dependencies, mock_env},
81        Empty,
82    };
83
84    use cw721::traits::{Cw721Execute, Cw721Query};
85    use msg::{ExecuteMsg, InstantiateMsg};
86
87    const CREATOR: &str = "creator";
88
89    // here we test cw721-base can be used with nft extension, test without nft extension is already covered in package tests
90    #[test]
91    fn use_empty_metadata_extension() {
92        let mut deps = mock_dependencies();
93        let contract = Cw721BaseExtensions::default();
94        let creator = deps.api.addr_make(CREATOR);
95        let info = message_info(&creator, &[]);
96        let init_msg = InstantiateMsg {
97            name: "SpaceShips".to_string(),
98            symbol: "SPACE".to_string(),
99            collection_info_extension: None,
100            minter: None,
101            creator: None,
102            withdraw_address: None,
103        };
104        contract
105            .instantiate(deps.as_mut(), &mock_env(), &info.clone(), init_msg)
106            .unwrap();
107
108        let token_id = "Enterprise";
109        let token_uri = Some("https://starships.example.com/Starship/Enterprise.json".into());
110        let extension = Some(Empty {});
111        let owner = deps.api.addr_make("john");
112        let exec_msg = ExecuteMsg::Mint {
113            token_id: token_id.to_string(),
114            owner: owner.to_string(),
115            token_uri: token_uri.clone(),
116            extension: extension.clone(),
117        };
118        contract
119            .execute(deps.as_mut(), &mock_env(), &info, exec_msg)
120            .unwrap();
121
122        let res = contract
123            .query_nft_info(deps.as_ref().storage, token_id.into())
124            .unwrap();
125        assert_eq!(res.token_uri, token_uri);
126        assert_eq!(res.extension, Some(Empty {}));
127    }
128}