shell_wallet_nft/
contract.rs

1#[cfg(not(feature = "library"))]
2use cosmwasm_std::entry_point;
3use cosmwasm_std::{to_binary, Binary, Empty, Deps, DepsMut, Env, MessageInfo, Response, StdResult, WasmMsg};
4use cw2::set_contract_version;
5
6
7use crate::error::ContractError;
8
9use cw721::{Cw721Query,NftInfoResponse};
10
11use cw721_base::{
12    InstantiateMsg as cw721InstantiateMsg,
13    ExecuteMsg as cw721ExecuteMsg,
14    Cw721Contract,
15    Extension,
16};
17
18use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg, GetNFTIndexResponse};
19use crate::state::{increment_token_index, TOKEN_INDEX};
20
21// version info for migration info
22const CONTRACT_NAME: &str = "crates.io:shell-wallet-nft";
23const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");
24
25const NFT_NAME: &str = "ShellPower";
26const NFT_SYMBOL: &str = "SPX";
27
28#[cfg_attr(not(feature = "library"), entry_point)]
29pub fn instantiate(
30    deps: DepsMut,
31    env: Env,
32    info: MessageInfo,
33    _msg: InstantiateMsg,
34) -> Result<Response, ContractError> {
35    set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
36    let contract = Cw721Contract::<Extension, Empty, Empty, Empty>::default();
37    let contract_address = String::from(env.contract.address.clone());
38    let cw721msg = cw721InstantiateMsg{
39        name: NFT_NAME.to_string(),
40        symbol: NFT_SYMBOL.to_string(),
41        minter: contract_address.clone(),
42    };
43
44    let _res = contract.instantiate(deps, env, info, cw721msg);
45    
46    Ok(Response::new()
47        .add_attribute("method", "instantiate")
48        .add_attribute("contract-address", contract_address)
49    )
50}
51
52#[cfg_attr(not(feature = "library"), entry_point)]
53pub fn execute(
54    deps: DepsMut,
55    _env: Env,
56    info: MessageInfo,
57    msg: ExecuteMsg,
58) -> Result<Response, ContractError> {
59    match msg {
60        ExecuteMsg::Mint {} => execute::mint_nft(deps, _env, info),
61    }
62}
63
64pub mod execute {
65    use super::*;
66
67    pub fn mint_nft(deps:DepsMut, _env: Env, info: MessageInfo) -> Result<Response, ContractError>{
68        let contract = Cw721Contract::<Extension, Empty, Empty, Empty>::default();
69        let token_uri = "https://shell.io/nft/minter/ShellPowerMeta.json";
70        let token_id = increment_token_index(deps.storage)?.to_string();
71        let mint_msg = cw721ExecuteMsg::<Empty, Empty>::Mint {
72            token_id: token_id.clone(),
73            owner: info.sender.to_string(),
74            token_uri: Some(token_uri.to_string()),
75            extension: Empty::default(),
76        };
77
78        WasmMsg::Execute {
79            contract_addr: _env.contract.address.into(),
80            msg: to_binary(&mint_msg)?,
81            funds: vec![],
82        };
83    
84        let count = contract.num_tokens(deps.as_ref()).unwrap();
85        assert_eq!(1, count.count);
86
87
88        // unknown nft returns error
89        let _ = contract
90            .nft_info(deps.as_ref(), "unknown".to_string())
91            .unwrap_err();
92
93        // this nft info is correct
94        let nft_info = contract.nft_info(deps.as_ref(), token_id.clone()).unwrap();
95        assert_eq!(
96            nft_info,
97            NftInfoResponse::<Extension> {
98                token_uri: Some(token_uri.to_string()),
99                extension: None,
100            }
101        );
102
103        // list the token_ids
104        let _tokens = contract.all_tokens(deps.as_ref(), None, None).unwrap();
105
106        Ok(Response::new()
107            .add_attribute("action", "mint NFT")
108            .add_attribute("token_id", token_id)
109            .add_attribute("contract_version", CONTRACT_VERSION)
110            .add_attribute("sender", info.sender.to_string())
111        )
112    }
113}
114
115#[cfg_attr(not(feature = "library"), entry_point)]
116pub fn query(_deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
117    match msg {
118        QueryMsg::GetNFTIndex {} => to_binary(&query::count(_deps)?),
119    }
120}
121
122pub mod query {
123    use super::*;
124
125    pub fn count(deps: Deps) -> StdResult<GetNFTIndexResponse> {
126        let state = TOKEN_INDEX.load(deps.storage)?;
127        Ok(GetNFTIndexResponse { index: state })
128    }
129}