This commit is contained in:
2026-05-01 12:01:13 +02:00
parent c542aa9d32
commit 60db521a88
29 changed files with 639 additions and 155 deletions

View File

@@ -5,7 +5,8 @@
use tauri::Manager;
/// Request payload for one pipeline inspection by signature.
#[derive(Clone, Debug, serde::Deserialize)]
#[derive(Clone, Debug, serde::Deserialize, ts_rs::TS)]
#[ts(export, export_to = "../frontend/ts/bindings/KbDemoPipelineInspectRequest.ts")]
#[serde(rename_all = "camelCase")]
pub(crate) struct KbDemoPipelineInspectRequest {
/// Transaction signature to inspect.
@@ -15,7 +16,8 @@ pub(crate) struct KbDemoPipelineInspectRequest {
}
/// Response payload for one pipeline inspection.
#[derive(Clone, Debug, serde::Serialize)]
#[derive(Clone, Debug, serde::Serialize, ts_rs::TS)]
#[ts(export, export_to = "../frontend/ts/bindings/KbDemoPipelineInspectPayload.ts")]
#[serde(rename_all = "camelCase")]
pub(crate) struct KbDemoPipelineInspectPayload {
/// Inspected signature.
@@ -47,7 +49,8 @@ pub(crate) struct KbDemoPipelineInspectPayload {
}
/// Request payload for one pipeline inspection by token mint.
#[derive(Clone, Debug, serde::Deserialize)]
#[derive(Clone, Debug, serde::Deserialize, ts_rs::TS)]
#[ts(export, export_to = "../frontend/ts/bindings/KbDemoPipelineInspectTokenRequest.ts")]
#[serde(rename_all = "camelCase")]
pub(crate) struct KbDemoPipelineInspectTokenRequest {
/// Token mint to inspect.
@@ -57,7 +60,8 @@ pub(crate) struct KbDemoPipelineInspectTokenRequest {
}
/// Request payload for one pipeline inspection by pair id.
#[derive(Clone, Debug, serde::Deserialize)]
#[derive(Clone, Debug, serde::Deserialize, ts_rs::TS)]
#[ts(export, export_to = "../frontend/ts/bindings/KbDemoPipelineInspectPairRequest.ts")]
#[serde(rename_all = "camelCase")]
pub(crate) struct KbDemoPipelineInspectPairRequest {
/// Pair id to inspect.
@@ -67,7 +71,8 @@ pub(crate) struct KbDemoPipelineInspectPairRequest {
}
/// Request payload for one pipeline inspection by pool address.
#[derive(Clone, Debug, serde::Deserialize)]
#[derive(Clone, Debug, serde::Deserialize, ts_rs::TS)]
#[ts(export, export_to = "../frontend/ts/bindings/KbDemoPipelineInspectPoolRequest.ts")]
#[serde(rename_all = "camelCase")]
pub(crate) struct KbDemoPipelineInspectPoolRequest {
/// Pool address to inspect.
@@ -76,6 +81,112 @@ pub(crate) struct KbDemoPipelineInspectPoolRequest {
pub custom_timeframe_seconds: std::option::Option<i64>,
}
/// Request payload for one token backfill launched from `kb_app`.
#[derive(Clone, Debug, serde::Deserialize, ts_rs::TS)]
#[ts(export, export_to = "../frontend/ts/bindings/KbDemoPipelineBackfillTokenRequest.ts")]
#[serde(rename_all = "camelCase")]
pub(crate) struct KbDemoPipelineBackfillTokenRequest {
/// Token mint to backfill.
pub token_mint: std::string::String,
/// HTTP role used to select one endpoint in the pool.
pub http_role: std::option::Option<std::string::String>,
/// Maximum number of signatures fetched directly from the mint.
pub mint_signature_limit: usize,
/// Maximum number of signatures fetched from each discovered pool.
pub pool_signature_limit: usize,
}
/// Response payload for one token backfill launched from `kb_app`.
#[derive(Clone, Debug, serde::Serialize, ts_rs::TS)]
#[ts(export, export_to = "../frontend/ts/bindings/KbDemoPipelineBackfillTokenPayload.ts")]
#[serde(rename_all = "camelCase")]
pub(crate) struct KbDemoPipelineBackfillTokenPayload {
/// Backfilled token mint.
pub token_mint: std::string::String,
/// HTTP role used during backfill.
pub http_role: std::string::String,
/// Pretty JSON summary returned by `KbTokenBackfillService`.
pub backfill_json: std::string::String,
/// Whether the token exists in persisted token objects after backfill.
pub token_persisted_after_backfill: bool,
}
/// Launches one token backfill through the persisted `kb_lib` services.
#[tauri::command]
pub(crate) async fn demo_pipeline_backfill_token_mint(
state: tauri::State<'_, crate::KbAppState>,
request: KbDemoPipelineBackfillTokenRequest,
) -> Result<KbDemoPipelineBackfillTokenPayload, std::string::String> {
let token_mint = request.token_mint.trim().to_string();
if token_mint.is_empty() {
return Err("demo pipeline backfill token mint must not be empty".to_string());
}
let http_role = match request.http_role.clone() {
Some(http_role) => {
let trimmed = http_role.trim().to_string();
if trimmed.is_empty() {
"history_backfill".to_string()
} else {
trimmed
}
}
None => "history_backfill".to_string(),
};
if request.mint_signature_limit == 0 {
return Err("demo pipeline mintSignatureLimit must be > 0".to_string());
}
if request.pool_signature_limit == 0 {
return Err("demo pipeline poolSignatureLimit must be > 0".to_string());
}
let database = state.database.clone();
let http_pool = std::sync::Arc::new(state.http_pool.clone());
let service =
kb_lib::KbTokenBackfillService::new(http_pool, database.clone(), http_role.clone());
let backfill_result = service
.backfill_token_by_mint(
token_mint.as_str(),
request.mint_signature_limit,
request.pool_signature_limit,
)
.await;
let backfill = match backfill_result {
Ok(backfill) => backfill,
Err(error) => {
return Err(format!(
"cannot backfill token mint '{}' with role '{}': {}",
token_mint, http_role, error
));
}
};
let backfill_json_result = serde_json::to_string_pretty(&backfill);
let backfill_json = match backfill_json_result {
Ok(backfill_json) => backfill_json,
Err(error) => {
return Err(format!(
"cannot serialize token backfill result for '{}': {}",
token_mint, error
));
}
};
let token_result = kb_lib::get_token_by_mint(database.as_ref(), token_mint.as_str()).await;
let token_option = match token_result {
Ok(token_option) => token_option,
Err(error) => {
return Err(format!(
"cannot verify persisted token mint '{}' after backfill with role '{}': {}",
token_mint, http_role, error
));
}
};
let token_persisted_after_backfill = token_option.is_some();
Ok(KbDemoPipelineBackfillTokenPayload {
token_mint,
http_role,
backfill_json,
token_persisted_after_backfill,
})
}
/// Inspects one pair id through the persisted `kb_lib` pipeline state.
#[tauri::command]
pub(crate) async fn demo_pipeline_inspect_pair_id(
@@ -159,10 +270,7 @@ pub(crate) async fn demo_pipeline_inspect_pool_address(
let pool_id = match pool.id {
Some(pool_id) => pool_id,
None => {
return Err(format!(
"pool '{}' has no internal id",
pool.address
));
return Err(format!("pool '{}' has no internal id", pool.address));
}
};
let pair_result = kb_lib::get_pair_by_pool_id(database.as_ref(), pool_id).await;