From fc72e8bb8d0600ec0dec640f4d817eff52d28a67 Mon Sep 17 00:00:00 2001 From: JoelVR17 Date: Sat, 28 Sep 2024 22:33:57 -0600 Subject: [PATCH 1/3] feat: improve the function with reguex --- src/utils.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/utils.rs b/src/utils.rs index 39c2dd6..72f7266 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 From 12821567573a9f06cc4d53d0a0cee9f77a34337d Mon Sep 17 00:00:00 2001 From: JoelVR17 Date: Sat, 28 Sep 2024 22:39:05 -0600 Subject: [PATCH 2/3] feat: implement the parse_string into verify_custom_api and verify_contract --- src/endpoints/quests/verify_contract.rs | 21 +++++++++++++++------ src/endpoints/quests/verify_custom_api.rs | 5 ++++- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/endpoints/quests/verify_contract.rs b/src/endpoints/quests/verify_contract.rs index 78fde32..398c8a2 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,34 +40,40 @@ 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, Err(e) => return get_error(format!("Invalid calldata: {}", e)), }; + let entry_point_selector = match FieldElement::from_hex_be(&call.entry_point) { Ok(selector) => selector, Err(e) => return get_error(format!("Invalid entry point: {}", e)), }; + let call_result = state .provider .call( @@ -79,6 +86,7 @@ pub async fn handler( ) .await; + match call_result { Ok(result) => { let regex = match Regex::new(&call.regex) { @@ -86,7 +94,8 @@ pub async fn handler( 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()); } @@ -103,4 +112,4 @@ pub async fn handler( } else { get_error("No calls specified for this task.".to_string()) } -} \ No newline at end of file +} diff --git a/src/endpoints/quests/verify_custom_api.rs b/src/endpoints/quests/verify_custom_api.rs index bda30a1..96f9456 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,7 +56,9 @@ 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) => { From 10db3f03c6b5dc5cb78d0150d2eee8ba64754704 Mon Sep 17 00:00:00 2001 From: JoelVR17 Date: Sun, 29 Sep 2024 22:04:47 -0600 Subject: [PATCH 3/3] feat: implement regex in both routes --- src/endpoints/quests/verify_contract.rs | 12 +++--------- src/endpoints/quests/verify_custom_api.rs | 3 ++- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/endpoints/quests/verify_contract.rs b/src/endpoints/quests/verify_contract.rs index 398c8a2..e82e454 100644 --- a/src/endpoints/quests/verify_contract.rs +++ b/src/endpoints/quests/verify_contract.rs @@ -47,17 +47,14 @@ pub async fn handler( 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| { - let replaced_calldata = parse_string(s, FieldElement::from_hex_be(s).unwrap()); FieldElement::from_hex_be(&replaced_calldata) }) @@ -67,13 +64,11 @@ pub async fn handler( Err(e) => return get_error(format!("Invalid calldata: {}", e)), }; - let entry_point_selector = match FieldElement::from_hex_be(&call.entry_point) { Ok(selector) => selector, Err(e) => return get_error(format!("Invalid entry point: {}", e)), }; - let call_result = state .provider .call( @@ -86,16 +81,15 @@ pub async fn handler( ) .await; - 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()); } @@ -112,4 +106,4 @@ pub async fn handler( } else { get_error("No calls specified for this task.".to_string()) } -} +} \ No newline at end of file diff --git a/src/endpoints/quests/verify_custom_api.rs b/src/endpoints/quests/verify_custom_api.rs index 96f9456..f94f2bf 100644 --- a/src/endpoints/quests/verify_custom_api.rs +++ b/src/endpoints/quests/verify_custom_api.rs @@ -65,7 +65,8 @@ pub async fn handler( 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 {