This commit is contained in:
2026-05-12 18:53:42 +02:00
parent 4f6a4806e2
commit 75c2b6983d
22 changed files with 1452 additions and 368 deletions

View File

@@ -199,7 +199,7 @@ fn parse_accounts_json(accounts_json: &str) -> std::vec::Vec<std::string::String
accounts.push(text.to_string());
continue;
}
if let Some(pubkey) = item.get("pubkey").and_then(|value| value.as_str()) {
if let Some(pubkey) = item.get("pubkey").and_then(|value| return value.as_str()) {
accounts.push(pubkey.to_string());
}
}

View File

@@ -177,12 +177,12 @@ fn build_program_instruction_discriminator_summaries(
});
}
summaries.sort_by(|left, right| {
right
return right
.undecoded_occurrence_count
.cmp(&left.undecoded_occurrence_count)
.then(right.transaction_count.cmp(&left.transaction_count))
.then(right.occurrence_count.cmp(&left.occurrence_count))
.then(right.latest_instruction_id.cmp(&left.latest_instruction_id))
.then(right.latest_instruction_id.cmp(&left.latest_instruction_id));
});
return Ok(summaries);
}

View File

@@ -26,178 +26,17 @@ pub(crate) struct DexCatalogItem {
pub(crate) fn dex_catalog_item_by_code(
code: &str,
) -> std::option::Option<crate::dex_catalog::DexCatalogItem> {
match code {
"raydium" => {
return Some(crate::dex_catalog::DexCatalogItem {
code: "raydium",
name: "Raydium AMM v4",
program_id: Some(crate::RAYDIUM_AMM_V4_PROGRAM_ID),
router_program_id: None,
is_enabled: true,
});
},
"raydium_cpmm" => {
return Some(crate::dex_catalog::DexCatalogItem {
code: "raydium_cpmm",
name: "Raydium CPMM",
program_id: Some(crate::RAYDIUM_CPMM_PROGRAM_ID),
router_program_id: None,
is_enabled: true,
});
},
"raydium_clmm" => {
return Some(crate::dex_catalog::DexCatalogItem {
code: "raydium_clmm",
name: "Raydium CLMM",
program_id: Some(crate::RAYDIUM_CLMM_PROGRAM_ID),
router_program_id: None,
is_enabled: true,
});
},
"pump_fun" => {
return Some(crate::dex_catalog::DexCatalogItem {
code: "pump_fun",
name: "Pump.fun",
program_id: Some(crate::PUMP_FUN_PROGRAM_ID),
router_program_id: None,
is_enabled: true,
});
},
"pump_swap" => {
return Some(crate::dex_catalog::DexCatalogItem {
code: "pump_swap",
name: "PumpSwap",
program_id: Some(crate::PUMP_SWAP_PROGRAM_ID),
router_program_id: None,
is_enabled: true,
});
},
"meteora_dbc" => {
return Some(crate::dex_catalog::DexCatalogItem {
code: "meteora_dbc",
name: "Meteora DBC",
program_id: Some(crate::METEORA_DBC_PROGRAM_ID),
router_program_id: None,
is_enabled: true,
});
},
"meteora_dlmm" => {
return Some(crate::dex_catalog::DexCatalogItem {
code: "meteora_dlmm",
name: "Meteora DLMM",
program_id: Some(crate::METEORA_DLMM_PROGRAM_ID),
router_program_id: None,
is_enabled: true,
});
},
"meteora_damm_v1" => {
return Some(crate::dex_catalog::DexCatalogItem {
code: "meteora_damm_v1",
name: "Meteora DAMM v1",
program_id: Some(crate::METEORA_DAMM_V1_PROGRAM_ID),
router_program_id: None,
is_enabled: true,
});
},
"meteora_damm_v2" => {
return Some(crate::dex_catalog::DexCatalogItem {
code: "meteora_damm_v2",
name: "Meteora DAMM v2",
program_id: Some(crate::METEORA_DAMM_V2_PROGRAM_ID),
router_program_id: None,
is_enabled: true,
});
},
"orca_whirlpools" => {
return Some(crate::dex_catalog::DexCatalogItem {
code: "orca_whirlpools",
name: "Orca Whirlpools",
program_id: Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID),
router_program_id: None,
is_enabled: true,
});
},
"fluxbeam" => {
return Some(crate::dex_catalog::DexCatalogItem {
code: "fluxbeam",
name: "FluxBeam",
program_id: Some(crate::FLUXBEAM_PROGRAM_ID),
router_program_id: None,
is_enabled: true,
});
},
"dexlab" => {
return Some(crate::dex_catalog::DexCatalogItem {
code: "dexlab",
name: "DexLab Swap/Pool",
program_id: Some(crate::DEXLAB_PROGRAM_ID),
router_program_id: None,
is_enabled: true,
});
},
// Planned launch/swap surfaces.
//
// These entries are intentionally present before decoder support so that
// the roadmap can evolve without duplicating DEX metadata later.
//
// Program ids should be filled only after validation against live
// transactions and official or otherwise trustworthy references.
"raydium_launchlab" => {
return Some(crate::dex_catalog::DexCatalogItem {
code: "raydium_launchlab",
name: "Raydium LaunchLab",
program_id: None,
router_program_id: None,
is_enabled: false,
});
},
"letsbonk" => {
return Some(crate::dex_catalog::DexCatalogItem {
code: "letsbonk",
name: "LetsBonk / Bonk.fun",
program_id: None,
router_program_id: None,
is_enabled: false,
});
},
"boop_fun" => {
return Some(crate::dex_catalog::DexCatalogItem {
code: "boop_fun",
name: "Boop.fun",
program_id: None,
router_program_id: None,
is_enabled: false,
});
},
"moonshot" => {
return Some(crate::dex_catalog::DexCatalogItem {
code: "moonshot",
name: "Moonshot",
program_id: None,
router_program_id: None,
is_enabled: false,
});
},
"believe" => {
return Some(crate::dex_catalog::DexCatalogItem {
code: "believe",
name: "Believe",
program_id: None,
router_program_id: None,
is_enabled: false,
});
},
"heaven" => {
return Some(crate::dex_catalog::DexCatalogItem {
code: "heaven",
name: "Heaven",
program_id: None,
router_program_id: None,
is_enabled: false,
});
},
_ => return None,
}
let matrix_entry = match crate::dex_support_matrix_entry_by_code(code) {
Some(matrix_entry) => matrix_entry,
None => return None,
};
return Some(crate::dex_catalog::DexCatalogItem {
code: matrix_entry.code,
name: matrix_entry.display_name,
program_id: matrix_entry.program_id,
router_program_id: matrix_entry.router_program_id,
is_enabled: matrix_entry.catalog_enabled,
});
}
/// Ensures that one known DEX exists in storage and returns its internal id.
@@ -283,7 +122,15 @@ mod tests {
#[test]
fn planned_launch_surfaces_are_present_but_disabled() {
let codes = ["raydium_launchlab", "letsbonk", "boop_fun", "moonshot", "believe", "heaven"];
let codes = [
"raydium_launchlab",
"raydium_launchpad",
"letsbonk",
"boop_fun",
"moonshot",
"believe",
"heaven",
];
for code in codes {
let item_option = crate::dex_catalog::dex_catalog_item_by_code(code);
let item = match item_option {
@@ -297,6 +144,23 @@ mod tests {
}
}
#[test]
fn catalog_entries_are_derived_from_support_matrix() {
let item = match crate::dex_catalog::dex_catalog_item_by_code("pump_swap") {
Some(item) => item,
None => panic!("expected pump_swap catalog item"),
};
let matrix_entry = match crate::dex_support_matrix_entry_by_code("pump_swap") {
Some(matrix_entry) => matrix_entry,
None => panic!("expected pump_swap matrix entry"),
};
assert_eq!(item.code, matrix_entry.code);
assert_eq!(item.name, matrix_entry.display_name);
assert_eq!(item.program_id, matrix_entry.program_id);
assert_eq!(item.router_program_id, matrix_entry.router_program_id);
assert_eq!(item.is_enabled, matrix_entry.catalog_enabled);
}
#[test]
fn unknown_dex_code_is_not_silently_accepted() {
let item_option = crate::dex_catalog::dex_catalog_item_by_code("zora_solana");

View File

@@ -0,0 +1,910 @@
// file: kb_lib/src/dex_support_matrix.rs
//! Shared DEX support matrix.
//!
//! This module centralizes protocol metadata that was previously duplicated
//! across catalog, transaction classification, candidate recording and roadmap
//! surfaces. It intentionally does not decode instructions and does not decide
//! whether one decoded event is actionable.
/// Support matrix entry for one DEX, router, aggregator or launch surface.
#[derive(Debug, Copy, Clone, Eq, PartialEq, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DexSupportMatrixEntry {
/// Stable internal protocol or surface code.
pub code: &'static str,
/// Human-readable protocol or surface name.
pub display_name: &'static str,
/// Protocol family, for example `raydium`, `meteora` or `pump`.
pub family: &'static str,
/// Protocol version or `unknown` when not verified locally.
pub version: &'static str,
/// Surface type: `launch`, `bonding_curve`, `AMM`, `CLMM`, `DLMM`, `router`, `aggregator` or `unknown`.
pub surface_type: &'static str,
/// Primary Solana program id, when verified in local constants or docs.
pub program_id: std::option::Option<&'static str>,
/// Optional router program id, when this entry uses a distinct router.
pub router_program_id: std::option::Option<&'static str>,
/// Program id confidence: `known`, `to_verify` or `unknown`.
pub program_id_status: &'static str,
/// Whether this protocol has been observed in the local replay corpus.
pub observed: bool,
/// Whether the code currently contains a decoder for this protocol.
pub decoded: bool,
/// Whether decoded events are currently materialized beyond raw decoded rows.
pub materialized: bool,
/// Whether this protocol can currently produce trade candidates.
pub trade_candidate: bool,
/// Whether this protocol can currently produce candle candidates.
pub candle_candidate: bool,
/// Whether this protocol can currently produce pair candidates.
pub pair_candidate: bool,
/// Whether this protocol can currently produce pool candidates.
pub pool_candidate: bool,
/// Operational support status: `supported`, `partial`, `planned`, `ignored`, `to_verify` or `unknown`.
pub status: &'static str,
/// Confidence level attached to this matrix entry.
pub confidence: &'static str,
/// Optional explicit skip reason for partial or ignored entries.
pub skip_reason: std::option::Option<&'static str>,
/// Whether the entry should be inserted as an enabled DEX in the storage catalog.
pub catalog_enabled: bool,
}
/// Owned DTO form of a DEX support matrix entry.
#[derive(Debug, Clone, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DexSupportMatrixEntryDto {
/// Stable internal protocol or surface code.
pub code: std::string::String,
/// Human-readable protocol or surface name.
pub display_name: std::string::String,
/// Protocol family, for example `raydium`, `meteora` or `pump`.
pub family: std::string::String,
/// Protocol version or `unknown` when not verified locally.
pub version: std::string::String,
/// Surface type: `launch`, `bonding_curve`, `AMM`, `CLMM`, `DLMM`, `router`, `aggregator` or `unknown`.
pub surface_type: std::string::String,
/// Primary Solana program id, when verified in local constants or docs.
pub program_id: std::option::Option<std::string::String>,
/// Optional router program id, when this entry uses a distinct router.
pub router_program_id: std::option::Option<std::string::String>,
/// Program id confidence: `known`, `to_verify` or `unknown`.
pub program_id_status: std::string::String,
/// Whether this protocol has been observed in the local replay corpus.
pub observed: bool,
/// Whether the code currently contains a decoder for this protocol.
pub decoded: bool,
/// Whether decoded events are currently materialized beyond raw decoded rows.
pub materialized: bool,
/// Whether this protocol can currently produce trade candidates.
pub trade_candidate: bool,
/// Whether this protocol can currently produce candle candidates.
pub candle_candidate: bool,
/// Whether this protocol can currently produce pair candidates.
pub pair_candidate: bool,
/// Whether this protocol can currently produce pool candidates.
pub pool_candidate: bool,
/// Operational support status: `supported`, `partial`, `planned`, `ignored`, `to_verify` or `unknown`.
pub status: std::string::String,
/// Confidence level attached to this matrix entry.
pub confidence: std::string::String,
/// Optional explicit skip reason for partial or ignored entries.
pub skip_reason: std::option::Option<std::string::String>,
/// Whether the entry should be inserted as an enabled DEX in the storage catalog.
pub catalog_enabled: bool,
}
impl DexSupportMatrixEntryDto {
/// Builds an owned DTO from one static support matrix entry.
pub fn from_entry(entry: &crate::DexSupportMatrixEntry) -> Self {
return Self {
code: entry.code.to_string(),
display_name: entry.display_name.to_string(),
family: entry.family.to_string(),
version: entry.version.to_string(),
surface_type: entry.surface_type.to_string(),
program_id: match entry.program_id {
Some(program_id) => Some(program_id.to_string()),
None => None,
},
router_program_id: match entry.router_program_id {
Some(router_program_id) => Some(router_program_id.to_string()),
None => None,
},
program_id_status: entry.program_id_status.to_string(),
observed: entry.observed,
decoded: entry.decoded,
materialized: entry.materialized,
trade_candidate: entry.trade_candidate,
candle_candidate: entry.candle_candidate,
pair_candidate: entry.pair_candidate,
pool_candidate: entry.pool_candidate,
status: entry.status.to_string(),
confidence: entry.confidence.to_string(),
skip_reason: match entry.skip_reason {
Some(skip_reason) => Some(skip_reason.to_string()),
None => None,
},
catalog_enabled: entry.catalog_enabled,
};
}
}
const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
DexSupportMatrixEntry {
code: "pump_fun",
display_name: "Pump.fun",
family: "pump",
version: "bonding_curve",
surface_type: "launch",
program_id: Some(crate::PUMP_FUN_PROGRAM_ID),
router_program_id: None,
program_id_status: "known",
observed: false,
decoded: true,
materialized: true,
trade_candidate: true,
candle_candidate: true,
pair_candidate: true,
pool_candidate: true,
status: "partial",
confidence: "high",
skip_reason: Some("launch_surface_requires_migration_linking_before_live_trading"),
catalog_enabled: true,
},
DexSupportMatrixEntry {
code: "pump_swap",
display_name: "PumpSwap",
family: "pump",
version: "amm",
surface_type: "AMM",
program_id: Some(crate::PUMP_SWAP_PROGRAM_ID),
router_program_id: None,
program_id_status: "known",
observed: true,
decoded: true,
materialized: true,
trade_candidate: true,
candle_candidate: true,
pair_candidate: true,
pool_candidate: true,
status: "supported",
confidence: "high",
skip_reason: None,
catalog_enabled: true,
},
DexSupportMatrixEntry {
code: "raydium_cpmm",
display_name: "Raydium CPMM",
family: "raydium",
version: "cpmm",
surface_type: "AMM",
program_id: Some(crate::RAYDIUM_CPMM_PROGRAM_ID),
router_program_id: None,
program_id_status: "known",
observed: true,
decoded: true,
materialized: true,
trade_candidate: true,
candle_candidate: true,
pair_candidate: true,
pool_candidate: true,
status: "supported",
confidence: "high",
skip_reason: None,
catalog_enabled: true,
},
DexSupportMatrixEntry {
code: "raydium_clmm",
display_name: "Raydium CLMM",
family: "raydium",
version: "clmm",
surface_type: "CLMM",
program_id: Some(crate::RAYDIUM_CLMM_PROGRAM_ID),
router_program_id: None,
program_id_status: "known",
observed: true,
decoded: true,
materialized: true,
trade_candidate: true,
candle_candidate: true,
pair_candidate: true,
pool_candidate: true,
status: "supported",
confidence: "high",
skip_reason: None,
catalog_enabled: true,
},
DexSupportMatrixEntry {
code: "raydium_amm_v4",
display_name: "Raydium AMM v4",
family: "raydium",
version: "amm_v4",
surface_type: "AMM",
program_id: Some(crate::RAYDIUM_AMM_V4_PROGRAM_ID),
router_program_id: None,
program_id_status: "known",
observed: false,
decoded: true,
materialized: true,
trade_candidate: true,
candle_candidate: true,
pair_candidate: true,
pool_candidate: true,
status: "partial",
confidence: "medium",
skip_reason: Some("not_observed_in_0_7_28_replay"),
catalog_enabled: true,
},
DexSupportMatrixEntry {
code: "raydium",
display_name: "Raydium AMM v4",
family: "raydium",
version: "amm_v4_alias",
surface_type: "AMM",
program_id: Some(crate::RAYDIUM_AMM_V4_PROGRAM_ID),
router_program_id: None,
program_id_status: "known",
observed: false,
decoded: true,
materialized: true,
trade_candidate: true,
candle_candidate: true,
pair_candidate: true,
pool_candidate: true,
status: "partial",
confidence: "medium",
skip_reason: Some("legacy_catalog_alias_for_raydium_amm_v4"),
catalog_enabled: true,
},
DexSupportMatrixEntry {
code: "raydium_launchlab",
display_name: "Raydium LaunchLab",
family: "raydium",
version: "launchlab",
surface_type: "launch",
program_id: Some(crate::RAYDIUM_LAUNCHLAB_PROGRAM_ID),
router_program_id: None,
program_id_status: "known",
observed: false,
decoded: false,
materialized: false,
trade_candidate: false,
candle_candidate: false,
pair_candidate: true,
pool_candidate: true,
status: "planned",
confidence: "medium",
skip_reason: Some("decoder_and_materialization_not_enabled"),
catalog_enabled: false,
},
DexSupportMatrixEntry {
code: "raydium_launchpad",
display_name: "Raydium Launchpad",
family: "raydium",
version: "unknown",
surface_type: "launch",
program_id: None,
router_program_id: None,
program_id_status: "to_verify",
observed: false,
decoded: false,
materialized: false,
trade_candidate: false,
candle_candidate: false,
pair_candidate: true,
pool_candidate: true,
status: "to_verify",
confidence: "low",
skip_reason: Some("program_id_to_verify"),
catalog_enabled: false,
},
DexSupportMatrixEntry {
code: "raydium_router",
display_name: "Raydium Router",
family: "raydium",
version: "router",
surface_type: "router",
program_id: Some(crate::RAYDIUM_AMM_ROUTING_PROGRAM_ID),
router_program_id: None,
program_id_status: "known",
observed: false,
decoded: false,
materialized: false,
trade_candidate: false,
candle_candidate: false,
pair_candidate: false,
pool_candidate: false,
status: "partial",
confidence: "medium",
skip_reason: Some("router_not_materialized_as_direct_trade_surface"),
catalog_enabled: false,
},
DexSupportMatrixEntry {
code: "raydium_stable_swap",
display_name: "Raydium Stable Swap AMM",
family: "raydium",
version: "stable_swap",
surface_type: "AMM",
program_id: Some(crate::RAYDIUM_STABLE_SWAP_AMM_PROGRAM_ID),
router_program_id: None,
program_id_status: "known",
observed: false,
decoded: false,
materialized: false,
trade_candidate: false,
candle_candidate: false,
pair_candidate: false,
pool_candidate: false,
status: "planned",
confidence: "medium",
skip_reason: Some("deprecated_program_not_prioritized"),
catalog_enabled: false,
},
DexSupportMatrixEntry {
code: "meteora_dlmm",
display_name: "Meteora DLMM",
family: "meteora",
version: "dlmm",
surface_type: "DLMM",
program_id: Some(crate::METEORA_DLMM_PROGRAM_ID),
router_program_id: None,
program_id_status: "known",
observed: true,
decoded: true,
materialized: true,
trade_candidate: true,
candle_candidate: true,
pair_candidate: true,
pool_candidate: true,
status: "supported",
confidence: "high",
skip_reason: None,
catalog_enabled: true,
},
DexSupportMatrixEntry {
code: "meteora_dlc",
display_name: "Meteora DLC",
family: "meteora",
version: "unknown",
surface_type: "unknown",
program_id: None,
router_program_id: None,
program_id_status: "to_verify",
observed: false,
decoded: false,
materialized: false,
trade_candidate: false,
candle_candidate: false,
pair_candidate: false,
pool_candidate: false,
status: "to_verify",
confidence: "low",
skip_reason: Some("surface_and_program_id_to_verify"),
catalog_enabled: false,
},
DexSupportMatrixEntry {
code: "meteora_damm_v1",
display_name: "Meteora DAMM v1",
family: "meteora",
version: "damm_v1",
surface_type: "AMM",
program_id: Some(crate::METEORA_DAMM_V1_PROGRAM_ID),
router_program_id: None,
program_id_status: "known",
observed: true,
decoded: true,
materialized: false,
trade_candidate: false,
candle_candidate: false,
pair_candidate: true,
pool_candidate: true,
status: "partial",
confidence: "medium",
skip_reason: Some("meteora_damm_v1_swap_without_amount_payload"),
catalog_enabled: true,
},
DexSupportMatrixEntry {
code: "meteora_damm_v2",
display_name: "Meteora DAMM v2",
family: "meteora",
version: "damm_v2",
surface_type: "AMM",
program_id: Some(crate::METEORA_DAMM_V2_PROGRAM_ID),
router_program_id: None,
program_id_status: "known",
observed: false,
decoded: true,
materialized: true,
trade_candidate: true,
candle_candidate: true,
pair_candidate: true,
pool_candidate: true,
status: "partial",
confidence: "medium",
skip_reason: Some("not_observed_in_0_7_28_replay"),
catalog_enabled: true,
},
DexSupportMatrixEntry {
code: "meteora_dbc",
display_name: "Meteora DBC",
family: "meteora",
version: "dbc",
surface_type: "bonding_curve",
program_id: Some(crate::METEORA_DBC_PROGRAM_ID),
router_program_id: None,
program_id_status: "known",
observed: false,
decoded: true,
materialized: true,
trade_candidate: true,
candle_candidate: true,
pair_candidate: true,
pool_candidate: true,
status: "partial",
confidence: "medium",
skip_reason: Some("not_observed_in_0_7_28_replay"),
catalog_enabled: true,
},
DexSupportMatrixEntry {
code: "orca_whirlpools",
display_name: "Orca Whirlpools",
family: "orca",
version: "whirlpools",
surface_type: "CLMM",
program_id: Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID),
router_program_id: None,
program_id_status: "known",
observed: false,
decoded: true,
materialized: true,
trade_candidate: true,
candle_candidate: true,
pair_candidate: true,
pool_candidate: true,
status: "partial",
confidence: "medium",
skip_reason: Some("not_observed_in_0_7_28_replay"),
catalog_enabled: true,
},
DexSupportMatrixEntry {
code: "fluxbeam",
display_name: "FluxBeam",
family: "fluxbeam",
version: "unknown",
surface_type: "AMM",
program_id: Some(crate::FLUXBEAM_PROGRAM_ID),
router_program_id: None,
program_id_status: "known",
observed: false,
decoded: true,
materialized: true,
trade_candidate: true,
candle_candidate: true,
pair_candidate: true,
pool_candidate: true,
status: "partial",
confidence: "medium",
skip_reason: Some("not_observed_in_0_7_28_replay"),
catalog_enabled: true,
},
DexSupportMatrixEntry {
code: "dexlab",
display_name: "DexLab Swap/Pool",
family: "dexlab",
version: "unknown",
surface_type: "AMM",
program_id: Some(crate::DEXLAB_PROGRAM_ID),
router_program_id: None,
program_id_status: "known",
observed: false,
decoded: true,
materialized: true,
trade_candidate: true,
candle_candidate: true,
pair_candidate: true,
pool_candidate: true,
status: "partial",
confidence: "medium",
skip_reason: Some("not_observed_in_0_7_28_replay"),
catalog_enabled: true,
},
DexSupportMatrixEntry {
code: "bags",
display_name: "Bags",
family: "bags",
version: "unknown",
surface_type: "launch",
program_id: None,
router_program_id: None,
program_id_status: "unknown",
observed: false,
decoded: false,
materialized: false,
trade_candidate: false,
candle_candidate: false,
pair_candidate: true,
pool_candidate: true,
status: "planned",
confidence: "low",
skip_reason: Some("program_id_to_verify"),
catalog_enabled: false,
},
DexSupportMatrixEntry {
code: "letsbonk",
display_name: "LetsBonk / Bonk.fun",
family: "bonk",
version: "unknown",
surface_type: "launch",
program_id: None,
router_program_id: None,
program_id_status: "unknown",
observed: false,
decoded: false,
materialized: false,
trade_candidate: false,
candle_candidate: false,
pair_candidate: true,
pool_candidate: true,
status: "planned",
confidence: "low",
skip_reason: Some("program_id_to_verify"),
catalog_enabled: false,
},
DexSupportMatrixEntry {
code: "bonk",
display_name: "Bonk launch surface",
family: "bonk",
version: "unknown",
surface_type: "launch",
program_id: None,
router_program_id: None,
program_id_status: "unknown",
observed: false,
decoded: false,
materialized: false,
trade_candidate: false,
candle_candidate: false,
pair_candidate: true,
pool_candidate: true,
status: "planned",
confidence: "low",
skip_reason: Some("program_id_to_verify"),
catalog_enabled: false,
},
DexSupportMatrixEntry {
code: "okx_dex",
display_name: "OKX DEX",
family: "okx",
version: "unknown",
surface_type: "aggregator",
program_id: None,
router_program_id: None,
program_id_status: "unknown",
observed: false,
decoded: false,
materialized: false,
trade_candidate: false,
candle_candidate: false,
pair_candidate: false,
pool_candidate: false,
status: "planned",
confidence: "low",
skip_reason: Some("program_id_to_verify"),
catalog_enabled: false,
},
DexSupportMatrixEntry {
code: "boop_fun",
display_name: "Boop.fun",
family: "boop",
version: "unknown",
surface_type: "launch",
program_id: None,
router_program_id: None,
program_id_status: "unknown",
observed: false,
decoded: false,
materialized: false,
trade_candidate: false,
candle_candidate: false,
pair_candidate: true,
pool_candidate: true,
status: "planned",
confidence: "low",
skip_reason: Some("program_id_to_verify"),
catalog_enabled: false,
},
DexSupportMatrixEntry {
code: "moonshot",
display_name: "Moonshot",
family: "moonshot",
version: "unknown",
surface_type: "launch",
program_id: None,
router_program_id: None,
program_id_status: "unknown",
observed: false,
decoded: false,
materialized: false,
trade_candidate: false,
candle_candidate: false,
pair_candidate: true,
pool_candidate: true,
status: "planned",
confidence: "low",
skip_reason: Some("program_id_to_verify"),
catalog_enabled: false,
},
DexSupportMatrixEntry {
code: "believe",
display_name: "Believe",
family: "believe",
version: "unknown",
surface_type: "launch",
program_id: None,
router_program_id: None,
program_id_status: "unknown",
observed: false,
decoded: false,
materialized: false,
trade_candidate: false,
candle_candidate: false,
pair_candidate: true,
pool_candidate: true,
status: "planned",
confidence: "low",
skip_reason: Some("program_id_to_verify"),
catalog_enabled: false,
},
DexSupportMatrixEntry {
code: "zora",
display_name: "Zora",
family: "zora",
version: "unknown",
surface_type: "unknown",
program_id: None,
router_program_id: None,
program_id_status: "to_verify",
observed: false,
decoded: false,
materialized: false,
trade_candidate: false,
candle_candidate: false,
pair_candidate: false,
pool_candidate: false,
status: "to_verify",
confidence: "low",
skip_reason: Some("surface_and_program_id_to_verify"),
catalog_enabled: false,
},
DexSupportMatrixEntry {
code: "moonit",
display_name: "Moonit",
family: "moonit",
version: "unknown",
surface_type: "launch",
program_id: None,
router_program_id: None,
program_id_status: "unknown",
observed: false,
decoded: false,
materialized: false,
trade_candidate: false,
candle_candidate: false,
pair_candidate: true,
pool_candidate: true,
status: "planned",
confidence: "low",
skip_reason: Some("program_id_to_verify"),
catalog_enabled: false,
},
DexSupportMatrixEntry {
code: "launchbeam",
display_name: "LaunchBeam",
family: "launchbeam",
version: "unknown",
surface_type: "launch",
program_id: None,
router_program_id: None,
program_id_status: "unknown",
observed: false,
decoded: false,
materialized: false,
trade_candidate: false,
candle_candidate: false,
pair_candidate: true,
pool_candidate: true,
status: "planned",
confidence: "low",
skip_reason: Some("program_id_to_verify"),
catalog_enabled: false,
},
DexSupportMatrixEntry {
code: "heaven",
display_name: "Heaven",
family: "heaven",
version: "unknown",
surface_type: "launch",
program_id: None,
router_program_id: None,
program_id_status: "unknown",
observed: false,
decoded: false,
materialized: false,
trade_candidate: false,
candle_candidate: false,
pair_candidate: true,
pool_candidate: true,
status: "planned",
confidence: "low",
skip_reason: Some("program_id_to_verify"),
catalog_enabled: false,
},
];
/// Returns all static DEX support matrix entries.
pub fn dex_support_matrix_entries() -> &'static [crate::DexSupportMatrixEntry] {
return DEX_SUPPORT_MATRIX_ENTRIES;
}
/// Returns all DEX support matrix entries as owned DTOs.
pub fn dex_support_matrix_entry_dtos() -> std::vec::Vec<crate::DexSupportMatrixEntryDto> {
let mut entries = std::vec::Vec::new();
for entry in crate::dex_support_matrix_entries() {
entries.push(crate::DexSupportMatrixEntryDto::from_entry(entry));
}
return entries;
}
/// Looks up one DEX support matrix entry by internal code.
pub fn dex_support_matrix_entry_by_code(
code: &str,
) -> std::option::Option<&'static crate::DexSupportMatrixEntry> {
for entry in crate::dex_support_matrix_entries() {
if entry.code == code {
return Some(entry);
}
}
return None;
}
/// Looks up one DEX support matrix entry by primary or router program id.
pub fn dex_support_matrix_entry_by_program_id(
program_id: &str,
) -> std::option::Option<&'static crate::DexSupportMatrixEntry> {
for entry in crate::dex_support_matrix_entries() {
if let Some(entry_program_id) = entry.program_id {
if entry_program_id == program_id {
return Some(entry);
}
}
if let Some(entry_router_program_id) = entry.router_program_id {
if entry_router_program_id == program_id {
return Some(entry);
}
}
}
return None;
}
#[cfg(test)]
mod tests {
#[test]
fn matrix_contains_required_0_7_29_entries() {
let codes = [
"pump_fun",
"pump_swap",
"raydium_cpmm",
"raydium_clmm",
"raydium_amm_v4",
"raydium_launchlab",
"raydium_launchpad",
"meteora_dlmm",
"meteora_dlc",
"meteora_damm_v1",
"meteora_damm_v2",
"bags",
"bonk",
"okx_dex",
"boop_fun",
"moonshot",
"believe",
"zora",
"moonit",
"launchbeam",
"heaven",
"dexlab",
];
for code in codes {
let entry = crate::dex_support_matrix_entry_by_code(code);
assert!(entry.is_some(), "missing matrix entry for {}", code);
}
}
#[test]
fn matrix_does_not_invent_program_ids_for_unverified_planned_surfaces() {
let codes = [
"bags",
"bonk",
"okx_dex",
"boop_fun",
"moonshot",
"believe",
"zora",
"moonit",
"launchbeam",
"heaven",
];
for code in codes {
let entry = match crate::dex_support_matrix_entry_by_code(code) {
Some(entry) => entry,
None => panic!("missing matrix entry for {}", code),
};
assert!(entry.program_id.is_none(), "{} should not have invented program id", code);
assert!(!entry.catalog_enabled, "{} should not be enabled before verification", code);
}
}
#[test]
fn matrix_lookup_by_program_id_returns_expected_protocol() {
let entry = match crate::dex_support_matrix_entry_by_program_id(crate::METEORA_DLMM_PROGRAM_ID)
{
Some(entry) => entry,
None => panic!("expected meteora_dlmm program id lookup"),
};
assert_eq!(entry.code, "meteora_dlmm");
let raydium_entry = match crate::dex_support_matrix_entry_by_program_id(
crate::RAYDIUM_AMM_V4_PROGRAM_ID,
) {
Some(entry) => entry,
None => panic!("expected raydium AMM v4 program id lookup"),
};
assert_eq!(raydium_entry.code, "raydium_amm_v4");
}
#[test]
fn matrix_marks_partial_meteora_damm_v1_correctly() {
let entry = match crate::dex_support_matrix_entry_by_code("meteora_damm_v1") {
Some(entry) => entry,
None => panic!("expected meteora_damm_v1 matrix entry"),
};
assert_eq!(entry.status, "partial");
assert!(entry.observed);
assert!(entry.decoded);
assert!(!entry.trade_candidate);
assert!(!entry.candle_candidate);
assert_eq!(entry.skip_reason, Some("meteora_damm_v1_swap_without_amount_payload"));
}
#[test]
fn matrix_marks_launch_surfaces_as_launch_or_bonding_curve() {
let codes = ["pump_fun", "raydium_launchlab", "bags", "moonshot", "moonit"];
for code in codes {
let entry = match crate::dex_support_matrix_entry_by_code(code) {
Some(entry) => entry,
None => panic!("missing matrix entry for {}", code),
};
assert!(
entry.surface_type == "launch" || entry.surface_type == "bonding_curve",
"{} has unexpected surface type {}",
code,
entry.surface_type
);
}
}
#[test]
fn matrix_dto_preserves_core_fields() {
let entry = match crate::dex_support_matrix_entry_by_code("pump_swap") {
Some(entry) => entry,
None => panic!("expected pump_swap matrix entry"),
};
let dto = crate::DexSupportMatrixEntryDto::from_entry(entry);
assert_eq!(dto.code, "pump_swap");
assert_eq!(dto.program_id, Some(crate::PUMP_SWAP_PROGRAM_ID.to_string()));
assert!(dto.trade_candidate);
assert!(dto.candle_candidate);
}
}

