From 651cfa5a281a082939271397fb911babf4ce54a9 Mon Sep 17 00:00:00 2001 From: willy-de7 Date: Wed, 29 Apr 2026 11:28:54 +0000 Subject: [PATCH 1/2] feat: add batch query functions for indexer support (#93) - get_projects_by_ids(Vec): fetch multiple projects in one call - get_reviews_by_ids(Vec<(u64, Address)>): batch review fetching - list_projects_by_verification_status(status, start, limit): filter by verification status - Add VerificationStatus to lib.rs imports --- dongle-smartcontract/src/lib.rs | 19 ++++++- dongle-smartcontract/src/project_registry.rs | 56 ++++++++++++++++++++ dongle-smartcontract/src/review_registry.rs | 13 +++++ 3 files changed, 87 insertions(+), 1 deletion(-) diff --git a/dongle-smartcontract/src/lib.rs b/dongle-smartcontract/src/lib.rs index 183386e..3dd1039 100644 --- a/dongle-smartcontract/src/lib.rs +++ b/dongle-smartcontract/src/lib.rs @@ -26,7 +26,7 @@ use crate::review_registry::ReviewRegistry; use crate::storage_manager::StorageManager; use crate::types::{ FeeConfig, Project, ProjectRegistrationParams, ProjectStats, ProjectUpdateParams, Review, - VerificationRecord, + VerificationRecord, VerificationStatus, }; use crate::verification_registry::VerificationRegistry; use soroban_sdk::{contract, contractimpl, Address, Env, String, Vec}; @@ -95,6 +95,19 @@ impl DongleContract { ProjectRegistry::get_owner_project_count(&env, &owner) } + pub fn get_projects_by_ids(env: Env, ids: Vec) -> Vec { + ProjectRegistry::get_projects_by_ids(&env, ids) + } + + pub fn list_projects_by_verification_status( + env: Env, + status: VerificationStatus, + start_id: u64, + limit: u32, + ) -> Vec { + ProjectRegistry::list_projects_by_verification_status(&env, status, start_id, limit) + } + // --- Review Registry --- pub fn add_review( @@ -129,6 +142,10 @@ impl DongleContract { ReviewRegistry::get_review(&env, project_id, reviewer) } + pub fn get_reviews_by_ids(env: Env, ids: Vec<(u64, Address)>) -> Vec { + ReviewRegistry::get_reviews_by_ids(&env, ids) + } + pub fn list_reviews(env: Env, project_id: u64, start_id: u32, limit: u32) -> Vec { ReviewRegistry::list_reviews(&env, project_id, start_id, limit) } diff --git a/dongle-smartcontract/src/project_registry.rs b/dongle-smartcontract/src/project_registry.rs index d1ec8a9..20cbc3e 100644 --- a/dongle-smartcontract/src/project_registry.rs +++ b/dongle-smartcontract/src/project_registry.rs @@ -264,6 +264,62 @@ impl ProjectRegistry { Self::owner_project_count(env, owner) } + pub fn get_projects_by_ids(env: &Env, ids: Vec) -> Vec { + let mut projects = Vec::new(env); + let len = ids.len(); + for i in 0..len { + if let Some(id) = ids.get(i) { + if let Some(project) = Self::get_project(env, id) { + projects.push_back(project); + } + } + } + projects + } + + pub fn list_projects_by_verification_status( + env: &Env, + status: VerificationStatus, + start_id: u64, + limit: u32, + ) -> Vec { + let effective_limit = if limit == 0 || limit > MAX_PAGE_LIMIT { + MAX_PAGE_LIMIT + } else { + limit + }; + + let count: u64 = env + .storage() + .persistent() + .get(&StorageKey::ProjectCount) + .unwrap_or(0); + + let mut projects = Vec::new(env); + if count == 0 { + return projects; + } + + let first = if start_id == 0 { 1u64 } else { start_id }; + if first > count { + return projects; + } + + let mut collected: u32 = 0; + for id in first..=count { + if collected >= effective_limit { + break; + } + if let Some(project) = Self::get_project(env, id) { + if project.verification_status == status { + projects.push_back(project); + collected += 1; + } + } + } + projects + } + pub fn list_projects(env: &Env, start_id: u64, limit: u32) -> Vec { // Enforce pagination limits: limit must be 1..=MAX_PAGE_LIMIT let effective_limit = if limit == 0 || limit > MAX_PAGE_LIMIT { diff --git a/dongle-smartcontract/src/review_registry.rs b/dongle-smartcontract/src/review_registry.rs index 8e41b75..9373018 100644 --- a/dongle-smartcontract/src/review_registry.rs +++ b/dongle-smartcontract/src/review_registry.rs @@ -285,6 +285,19 @@ impl ReviewRegistry { Ok(()) } + pub fn get_reviews_by_ids(env: &Env, ids: Vec<(u64, Address)>) -> Vec { + let mut reviews = Vec::new(env); + let len = ids.len(); + for i in 0..len { + if let Some((project_id, reviewer)) = ids.get(i) { + if let Some(review) = Self::get_review(env, project_id, reviewer) { + reviews.push_back(review); + } + } + } + reviews + } + pub fn get_review(env: &Env, project_id: u64, reviewer: Address) -> Option { env.storage() .persistent() From 6c9d53f0f8e03939c51e1cd8afacb02398acaac4 Mon Sep 17 00:00:00 2001 From: willy-de7 Date: Wed, 29 Apr 2026 11:38:11 +0000 Subject: [PATCH 2/2] fix: rename list_projects_by_verification_status to list_projects_by_status Soroban contract function names have a 32-char max. 'list_projects_by_verification_status' is 36 chars. --- dongle-smartcontract/src/lib.rs | 4 ++-- dongle-smartcontract/src/project_registry.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dongle-smartcontract/src/lib.rs b/dongle-smartcontract/src/lib.rs index 3dd1039..fe5cc3d 100644 --- a/dongle-smartcontract/src/lib.rs +++ b/dongle-smartcontract/src/lib.rs @@ -99,13 +99,13 @@ impl DongleContract { ProjectRegistry::get_projects_by_ids(&env, ids) } - pub fn list_projects_by_verification_status( + pub fn list_projects_by_status( env: Env, status: VerificationStatus, start_id: u64, limit: u32, ) -> Vec { - ProjectRegistry::list_projects_by_verification_status(&env, status, start_id, limit) + ProjectRegistry::list_projects_by_status(&env, status, start_id, limit) } // --- Review Registry --- diff --git a/dongle-smartcontract/src/project_registry.rs b/dongle-smartcontract/src/project_registry.rs index 20cbc3e..e020f96 100644 --- a/dongle-smartcontract/src/project_registry.rs +++ b/dongle-smartcontract/src/project_registry.rs @@ -277,7 +277,7 @@ impl ProjectRegistry { projects } - pub fn list_projects_by_verification_status( + pub fn list_projects_by_status( env: &Env, status: VerificationStatus, start_id: u64,