Skip to content

Commit

Permalink
fix: update instantiation of cw721 with onchain metadata template
Browse files Browse the repository at this point in the history
  • Loading branch information
eliasmpw committed Oct 2, 2023
1 parent e79eacf commit e179351
Showing 1 changed file with 51 additions and 44 deletions.
95 changes: 51 additions & 44 deletions cw721/on-chain-metadata/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

use cosmwasm_schema::cw_serde;
use cosmwasm_std::Empty;
use cw2::set_contract_version;
use cw721::ContractInfoResponse;
pub use cw721_base::{ContractError, InstantiateMsg, MinterResponse, QueryMsg};
pub use cw721_base::{ContractError, InstantiateMsg, MinterResponse};

// Version info for migration
const CONTRACT_NAME: &str = "crates.io:cw721-metadata-onchain";
const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");

#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug, Default)]
#[cw_serde]
pub struct Trait {
pub display_type: Option<String>,
pub trait_type: String,
pub value: String,
}

// see: https://docs.opensea.io/docs/metadata-standards
#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug, Default)]
#[cw_serde]
#[derive(Default)]
pub struct Metadata {
pub image: Option<String>,
pub image_data: Option<String>,
Expand All @@ -31,9 +32,7 @@ pub type Extension = Option<Metadata>;

pub type Cw721MetadataContract<'a> = cw721_base::Cw721Contract<'a, Extension, Empty, Empty, Empty>;
pub type ExecuteMsg = cw721_base::ExecuteMsg<Extension, Empty>;

const CONTRACT_NAME: &str = "crates.io:{{project-name}}";
const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");
pub type QueryMsg = cw721_base::QueryMsg<Empty>;

#[cfg(not(feature = "library"))]
pub mod entry {
Expand All @@ -42,26 +41,17 @@ pub mod entry {
use cosmwasm_std::entry_point;
use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult};

// This is a simple type to let us handle empty extensions

// This makes a conscious choice on the various generics used by the contract
#[entry_point]
pub fn instantiate(
deps: DepsMut,
_env: Env,
_info: MessageInfo,
mut deps: DepsMut,
env: Env,
info: MessageInfo,
msg: InstantiateMsg,
) -> StdResult<Response> {
set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;

let info = ContractInfoResponse {
name: msg.name,
symbol: msg.symbol,
};
Cw721MetadataContract::default()
.contract_info
.save(deps.storage, &info)?;
Ok(Response::default())
Cw721MetadataContract::default().instantiate(deps.branch(), env, info, msg)
}

#[entry_point]
Expand All @@ -75,7 +65,7 @@ pub mod entry {
}

#[entry_point]
pub fn query(deps: Deps, env: Env, msg: QueryMsg<Empty>) -> StdResult<Binary> {
pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult<Binary> {
Cw721MetadataContract::default().query(deps, env, msg)
}
}
Expand All @@ -89,6 +79,29 @@ mod tests {

const CREATOR: &str = "creator";

/// Make sure cw2 version info is properly initialized during instantiation,
/// and NOT overwritten by the base contract.
#[test]
fn proper_cw2_initialization() {
let mut deps = mock_dependencies();

entry::instantiate(
deps.as_mut(),
mock_env(),
mock_info("larry", &[]),
InstantiateMsg {
name: "".into(),
symbol: "".into(),
minter: "larry".into(),
},
)
.unwrap();

let version = cw2::get_contract_version(deps.as_ref().storage).unwrap();
assert_eq!(version.contract, CONTRACT_NAME);
assert_ne!(version.contract, cw721_base::CONTRACT_NAME);
}

#[test]
fn use_metadata_extension() {
let mut deps = mock_dependencies();
Expand All @@ -105,30 +118,24 @@ mod tests {
.unwrap();

let token_id = "Enterprise";
let mint_msg = ExecuteMsg::Mint {
let token_uri = Some("https://starships.example.com/Starship/Enterprise.json".into());
let extension = Some(Metadata {
description: Some("Spaceship with Warp Drive".into()),
name: Some("Starship USS Enterprise".to_string()),
..Metadata::default()
});
let exec_msg = ExecuteMsg::Mint {
token_id: token_id.to_string(),
owner: "john".to_string(),
token_uri: Some("https://starships.example.com/Starship/Enterprise.json".into()),
extension: Some(Metadata {
description: Some("Spaceship with Warp Drive".into()),
name: Some("Starship USS Enterprise".to_string()),
..Metadata::default()
}),
token_uri: token_uri.clone(),
extension: extension.clone(),
};
contract
.execute(deps.as_mut(), mock_env(), info, mint_msg.clone())
.execute(deps.as_mut(), mock_env(), info, exec_msg)
.unwrap();

let res = contract.nft_info(deps.as_ref(), token_id.into()).unwrap();
if let ExecuteMsg::Mint {
token_id: _,
owner: _,
token_uri,
extension,
} = mint_msg
{
assert_eq!(res.token_uri, token_uri);
assert_eq!(res.extension, extension);
}
assert_eq!(res.token_uri, token_uri);
assert_eq!(res.extension, extension);
}
}

0 comments on commit e179351

Please sign in to comment.