View File

@@ -39,6 +39,8 @@ mod dex_detection_route;
mod dex_event_classification;
/// Shared DEX pool materialization helpers.
mod dex_pool_materialization;
/// Shared DEX support matrix.
mod dex_support_matrix;
/// Shared error type for `kb_lib`.
mod error;
/// Generic asynchronous HTTP JSON-RPC client.
@@ -859,6 +861,18 @@ pub use dex_event_classification::is_dex_pool_lifecycle_event_kind;
pub use dex_event_classification::is_dex_reward_event_kind;
/// Returns true for swap-like DEX events.
pub use dex_event_classification::is_dex_trade_event_kind;
/// Static DEX support matrix entry.
pub use dex_support_matrix::DexSupportMatrixEntry;
/// Owned DEX support matrix entry DTO.
pub use dex_support_matrix::DexSupportMatrixEntryDto;
/// Returns all static DEX support matrix entries.
pub use dex_support_matrix::dex_support_matrix_entries;
/// Looks up one DEX support matrix entry by internal code.
pub use dex_support_matrix::dex_support_matrix_entry_by_code;
/// Looks up one DEX support matrix entry by primary or router program id.
pub use dex_support_matrix::dex_support_matrix_entry_by_program_id;
/// Returns all DEX support matrix entries as owned DTOs.
pub use dex_support_matrix::dex_support_matrix_entry_dtos;
/// Global error type used by the `kb_lib` crate.
///
/// The project intentionally avoids `anyhow` and `thiserror`, so this

