diff --git a/Cargo.toml b/Cargo.toml index 6c85dc3c..7554e289 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,3 +22,4 @@ async-trait = "0.1.68" percent-encoding = "2.3.0" chrono = "0.4.19" lazy_static = "1.4.0" +regex = "1.10.0" diff --git a/src/common/verify_has_nft.rs b/src/common/verify_has_nft.rs index 5083ea5a..5b895ee6 100644 --- a/src/common/verify_has_nft.rs +++ b/src/common/verify_has_nft.rs @@ -10,7 +10,7 @@ pub async fn execute_has_nft( addr: FieldElement, contract: FieldElement, limit: u32, - is_whitelisted: fn(&Nft) -> bool, + is_whitelisted: fn(&Nft, &mut Vec), ) -> Result { let url = format!( "https://api.starkscan.co/api/v0/nfts?contract_address={}&owner_address={}", @@ -34,11 +34,8 @@ pub async fn execute_has_nft( let nft_data = res.data; let mut unique_nfts: Vec = Vec::new(); for nft in nft_data { - if nft.name.is_some() && is_whitelisted(&nft) { - let name = nft.name.unwrap(); - if !unique_nfts.contains(&name) { - unique_nfts.push(name); - } + if nft.name.is_some() { + is_whitelisted(&nft, &mut unique_nfts) } } Ok(unique_nfts.len() >= limit as usize) diff --git a/src/endpoints/achievements/verify_default.rs b/src/endpoints/achievements/verify_default.rs index bcfa8150..3dcfe3e2 100644 --- a/src/endpoints/achievements/verify_default.rs +++ b/src/endpoints/achievements/verify_default.rs @@ -19,7 +19,7 @@ use mongodb::bson::doc; use serde_json::json; use starknet::core::types::FieldElement; -type NftCheck = fn(&Nft) -> bool; +type NftCheck = fn(&Nft, unique_nfts: &mut Vec); fn get_args(config: Config, achievement_id: u32) -> Result<(FieldElement, u32, NftCheck), String> { let argent_contract = config.achievements.argent.contract; diff --git a/src/endpoints/achievements/verify_whitelisted.rs b/src/endpoints/achievements/verify_whitelisted.rs index 54e2d531..4b154f43 100644 --- a/src/endpoints/achievements/verify_whitelisted.rs +++ b/src/endpoints/achievements/verify_whitelisted.rs @@ -1,23 +1,39 @@ use crate::models::Nft; +use regex::Regex; -pub fn is_braavos_whitelisted(nft: &Nft) -> bool { - let whitelist = vec![ - "Starknet Onboarding Journey NFT", - "Starknet Identity Journey", - "Starknet Exchange Journey", - "Starknet Mobile Journey", - "Starknet Journey Coin NFT", +lazy_static::lazy_static! { + static ref BRAAVOS_WHITELIST : Vec = vec![ + Regex::new(r"Starknet Onboarding Journey( NFT)?").unwrap(), + Regex::new(r"Starknet Identity Journey").unwrap(), + Regex::new(r"Starknet Exchange Journey").unwrap(), + Regex::new(r"Starknet Mobile Journey").unwrap(), + Regex::new(r"(Starknet Journey Coin NFT|starknet-journey-coin)").unwrap() ]; +} + +pub fn is_braavos_whitelisted(nft: &Nft, unique_nfts: &mut Vec) { if let Some(name) = nft.name.as_ref() { - return whitelist.contains(&name.as_str()); + for pattern in &*BRAAVOS_WHITELIST { + if pattern.is_match(name) && !unique_nfts.contains(name) { + unique_nfts.push(name.clone()); + return; + } + } } - false } -pub fn is_argent_whitelisted(_nft: &Nft) -> bool { - true +pub fn is_argent_whitelisted(nft: &Nft, unique_nfts: &mut Vec) { + if let Some(name) = nft.name.as_ref() { + if !unique_nfts.contains(name) { + unique_nfts.push(name.to_string()); + } + } } -pub fn is_carbonable_whitelisted(_nft: &Nft) -> bool { - true +pub fn is_carbonable_whitelisted(nft: &Nft, unique_nfts: &mut Vec) { + if let Some(name) = nft.name.as_ref() { + if !unique_nfts.contains(name) { + unique_nfts.push(name.to_string()); + } + } }