diff --git a/fplus-lib/src/config.rs b/fplus-lib/src/config.rs index 2498ccac..6a786444 100644 --- a/fplus-lib/src/config.rs +++ b/fplus-lib/src/config.rs @@ -34,6 +34,7 @@ pub fn default_env_vars() -> &'static HashMap<&'static str, &'static str> { m.insert("KYC_URL", "https://kyc.allocator.tech"); m.insert("RPC_URL", "https://mainnet.optimism.io"); m.insert("DMOB_API_URL", "https://api.datacapstats.io/public/api"); + m.insert("DATACAPSTATS_API_URL", "https://api.datacapstats.io/api"); m.insert("DMOB_API_KEY", "5c993a17-7b18-4ead-a8a8-89dad981d87e"); m.insert("DAYS_TO_NEXT_AUTOALLOCATION", "14"); m.insert( diff --git a/fplus-lib/src/core/mod.rs b/fplus-lib/src/core/mod.rs index a8c6b2f6..56605d97 100644 --- a/fplus-lib/src/core/mod.rs +++ b/fplus-lib/src/core/mod.rs @@ -15,6 +15,7 @@ use reqwest::Response; use serde::{Deserialize, Serialize}; use serde_json::from_str; +use crate::external_services::filecoin::get_client_allocation; use crate::{ base64, config::get_env_var_or_default, @@ -752,6 +753,33 @@ impl LDNApplication { } } } + + match get_client_allocation(&application_id).await { + Ok(response) => { + if let Some(_) = response.count { + log::info!("Allocation found for client {}", application_id); + Self::issue_pathway_mismatch_comment( + issue_number, + info.owner, + info.repo, + None, + ) + .await?; + + return Err(LDNError::New( + "Pathway mismatch: Client has already allocation".to_string(), + )); + } else { + log::info!("Client allocation not found"); + } + } + Err(e) => { + return Err(LDNError::New(format!( + "Getting client allocation failed /// {}", + e + ))); + } + } } let file_content = match serde_json::to_string_pretty(&application_file) { diff --git a/fplus-lib/src/external_services/filecoin.rs b/fplus-lib/src/external_services/filecoin.rs index ed95d7e7..faea4925 100644 --- a/fplus-lib/src/external_services/filecoin.rs +++ b/fplus-lib/src/external_services/filecoin.rs @@ -4,6 +4,7 @@ use crate::{ config::get_env_var_or_default, models::filecoin::{ StateReadStateResponse, StateVerifiedClientStatusResponse, StateVerifierStatusResponse, + VerifiedClientResponse, }, }; @@ -86,3 +87,20 @@ pub async fn get_allowance_for_client(address: &str) -> Result Result { + let api_url = get_env_var_or_default("DATACAPSTATS_API_URL"); + let url = format!("{}/getVerifiedClients?filter={}", api_url, address); + + let client = reqwest::Client::new(); + + let response = client + .get(&url) + .send() + .await? + .json::() + .await?; + Ok(response) +} diff --git a/fplus-lib/src/models/filecoin.rs b/fplus-lib/src/models/filecoin.rs index 7e4e4123..e3350c31 100644 --- a/fplus-lib/src/models/filecoin.rs +++ b/fplus-lib/src/models/filecoin.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use serde_json::Value; pub type StateReadStateResponse = JSONRPCResponse; pub type StateVerifierStatusResponse = JSONRPCResponse; @@ -47,3 +48,25 @@ pub struct MultisigState { #[serde(rename = "PendingTxns")] pub pending_txns: Code, } + +#[derive(Serialize, Deserialize, Debug)] +pub struct VerifiedClientResponse { + #[serde(deserialize_with = "number_to_string")] + pub count: Option, +} + +fn number_to_string<'de, D>(de: D) -> Result, D::Error> +where + D: serde::Deserializer<'de>, +{ + let helper: Value = Deserialize::deserialize(de)?; + + match helper { + Value::Number(n) => Ok(n + .as_u64() + .filter(|&number| number != 0) + .map(|_| n.to_string())), + Value::String(s) => Ok(Some(s)), + _ => Ok(None), + } +}