View File

@@ -64,7 +64,7 @@ impl LocalPipelineValidationConfig {
/// Builds the strict validation config for `0.7.27` non-regression runs.
pub fn v0_7_27_multi_dex_non_regression() -> Self {
return Self {
profile_code: "0.7.27_multi_dex_non_regression".to_string(),
profile_code: "0.7.27_multi_dex_non_regression (obsolete)".to_string(),
expected_dex_codes: vec![
"pump_fun".to_string(),
"pump_swap".to_string(),
@@ -115,6 +115,37 @@ impl LocalPipelineValidationConfig {
require_candles_per_dex: false,
};
}
/// Builds the `0.7.29` DEX support matrix baseline validation config.
///
/// This profile preserves the `0.7.28` trade/candle non-regression checks
/// while requiring the observed partial Meteora DAMM v1 surface to remain
/// visible in diagnostics. It also exposes the DEX support matrix in the
/// validation report without making planned DEXes blocking.
pub fn v0_7_29_multi_dex_matrix_baseline() -> Self {
return Self {
profile_code: "0.7.29_multi_dex_matrix_baseline".to_string(),
expected_dex_codes: vec![
"pump_swap".to_string(),
"raydium_cpmm".to_string(),
"raydium_clmm".to_string(),
"meteora_dlmm".to_string(),
"meteora_damm_v1".to_string(),
],
require_all_expected_dexes: true,
allow_unexpected_dexes: true,
require_clean_diagnostics: false,
require_ok_trade_candidates_fully_materialized: true,
require_no_invalid_trade_events: true,
require_no_duplicate_decoded_event_trades: true,
require_no_duplicate_candle_buckets: true,
require_no_pair_gaps: false,
require_decoded_events_per_dex: true,
require_trade_events_per_dex: false,
require_candles_per_dex: false,
};
}
}
/// A single local pipeline validation issue.
@@ -147,6 +178,10 @@ pub struct LocalPipelineValidationReportDto {
pub expected_dex_codes: std::vec::Vec<std::string::String>,
/// Observed DEX codes found in diagnostics.
pub observed_dex_codes: std::vec::Vec<std::string::String>,
/// Number of entries currently exposed by the DEX support matrix.
pub dex_support_matrix_entry_count: i64,
/// DEX support matrix snapshot exposed with the validation report.
pub dex_support_matrix: std::vec::Vec<crate::DexSupportMatrixEntryDto>,
/// Issues produced by validation.
pub issues: std::vec::Vec<LocalPipelineValidationIssueDto>,
}
@@ -224,6 +259,15 @@ impl LocalPipelineValidationService {
let config = crate::LocalPipelineValidationConfig::v0_7_28_multi_dex_non_regression();
return self.validate_current_database(&config).await;
}
/// Diagnoses the current database with the `0.7.29` DEX matrix baseline profile.
pub async fn validate_v0_7_29_current_database(
&self,
) -> Result<crate::LocalPipelineValidationRunDto, crate::Error> {
let config = crate::LocalPipelineValidationConfig::v0_7_29_multi_dex_matrix_baseline();
return self.validate_current_database(&config).await;
}
}
/// Validates a diagnostics summary without performing database access.
@@ -383,6 +427,8 @@ pub fn validate_local_pipeline_diagnostics_summary(
warning_count,
expected_dex_codes,
observed_dex_codes,
dex_support_matrix_entry_count: crate::dex_support_matrix_entries().len() as i64,
dex_support_matrix: crate::dex_support_matrix_entry_dtos(),
issues,
};
}
@@ -553,6 +599,38 @@ mod tests {
assert!(report.observed_dex_codes.contains(&"meteora_damm_v1".to_string()));
}
#[test]
fn validation_accepts_0_7_29_matrix_baseline_summary() {
let summary = make_0_7_28_summary_with_meteora();
let config = crate::LocalPipelineValidationConfig::v0_7_29_multi_dex_matrix_baseline();
let report = crate::validate_local_pipeline_diagnostics_summary(&summary, &config);
assert!(report.validation_passed);
assert_eq!(report.validation_profile_code, "0.7.29_multi_dex_matrix_baseline");
assert!(report.observed_dex_codes.contains(&"meteora_damm_v1".to_string()));
assert!(report.expected_dex_codes.contains(&"meteora_damm_v1".to_string()));
}
#[test]
fn validation_report_exposes_dex_support_matrix() {
let summary = make_0_7_28_summary_with_meteora();
let config = crate::LocalPipelineValidationConfig::v0_7_29_multi_dex_matrix_baseline();
let report = crate::validate_local_pipeline_diagnostics_summary(&summary, &config);
assert!(report.dex_support_matrix_entry_count > 0);
assert_eq!(
report.dex_support_matrix_entry_count,
crate::dex_support_matrix_entries().len() as i64
);
let mut found_pump_swap = false;
for entry in &report.dex_support_matrix {
if entry.code == "pump_swap" {
found_pump_swap = true;
assert!(entry.trade_candidate);
assert!(entry.candle_candidate);
}
}
assert!(found_pump_swap);
}
#[test]
fn validation_rejects_missing_expected_dex() {
let mut summary = make_clean_summary();

View File

@@ -192,52 +192,11 @@ fn build_instruction_evidence_json(
}
fn known_dex_protocol_name(program_id: &str) -> std::option::Option<&'static str> {
if program_id == crate::RAYDIUM_AMM_V4_PROGRAM_ID {
return Some("raydium_amm_v4");
}
if program_id == crate::RAYDIUM_CPMM_PROGRAM_ID {
return Some("raydium_cpmm");
}
if program_id == crate::RAYDIUM_CLMM_PROGRAM_ID {
return Some("raydium_clmm");
}
if program_id == crate::RAYDIUM_LAUNCHLAB_PROGRAM_ID {
return Some("raydium_launchlab");
}
if program_id == crate::RAYDIUM_AMM_ROUTING_PROGRAM_ID {
return Some("raydium_router");
}
if program_id == crate::RAYDIUM_STABLE_SWAP_AMM_PROGRAM_ID {
return Some("raydium_stable_swap");
}
if program_id == crate::PUMP_FUN_PROGRAM_ID {
return Some("pump_fun");
}
if program_id == crate::PUMP_SWAP_PROGRAM_ID {
return Some("pump_swap");
}
if program_id == crate::METEORA_DBC_PROGRAM_ID {
return Some("meteora_dbc");
}
if program_id == crate::METEORA_DLMM_PROGRAM_ID {
return Some("meteora_dlmm");
}
if program_id == crate::METEORA_DAMM_V1_PROGRAM_ID {
return Some("meteora_damm_v1");
}
if program_id == crate::METEORA_DAMM_V2_PROGRAM_ID {
return Some("meteora_damm_v2");
}
if program_id == crate::ORCA_WHIRLPOOLS_PROGRAM_ID {
return Some("orca_whirlpools");
}
if program_id == crate::FLUXBEAM_PROGRAM_ID {
return Some("fluxbeam");
}
if program_id == crate::DEXLAB_PROGRAM_ID {
return Some("dexlab");
}
return None;
let matrix_entry = match crate::dex_support_matrix_entry_by_program_id(program_id) {
Some(matrix_entry) => matrix_entry,
None => return None,
};
return Some(matrix_entry.code);
}
fn should_ignore_program_id(program_id: &str) -> bool {
@@ -385,6 +344,24 @@ fn is_known_launch_surface_program_id(_program_id: &str) -> bool {
#[cfg(test)]
mod tests {
#[test]
fn known_dex_candidate_uses_support_matrix_for_priority_dexes() {
let samples = [
(crate::PUMP_SWAP_PROGRAM_ID, "pump_swap"),
(crate::RAYDIUM_CPMM_PROGRAM_ID, "raydium_cpmm"),
(crate::RAYDIUM_CLMM_PROGRAM_ID, "raydium_clmm"),
(crate::METEORA_DLMM_PROGRAM_ID, "meteora_dlmm"),
(crate::METEORA_DAMM_V1_PROGRAM_ID, "meteora_damm_v1"),
];
for (program_id, expected_protocol) in samples {
let protocol = match super::known_dex_protocol_name(program_id) {
Some(protocol) => protocol,
None => panic!("expected known protocol for {}", program_id),
};
assert_eq!(protocol, expected_protocol);
}
}
#[test]
fn associated_token_program_is_ignored() {
let transaction = test_transaction();

View File

@@ -139,7 +139,7 @@ impl TradeAggregationService {
Ok(amount_resolution) => amount_resolution,
Err(error) => return Err(error),
};
let trade_side = match amount_resolution.resolved_trade_side.clone() {
let trade_side = match amount_resolution.resolved_trade_side {
Some(resolved_trade_side) => resolved_trade_side,
None => trade_side,
};

View File

@@ -1321,7 +1321,7 @@ fn collect_account_keys_from_candidate_path(
target.push(text.to_string());
continue;
}
if let Some(pubkey) = item.get("pubkey").and_then(|value| value.as_str()) {
if let Some(pubkey) = item.get("pubkey").and_then(|value| return value.as_str()) {
target.push(pubkey.to_string());
}
}
@@ -1344,7 +1344,7 @@ fn collect_loaded_address_array(
key: &str,
target: &mut std::vec::Vec<std::string::String>,
) {
let array = match loaded_addresses.get(key).and_then(|value| value.as_array()) {
let array = match loaded_addresses.get(key).and_then(|value| return value.as_array()) {
Some(array) => array,
None => return,
};
@@ -1391,12 +1391,12 @@ fn token_balance_amount_for_account_index(
key: &str,
account_index: usize,
) -> std::option::Option<i128> {
let balances = match meta.get(key).and_then(|value| value.as_array()) {
let balances = match meta.get(key).and_then(|value| return value.as_array()) {
Some(balances) => balances,
None => return None,
};
for balance in balances {
let balance_index = balance.get("accountIndex").and_then(|value| value.as_u64());
let balance_index = balance.get("accountIndex").and_then(|value| return value.as_u64());
let balance_index = match balance_index {
Some(balance_index) => balance_index,
None => continue,
@@ -1410,8 +1410,8 @@ fn token_balance_amount_for_account_index(
}
let amount_text = balance
.get("uiTokenAmount")
.and_then(|value| value.get("amount"))
.and_then(|value| value.as_str());
.and_then(|value| return value.get("amount"))
.and_then(|value| return value.as_str());
let amount_text = match amount_text {
Some(amount_text) => amount_text,
None => return None,
@@ -1504,7 +1504,7 @@ mod tests {
stack_height,
accounts_json: "[]".to_string(),
data_json: None,
parsed_type: parsed_type.map(|value| value.to_string()),
parsed_type: parsed_type.map(|value| return value.to_string()),
parsed_json,
created_at: chrono::Utc::now(),
};

View File

@@ -352,41 +352,12 @@ fn known_dex_program_match(
Some(program_id) => program_id,
None => return None,
};
let protocol_name = if program_id == crate::RAYDIUM_AMM_V4_PROGRAM_ID {
"raydium_amm_v4"
} else if program_id == crate::RAYDIUM_CPMM_PROGRAM_ID {
"raydium_cpmm"
} else if program_id == crate::RAYDIUM_CLMM_PROGRAM_ID {
"raydium_clmm"
} else if program_id == crate::RAYDIUM_LAUNCHLAB_PROGRAM_ID {
"raydium_launchlab"
} else if program_id == crate::RAYDIUM_AMM_ROUTING_PROGRAM_ID {
"raydium_router"
} else if program_id == crate::RAYDIUM_STABLE_SWAP_AMM_PROGRAM_ID {
"raydium_stable_swap"
} else if program_id == crate::PUMP_FUN_PROGRAM_ID {
"pump_fun"
} else if program_id == crate::PUMP_SWAP_PROGRAM_ID {
"pump_swap"
} else if program_id == crate::METEORA_DBC_PROGRAM_ID {
"meteora_dbc"
} else if program_id == crate::METEORA_DLMM_PROGRAM_ID {
"meteora_dlmm"
} else if program_id == crate::METEORA_DAMM_V1_PROGRAM_ID {
"meteora_damm_v1"
} else if program_id == crate::METEORA_DAMM_V2_PROGRAM_ID {
"meteora_damm_v2"
} else if program_id == crate::ORCA_WHIRLPOOLS_PROGRAM_ID {
"orca_whirlpools"
} else if program_id == crate::FLUXBEAM_PROGRAM_ID {
"fluxbeam"
} else if program_id == crate::DEXLAB_PROGRAM_ID {
"dexlab"
} else {
return None;
let matrix_entry = match crate::dex_support_matrix_entry_by_program_id(program_id) {
Some(matrix_entry) => matrix_entry,
None => return None,
};
return Some(KnownDexProgramMatch {
protocol_name,
protocol_name: matrix_entry.code,
program_id: program_id.to_string(),
instruction_id: instruction.id,
instruction_index: instruction.instruction_index,
@@ -442,6 +413,26 @@ mod tests {
assert_eq!(program_match.instruction_index, 0);
}
#[test]
fn known_program_match_uses_support_matrix_for_priority_dexes() {
let samples = [
(crate::PUMP_SWAP_PROGRAM_ID, "pump_swap"),
(crate::RAYDIUM_CPMM_PROGRAM_ID, "raydium_cpmm"),
(crate::RAYDIUM_CLMM_PROGRAM_ID, "raydium_clmm"),
(crate::METEORA_DLMM_PROGRAM_ID, "meteora_dlmm"),
(crate::METEORA_DAMM_V1_PROGRAM_ID, "meteora_damm_v1"),
];
for (program_id, expected_protocol) in samples {
let instruction = test_instruction(Some(program_id.to_string()));
let program_match = match super::known_dex_program_match(&instruction) {
Some(program_match) => program_match,
None => panic!("expected program match for {}", expected_protocol),
};
assert_eq!(program_match.protocol_name, expected_protocol);
assert_eq!(program_match.program_id, program_id);
}
}
#[test]
fn unknown_program_id_is_not_matched() {
let instruction =