lib.rs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. pub mod msg;
  2. pub mod state;
  3. use schemars::JsonSchema;
  4. use serde::{
  5. Deserialize,
  6. Serialize,
  7. };
  8. pub use cosmwasm_std::to_binary;
  9. use cosmwasm_std::Empty;
  10. #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug, Default)]
  11. pub struct Trait {
  12. pub display_type: Option<String>,
  13. pub trait_type: String,
  14. pub value: String,
  15. }
  16. pub type Extension = Option<Empty>;
  17. pub type Cw721MetadataContract<'a> = cw721_base::Cw721Contract<'a, Extension, Empty>;
  18. pub type ExecuteMsg = cw721_base::ExecuteMsg<Extension>;
  19. #[cfg(not(feature = "library"))]
  20. pub mod entry {
  21. use std::convert::TryInto;
  22. use crate::msg::{
  23. InstantiateMsg,
  24. WrappedAssetInfoResponse,
  25. };
  26. pub use crate::{
  27. msg::QueryMsg,
  28. state::{
  29. wrapped_asset_info,
  30. wrapped_asset_info_read,
  31. WrappedAssetInfo,
  32. },
  33. };
  34. use super::*;
  35. use cosmwasm_std::{
  36. entry_point,
  37. to_binary,
  38. Binary,
  39. CosmosMsg,
  40. Deps,
  41. DepsMut,
  42. Env,
  43. MessageInfo,
  44. Response,
  45. StdError,
  46. StdResult,
  47. WasmMsg,
  48. };
  49. use cw721::Cw721Query;
  50. // version info for migration info
  51. const CONTRACT_NAME: &str = "crates.io:cw721-wrapped";
  52. const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");
  53. // This is a simple type to let us handle empty extensions
  54. // This makes a conscious choice on the various generics used by the contract
  55. #[entry_point]
  56. pub fn instantiate(
  57. deps: DepsMut,
  58. env: Env,
  59. info: MessageInfo,
  60. msg: InstantiateMsg,
  61. ) -> StdResult<Response> {
  62. let base = Cw721MetadataContract::default();
  63. cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
  64. let contract_info = cw721::ContractInfoResponse {
  65. name: msg.name,
  66. symbol: msg.symbol,
  67. };
  68. base.contract_info.save(deps.storage, &contract_info)?;
  69. let minter = deps.api.addr_validate(&msg.minter)?;
  70. base.minter.save(deps.storage, &minter)?;
  71. // save wrapped asset info
  72. let data =
  73. WrappedAssetInfo {
  74. asset_chain: msg.asset_chain,
  75. asset_address: msg.asset_address.to_vec().try_into().map_err(
  76. |_err| -> StdError {
  77. StdError::GenericErr {
  78. msg: "WrongSize".to_string(),
  79. }
  80. },
  81. )?,
  82. bridge: deps.api.addr_canonicalize(&info.sender.as_str())?,
  83. };
  84. wrapped_asset_info(deps.storage).save(&data)?;
  85. if let Some(mint_msg) = msg.mint {
  86. execute(deps, env, info, ExecuteMsg::Mint(mint_msg))
  87. .map_err(|e| StdError::generic_err(format!("{}", e)))?;
  88. }
  89. if let Some(hook) = msg.init_hook {
  90. Ok(
  91. Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Execute {
  92. contract_addr: hook.contract_addr,
  93. msg: hook.msg,
  94. funds: vec![],
  95. })),
  96. )
  97. } else {
  98. Ok(Response::default())
  99. }
  100. }
  101. #[entry_point]
  102. pub fn execute(
  103. deps: DepsMut,
  104. env: Env,
  105. info: MessageInfo,
  106. msg: ExecuteMsg,
  107. ) -> Result<Response, cw721_base::ContractError> {
  108. Cw721MetadataContract::default().execute(deps, env, info, msg)
  109. }
  110. #[entry_point]
  111. pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult<Binary> {
  112. let base = Cw721MetadataContract::default();
  113. match msg {
  114. QueryMsg::WrappedAssetInfo {} => to_binary(&query_wrapped_asset_info(deps)?),
  115. QueryMsg::OwnerOf {
  116. token_id,
  117. include_expired,
  118. } => {
  119. to_binary(&base.owner_of(deps, env, token_id, include_expired.unwrap_or(false))?)
  120. }
  121. QueryMsg::Approval {
  122. token_id,
  123. spender,
  124. include_expired,
  125. } => to_binary(&base.approval(
  126. deps,
  127. env,
  128. token_id,
  129. spender,
  130. include_expired.unwrap_or(false),
  131. )?),
  132. QueryMsg::Approvals {
  133. token_id,
  134. include_expired,
  135. } => {
  136. to_binary(&base.approvals(deps, env, token_id, include_expired.unwrap_or(false))?)
  137. }
  138. QueryMsg::AllOperators {
  139. owner,
  140. include_expired,
  141. start_after,
  142. limit,
  143. } => to_binary(&base.operators(
  144. deps,
  145. env,
  146. owner,
  147. include_expired.unwrap_or(false),
  148. start_after,
  149. limit,
  150. )?),
  151. QueryMsg::NumTokens {} => to_binary(&base.num_tokens(deps)?),
  152. QueryMsg::Tokens {
  153. owner,
  154. start_after,
  155. limit,
  156. } => to_binary(&base.tokens(deps, owner, start_after, limit)?),
  157. QueryMsg::AllTokens { start_after, limit } => {
  158. to_binary(&base.all_tokens(deps, start_after, limit)?)
  159. }
  160. QueryMsg::Minter {} => to_binary(&base.minter(deps)?),
  161. QueryMsg::ContractInfo {} => to_binary(&base.contract_info(deps)?),
  162. QueryMsg::NftInfo { token_id } => to_binary(&base.nft_info(deps, token_id)?),
  163. QueryMsg::AllNftInfo {
  164. token_id,
  165. include_expired,
  166. } => to_binary(&base.all_nft_info(
  167. deps,
  168. env,
  169. token_id,
  170. include_expired.unwrap_or(false),
  171. )?),
  172. }
  173. }
  174. pub fn query_wrapped_asset_info(deps: Deps) -> StdResult<WrappedAssetInfoResponse> {
  175. let info = wrapped_asset_info_read(deps.storage).load()?;
  176. Ok(WrappedAssetInfoResponse {
  177. asset_chain: info.asset_chain,
  178. asset_address: info.asset_address,
  179. bridge: deps.api.addr_humanize(&info.bridge)?,
  180. })
  181. }
  182. }