diff --git a/src/endpoints/quests/verify_contract.rs b/src/endpoints/quests/verify_contract.rs index 78fde32c..e82e4545 100644 --- a/src/endpoints/quests/verify_contract.rs +++ b/src/endpoints/quests/verify_contract.rs @@ -19,6 +19,7 @@ use starknet::{ providers::Provider, }; use regex::Regex; +use crate::utils::parse_string; #[derive(Debug, Serialize, Deserialize, Default)] pub struct VerifyContractQuery { @@ -39,23 +40,24 @@ pub async fn handler( Ok(None) => return get_error("Task not found".to_string()), Err(e) => return get_error(format!("Database error: {}", e)), }; - if task.task_type != Some("contract".to_string()) { return get_error("Invalid task type.".to_string()); } let addr = &query.addr; - if let Some(calls) = task.calls { for call in calls { let contract_address = match FieldElement::from_hex_be(&call.contract) { Ok(address) => address, Err(e) => return get_error(format!("Invalid contract address: {}", e)), }; - + let calldata: Vec = match call.call_data .iter() - .map(|s| FieldElement::from_hex_be(s)) + .map(|s| { + let replaced_calldata = parse_string(s, FieldElement::from_hex_be(s).unwrap()); + FieldElement::from_hex_be(&replaced_calldata) + }) .collect::, _>>() { Ok(data) => data, @@ -81,12 +83,13 @@ pub async fn handler( match call_result { Ok(result) => { - let regex = match Regex::new(&call.regex) { + let regex_str = parse_string(&call.regex, FieldElement::from_hex_be(&call.contract).unwrap()); + let regex = match Regex::new(®ex_str) { Ok(re) => re, Err(e) => return get_error(format!("Invalid regex: {}", e)), }; let result_str = result.iter().map(|&r| r.to_string()).collect::>().join(","); - + if !regex.is_match(&result_str) { return get_error("Contract call result does not match the expected pattern.".to_string()); } diff --git a/src/endpoints/quests/verify_custom_api.rs b/src/endpoints/quests/verify_custom_api.rs index bda30a19..f94f2bf3 100644 --- a/src/endpoints/quests/verify_custom_api.rs +++ b/src/endpoints/quests/verify_custom_api.rs @@ -16,6 +16,7 @@ use serde_json::json; use regex::Regex; use reqwest::get; use starknet::core::types::FieldElement; +use crate::utils::parse_string; #[derive(Debug, Serialize, Deserialize, Default)] pub struct VerifyCustomApiQuery { @@ -55,14 +56,17 @@ pub async fn handler( }; // Call the specified API - let response = get(api_url).await; + let parsed_api_url = parse_string(api_url, FieldElement::from_str(&query.addr).unwrap()); + + let response = get(&parsed_api_url).await; match response { Ok(res) => { let res_text = res.text().await.unwrap(); // Check response against the regex - let re = Regex::new(regex_str).unwrap(); + let parsed_regex_str = parse_string(regex_str, FieldElement::from_str(&query.addr).unwrap()); + let re = Regex::new(&parsed_regex_str).unwrap(); if re.is_match(&res_text) { // Mark the task as completed match state.upsert_completed_task(FieldElement::from_str(&query.addr).unwrap(), task_id).await { diff --git a/src/utils.rs b/src/utils.rs index 39c2dd6c..72f72667 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -33,6 +33,8 @@ use std::str::FromStr; use std::{fmt::Write, sync::Arc}; use tokio::time::{sleep, Duration}; +use regex::Regex; + #[macro_export] macro_rules! pub_struct { ($($derive:path),*; $name:ident {$($field:ident: $t:ty),* $(,)?}) => { @@ -830,12 +832,17 @@ impl Clone for Box { pub fn parse_string(input: &str, address: FieldElement) -> String { let mut result = input.to_string(); - if input.contains("{addr_hex}") { - result = result.replace("{addr_hex}", to_hex(address).as_str()); - } + let hex_address = to_hex(address); + let dec_address = address.to_string(); - if input.contains("{addr_dec}") { - result = result.replace("{addr_dec}", address.to_string().as_str()); + let regex_patterns = vec![ + (r"\{addr_hex\}", hex_address.as_str()), + (r"\{addr_dec\}", dec_address.as_str()), + ]; + + for (pattern, replacement) in regex_patterns { + let re = Regex::new(pattern).unwrap(); + result = re.replace_all(&result, replacement).to_string(); } result