Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

token URI scheme as init arg #627

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions contracts/minters/base-minter/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ pub fn instantiate(
// assume the mint price is the minimum mint price
// 100% is fair burned
mint_price: factory_params.params.min_mint_price,
uri_scheme: factory_params
.params
.uri_scheme
.unwrap_or("ipfs".to_owned())
.to_string(),
extension: Empty {},
};

Expand Down Expand Up @@ -116,6 +121,7 @@ pub fn execute_mint_sender(
) -> Result<Response, ContractError> {
let config = CONFIG.load(deps.storage)?;
let collection_address = COLLECTION_ADDRESS.load(deps.storage)?;
let token_uri = token_uri.trim().to_owned();

// This is a 1:1 minter, minted at min_mint_price
// Should mint and then list on the marketplace for secondary sales
Expand All @@ -130,9 +136,10 @@ pub fn execute_mint_sender(
));
};

let parsed_token_uri = Url::parse(&token_uri)?;
if parsed_token_uri.scheme() != "ipfs" {
return Err(ContractError::InvalidTokenURI {});
if Url::parse(&token_uri)?.scheme() != config.uri_scheme {
return Err(ContractError::InvalidTokenURI {
expected_scheme: config.uri_scheme,
});
}

let mut res = Response::new();
Expand Down
4 changes: 2 additions & 2 deletions contracts/minters/base-minter/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ pub enum ContractError {
#[error("InvalidMintPrice")]
InvalidMintPrice {},

#[error("InvalidTokenURI")]
InvalidTokenURI {},
#[error("InvalidTokenURI (must be an {expected_scheme} URI)")]
InvalidTokenURI { expected_scheme: String },

#[error("Invalid reply ID")]
InvalidReplyID {},
Expand Down
24 changes: 20 additions & 4 deletions contracts/minters/open-edition-minter/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ pub fn instantiate(
// set default status so it can be queried without failing
STATUS.save(deps.storage, &Status::default())?;

let uri_scheme = factory_params
.uri_scheme
.unwrap_or("ipfs".to_owned())
.to_string();

match msg.init_msg.nft_data.nft_data_type {
// If off-chain metadata -> Sanitize base token uri
NftMetadataType::OffChainMetadata => {
Expand All @@ -65,10 +70,19 @@ pub fn instantiate(
.token_uri
.as_ref()
.map(|uri| uri.trim().to_string())
.map_or_else(|| Err(ContractError::InvalidBaseTokenURI {}), Ok)?;

if Url::parse(&base_token_uri)?.scheme() != "ipfs" {
return Err(ContractError::InvalidBaseTokenURI {});
.map_or_else(
|| {
Err(ContractError::InvalidBaseTokenURI {
expected_scheme: uri_scheme.clone(),
})
},
Ok,
)?;

if Url::parse(&base_token_uri)?.scheme() != uri_scheme {
return Err(ContractError::InvalidBaseTokenURI {
expected_scheme: uri_scheme,
});
}

msg.init_msg.nft_data.token_uri = Some(base_token_uri);
Expand Down Expand Up @@ -127,6 +141,7 @@ pub fn instantiate(
nft_data: msg.init_msg.nft_data,
},
mint_price: msg.init_msg.mint_price,
uri_scheme,
};

CONFIG.save(deps.storage, &config)?;
Expand Down Expand Up @@ -696,6 +711,7 @@ fn query_config(deps: Deps) -> StdResult<ConfigResponse> {
start_time: config.extension.start_time,
mint_price: config.mint_price,
factory: config.factory.to_string(),
uri_scheme: config.uri_scheme,
})
}

Expand Down
4 changes: 2 additions & 2 deletions contracts/minters/open-edition-minter/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ pub enum ContractError {
#[error("Instantiate sg721 error")]
InstantiateSg721Error {},

#[error("Invalid base token URI (must be an IPFS URI)")]
InvalidBaseTokenURI {},
#[error("Invalid base token URI (must be an {expected_scheme} URI)")]
InvalidBaseTokenURI { expected_scheme: String },

#[error("address not on whitelist: {addr}")]
NotWhitelisted { addr: String },
Expand Down
1 change: 1 addition & 0 deletions contracts/minters/open-edition-minter/src/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ pub struct ConfigResponse {
pub start_time: Timestamp,
pub mint_price: Coin,
pub factory: String,
pub uri_scheme: String,
}

#[cw_serde]
Expand Down
19 changes: 13 additions & 6 deletions contracts/minters/vending-minter-wl-flex/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,20 @@ pub fn instantiate(
// set default status so it can be queried without failing
STATUS.save(deps.storage, &Status::default())?;

let uri_scheme = factory_params
.uri_scheme
.unwrap_or("ipfs".to_owned())
.to_string();

// sanitize base token uri
let mut base_token_uri = msg.init_msg.base_token_uri.trim().to_string();
// Check that base_token_uri is a valid IPFS uri
let parsed_token_uri = Url::parse(&base_token_uri)?;
if parsed_token_uri.scheme() != "ipfs" {
return Err(ContractError::InvalidBaseTokenURI {});
let url = Url::parse(&msg.init_msg.base_token_uri.trim().to_string())?;
if url.scheme() != uri_scheme {
return Err(ContractError::InvalidBaseTokenURI {
expected_scheme: uri_scheme,
});
}
base_token_uri = parsed_token_uri.to_string();

let base_token_uri = url.to_string();

let genesis_time = Timestamp::from_nanos(GENESIS_MINT_START_TIME);
// If start time is before genesis time return error
Expand Down Expand Up @@ -147,6 +153,7 @@ pub fn instantiate(
discount_price: None,
},
mint_price: msg.init_msg.mint_price,
uri_scheme,
};

CONFIG.save(deps.storage, &config)?;
Expand Down
4 changes: 2 additions & 2 deletions contracts/minters/vending-minter-wl-flex/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ pub enum ContractError {
#[error("Instantiate sg721 error")]
InstantiateSg721Error {},

#[error("Invalid base token URI (must be an IPFS URI)")]
InvalidBaseTokenURI {},
#[error("Invalid base token URI (must be an {expected_scheme} URI)")]
InvalidBaseTokenURI { expected_scheme: String },

#[error("address not on whitelist: {addr}")]
NotWhitelisted { addr: String },
Expand Down
19 changes: 13 additions & 6 deletions contracts/minters/vending-minter/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,20 @@ pub fn instantiate(
});
}

let uri_scheme = factory_params
.uri_scheme
.unwrap_or("ipfs".to_owned())
.to_string();

// sanitize base token uri
let mut base_token_uri = msg.init_msg.base_token_uri.trim().to_string();
// Check that base_token_uri is a valid IPFS uri
let parsed_token_uri = Url::parse(&base_token_uri)?;
if parsed_token_uri.scheme() != "ipfs" {
return Err(ContractError::InvalidBaseTokenURI {});
let url = Url::parse(&msg.init_msg.base_token_uri.trim().to_string())?;
if url.scheme() != uri_scheme {
return Err(ContractError::InvalidBaseTokenURI {
expected_scheme: uri_scheme,
});
}
base_token_uri = parsed_token_uri.to_string();

let base_token_uri = url.to_string();

let genesis_time = Timestamp::from_nanos(GENESIS_MINT_START_TIME);
// If start time is before genesis time return error
Expand Down Expand Up @@ -162,6 +168,7 @@ pub fn instantiate(
discount_price: None,
},
mint_price: msg.init_msg.mint_price,
uri_scheme,
};

CONFIG.save(deps.storage, &config)?;
Expand Down
4 changes: 2 additions & 2 deletions contracts/minters/vending-minter/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ pub enum ContractError {
#[error("Instantiate sg721 error")]
InstantiateSg721Error {},

#[error("Invalid base token URI (must be an IPFS URI)")]
InvalidBaseTokenURI {},
#[error("Invalid base token URI (must be an {expected_scheme} URI)")]
InvalidBaseTokenURI { expected_scheme: String },

#[error("address not on whitelist: {addr}")]
NotWhitelisted { addr: String },
Expand Down
1 change: 1 addition & 0 deletions e2e/src/helpers/helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ pub fn instantiate_factory(
},
mint_fee_bps: 1000, // 10%
max_trading_offset_secs: (60 * 60) * 24,
uri_scheme: None,
extension: ParamsExtension {
max_token_limit: MAX_TOKENS,
max_per_address_limit: 50,
Expand Down
1 change: 1 addition & 0 deletions e2e/src/helpers/open_edition_minter_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ pub fn instantiate_factory(
},
mint_fee_bps: 1000, // 10%
max_trading_offset_secs: (60 * 60) * 24,
uri_scheme: None,
extension: ParamsExtension {
max_per_address_limit: 50,
airdrop_mint_fee_bps: 0,
Expand Down
1 change: 1 addition & 0 deletions packages/sg2/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ pub struct MinterParams<T> {
pub min_mint_price: Coin,
pub mint_fee_bps: u64,
pub max_trading_offset_secs: u64,
pub uri_scheme: Option<String>,
pub extension: T,
}
1 change: 1 addition & 0 deletions packages/sg4/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub struct MinterConfig<T> {
pub factory: Addr,
pub collection_code_id: u64,
pub mint_price: Coin,
pub uri_scheme: String,
pub extension: T,
}

Expand Down
3 changes: 3 additions & 0 deletions test-suite/src/common_setup/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub struct MinterSetupParams<'a> {
pub factory_code_id: u64,
pub sg721_code_id: u64,
pub init_msg: Option<VendingMinterInitMsgExtension>,
pub uri_scheme: Option<String>,
}
pub struct MinterCollectionResponse {
pub minter: Option<Addr>,
Expand Down Expand Up @@ -73,6 +74,7 @@ pub struct OpenEditionMinterSetupParams<'a> {
pub minter_code_id: u64,
pub factory_code_id: u64,
pub sg721_code_id: u64,
pub uri_scheme: Option<String>,
pub init_msg: Option<OpenEditionMinterInitMsgExtension>,
pub custom_params: Option<OpenEditionMinterParams>,
}
Expand All @@ -92,4 +94,5 @@ pub struct OpenEditionMinterCustomParams<'a> {
pub denom: Option<&'a str>,
pub mint_fee_bps: Option<u64>,
pub airdrop_mint_price_amount: Option<Uint128>,
pub uri_scheme: Option<String>,
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub fn mock_params() -> BaseMinterParams {
mint_fee_bps: MINT_FEE_BPS,
max_trading_offset_secs: 60 * 60 * 24 * 7,
extension: None,
uri_scheme: Some("ipfs".to_owned()),
}
}

Expand Down
2 changes: 2 additions & 0 deletions test-suite/src/common_setup/setup_minter/base_minter/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ pub fn configure_base_minter(
collection_params_vec: Vec<CollectionParams>,
minter_instantiate_params_vec: Vec<MinterInstantiateParams>,
code_ids: CodeIds,
uri_scheme: Option<String>,
) -> Vec<MinterCollectionResponse> {
let mut minter_collection_info: Vec<MinterCollectionResponse> = vec![];
for (index, collection_param) in collection_params_vec.iter().enumerate() {
Expand All @@ -144,6 +145,7 @@ pub fn configure_base_minter(
sg721_code_id: code_ids.sg721_code_id,
start_time: minter_instantiate_params_vec[index].start_time,
init_msg: minter_instantiate_params_vec[index].init_msg.clone(),
uri_scheme: uri_scheme.clone(),
};
let minter_collection_res = setup_minter_contract(setup_params);
minter_collection_info.push(minter_collection_res);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,25 @@ pub fn minter_params_open_edition(
start_time: Option<Timestamp>,
end_time: Option<Timestamp>,
nft_data: Option<NftData>,
uri_scheme: Option<String>,
custom_params: Option<OpenEditionMinterParams>,
) -> OpenEditionMinterInstantiateParams {
let start_time = start_time.unwrap_or(Timestamp::from_nanos(GENESIS_MINT_START_TIME + 100));
let end_time = end_time.unwrap_or(Timestamp::from_nanos(GENESIS_MINT_START_TIME + 10_000));
let uri_scheme = uri_scheme.unwrap_or("ipfs".to_owned());

OpenEditionMinterInstantiateParams {
start_time: Some(start_time),
end_time: Some(end_time),
per_address_limit: Some(init_msg.per_address_limit),
nft_data: Some(
nft_data.unwrap_or(NftData {
nft_data_type: NftMetadataType::OffChainMetadata,
extension: None,
token_uri: Some(
"ipfs://bafybeiavall5udkxkdtdm4djezoxrmfc6o5fn2ug3ymrlvibvwmwydgrkm/1.jpg"
.to_string(),
),
}),
),
nft_data: Some(nft_data.unwrap_or(NftData {
nft_data_type: NftMetadataType::OffChainMetadata,
extension: None,
token_uri: Some(format!(
"{}://bafybeiavall5udkxkdtdm4djezoxrmfc6o5fn2ug3ymrlvibvwmwydgrkm/1.jpg",
uri_scheme
)),
})),
init_msg: Some(init_msg),
params_extension: Some(params_extension),
custom_params,
Expand All @@ -53,6 +53,17 @@ pub fn default_nft_data() -> NftData {
}
}

pub fn nft_data_with_uri_scheme(uri_scheme: String) -> NftData {
NftData {
nft_data_type: NftMetadataType::OffChainMetadata,
extension: None,
token_uri: Some(format!(
"{}://bafybeiavall5udkxkdtdm4djezoxrmfc6o5fn2ug3ymrlvibvwmwydgrkm/1.jpg",
uri_scheme
)),
}
}

pub fn init_msg(
nft_data: NftData,
per_address_limit_minter: Option<u32>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ pub fn mock_params_proper() -> OpenEditionMinterParams {
min_mint_price: coin(MIN_MINT_PRICE_OPEN_EDITION, NATIVE_DENOM),
mint_fee_bps: MINT_FEE_FAIR_BURN,
max_trading_offset_secs: 60 * 60 * 24 * 7,
uri_scheme: Some("ipfs".to_owned()),
extension: ParamsExtension {
max_per_address_limit: 10,
airdrop_mint_fee_bps: 100,
Expand All @@ -86,6 +87,7 @@ pub fn mock_params_proper() -> OpenEditionMinterParams {
// Pass custom params to change minter values
pub fn mock_params_custom(custom_params: OpenEditionMinterCustomParams) -> OpenEditionMinterParams {
let denom = custom_params.denom.unwrap_or(NATIVE_DENOM);
let uri_scheme = custom_params.uri_scheme.clone();
let mint_fee_bps = custom_params.mint_fee_bps.unwrap_or(MINT_FEE_FAIR_BURN);
let airdrop_mint_price_amount = custom_params
.airdrop_mint_price_amount
Expand All @@ -98,6 +100,7 @@ pub fn mock_params_custom(custom_params: OpenEditionMinterCustomParams) -> OpenE
min_mint_price: coin(MIN_MINT_PRICE_OPEN_EDITION, denom),
mint_fee_bps,
max_trading_offset_secs: 60 * 60 * 24 * 7,
uri_scheme,
extension: ParamsExtension {
max_per_address_limit: 10,
airdrop_mint_fee_bps: 100,
Expand All @@ -122,6 +125,7 @@ pub fn mock_params_custom_min_mint_price(
min_mint_price,
mint_fee_bps: MINT_FEE_FAIR_BURN,
max_trading_offset_secs: 60 * 60 * 24 * 7,
uri_scheme: Some("ipfs".to_owned()),
extension: ParamsExtension {
max_per_address_limit: 10,
airdrop_mint_fee_bps: 100,
Expand Down
Loading