This commit is contained in:
2026-05-14 07:52:36 +02:00
parent cfa1ff2289
commit 348ae7f153
29 changed files with 1956 additions and 35 deletions

View File

@@ -65,3 +65,4 @@
0.7.32 - Clarification des sémantiques de validation locale : distinction entre gaps littéraux, gaps bloquants et paires actionnables, afin déviter de bloquer sur des paires détectées mais non matérialisées par trade. 0.7.32 - Clarification des sémantiques de validation locale : distinction entre gaps littéraux, gaps bloquants et paires actionnables, afin déviter de bloquer sur des paires détectées mais non matérialisées par trade.
0.7.33 - Ajout du profil `0.7.33_pair_trading_readiness`, avec classification des paires directes WSOL, directes stable, inverses stable/WSOL et cross-quotes nécessitant un router. 0.7.33 - Ajout du profil `0.7.33_pair_trading_readiness`, avec classification des paires directes WSOL, directes stable, inverses stable/WSOL et cross-quotes nécessitant un router.
0.7.34 - Ajout du profil `0.7.34_non_trade_liquidity_lifecycle`, matérialisation des tables non-trade liquidité/lifecycle, warning non bloquant pour DEX attendus absents du corpus local, première tranche DLMM : `add_liquidity`, `remove_liquidity`, `initialize_position`, `initialize_bin_array`, intégration de la matérialisation non-trade dans les backfills token/pool ciblés, et distinction `PositionOpen`/`PositionClose` dans `LiquidityEventKind`. 0.7.34 - Ajout du profil `0.7.34_non_trade_liquidity_lifecycle`, matérialisation des tables non-trade liquidité/lifecycle, warning non bloquant pour DEX attendus absents du corpus local, première tranche DLMM : `add_liquidity`, `remove_liquidity`, `initialize_position`, `initialize_bin_array`, intégration de la matérialisation non-trade dans les backfills token/pool ciblés, et distinction `PositionOpen`/`PositionClose` dans `LiquidityEventKind`.
0.7.35 - Ajout du profil `0.7.35_non_trade_fee_reward_admin`, événements non-trade p2 : fees, rewards et administration.

View File

@@ -8,7 +8,7 @@ members = [
] ]
[workspace.package] [workspace.package]
version = "0.7.34" version = "0.7.35"
edition = "2024" edition = "2024"
license = "MIT" license = "MIT"
repository = "https://git.sasedev.com/Sasedev/khadhroony-bobobot" repository = "https://git.sasedev.com/Sasedev/khadhroony-bobobot"

View File

@@ -881,9 +881,7 @@ Réalisé :
- conserver `meteora_damm_v1` manquant comme warning non bloquant lorsque le corpus de backfill local ne contient pas ce DEX. - conserver `meteora_damm_v1` manquant comme warning non bloquant lorsque le corpus de backfill local ne contient pas ce DEX.
### 6.067. Version `0.7.35` — Événements non-trade v2 : fees, rewards et administration ### 6.067. Version `0.7.35` — Événements non-trade v2 : fees, rewards et administration
Objectif : conserver les événements utiles au risque, au scoring, à léconomie du pool et à la traçabilité opérationnelle. Réalisé :
À faire :
- ajouter `k_sol_fee_events`, - ajouter `k_sol_fee_events`,
- ajouter `k_sol_reward_events`, - ajouter `k_sol_reward_events`,

View File

@@ -166,7 +166,8 @@
<div class="mb-3"> <div class="mb-3">
<label for="demoPipeline2ValidationProfileSelect" class="form-label">Validation profile</label> <label for="demoPipeline2ValidationProfileSelect" class="form-label">Validation profile</label>
<select id="demoPipeline2ValidationProfileSelect" class="form-select"> <select id="demoPipeline2ValidationProfileSelect" class="form-select">
<option value="0.7.34_non_trade_liquidity_lifecycle" selected>0.7.34 — non-trade liquidity/lifecycle</option> <option value="0.7.35_non_trade_fee_reward_admin" selected>0.7.35 — non-trade fee/reward admin</option>
<option value="0.7.34_non_trade_liquidity_lifecycle">0.7.34 — non-trade liquidity/lifecycle</option>
<option value="0.7.33_pair_trading_readiness">0.7.33 — pair trading readiness</option> <option value="0.7.33_pair_trading_readiness">0.7.33 — pair trading readiness</option>
<option value="0.7.32_validation_report_semantics">0.7.32 — validation report semantics</option> <option value="0.7.32_validation_report_semantics">0.7.32 — validation report semantics</option>
<option value="0.7.31_trade_event_actionability_policy">0.7.31 — trade event actionability policy</option> <option value="0.7.31_trade_event_actionability_policy">0.7.31 — trade event actionability policy</option>

View File

@@ -1,7 +1,7 @@
{ {
"name": "kb-demo-app", "name": "kb-demo-app",
"private": true, "private": true,
"version": "0.7.34", "version": "0.7.35",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",

View File

@@ -1087,7 +1087,7 @@ pub(crate) async fn demo_pipeline2_validate_local_pipeline(
let service = kb_lib::LocalPipelineValidationService::new(database.clone()); let service = kb_lib::LocalPipelineValidationService::new(database.clone());
let profile_code = match request { let profile_code = match request {
Some(request) => request.profile_code, Some(request) => request.profile_code,
None => "0.7.34_non_trade_liquidity_lifecycle".to_string(), None => "0.7.35_non_trade_fee_reward_admin".to_string(),
}; };
let run_result = match profile_code.as_str() { let run_result = match profile_code.as_str() {
"0.7.27" | "0.7.27_dexes_non_regression" => { "0.7.27" | "0.7.27_dexes_non_regression" => {
@@ -1114,6 +1114,9 @@ pub(crate) async fn demo_pipeline2_validate_local_pipeline(
"0.7.34" | "0.7.34_non_trade_liquidity_lifecycle" => { "0.7.34" | "0.7.34_non_trade_liquidity_lifecycle" => {
service.validate_v0_7_34_current_database().await service.validate_v0_7_34_current_database().await
}, },
"0.7.35" | "0.7.35_non_trade_fee_reward_admin" => {
service.validate_v0_7_35_current_database().await
},
other => Err(kb_lib::Error::InvalidState(format!( other => Err(kb_lib::Error::InvalidState(format!(
"unsupported local pipeline validation profile: {other}" "unsupported local pipeline validation profile: {other}"
))), ))),

View File

@@ -1,7 +1,7 @@
{ {
"$schema": "https://schema.tauri.app/config/2", "$schema": "https://schema.tauri.app/config/2",
"productName": "kb-demo-app", "productName": "kb-demo-app",
"version": "0.7.34", "version": "0.7.35",
"identifier": "com.sasedev.kb-demo-app", "identifier": "com.sasedev.kb-demo-app",
"build": { "build": {
"beforeDevCommand": "npm run dev", "beforeDevCommand": "npm run dev",

View File

@@ -23,6 +23,7 @@ pub use dtos::DbMetadataDto;
pub use dtos::DbRuntimeEventDto; pub use dtos::DbRuntimeEventDto;
pub use dtos::DexDecodedEventDto; pub use dtos::DexDecodedEventDto;
pub use dtos::DexDto; pub use dtos::DexDto;
pub use dtos::FeeEventDto;
pub use dtos::KnownHttpEndpointDto; pub use dtos::KnownHttpEndpointDto;
pub use dtos::KnownWsEndpointDto; pub use dtos::KnownWsEndpointDto;
pub use dtos::LaunchAttributionDto; pub use dtos::LaunchAttributionDto;
@@ -49,6 +50,7 @@ pub use dtos::PairAnalyticSignalDto;
pub use dtos::PairCandleDto; pub use dtos::PairCandleDto;
pub use dtos::PairDto; pub use dtos::PairDto;
pub use dtos::PairMetricDto; pub use dtos::PairMetricDto;
pub use dtos::PoolAdminEventDto;
pub use dtos::PoolDto; pub use dtos::PoolDto;
pub use dtos::PoolLifecycleEventDto; pub use dtos::PoolLifecycleEventDto;
pub use dtos::PoolListingDto; pub use dtos::PoolListingDto;
@@ -58,6 +60,7 @@ pub use dtos::ProgramInstructionDiagnosticDto;
pub use dtos::ProgramInstructionDiscriminatorSummaryDto; pub use dtos::ProgramInstructionDiscriminatorSummaryDto;
pub use dtos::ProtocolCandidateDto; pub use dtos::ProtocolCandidateDto;
pub use dtos::ProtocolCandidateSummaryDto; pub use dtos::ProtocolCandidateSummaryDto;
pub use dtos::RewardEventDto;
pub use dtos::SwapDto; pub use dtos::SwapDto;
pub use dtos::TokenBurnEventDto; pub use dtos::TokenBurnEventDto;
pub use dtos::TokenDto; pub use dtos::TokenDto;
@@ -75,6 +78,7 @@ pub use entities::DbMetadataEntity;
pub use entities::DbRuntimeEventEntity; pub use entities::DbRuntimeEventEntity;
pub use entities::DexDecodedEventEntity; pub use entities::DexDecodedEventEntity;
pub use entities::DexEntity; pub use entities::DexEntity;
pub use entities::FeeEventEntity;
pub use entities::KnownHttpEndpointEntity; pub use entities::KnownHttpEndpointEntity;
pub use entities::KnownWsEndpointEntity; pub use entities::KnownWsEndpointEntity;
pub use entities::LaunchAttributionEntity; pub use entities::LaunchAttributionEntity;
@@ -87,6 +91,7 @@ pub use entities::PairAnalyticSignalEntity;
pub use entities::PairCandleEntity; pub use entities::PairCandleEntity;
pub use entities::PairEntity; pub use entities::PairEntity;
pub use entities::PairMetricEntity; pub use entities::PairMetricEntity;
pub use entities::PoolAdminEventEntity;
pub use entities::PoolEntity; pub use entities::PoolEntity;
pub use entities::PoolLifecycleEventEntity; pub use entities::PoolLifecycleEventEntity;
pub use entities::PoolListingEntity; pub use entities::PoolListingEntity;
@@ -96,6 +101,7 @@ pub use entities::ProgramInstructionDiagnosticEntity;
pub use entities::ProgramInstructionDiscriminatorRowEntity; pub use entities::ProgramInstructionDiscriminatorRowEntity;
pub use entities::ProtocolCandidateEntity; pub use entities::ProtocolCandidateEntity;
pub use entities::ProtocolCandidateSummaryEntity; pub use entities::ProtocolCandidateSummaryEntity;
pub use entities::RewardEventEntity;
pub use entities::SwapEntity; pub use entities::SwapEntity;
pub use entities::TokenBurnEventEntity; pub use entities::TokenBurnEventEntity;
pub use entities::TokenEntity; pub use entities::TokenEntity;
@@ -130,6 +136,9 @@ pub use queries::query_dex_decoded_events_upsert;
pub use queries::query_dexs_get_by_code; pub use queries::query_dexs_get_by_code;
pub use queries::query_dexs_list; pub use queries::query_dexs_list;
pub use queries::query_dexs_upsert; pub use queries::query_dexs_upsert;
pub use queries::query_fee_events_get_by_decoded_event_id;
pub use queries::query_fee_events_list_recent;
pub use queries::query_fee_events_upsert;
pub use queries::query_known_http_endpoints_get; pub use queries::query_known_http_endpoints_get;
pub use queries::query_known_http_endpoints_list; pub use queries::query_known_http_endpoints_list;
pub use queries::query_known_http_endpoints_upsert; pub use queries::query_known_http_endpoints_upsert;
@@ -179,6 +188,9 @@ pub use queries::query_pairs_get_by_pool_id;
pub use queries::query_pairs_list; pub use queries::query_pairs_list;
pub use queries::query_pairs_update_symbol; pub use queries::query_pairs_update_symbol;
pub use queries::query_pairs_upsert; pub use queries::query_pairs_upsert;
pub use queries::query_pool_admin_events_get_by_decoded_event_id;
pub use queries::query_pool_admin_events_list_recent;
pub use queries::query_pool_admin_events_upsert;
pub use queries::query_pool_lifecycle_events_get_by_decoded_event_id; pub use queries::query_pool_lifecycle_events_get_by_decoded_event_id;
pub use queries::query_pool_lifecycle_events_list_recent; pub use queries::query_pool_lifecycle_events_list_recent;
pub use queries::query_pool_lifecycle_events_upsert; pub use queries::query_pool_lifecycle_events_upsert;
@@ -201,6 +213,9 @@ pub use queries::query_protocol_candidates_insert;
pub use queries::query_protocol_candidates_list_by_program_id; pub use queries::query_protocol_candidates_list_by_program_id;
pub use queries::query_protocol_candidates_list_by_transaction_id; pub use queries::query_protocol_candidates_list_by_transaction_id;
pub use queries::query_protocol_candidates_list_recent; pub use queries::query_protocol_candidates_list_recent;
pub use queries::query_reward_events_get_by_decoded_event_id;
pub use queries::query_reward_events_list_recent;
pub use queries::query_reward_events_upsert;
pub use queries::query_swaps_list_recent; pub use queries::query_swaps_list_recent;
pub use queries::query_swaps_upsert; pub use queries::query_swaps_upsert;
pub use queries::query_token_burn_events_list_recent; pub use queries::query_token_burn_events_list_recent;

View File

@@ -10,6 +10,7 @@ mod db_metadata;
mod db_runtime_event; mod db_runtime_event;
mod dex; mod dex;
mod dex_decoded_event; mod dex_decoded_event;
mod fee_event;
mod known_http_endpoint; mod known_http_endpoint;
mod known_ws_endpoint; mod known_ws_endpoint;
mod launch_attribution; mod launch_attribution;
@@ -24,13 +25,16 @@ mod pair_analytic_signal;
mod pair_candle; mod pair_candle;
mod pair_metric; mod pair_metric;
mod pool; mod pool;
mod pool_listing; mod pool_admin_event;
mod pool_lifecycle_event; mod pool_lifecycle_event;
mod pool_listing;
mod pool_origin; mod pool_origin;
mod pool_token; mod pool_token;
mod program_instruction_diagnostic; mod program_instruction_diagnostic;
mod program_instruction_discriminator_summary;
mod protocol_candidate; mod protocol_candidate;
mod protocol_candidate_summary; mod protocol_candidate_summary;
mod reward_event;
mod swap; mod swap;
mod token; mod token;
mod token_burn_event; mod token_burn_event;
@@ -39,24 +43,22 @@ mod trade_event;
mod transaction_classification; mod transaction_classification;
mod wallet; mod wallet;
mod wallet_holding; mod wallet_holding;
mod program_instruction_discriminator_summary;
mod wallet_participation; mod wallet_participation;
pub(crate) use local_pipeline_diagnostics::LocalDecodedEventDiagnosticSummaryRow; pub(crate) use local_pipeline_diagnostics::LocalDecodedEventDiagnosticSummaryRow;
pub(crate) use local_pipeline_diagnostics::LocalEventClassificationDiagnosticSummaryRow;
pub(crate) use local_pipeline_diagnostics::LocalDexDiagnosticSummaryRow; pub(crate) use local_pipeline_diagnostics::LocalDexDiagnosticSummaryRow;
pub(crate) use local_pipeline_diagnostics::LocalDuplicateDecodedEventTradeDiagnosticSampleRow; pub(crate) use local_pipeline_diagnostics::LocalDuplicateDecodedEventTradeDiagnosticSampleRow;
pub(crate) use local_pipeline_diagnostics::LocalEventClassificationDiagnosticSummaryRow;
pub(crate) use local_pipeline_diagnostics::LocalMissingTradeEventDiagnosticSampleRow; pub(crate) use local_pipeline_diagnostics::LocalMissingTradeEventDiagnosticSampleRow;
pub(crate) use local_pipeline_diagnostics::LocalMissingTradeEventReasonSummaryRow; pub(crate) use local_pipeline_diagnostics::LocalMissingTradeEventReasonSummaryRow;
pub(crate) use local_pipeline_diagnostics::LocalMultiTradeSignaturePairDiagnosticSampleRow; pub(crate) use local_pipeline_diagnostics::LocalMultiTradeSignaturePairDiagnosticSampleRow;
pub(crate) use local_pipeline_diagnostics::LocalNonActionablePairDiagnosticSummaryRow; pub(crate) use local_pipeline_diagnostics::LocalNonActionablePairDiagnosticSummaryRow;
pub(crate) use local_pipeline_diagnostics::LocalPairDiagnosticSummaryRow;
pub(crate) use local_pipeline_diagnostics::LocalPairActionabilityDiagnosticSummaryRow; pub(crate) use local_pipeline_diagnostics::LocalPairActionabilityDiagnosticSummaryRow;
pub(crate) use local_pipeline_diagnostics::LocalPairTradingReadinessDiagnosticSummaryRow; pub(crate) use local_pipeline_diagnostics::LocalPairDiagnosticSummaryRow;
pub(crate) use local_pipeline_diagnostics::LocalPairGapDiagnosticSampleRow; pub(crate) use local_pipeline_diagnostics::LocalPairGapDiagnosticSampleRow;
pub(crate) use local_pipeline_diagnostics::LocalPairTradingReadinessDiagnosticSummaryRow;
pub(crate) use local_pipeline_diagnostics::LocalPipelineDiagnosticCountersRow; pub(crate) use local_pipeline_diagnostics::LocalPipelineDiagnosticCountersRow;
pub use program_instruction_discriminator_summary::ProgramInstructionDiscriminatorSummaryDto;
pub use analysis_signal::AnalysisSignalDto; pub use analysis_signal::AnalysisSignalDto;
pub use chain_instruction::ChainInstructionDto; pub use chain_instruction::ChainInstructionDto;
pub use chain_slot::ChainSlotDto; pub use chain_slot::ChainSlotDto;
@@ -65,6 +67,7 @@ pub use db_metadata::DbMetadataDto;
pub use db_runtime_event::DbRuntimeEventDto; pub use db_runtime_event::DbRuntimeEventDto;
pub use dex::DexDto; pub use dex::DexDto;
pub use dex_decoded_event::DexDecodedEventDto; pub use dex_decoded_event::DexDecodedEventDto;
pub use fee_event::FeeEventDto;
pub use known_http_endpoint::KnownHttpEndpointDto; pub use known_http_endpoint::KnownHttpEndpointDto;
pub use known_ws_endpoint::KnownWsEndpointDto; pub use known_ws_endpoint::KnownWsEndpointDto;
pub use launch_attribution::LaunchAttributionDto; pub use launch_attribution::LaunchAttributionDto;
@@ -72,17 +75,17 @@ pub use launch_surface::LaunchSurfaceDto;
pub use launch_surface_key::LaunchSurfaceKeyDto; pub use launch_surface_key::LaunchSurfaceKeyDto;
pub use liquidity_event::LiquidityEventDto; pub use liquidity_event::LiquidityEventDto;
pub use local_pipeline_diagnostics::LocalDecodedEventDiagnosticSummaryDto; pub use local_pipeline_diagnostics::LocalDecodedEventDiagnosticSummaryDto;
pub use local_pipeline_diagnostics::LocalEventClassificationDiagnosticSummaryDto;
pub use local_pipeline_diagnostics::LocalDexDiagnosticSummaryDto; pub use local_pipeline_diagnostics::LocalDexDiagnosticSummaryDto;
pub use local_pipeline_diagnostics::LocalDuplicateDecodedEventTradeDiagnosticSampleDto; pub use local_pipeline_diagnostics::LocalDuplicateDecodedEventTradeDiagnosticSampleDto;
pub use local_pipeline_diagnostics::LocalEventClassificationDiagnosticSummaryDto;
pub use local_pipeline_diagnostics::LocalMissingTradeEventDiagnosticSampleDto; pub use local_pipeline_diagnostics::LocalMissingTradeEventDiagnosticSampleDto;
pub use local_pipeline_diagnostics::LocalMissingTradeEventReasonSummaryDto; pub use local_pipeline_diagnostics::LocalMissingTradeEventReasonSummaryDto;
pub use local_pipeline_diagnostics::LocalMultiTradeSignaturePairDiagnosticSampleDto; pub use local_pipeline_diagnostics::LocalMultiTradeSignaturePairDiagnosticSampleDto;
pub use local_pipeline_diagnostics::LocalNonActionablePairDiagnosticSummaryDto; pub use local_pipeline_diagnostics::LocalNonActionablePairDiagnosticSummaryDto;
pub use local_pipeline_diagnostics::LocalPairDiagnosticSummaryDto;
pub use local_pipeline_diagnostics::LocalPairActionabilityDiagnosticSummaryDto; pub use local_pipeline_diagnostics::LocalPairActionabilityDiagnosticSummaryDto;
pub use local_pipeline_diagnostics::LocalPairTradingReadinessDiagnosticSummaryDto; pub use local_pipeline_diagnostics::LocalPairDiagnosticSummaryDto;
pub use local_pipeline_diagnostics::LocalPairGapDiagnosticSampleDto; pub use local_pipeline_diagnostics::LocalPairGapDiagnosticSampleDto;
pub use local_pipeline_diagnostics::LocalPairTradingReadinessDiagnosticSummaryDto;
pub use local_pipeline_diagnostics::LocalPipelineDiagnosticCountersDto; pub use local_pipeline_diagnostics::LocalPipelineDiagnosticCountersDto;
pub use local_pipeline_diagnostics::LocalPipelineDiagnosticSummaryDto; pub use local_pipeline_diagnostics::LocalPipelineDiagnosticSummaryDto;
pub use observed_token::ObservedTokenDto; pub use observed_token::ObservedTokenDto;
@@ -92,13 +95,16 @@ pub use pair_analytic_signal::PairAnalyticSignalDto;
pub use pair_candle::PairCandleDto; pub use pair_candle::PairCandleDto;
pub use pair_metric::PairMetricDto; pub use pair_metric::PairMetricDto;
pub use pool::PoolDto; pub use pool::PoolDto;
pub use pool_listing::PoolListingDto; pub use pool_admin_event::PoolAdminEventDto;
pub use pool_lifecycle_event::PoolLifecycleEventDto; pub use pool_lifecycle_event::PoolLifecycleEventDto;
pub use pool_listing::PoolListingDto;
pub use pool_origin::PoolOriginDto; pub use pool_origin::PoolOriginDto;
pub use pool_token::PoolTokenDto; pub use pool_token::PoolTokenDto;
pub use program_instruction_diagnostic::ProgramInstructionDiagnosticDto; pub use program_instruction_diagnostic::ProgramInstructionDiagnosticDto;
pub use program_instruction_discriminator_summary::ProgramInstructionDiscriminatorSummaryDto;
pub use protocol_candidate::ProtocolCandidateDto; pub use protocol_candidate::ProtocolCandidateDto;
pub use protocol_candidate_summary::ProtocolCandidateSummaryDto; pub use protocol_candidate_summary::ProtocolCandidateSummaryDto;
pub use reward_event::RewardEventDto;
pub use swap::SwapDto; pub use swap::SwapDto;
pub use token::TokenDto; pub use token::TokenDto;
pub use token_burn_event::TokenBurnEventDto; pub use token_burn_event::TokenBurnEventDto;

View File

@@ -0,0 +1,150 @@
// file: kb_lib/src/db/dtos/fee_event.rs
//! Fee event DTO.
/// Application-facing normalized fee event DTO.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct FeeEventDto {
/// Optional numeric primary key.
pub id: std::option::Option<i64>,
/// Related transaction id.
pub transaction_id: i64,
/// Related decoded DEX event id, when available.
pub decoded_event_id: std::option::Option<i64>,
/// Related DEX id, when the DEX row is known.
pub dex_id: std::option::Option<i64>,
/// Related pool id, when the pool row is known.
pub pool_id: std::option::Option<i64>,
/// Related pair id, when the pair row is known.
pub pair_id: std::option::Option<i64>,
/// Transaction signature.
pub signature: std::string::String,
/// Optional slot number.
pub slot: std::option::Option<u64>,
/// Protocol name that emitted the decoded event.
pub protocol_name: std::string::String,
/// Program id that emitted the decoded event.
pub program_id: std::string::String,
/// Stable decoded event kind.
pub event_kind: std::string::String,
/// Pool account address, when decoded.
pub pool_account: std::option::Option<std::string::String>,
/// Wallet or authority associated with the fee event, when decoded.
pub actor_wallet: std::option::Option<std::string::String>,
/// Token mint used to pay or collect the fee, when decoded.
pub fee_token_mint: std::option::Option<std::string::String>,
/// Raw fee amount as decimal text, when decoded.
pub fee_amount_raw: std::option::Option<std::string::String>,
/// Source decoded payload JSON.
pub payload_json: std::string::String,
/// Execution timestamp.
pub executed_at: chrono::DateTime<chrono::Utc>,
/// Creation timestamp.
pub created_at: chrono::DateTime<chrono::Utc>,
}
impl FeeEventDto {
/// Creates a new fee event DTO.
#[allow(clippy::too_many_arguments)]
pub fn new(
transaction_id: i64,
decoded_event_id: std::option::Option<i64>,
dex_id: std::option::Option<i64>,
pool_id: std::option::Option<i64>,
pair_id: std::option::Option<i64>,
signature: std::string::String,
slot: std::option::Option<u64>,
protocol_name: std::string::String,
program_id: std::string::String,
event_kind: std::string::String,
pool_account: std::option::Option<std::string::String>,
actor_wallet: std::option::Option<std::string::String>,
fee_token_mint: std::option::Option<std::string::String>,
fee_amount_raw: std::option::Option<std::string::String>,
payload_json: std::string::String,
) -> Self {
let now = chrono::Utc::now();
return Self {
id: None,
transaction_id,
decoded_event_id,
dex_id,
pool_id,
pair_id,
signature,
slot,
protocol_name,
program_id,
event_kind,
pool_account,
actor_wallet,
fee_token_mint,
fee_amount_raw,
payload_json,
executed_at: now,
created_at: now,
};
}
}
impl TryFrom<crate::FeeEventEntity> for FeeEventDto {
type Error = crate::Error;
fn try_from(entity: crate::FeeEventEntity) -> Result<Self, Self::Error> {
let executed_at_result = chrono::DateTime::parse_from_rfc3339(&entity.executed_at);
let executed_at = match executed_at_result {
Ok(executed_at) => executed_at.with_timezone(&chrono::Utc),
Err(error) => {
return Err(crate::Error::Db(format!(
"cannot parse fee event executed_at '{}': {}",
entity.executed_at, error
)));
},
};
let created_at_result = chrono::DateTime::parse_from_rfc3339(&entity.created_at);
let created_at = match created_at_result {
Ok(created_at) => created_at.with_timezone(&chrono::Utc),
Err(error) => {
return Err(crate::Error::Db(format!(
"cannot parse fee event created_at '{}': {}",
entity.created_at, error
)));
},
};
let slot = match entity.slot {
Some(slot) => {
let slot_result = u64::try_from(slot);
match slot_result {
Ok(slot) => Some(slot),
Err(error) => {
return Err(crate::Error::Db(format!(
"cannot convert fee event slot '{}' to u64: {}",
slot, error
)));
},
}
},
None => None,
};
return Ok(Self {
id: Some(entity.id),
transaction_id: entity.transaction_id,
decoded_event_id: entity.decoded_event_id,
dex_id: entity.dex_id,
pool_id: entity.pool_id,
pair_id: entity.pair_id,
signature: entity.signature,
slot,
protocol_name: entity.protocol_name,
program_id: entity.program_id,
event_kind: entity.event_kind,
pool_account: entity.pool_account,
actor_wallet: entity.actor_wallet,
fee_token_mint: entity.fee_token_mint,
fee_amount_raw: entity.fee_amount_raw,
payload_json: entity.payload_json,
executed_at,
created_at,
});
}
}

View File

@@ -27,6 +27,12 @@ pub struct LocalPipelineDiagnosticSummaryDto {
pub liquidity_event_count: i64, pub liquidity_event_count: i64,
/// Total persisted pool lifecycle events. /// Total persisted pool lifecycle events.
pub pool_lifecycle_event_count: i64, pub pool_lifecycle_event_count: i64,
/// Total persisted fee events.
pub fee_event_count: i64,
/// Total persisted reward events.
pub reward_event_count: i64,
/// Total persisted pool administration events.
pub pool_admin_event_count: i64,
/// Whether the local persisted pipeline has no blocking diagnostic issue. /// Whether the local persisted pipeline has no blocking diagnostic issue.
pub diagnostics_clean: bool, pub diagnostics_clean: bool,
/// Number of blocking diagnostic issues. /// Number of blocking diagnostic issues.
@@ -371,6 +377,12 @@ pub struct LocalPipelineDiagnosticCountersDto {
pub liquidity_event_count: i64, pub liquidity_event_count: i64,
/// Total persisted pool lifecycle events. /// Total persisted pool lifecycle events.
pub pool_lifecycle_event_count: i64, pub pool_lifecycle_event_count: i64,
/// Total persisted fee events.
pub fee_event_count: i64,
/// Total persisted reward events.
pub reward_event_count: i64,
/// Total persisted pool administration events.
pub pool_admin_event_count: i64,
/// Total decoded trade candidates without trade event, including ignored failed transactions. /// Total decoded trade candidates without trade event, including ignored failed transactions.
pub missing_trade_event_count: i64, pub missing_trade_event_count: i64,
/// Explicit alias for decoded trade candidates without linked trade event. /// Explicit alias for decoded trade candidates without linked trade event.
@@ -443,6 +455,9 @@ pub(crate) struct LocalPipelineDiagnosticCountersRow {
pub(crate) decoded_unknown_event_count: i64, pub(crate) decoded_unknown_event_count: i64,
pub(crate) liquidity_event_count: i64, pub(crate) liquidity_event_count: i64,
pub(crate) pool_lifecycle_event_count: i64, pub(crate) pool_lifecycle_event_count: i64,
pub(crate) fee_event_count: i64,
pub(crate) reward_event_count: i64,
pub(crate) pool_admin_event_count: i64,
pub(crate) missing_trade_event_count: i64, pub(crate) missing_trade_event_count: i64,
pub(crate) decoded_trade_candidate_without_trade_event_count: i64, pub(crate) decoded_trade_candidate_without_trade_event_count: i64,
pub(crate) decoded_trade_candidate_without_trade_event_on_ok_transaction_count: i64, pub(crate) decoded_trade_candidate_without_trade_event_on_ok_transaction_count: i64,

View File

@@ -0,0 +1,145 @@
// file: kb_lib/src/db/dtos/pool_admin_event.rs
//! Pool administration event DTO.
/// Application-facing normalized pool administration event DTO.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct PoolAdminEventDto {
/// Optional numeric primary key.
pub id: std::option::Option<i64>,
/// Related transaction id.
pub transaction_id: i64,
/// Related decoded DEX event id, when available.
pub decoded_event_id: std::option::Option<i64>,
/// Related DEX id, when the DEX row is known.
pub dex_id: std::option::Option<i64>,
/// Related pool id, when the pool row is known.
pub pool_id: std::option::Option<i64>,
/// Related pair id, when the pair row is known.
pub pair_id: std::option::Option<i64>,
/// Transaction signature.
pub signature: std::string::String,
/// Optional slot number.
pub slot: std::option::Option<u64>,
/// Protocol name that emitted the decoded event.
pub protocol_name: std::string::String,
/// Program id that emitted the decoded event.
pub program_id: std::string::String,
/// Stable decoded event kind.
pub event_kind: std::string::String,
/// Pool account address, when decoded.
pub pool_account: std::option::Option<std::string::String>,
/// Wallet or authority associated with the admin event, when decoded.
pub actor_wallet: std::option::Option<std::string::String>,
/// Normalized admin action label, when available.
pub admin_action: std::option::Option<std::string::String>,
/// Source decoded payload JSON.
pub payload_json: std::string::String,
/// Execution timestamp.
pub executed_at: chrono::DateTime<chrono::Utc>,
/// Creation timestamp.
pub created_at: chrono::DateTime<chrono::Utc>,
}
impl PoolAdminEventDto {
/// Creates a new pool administration event DTO.
#[allow(clippy::too_many_arguments)]
pub fn new(
transaction_id: i64,
decoded_event_id: std::option::Option<i64>,
dex_id: std::option::Option<i64>,
pool_id: std::option::Option<i64>,
pair_id: std::option::Option<i64>,
signature: std::string::String,
slot: std::option::Option<u64>,
protocol_name: std::string::String,
program_id: std::string::String,
event_kind: std::string::String,
pool_account: std::option::Option<std::string::String>,
actor_wallet: std::option::Option<std::string::String>,
admin_action: std::option::Option<std::string::String>,
payload_json: std::string::String,
) -> Self {
let now = chrono::Utc::now();
return Self {
id: None,
transaction_id,
decoded_event_id,
dex_id,
pool_id,
pair_id,
signature,
slot,
protocol_name,
program_id,
event_kind,
pool_account,
actor_wallet,
admin_action,
payload_json,
executed_at: now,
created_at: now,
};
}
}
impl TryFrom<crate::PoolAdminEventEntity> for PoolAdminEventDto {
type Error = crate::Error;
fn try_from(entity: crate::PoolAdminEventEntity) -> Result<Self, Self::Error> {
let executed_at_result = chrono::DateTime::parse_from_rfc3339(&entity.executed_at);
let executed_at = match executed_at_result {
Ok(executed_at) => executed_at.with_timezone(&chrono::Utc),
Err(error) => {
return Err(crate::Error::Db(format!(
"cannot parse pool admin event executed_at '{}': {}",
entity.executed_at, error
)));
},
};
let created_at_result = chrono::DateTime::parse_from_rfc3339(&entity.created_at);
let created_at = match created_at_result {
Ok(created_at) => created_at.with_timezone(&chrono::Utc),
Err(error) => {
return Err(crate::Error::Db(format!(
"cannot parse pool admin event created_at '{}': {}",
entity.created_at, error
)));
},
};
let slot = match entity.slot {
Some(slot) => {
let slot_result = u64::try_from(slot);
match slot_result {
Ok(slot) => Some(slot),
Err(error) => {
return Err(crate::Error::Db(format!(
"cannot convert pool admin event slot '{}' to u64: {}",
slot, error
)));
},
}
},
None => None,
};
return Ok(Self {
id: Some(entity.id),
transaction_id: entity.transaction_id,
decoded_event_id: entity.decoded_event_id,
dex_id: entity.dex_id,
pool_id: entity.pool_id,
pair_id: entity.pair_id,
signature: entity.signature,
slot,
protocol_name: entity.protocol_name,
program_id: entity.program_id,
event_kind: entity.event_kind,
pool_account: entity.pool_account,
actor_wallet: entity.actor_wallet,
admin_action: entity.admin_action,
payload_json: entity.payload_json,
executed_at,
created_at,
});
}
}

View File

@@ -0,0 +1,150 @@
// file: kb_lib/src/db/dtos/reward_event.rs
//! Reward event DTO.
/// Application-facing normalized reward event DTO.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct RewardEventDto {
/// Optional numeric primary key.
pub id: std::option::Option<i64>,
/// Related transaction id.
pub transaction_id: i64,
/// Related decoded DEX event id, when available.
pub decoded_event_id: std::option::Option<i64>,
/// Related DEX id, when the DEX row is known.
pub dex_id: std::option::Option<i64>,
/// Related pool id, when the pool row is known.
pub pool_id: std::option::Option<i64>,
/// Related pair id, when the pair row is known.
pub pair_id: std::option::Option<i64>,
/// Transaction signature.
pub signature: std::string::String,
/// Optional slot number.
pub slot: std::option::Option<u64>,
/// Protocol name that emitted the decoded event.
pub protocol_name: std::string::String,
/// Program id that emitted the decoded event.
pub program_id: std::string::String,
/// Stable decoded event kind.
pub event_kind: std::string::String,
/// Pool account address, when decoded.
pub pool_account: std::option::Option<std::string::String>,
/// Wallet or authority associated with the reward event, when decoded.
pub actor_wallet: std::option::Option<std::string::String>,
/// Token mint used by the reward event, when decoded.
pub reward_token_mint: std::option::Option<std::string::String>,
/// Raw reward amount as decimal text, when decoded.
pub reward_amount_raw: std::option::Option<std::string::String>,
/// Source decoded payload JSON.
pub payload_json: std::string::String,
/// Execution timestamp.
pub executed_at: chrono::DateTime<chrono::Utc>,
/// Creation timestamp.
pub created_at: chrono::DateTime<chrono::Utc>,
}
impl RewardEventDto {
/// Creates a new reward event DTO.
#[allow(clippy::too_many_arguments)]
pub fn new(
transaction_id: i64,
decoded_event_id: std::option::Option<i64>,
dex_id: std::option::Option<i64>,
pool_id: std::option::Option<i64>,
pair_id: std::option::Option<i64>,
signature: std::string::String,
slot: std::option::Option<u64>,
protocol_name: std::string::String,
program_id: std::string::String,
event_kind: std::string::String,
pool_account: std::option::Option<std::string::String>,
actor_wallet: std::option::Option<std::string::String>,
reward_token_mint: std::option::Option<std::string::String>,
reward_amount_raw: std::option::Option<std::string::String>,
payload_json: std::string::String,
) -> Self {
let now = chrono::Utc::now();
return Self {
id: None,
transaction_id,
decoded_event_id,
dex_id,
pool_id,
pair_id,
signature,
slot,
protocol_name,
program_id,
event_kind,
pool_account,
actor_wallet,
reward_token_mint,
reward_amount_raw,
payload_json,
executed_at: now,
created_at: now,
};
}
}
impl TryFrom<crate::RewardEventEntity> for RewardEventDto {
type Error = crate::Error;
fn try_from(entity: crate::RewardEventEntity) -> Result<Self, Self::Error> {
let executed_at_result = chrono::DateTime::parse_from_rfc3339(&entity.executed_at);
let executed_at = match executed_at_result {
Ok(executed_at) => executed_at.with_timezone(&chrono::Utc),
Err(error) => {
return Err(crate::Error::Db(format!(
"cannot parse reward event executed_at '{}': {}",
entity.executed_at, error
)));
},
};
let created_at_result = chrono::DateTime::parse_from_rfc3339(&entity.created_at);
let created_at = match created_at_result {
Ok(created_at) => created_at.with_timezone(&chrono::Utc),
Err(error) => {
return Err(crate::Error::Db(format!(
"cannot parse reward event created_at '{}': {}",
entity.created_at, error
)));
},
};
let slot = match entity.slot {
Some(slot) => {
let slot_result = u64::try_from(slot);
match slot_result {
Ok(slot) => Some(slot),
Err(error) => {
return Err(crate::Error::Db(format!(
"cannot convert reward event slot '{}' to u64: {}",
slot, error
)));
},
}
},
None => None,
};
return Ok(Self {
id: Some(entity.id),
transaction_id: entity.transaction_id,
decoded_event_id: entity.decoded_event_id,
dex_id: entity.dex_id,
pool_id: entity.pool_id,
pair_id: entity.pair_id,
signature: entity.signature,
slot,
protocol_name: entity.protocol_name,
program_id: entity.program_id,
event_kind: entity.event_kind,
pool_account: entity.pool_account,
actor_wallet: entity.actor_wallet,
reward_token_mint: entity.reward_token_mint,
reward_amount_raw: entity.reward_amount_raw,
payload_json: entity.payload_json,
executed_at,
created_at,
});
}
}

View File

@@ -12,6 +12,7 @@ mod db_metadata;
mod db_runtime_event; mod db_runtime_event;
mod dex; mod dex;
mod dex_decoded_event; mod dex_decoded_event;
mod fee_event;
mod known_http_endpoint; mod known_http_endpoint;
mod known_ws_endpoint; mod known_ws_endpoint;
mod launch_attribution; mod launch_attribution;
@@ -25,14 +26,16 @@ mod pair_analytic_signal;
mod pair_candle; mod pair_candle;
mod pair_metric; mod pair_metric;
mod pool; mod pool;
mod pool_listing; mod pool_admin_event;
mod pool_lifecycle_event; mod pool_lifecycle_event;
mod pool_listing;
mod pool_origin; mod pool_origin;
mod pool_token; mod pool_token;
mod program_instruction_diagnostic; mod program_instruction_diagnostic;
mod program_instruction_discriminator_row; mod program_instruction_discriminator_row;
mod protocol_candidate; mod protocol_candidate;
mod protocol_candidate_summary; mod protocol_candidate_summary;
mod reward_event;
mod swap; mod swap;
mod token; mod token;
mod token_burn_event; mod token_burn_event;
@@ -51,6 +54,7 @@ pub use db_metadata::DbMetadataEntity;
pub use db_runtime_event::DbRuntimeEventEntity; pub use db_runtime_event::DbRuntimeEventEntity;
pub use dex::DexEntity; pub use dex::DexEntity;
pub use dex_decoded_event::DexDecodedEventEntity; pub use dex_decoded_event::DexDecodedEventEntity;
pub use fee_event::FeeEventEntity;
pub use known_http_endpoint::KnownHttpEndpointEntity; pub use known_http_endpoint::KnownHttpEndpointEntity;
pub use known_ws_endpoint::KnownWsEndpointEntity; pub use known_ws_endpoint::KnownWsEndpointEntity;
pub use launch_attribution::LaunchAttributionEntity; pub use launch_attribution::LaunchAttributionEntity;
@@ -64,14 +68,16 @@ pub use pair_analytic_signal::PairAnalyticSignalEntity;
pub use pair_candle::PairCandleEntity; pub use pair_candle::PairCandleEntity;
pub use pair_metric::PairMetricEntity; pub use pair_metric::PairMetricEntity;
pub use pool::PoolEntity; pub use pool::PoolEntity;
pub use pool_listing::PoolListingEntity; pub use pool_admin_event::PoolAdminEventEntity;
pub use pool_lifecycle_event::PoolLifecycleEventEntity; pub use pool_lifecycle_event::PoolLifecycleEventEntity;
pub use pool_listing::PoolListingEntity;
pub use pool_origin::PoolOriginEntity; pub use pool_origin::PoolOriginEntity;
pub use pool_token::PoolTokenEntity; pub use pool_token::PoolTokenEntity;
pub use program_instruction_diagnostic::ProgramInstructionDiagnosticEntity; pub use program_instruction_diagnostic::ProgramInstructionDiagnosticEntity;
pub use program_instruction_discriminator_row::ProgramInstructionDiscriminatorRowEntity; pub use program_instruction_discriminator_row::ProgramInstructionDiscriminatorRowEntity;
pub use protocol_candidate::ProtocolCandidateEntity; pub use protocol_candidate::ProtocolCandidateEntity;
pub use protocol_candidate_summary::ProtocolCandidateSummaryEntity; pub use protocol_candidate_summary::ProtocolCandidateSummaryEntity;
pub use reward_event::RewardEventEntity;
pub use swap::SwapEntity; pub use swap::SwapEntity;
pub use token::TokenEntity; pub use token::TokenEntity;
pub use token_burn_event::TokenBurnEventEntity; pub use token_burn_event::TokenBurnEventEntity;

View File

@@ -0,0 +1,44 @@
// file: kb_lib/src/db/entities/fee_event.rs
//! Fee event entity.
/// Persisted normalized fee event row.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
pub struct FeeEventEntity {
/// Numeric primary key.
pub id: i64,
/// Related transaction id.
pub transaction_id: i64,
/// Related decoded DEX event id, when available.
pub decoded_event_id: std::option::Option<i64>,
/// Related DEX id, when the DEX row is known.
pub dex_id: std::option::Option<i64>,
/// Related pool id, when the pool row is known.
pub pool_id: std::option::Option<i64>,
/// Related pair id, when the pair row is known.
pub pair_id: std::option::Option<i64>,
/// Transaction signature.
pub signature: std::string::String,
/// Optional slot number.
pub slot: std::option::Option<i64>,
/// Protocol name that emitted the decoded event.
pub protocol_name: std::string::String,
/// Program id that emitted the decoded event.
pub program_id: std::string::String,
/// Stable decoded event kind.
pub event_kind: std::string::String,
/// Pool account address, when decoded.
pub pool_account: std::option::Option<std::string::String>,
/// Wallet or authority associated with the fee event, when decoded.
pub actor_wallet: std::option::Option<std::string::String>,
/// Token mint used to pay or collect the fee, when decoded.
pub fee_token_mint: std::option::Option<std::string::String>,
/// Raw fee amount as decimal text, when decoded.
pub fee_amount_raw: std::option::Option<std::string::String>,
/// Source decoded payload JSON.
pub payload_json: std::string::String,
/// Execution timestamp encoded as RFC3339 UTC text.
pub executed_at: std::string::String,
/// Creation timestamp encoded as RFC3339 UTC text.
pub created_at: std::string::String,
}

View File

@@ -0,0 +1,42 @@
// file: kb_lib/src/db/entities/pool_admin_event.rs
//! Pool administration event entity.
/// Persisted normalized pool administration event row.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
pub struct PoolAdminEventEntity {
/// Numeric primary key.
pub id: i64,
/// Related transaction id.
pub transaction_id: i64,
/// Related decoded DEX event id, when available.
pub decoded_event_id: std::option::Option<i64>,
/// Related DEX id, when the DEX row is known.
pub dex_id: std::option::Option<i64>,
/// Related pool id, when the pool row is known.
pub pool_id: std::option::Option<i64>,
/// Related pair id, when the pair row is known.
pub pair_id: std::option::Option<i64>,
/// Transaction signature.
pub signature: std::string::String,
/// Optional slot number.
pub slot: std::option::Option<i64>,
/// Protocol name that emitted the decoded event.
pub protocol_name: std::string::String,
/// Program id that emitted the decoded event.
pub program_id: std::string::String,
/// Stable decoded event kind.
pub event_kind: std::string::String,
/// Pool account address, when decoded.
pub pool_account: std::option::Option<std::string::String>,
/// Wallet or authority associated with the admin event, when decoded.
pub actor_wallet: std::option::Option<std::string::String>,
/// Normalized admin action label, when available.
pub admin_action: std::option::Option<std::string::String>,
/// Source decoded payload JSON.
pub payload_json: std::string::String,
/// Execution timestamp encoded as RFC3339 UTC text.
pub executed_at: std::string::String,
/// Creation timestamp encoded as RFC3339 UTC text.
pub created_at: std::string::String,
}

View File

@@ -0,0 +1,44 @@
// file: kb_lib/src/db/entities/reward_event.rs
//! Reward event entity.
/// Persisted normalized reward event row.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
pub struct RewardEventEntity {
/// Numeric primary key.
pub id: i64,
/// Related transaction id.
pub transaction_id: i64,
/// Related decoded DEX event id, when available.
pub decoded_event_id: std::option::Option<i64>,
/// Related DEX id, when the DEX row is known.
pub dex_id: std::option::Option<i64>,
/// Related pool id, when the pool row is known.
pub pool_id: std::option::Option<i64>,
/// Related pair id, when the pair row is known.
pub pair_id: std::option::Option<i64>,
/// Transaction signature.
pub signature: std::string::String,
/// Optional slot number.
pub slot: std::option::Option<i64>,
/// Protocol name that emitted the decoded event.
pub protocol_name: std::string::String,
/// Program id that emitted the decoded event.
pub program_id: std::string::String,
/// Stable decoded event kind.
pub event_kind: std::string::String,
/// Pool account address, when decoded.
pub pool_account: std::option::Option<std::string::String>,
/// Wallet or authority associated with the reward event, when decoded.
pub actor_wallet: std::option::Option<std::string::String>,
/// Token mint used by the reward event, when decoded.
pub reward_token_mint: std::option::Option<std::string::String>,
/// Raw reward amount as decimal text, when decoded.
pub reward_amount_raw: std::option::Option<std::string::String>,
/// Source decoded payload JSON.
pub payload_json: std::string::String,
/// Execution timestamp encoded as RFC3339 UTC text.
pub executed_at: std::string::String,
/// Creation timestamp encoded as RFC3339 UTC text.
pub created_at: std::string::String,
}

View File

@@ -10,6 +10,7 @@ mod db_metadata;
mod db_runtime_event; mod db_runtime_event;
mod dex; mod dex;
mod dex_decoded_event; mod dex_decoded_event;
mod fee_event;
mod known_http_endpoint; mod known_http_endpoint;
mod known_ws_endpoint; mod known_ws_endpoint;
mod launch_attribution; mod launch_attribution;
@@ -24,12 +25,14 @@ mod pair_analytic_signal;
mod pair_candle; mod pair_candle;
mod pair_metric; mod pair_metric;
mod pool; mod pool;
mod pool_admin_event;
mod pool_lifecycle_event; mod pool_lifecycle_event;
mod pool_listing; mod pool_listing;
mod pool_origin; mod pool_origin;
mod pool_token; mod pool_token;
mod program_instruction_diagnostic; mod program_instruction_diagnostic;
mod protocol_candidate; mod protocol_candidate;
mod reward_event;
mod swap; mod swap;
mod token; mod token;
mod token_burn_event; mod token_burn_event;
@@ -65,6 +68,9 @@ pub use dex_decoded_event::query_dex_decoded_events_get_by_key;
pub use dex_decoded_event::query_dex_decoded_events_get_latest_pump_fun_create_payload_by_mint; pub use dex_decoded_event::query_dex_decoded_events_get_latest_pump_fun_create_payload_by_mint;
pub use dex_decoded_event::query_dex_decoded_events_list_by_transaction_id; pub use dex_decoded_event::query_dex_decoded_events_list_by_transaction_id;
pub use dex_decoded_event::query_dex_decoded_events_upsert; pub use dex_decoded_event::query_dex_decoded_events_upsert;
pub use fee_event::query_fee_events_get_by_decoded_event_id;
pub use fee_event::query_fee_events_list_recent;
pub use fee_event::query_fee_events_upsert;
pub use known_http_endpoint::query_known_http_endpoints_get; pub use known_http_endpoint::query_known_http_endpoints_get;
pub use known_http_endpoint::query_known_http_endpoints_list; pub use known_http_endpoint::query_known_http_endpoints_list;
pub use known_http_endpoint::query_known_http_endpoints_upsert; pub use known_http_endpoint::query_known_http_endpoints_upsert;
@@ -117,6 +123,9 @@ pub use pair_metric::query_pair_metrics_upsert;
pub use pool::query_pools_get_by_address; pub use pool::query_pools_get_by_address;
pub use pool::query_pools_list; pub use pool::query_pools_list;
pub use pool::query_pools_upsert; pub use pool::query_pools_upsert;
pub use pool_admin_event::query_pool_admin_events_get_by_decoded_event_id;
pub use pool_admin_event::query_pool_admin_events_list_recent;
pub use pool_admin_event::query_pool_admin_events_upsert;
pub use pool_lifecycle_event::query_pool_lifecycle_events_get_by_decoded_event_id; pub use pool_lifecycle_event::query_pool_lifecycle_events_get_by_decoded_event_id;
pub use pool_lifecycle_event::query_pool_lifecycle_events_list_recent; pub use pool_lifecycle_event::query_pool_lifecycle_events_list_recent;
pub use pool_lifecycle_event::query_pool_lifecycle_events_upsert; pub use pool_lifecycle_event::query_pool_lifecycle_events_upsert;
@@ -136,6 +145,9 @@ pub use protocol_candidate::query_protocol_candidates_insert;
pub use protocol_candidate::query_protocol_candidates_list_by_program_id; pub use protocol_candidate::query_protocol_candidates_list_by_program_id;
pub use protocol_candidate::query_protocol_candidates_list_by_transaction_id; pub use protocol_candidate::query_protocol_candidates_list_by_transaction_id;
pub use protocol_candidate::query_protocol_candidates_list_recent; pub use protocol_candidate::query_protocol_candidates_list_recent;
pub use reward_event::query_reward_events_get_by_decoded_event_id;
pub use reward_event::query_reward_events_list_recent;
pub use reward_event::query_reward_events_upsert;
pub use swap::query_swaps_list_recent; pub use swap::query_swaps_list_recent;
pub use swap::query_swaps_upsert; pub use swap::query_swaps_upsert;
pub use token::query_tokens_get_by_id; pub use token::query_tokens_get_by_id;

View File

@@ -0,0 +1,302 @@
// file: kb_lib/src/db/queries/fee_event.rs
//! Queries for `k_sol_fee_events`.
/// Returns one fee event by decoded event id.
pub async fn query_fee_events_get_by_decoded_event_id(
database: &crate::Database,
decoded_event_id: i64,
) -> Result<std::option::Option<crate::FeeEventDto>, crate::Error> {
match database.connection() {
crate::DatabaseConnection::Sqlite(pool) => {
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::FeeEventEntity>(
r#"
SELECT
id,
transaction_id,
decoded_event_id,
dex_id,
pool_id,
pair_id,
signature,
slot,
protocol_name,
program_id,
event_kind,
pool_account,
actor_wallet,
fee_token_mint,
fee_amount_raw,
payload_json,
executed_at,
created_at
FROM k_sol_fee_events
WHERE decoded_event_id = ?
LIMIT 1
"#,
)
.bind(decoded_event_id)
.fetch_optional(pool)
.await;
let entity_option = match query_result {
Ok(entity_option) => entity_option,
Err(error) => {
return Err(crate::Error::Db(format!(
"cannot fetch k_sol_fee_events by decoded_event_id '{}' on sqlite: {}",
decoded_event_id, error
)));
},
};
match entity_option {
Some(entity) => {
let dto_result = crate::FeeEventDto::try_from(entity);
match dto_result {
Ok(dto) => return Ok(Some(dto)),
Err(error) => return Err(error),
}
},
None => return Ok(None),
}
},
}
}
/// Inserts or updates one normalized fee event row.
pub async fn query_fee_events_upsert(
database: &crate::Database,
dto: &crate::FeeEventDto,
) -> Result<i64, crate::Error> {
let slot_i64 = match dto.slot {
Some(slot) => {
let slot_result = i64::try_from(slot);
match slot_result {
Ok(slot) => Some(slot),
Err(error) => {
return Err(crate::Error::Db(format!(
"cannot convert fee event slot '{}' to i64: {}",
slot, error
)));
},
}
},
None => None,
};
match database.connection() {
crate::DatabaseConnection::Sqlite(pool) => {
let existing_id = match dto.decoded_event_id {
Some(decoded_event_id) => {
let existing_result = sqlx::query_scalar::<sqlx::Sqlite, i64>(
r#"
SELECT id
FROM k_sol_fee_events
WHERE decoded_event_id = ?
LIMIT 1
"#,
)
.bind(decoded_event_id)
.fetch_optional(pool)
.await;
match existing_result {
Ok(existing_id) => existing_id,
Err(error) => {
return Err(crate::Error::Db(format!(
"cannot fetch k_sol_fee_events id for decoded_event_id '{}' on sqlite: {}",
decoded_event_id, error
)));
},
}
},
None => None,
};
if let Some(id) = existing_id {
let update_result = sqlx::query(
r#"
UPDATE k_sol_fee_events
SET
transaction_id = ?,
dex_id = ?,
pool_id = ?,
pair_id = ?,
signature = ?,
slot = ?,
protocol_name = ?,
program_id = ?,
event_kind = ?,
pool_account = ?,
actor_wallet = ?,
fee_token_mint = ?,
fee_amount_raw = ?,
payload_json = ?,
executed_at = ?
WHERE id = ?
"#,
)
.bind(dto.transaction_id)
.bind(dto.dex_id)
.bind(dto.pool_id)
.bind(dto.pair_id)
.bind(dto.signature.clone())
.bind(slot_i64)
.bind(dto.protocol_name.clone())
.bind(dto.program_id.clone())
.bind(dto.event_kind.clone())
.bind(dto.pool_account.clone())
.bind(dto.actor_wallet.clone())
.bind(dto.fee_token_mint.clone())
.bind(dto.fee_amount_raw.clone())
.bind(dto.payload_json.clone())
.bind(dto.executed_at.to_rfc3339())
.bind(id)
.execute(pool)
.await;
if let Err(error) = update_result {
return Err(crate::Error::Db(format!(
"cannot update k_sol_fee_events id '{}' on sqlite: {}",
id, error
)));
}
return Ok(id);
}
let insert_result = sqlx::query(
r#"
INSERT INTO k_sol_fee_events (
transaction_id,
decoded_event_id,
dex_id,
pool_id,
pair_id,
signature,
slot,
protocol_name,
program_id,
event_kind,
pool_account,
actor_wallet,
fee_token_mint,
fee_amount_raw,
payload_json,
executed_at,
created_at
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
"#,
)
.bind(dto.transaction_id)
.bind(dto.decoded_event_id)
.bind(dto.dex_id)
.bind(dto.pool_id)
.bind(dto.pair_id)
.bind(dto.signature.clone())
.bind(slot_i64)
.bind(dto.protocol_name.clone())
.bind(dto.program_id.clone())
.bind(dto.event_kind.clone())
.bind(dto.pool_account.clone())
.bind(dto.actor_wallet.clone())
.bind(dto.fee_token_mint.clone())
.bind(dto.fee_amount_raw.clone())
.bind(dto.payload_json.clone())
.bind(dto.executed_at.to_rfc3339())
.bind(dto.created_at.to_rfc3339())
.execute(pool)
.await;
if let Err(error) = insert_result {
return Err(crate::Error::Db(format!(
"cannot insert k_sol_fee_events on sqlite: {}",
error
)));
}
let id_result = sqlx::query_scalar::<sqlx::Sqlite, i64>(
r#"
SELECT id
FROM k_sol_fee_events
WHERE transaction_id = ?
AND protocol_name = ?
AND event_kind = ?
AND signature = ?
ORDER BY id DESC
LIMIT 1
"#,
)
.bind(dto.transaction_id)
.bind(dto.protocol_name.clone())
.bind(dto.event_kind.clone())
.bind(dto.signature.clone())
.fetch_one(pool)
.await;
match id_result {
Ok(id) => return Ok(id),
Err(error) => {
return Err(crate::Error::Db(format!(
"cannot fetch inserted k_sol_fee_events id for signature '{}' on sqlite: {}",
dto.signature, error
)));
},
}
},
}
}
/// Lists recent fee events ordered from newest to oldest.
pub async fn query_fee_events_list_recent(
database: &crate::Database,
limit: u32,
) -> Result<std::vec::Vec<crate::FeeEventDto>, crate::Error> {
if limit == 0 {
return Ok(std::vec::Vec::new());
}
match database.connection() {
crate::DatabaseConnection::Sqlite(pool) => {
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::FeeEventEntity>(
r#"
SELECT
id,
transaction_id,
decoded_event_id,
dex_id,
pool_id,
pair_id,
signature,
slot,
protocol_name,
program_id,
event_kind,
pool_account,
actor_wallet,
fee_token_mint,
fee_amount_raw,
payload_json,
executed_at,
created_at
FROM k_sol_fee_events
ORDER BY id DESC
LIMIT ?
"#,
)
.bind(i64::from(limit))
.fetch_all(pool)
.await;
let entities = match query_result {
Ok(entities) => entities,
Err(error) => {
return Err(crate::Error::Db(format!(
"cannot list k_sol_fee_events on sqlite: {}",
error
)));
},
};
let mut dtos = std::vec::Vec::with_capacity(entities.len());
for entity in entities {
let dto_result = crate::FeeEventDto::try_from(entity);
match dto_result {
Ok(dto) => dtos.push(dto),
Err(error) => return Err(error),
}
}
return Ok(dtos);
},
}
}

View File

@@ -50,6 +50,9 @@ SELECT
) AS decoded_unknown_event_count, ) AS decoded_unknown_event_count,
(SELECT COUNT(*) FROM k_sol_liquidity_events) AS liquidity_event_count, (SELECT COUNT(*) FROM k_sol_liquidity_events) AS liquidity_event_count,
(SELECT COUNT(*) FROM k_sol_pool_lifecycle_events) AS pool_lifecycle_event_count, (SELECT COUNT(*) FROM k_sol_pool_lifecycle_events) AS pool_lifecycle_event_count,
(SELECT COUNT(*) FROM k_sol_fee_events) AS fee_event_count,
(SELECT COUNT(*) FROM k_sol_reward_events) AS reward_event_count,
(SELECT COUNT(*) FROM k_sol_pool_admin_events) AS pool_admin_event_count,
( (
SELECT COUNT(*) SELECT COUNT(*)
FROM k_sol_dex_decoded_events dde FROM k_sol_dex_decoded_events dde
@@ -361,6 +364,9 @@ SELECT
decoded_unknown_event_count: row.decoded_unknown_event_count, decoded_unknown_event_count: row.decoded_unknown_event_count,
liquidity_event_count: row.liquidity_event_count, liquidity_event_count: row.liquidity_event_count,
pool_lifecycle_event_count: row.pool_lifecycle_event_count, pool_lifecycle_event_count: row.pool_lifecycle_event_count,
fee_event_count: row.fee_event_count,
reward_event_count: row.reward_event_count,
pool_admin_event_count: row.pool_admin_event_count,
missing_trade_event_count: row.missing_trade_event_count, missing_trade_event_count: row.missing_trade_event_count,
decoded_trade_candidate_without_trade_event_count: row decoded_trade_candidate_without_trade_event_count: row
.decoded_trade_candidate_without_trade_event_count, .decoded_trade_candidate_without_trade_event_count,
@@ -772,7 +778,7 @@ ORDER BY
return Ok(summaries); return Ok(summaries);
}, },
} }
} }
/// Lists local pair trading-readiness summaries. /// Lists local pair trading-readiness summaries.
pub async fn query_local_pair_trading_readiness_diagnostic_list_summaries( pub async fn query_local_pair_trading_readiness_diagnostic_list_summaries(

View File

@@ -0,0 +1,293 @@
// file: kb_lib/src/db/queries/pool_admin_event.rs
//! Queries for `k_sol_pool_admin_events`.
/// Returns one pool admin event by decoded event id.
pub async fn query_pool_admin_events_get_by_decoded_event_id(
database: &crate::Database,
decoded_event_id: i64,
) -> Result<std::option::Option<crate::PoolAdminEventDto>, crate::Error> {
match database.connection() {
crate::DatabaseConnection::Sqlite(pool) => {
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::PoolAdminEventEntity>(
r#"
SELECT
id,
transaction_id,
decoded_event_id,
dex_id,
pool_id,
pair_id,
signature,
slot,
protocol_name,
program_id,
event_kind,
pool_account,
actor_wallet,
admin_action,
payload_json,
executed_at,
created_at
FROM k_sol_pool_admin_events
WHERE decoded_event_id = ?
LIMIT 1
"#,
)
.bind(decoded_event_id)
.fetch_optional(pool)
.await;
let entity_option = match query_result {
Ok(entity_option) => entity_option,
Err(error) => {
return Err(crate::Error::Db(format!(
"cannot fetch k_sol_pool_admin_events by decoded_event_id '{}' on sqlite: {}",
decoded_event_id, error
)));
},
};
match entity_option {
Some(entity) => {
let dto_result = crate::PoolAdminEventDto::try_from(entity);
match dto_result {
Ok(dto) => return Ok(Some(dto)),
Err(error) => return Err(error),
}
},
None => return Ok(None),
}
},
}
}
/// Inserts or updates one normalized pool admin event row.
pub async fn query_pool_admin_events_upsert(
database: &crate::Database,
dto: &crate::PoolAdminEventDto,
) -> Result<i64, crate::Error> {
let slot_i64 = match dto.slot {
Some(slot) => {
let slot_result = i64::try_from(slot);
match slot_result {
Ok(slot) => Some(slot),
Err(error) => {
return Err(crate::Error::Db(format!(
"cannot convert pool admin event slot '{}' to i64: {}",
slot, error
)));
},
}
},
None => None,
};
match database.connection() {
crate::DatabaseConnection::Sqlite(pool) => {
let existing_id = match dto.decoded_event_id {
Some(decoded_event_id) => {
let existing_result = sqlx::query_scalar::<sqlx::Sqlite, i64>(
r#"
SELECT id
FROM k_sol_pool_admin_events
WHERE decoded_event_id = ?
LIMIT 1
"#,
)
.bind(decoded_event_id)
.fetch_optional(pool)
.await;
match existing_result {
Ok(existing_id) => existing_id,
Err(error) => {
return Err(crate::Error::Db(format!(
"cannot fetch k_sol_pool_admin_events id for decoded_event_id '{}' on sqlite: {}",
decoded_event_id, error
)));
},
}
},
None => None,
};
if let Some(id) = existing_id {
let update_result = sqlx::query(
r#"
UPDATE k_sol_pool_admin_events
SET
transaction_id = ?,
dex_id = ?,
pool_id = ?,
pair_id = ?,
signature = ?,
slot = ?,
protocol_name = ?,
program_id = ?,
event_kind = ?,
pool_account = ?,
actor_wallet = ?,
admin_action = ?,
payload_json = ?,
executed_at = ?
WHERE id = ?
"#,
)
.bind(dto.transaction_id)
.bind(dto.dex_id)
.bind(dto.pool_id)
.bind(dto.pair_id)
.bind(dto.signature.clone())
.bind(slot_i64)
.bind(dto.protocol_name.clone())
.bind(dto.program_id.clone())
.bind(dto.event_kind.clone())
.bind(dto.pool_account.clone())
.bind(dto.actor_wallet.clone())
.bind(dto.admin_action.clone())
.bind(dto.payload_json.clone())
.bind(dto.executed_at.to_rfc3339())
.bind(id)
.execute(pool)
.await;
if let Err(error) = update_result {
return Err(crate::Error::Db(format!(
"cannot update k_sol_pool_admin_events id '{}' on sqlite: {}",
id, error
)));
}
return Ok(id);
}
let insert_result = sqlx::query(
r#"
INSERT INTO k_sol_pool_admin_events (
transaction_id,
decoded_event_id,
dex_id,
pool_id,
pair_id,
signature,
slot,
protocol_name,
program_id,
event_kind,
pool_account,
actor_wallet,
admin_action,
payload_json,
executed_at,
created_at
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
"#,
)
.bind(dto.transaction_id)
.bind(dto.decoded_event_id)
.bind(dto.dex_id)
.bind(dto.pool_id)
.bind(dto.pair_id)
.bind(dto.signature.clone())
.bind(slot_i64)
.bind(dto.protocol_name.clone())
.bind(dto.program_id.clone())
.bind(dto.event_kind.clone())
.bind(dto.pool_account.clone())
.bind(dto.actor_wallet.clone())
.bind(dto.admin_action.clone())
.bind(dto.payload_json.clone())
.bind(dto.executed_at.to_rfc3339())
.bind(dto.created_at.to_rfc3339())
.execute(pool)
.await;
if let Err(error) = insert_result {
return Err(crate::Error::Db(format!(
"cannot insert k_sol_pool_admin_events on sqlite: {}",
error
)));
}
let id_result = sqlx::query_scalar::<sqlx::Sqlite, i64>(
r#"
SELECT id
FROM k_sol_pool_admin_events
WHERE transaction_id = ?
AND protocol_name = ?
AND event_kind = ?
AND signature = ?
ORDER BY id DESC
LIMIT 1
"#,
)
.bind(dto.transaction_id)
.bind(dto.protocol_name.clone())
.bind(dto.event_kind.clone())
.bind(dto.signature.clone())
.fetch_one(pool)
.await;
match id_result {
Ok(id) => return Ok(id),
Err(error) => {
return Err(crate::Error::Db(format!(
"cannot fetch inserted k_sol_pool_admin_events id for signature '{}' on sqlite: {}",
dto.signature, error
)));
},
}
},
}
}
/// Lists recent pool admin events ordered from newest to oldest.
pub async fn query_pool_admin_events_list_recent(
database: &crate::Database,
limit: u32,
) -> Result<std::vec::Vec<crate::PoolAdminEventDto>, crate::Error> {
if limit == 0 {
return Ok(std::vec::Vec::new());
}
match database.connection() {
crate::DatabaseConnection::Sqlite(pool) => {
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::PoolAdminEventEntity>(
r#"
SELECT
id,
transaction_id,
decoded_event_id,
dex_id,
pool_id,
pair_id,
signature,
slot,
protocol_name,
program_id,
event_kind,
pool_account,
actor_wallet,
admin_action,
payload_json,
executed_at,
created_at
FROM k_sol_pool_admin_events
ORDER BY id DESC
LIMIT ?
"#,
)
.bind(i64::from(limit))
.fetch_all(pool)
.await;
let entities = match query_result {
Ok(entities) => entities,
Err(error) => {
return Err(crate::Error::Db(format!(
"cannot list k_sol_pool_admin_events on sqlite: {}",
error
)));
},
};
let mut dtos = std::vec::Vec::with_capacity(entities.len());
for entity in entities {
let dto_result = crate::PoolAdminEventDto::try_from(entity);
match dto_result {
Ok(dto) => dtos.push(dto),
Err(error) => return Err(error),
}
}
return Ok(dtos);
},
}
}

View File

@@ -0,0 +1,299 @@
// file: kb_lib/src/db/queries/reward_event.rs
//! Queries for `k_sol_reward_events`.
/// Returns one reward event by decoded event id.
pub async fn query_reward_events_get_by_decoded_event_id(
database: &crate::Database,
decoded_event_id: i64,
) -> Result<std::option::Option<crate::RewardEventDto>, crate::Error> {
match database.connection() {
crate::DatabaseConnection::Sqlite(pool) => {
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::RewardEventEntity>(
r#"
SELECT
id,
transaction_id,
decoded_event_id,
dex_id,
pool_id,
pair_id,
signature,
slot,
protocol_name,
program_id,
event_kind,
pool_account,
actor_wallet,
reward_token_mint,
reward_amount_raw,
payload_json,
executed_at,
created_at
FROM k_sol_reward_events
WHERE decoded_event_id = ?
LIMIT 1
"#,
)
.bind(decoded_event_id)
.fetch_optional(pool)
.await;
let entity_option = match query_result {
Ok(entity_option) => entity_option,
Err(error) => {
return Err(crate::Error::Db(format!(
"cannot fetch k_sol_reward_events by decoded_event_id '{}' on sqlite: {}",
decoded_event_id, error
)));
},
};
match entity_option {
Some(entity) => {
let dto_result = crate::RewardEventDto::try_from(entity);
match dto_result {
Ok(dto) => return Ok(Some(dto)),
Err(error) => return Err(error),
}
},
None => return Ok(None),
}
},
}
}
/// Inserts or updates one normalized reward event row.
pub async fn query_reward_events_upsert(
database: &crate::Database,
dto: &crate::RewardEventDto,
) -> Result<i64, crate::Error> {
let slot_i64 = match dto.slot {
Some(slot) => {
let slot_result = i64::try_from(slot);
match slot_result {
Ok(slot) => Some(slot),
Err(error) => {
return Err(crate::Error::Db(format!(
"cannot convert reward event slot '{}' to i64: {}",
slot, error
)));
},
}
},
None => None,
};
match database.connection() {
crate::DatabaseConnection::Sqlite(pool) => {
let existing_id = match dto.decoded_event_id {
Some(decoded_event_id) => {
let existing_result = sqlx::query_scalar::<sqlx::Sqlite, i64>(
r#"
SELECT id
FROM k_sol_reward_events
WHERE decoded_event_id = ?
LIMIT 1
"#,
)
.bind(decoded_event_id)
.fetch_optional(pool)
.await;
match existing_result {
Ok(existing_id) => existing_id,
Err(error) => {
return Err(crate::Error::Db(format!(
"cannot fetch k_sol_reward_events id for decoded_event_id '{}' on sqlite: {}",
decoded_event_id, error
)));
},
}
},
None => None,
};
if let Some(id) = existing_id {
let update_result = sqlx::query(
r#"
UPDATE k_sol_reward_events
SET
transaction_id = ?,
dex_id = ?,
pool_id = ?,
pair_id = ?,
signature = ?,
slot = ?,
protocol_name = ?,
program_id = ?,
event_kind = ?,
pool_account = ?,
actor_wallet = ?,
reward_token_mint = ?,
reward_amount_raw = ?,
payload_json = ?,
executed_at = ?
WHERE id = ?
"#,
)
.bind(dto.transaction_id)
.bind(dto.dex_id)
.bind(dto.pool_id)
.bind(dto.pair_id)
.bind(dto.signature.clone())
.bind(slot_i64)
.bind(dto.protocol_name.clone())
.bind(dto.program_id.clone())
.bind(dto.event_kind.clone())
.bind(dto.pool_account.clone())
.bind(dto.actor_wallet.clone())
.bind(dto.reward_token_mint.clone())
.bind(dto.reward_amount_raw.clone())
.bind(dto.payload_json.clone())
.bind(dto.executed_at.to_rfc3339())
.bind(id)
.execute(pool)
.await;
if let Err(error) = update_result {
return Err(crate::Error::Db(format!(
"cannot update k_sol_reward_events id '{}' on sqlite: {}",
id, error
)));
}
return Ok(id);
}
let insert_result = sqlx::query(
r#"
INSERT INTO k_sol_reward_events (
transaction_id,
decoded_event_id,
dex_id,
pool_id,
pair_id,
signature,
slot,
protocol_name,
program_id,
event_kind,
pool_account,
actor_wallet,
reward_token_mint,
reward_amount_raw,
payload_json,
executed_at,
created_at
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
"#,
)
.bind(dto.transaction_id)
.bind(dto.decoded_event_id)
.bind(dto.dex_id)
.bind(dto.pool_id)
.bind(dto.pair_id)
.bind(dto.signature.clone())
.bind(slot_i64)
.bind(dto.protocol_name.clone())
.bind(dto.program_id.clone())
.bind(dto.event_kind.clone())
.bind(dto.pool_account.clone())
.bind(dto.actor_wallet.clone())
.bind(dto.reward_token_mint.clone())
.bind(dto.reward_amount_raw.clone())
.bind(dto.payload_json.clone())
.bind(dto.executed_at.to_rfc3339())
.bind(dto.created_at.to_rfc3339())
.execute(pool)
.await;
if let Err(error) = insert_result {
return Err(crate::Error::Db(format!(
"cannot insert k_sol_reward_events on sqlite: {}",
error
)));
}
let id_result = sqlx::query_scalar::<sqlx::Sqlite, i64>(
r#"
SELECT id
FROM k_sol_reward_events
WHERE transaction_id = ?
AND protocol_name = ?
AND event_kind = ?
AND signature = ?
ORDER BY id DESC
LIMIT 1
"#,
)
.bind(dto.transaction_id)
.bind(dto.protocol_name.clone())
.bind(dto.event_kind.clone())
.bind(dto.signature.clone())
.fetch_one(pool)
.await;
match id_result {
Ok(id) => return Ok(id),
Err(error) => {
return Err(crate::Error::Db(format!(
"cannot fetch inserted k_sol_reward_events id for signature '{}' on sqlite: {}",
dto.signature, error
)));
},
}
},
}
}
/// Lists recent reward events ordered from newest to oldest.
pub async fn query_reward_events_list_recent(
database: &crate::Database,
limit: u32,
) -> Result<std::vec::Vec<crate::RewardEventDto>, crate::Error> {
if limit == 0 {
return Ok(std::vec::Vec::new());
}
match database.connection() {
crate::DatabaseConnection::Sqlite(pool) => {
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::RewardEventEntity>(
r#"
SELECT
id,
transaction_id,
decoded_event_id,
dex_id,
pool_id,
pair_id,
signature,
slot,
protocol_name,
program_id,
event_kind,
pool_account,
actor_wallet,
reward_token_mint,
reward_amount_raw,
payload_json,
executed_at,
created_at
FROM k_sol_reward_events
ORDER BY id DESC
LIMIT ?
"#,
)
.bind(i64::from(limit))
.fetch_all(pool)
.await;
let entities = match query_result {
Ok(entities) => entities,
Err(error) => {
return Err(crate::Error::Db(format!(
"cannot list k_sol_reward_events on sqlite: {}",
error
)));
},
};
let mut dtos = std::vec::Vec::with_capacity(entities.len());
for entity in entities {
let dto_result = crate::RewardEventDto::try_from(entity);
match dto_result {
Ok(dto) => dtos.push(dto),
Err(error) => return Err(error),
}
}
return Ok(dtos);
},
}
}

View File

@@ -317,6 +317,10 @@ pub use db::DexDecodedEventEntity;
pub use db::DexDto; pub use db::DexDto;
/// Persisted normalized DEX row. /// Persisted normalized DEX row.
pub use db::DexEntity; pub use db::DexEntity;
/// Normalized fee event persisted from useful non-trade DEX events.
pub use db::FeeEventDto;
/// Persisted fee event row.
pub use db::FeeEventEntity;
/// Application-facing known HTTP endpoint DTO. /// Application-facing known HTTP endpoint DTO.
pub use db::KnownHttpEndpointDto; pub use db::KnownHttpEndpointDto;
/// Application-facing known WebSocket endpoint DTO. /// Application-facing known WebSocket endpoint DTO.
@@ -399,6 +403,10 @@ pub use db::PairEntity;
pub use db::PairMetricDto; pub use db::PairMetricDto;
/// Persisted pair-metric row. /// Persisted pair-metric row.
pub use db::PairMetricEntity; pub use db::PairMetricEntity;
/// Normalized pool administration event persisted from useful non-trade DEX events.
pub use db::PoolAdminEventDto;
/// Persisted pool administration event row.
pub use db::PoolAdminEventEntity;
/// Application-facing normalized pool DTO. /// Application-facing normalized pool DTO.
pub use db::PoolDto; pub use db::PoolDto;
/// Persisted normalized pool row. /// Persisted normalized pool row.
@@ -445,6 +453,10 @@ pub use db::ProtocolCandidateEntity;
pub use db::ProtocolCandidateSummaryDto; pub use db::ProtocolCandidateSummaryDto;
/// Aggregated protocol candidate diagnostic row. /// Aggregated protocol candidate diagnostic row.
pub use db::ProtocolCandidateSummaryEntity; pub use db::ProtocolCandidateSummaryEntity;
/// Normalized reward event persisted from useful non-trade DEX events.
pub use db::RewardEventDto;
/// Persisted reward event row.
pub use db::RewardEventEntity;
/// Application-facing normalized swap DTO. /// Application-facing normalized swap DTO.
pub use db::SwapDto; pub use db::SwapDto;
/// Persisted normalized swap row. /// Persisted normalized swap row.
@@ -533,6 +545,12 @@ pub use db::query_dexs_get_by_code;
pub use db::query_dexs_list; pub use db::query_dexs_list;
/// Inserts or updates one normalized DEX row by code. /// Inserts or updates one normalized DEX row by code.
pub use db::query_dexs_upsert; pub use db::query_dexs_upsert;
/// Returns one fee event by decoded-event id.
pub use db::query_fee_events_get_by_decoded_event_id;
/// Lists recent fee events ordered from newest to oldest.
pub use db::query_fee_events_list_recent;
/// Inserts or updates one normalized fee event row.
pub use db::query_fee_events_upsert;
/// Reads one known HTTP endpoint by name. /// Reads one known HTTP endpoint by name.
pub use db::query_known_http_endpoints_get; pub use db::query_known_http_endpoints_get;
/// Lists all known HTTP endpoints. /// Lists all known HTTP endpoints.
@@ -631,6 +649,12 @@ pub use db::query_pairs_list;
pub use db::query_pairs_update_symbol; pub use db::query_pairs_update_symbol;
/// Inserts or updates one normalized pair row by pool id. /// Inserts or updates one normalized pair row by pool id.
pub use db::query_pairs_upsert; pub use db::query_pairs_upsert;
/// Returns one pool administration event by decoded-event id.
pub use db::query_pool_admin_events_get_by_decoded_event_id;
/// Lists recent pool administration events ordered from newest to oldest.
pub use db::query_pool_admin_events_list_recent;
/// Inserts or updates one normalized pool administration event row.
pub use db::query_pool_admin_events_upsert;
/// Returns one pool lifecycle event by decoded event id. /// Returns one pool lifecycle event by decoded event id.
pub use db::query_pool_lifecycle_events_get_by_decoded_event_id; pub use db::query_pool_lifecycle_events_get_by_decoded_event_id;
/// Lists recent pool lifecycle events ordered from newest to oldest. /// Lists recent pool lifecycle events ordered from newest to oldest.
@@ -677,6 +701,12 @@ pub use db::query_protocol_candidates_list_by_program_id;
pub use db::query_protocol_candidates_list_by_transaction_id; pub use db::query_protocol_candidates_list_by_transaction_id;
/// Lists recent protocol candidates ordered from newest to oldest. /// Lists recent protocol candidates ordered from newest to oldest.
pub use db::query_protocol_candidates_list_recent; pub use db::query_protocol_candidates_list_recent;
/// Returns one reward event by decoded-event id.
pub use db::query_reward_events_get_by_decoded_event_id;
/// Lists recent reward events ordered from newest to oldest.
pub use db::query_reward_events_list_recent;
/// Inserts or updates one normalized reward event row.
pub use db::query_reward_events_upsert;
/// Lists recent swaps ordered from newest to oldest. /// Lists recent swaps ordered from newest to oldest.
pub use db::query_swaps_list_recent; pub use db::query_swaps_list_recent;
/// Inserts or updates one normalized swap row. /// Inserts or updates one normalized swap row.

View File

@@ -154,6 +154,9 @@ impl LocalPipelineDiagnosticsService {
decoded_unknown_event_count: counters.decoded_unknown_event_count, decoded_unknown_event_count: counters.decoded_unknown_event_count,
liquidity_event_count: counters.liquidity_event_count, liquidity_event_count: counters.liquidity_event_count,
pool_lifecycle_event_count: counters.pool_lifecycle_event_count, pool_lifecycle_event_count: counters.pool_lifecycle_event_count,
fee_event_count: counters.fee_event_count,
reward_event_count: counters.reward_event_count,
pool_admin_event_count: counters.pool_admin_event_count,
diagnostics_clean, diagnostics_clean,
blocking_issue_count, blocking_issue_count,
missing_trade_event_count: counters.missing_trade_event_count, missing_trade_event_count: counters.missing_trade_event_count,

View File

@@ -61,6 +61,12 @@ pub struct LocalPipelineReplayResult {
pub liquidity_event_count: usize, pub liquidity_event_count: usize,
/// Total pool lifecycle event materialization results returned by replayed non-trade calls. /// Total pool lifecycle event materialization results returned by replayed non-trade calls.
pub pool_lifecycle_event_count: usize, pub pool_lifecycle_event_count: usize,
/// Total fee event materialization results returned by replayed non-trade calls.
pub fee_event_count: usize,
/// Total reward event materialization results returned by replayed non-trade calls.
pub reward_event_count: usize,
/// Total pool administration event materialization results returned by replayed non-trade calls.
pub pool_admin_event_count: usize,
/// Total candle upsert results returned by replayed candle calls. /// Total candle upsert results returned by replayed candle calls.
/// ///
/// This is a replay write/result counter, not the number of distinct rows /// This is a replay write/result counter, not the number of distinct rows
@@ -203,6 +209,9 @@ impl LocalPipelineReplayService {
result.liquidity_event_count += non_trade_result.liquidity_event_count; result.liquidity_event_count += non_trade_result.liquidity_event_count;
result.pool_lifecycle_event_count += result.pool_lifecycle_event_count +=
non_trade_result.pool_lifecycle_event_count; non_trade_result.pool_lifecycle_event_count;
result.fee_event_count += non_trade_result.fee_event_count;
result.reward_event_count += non_trade_result.reward_event_count;
result.pool_admin_event_count += non_trade_result.pool_admin_event_count;
}, },
Err(error) => { Err(error) => {
result.non_trade_materialization_error_count += 1; result.non_trade_materialization_error_count += 1;

View File

@@ -224,6 +224,17 @@ impl LocalPipelineValidationConfig {
config.allow_unexpected_dexes = true; config.allow_unexpected_dexes = true;
return config; return config;
} }
/// Builds the `0.7.35` non-trade fee/reward/admin validation config.
///
/// This profile keeps the `0.7.34` checks and exposes fee, reward and
/// administration materialization counters without changing trade/candle
/// validation semantics.
pub fn v0_7_35_non_trade_fee_reward_admin() -> Self {
let mut config = Self::v0_7_34_non_trade_liquidity_lifecycle();
config.profile_code = "0.7.35_non_trade_fee_reward_admin".to_string();
return config;
}
} }
/// A single local pipeline validation issue. /// A single local pipeline validation issue.
@@ -266,6 +277,12 @@ pub struct LocalPipelineValidationReportDto {
pub liquidity_event_count: i64, pub liquidity_event_count: i64,
/// Total persisted pool lifecycle events. /// Total persisted pool lifecycle events.
pub pool_lifecycle_event_count: i64, pub pool_lifecycle_event_count: i64,
/// Total persisted fee events.
pub fee_event_count: i64,
/// Total persisted reward events.
pub reward_event_count: i64,
/// Total persisted pool administration events.
pub pool_admin_event_count: i64,
/// Number of entries currently exposed by the DEX support matrix. /// Number of entries currently exposed by the DEX support matrix.
pub dex_support_matrix_entry_count: i64, pub dex_support_matrix_entry_count: i64,
/// DEX support matrix snapshot exposed with the validation report. /// DEX support matrix snapshot exposed with the validation report.
@@ -396,6 +413,14 @@ impl LocalPipelineValidationService {
let config = crate::LocalPipelineValidationConfig::v0_7_34_non_trade_liquidity_lifecycle(); let config = crate::LocalPipelineValidationConfig::v0_7_34_non_trade_liquidity_lifecycle();
return self.validate_current_database(&config).await; return self.validate_current_database(&config).await;
} }
/// Diagnoses the current database with the `0.7.35` non-trade fee/reward/admin profile.
pub async fn validate_v0_7_35_current_database(
&self,
) -> Result<crate::LocalPipelineValidationRunDto, crate::Error> {
let config = crate::LocalPipelineValidationConfig::v0_7_35_non_trade_fee_reward_admin();
return self.validate_current_database(&config).await;
}
} }
/// Validates a diagnostics summary without performing database access. /// Validates a diagnostics summary without performing database access.
@@ -513,8 +538,9 @@ pub fn validate_local_pipeline_diagnostics_summary(
if config.require_pair_trading_readiness_semantics { if config.require_pair_trading_readiness_semantics {
validate_pair_trading_readiness_semantics(&mut issues, summary); validate_pair_trading_readiness_semantics(&mut issues, summary);
} }
let missing_expected_dex_is_warning = let missing_expected_dex_is_warning = config.profile_code
config.profile_code == "0.7.34_non_trade_liquidity_lifecycle"; == "0.7.34_non_trade_liquidity_lifecycle"
|| config.profile_code == "0.7.35_non_trade_fee_reward_admin";
if config.require_all_expected_dexes || missing_expected_dex_is_warning { if config.require_all_expected_dexes || missing_expected_dex_is_warning {
for expected_dex_code in &expected_dex_codes { for expected_dex_code in &expected_dex_codes {
if !observed_dex_codes.contains(expected_dex_code) { if !observed_dex_codes.contains(expected_dex_code) {
@@ -586,6 +612,9 @@ pub fn validate_local_pipeline_diagnostics_summary(
decoded_unknown_event_count: summary.decoded_unknown_event_count, decoded_unknown_event_count: summary.decoded_unknown_event_count,
liquidity_event_count: summary.liquidity_event_count, liquidity_event_count: summary.liquidity_event_count,
pool_lifecycle_event_count: summary.pool_lifecycle_event_count, pool_lifecycle_event_count: summary.pool_lifecycle_event_count,
fee_event_count: summary.fee_event_count,
reward_event_count: summary.reward_event_count,
pool_admin_event_count: summary.pool_admin_event_count,
dex_support_matrix_entry_count: crate::dex_support_matrix_entries().len() as i64, dex_support_matrix_entry_count: crate::dex_support_matrix_entries().len() as i64,
dex_support_matrix: crate::dex_support_matrix_entry_dtos(), dex_support_matrix: crate::dex_support_matrix_entry_dtos(),
issues, issues,
@@ -796,6 +825,9 @@ mod tests {
decoded_unknown_event_count: 0, decoded_unknown_event_count: 0,
liquidity_event_count: 0, liquidity_event_count: 0,
pool_lifecycle_event_count: 0, pool_lifecycle_event_count: 0,
fee_event_count: 0,
reward_event_count: 0,
pool_admin_event_count: 0,
diagnostics_clean: true, diagnostics_clean: true,
blocking_issue_count: 0, blocking_issue_count: 0,
missing_trade_event_count: 6, missing_trade_event_count: 6,
@@ -1125,6 +1157,24 @@ mod tests {
assert!(!report.issues[0].blocking); assert!(!report.issues[0].blocking);
} }
#[test]
fn validation_accepts_0_7_35_non_trade_fee_reward_admin_summary() {
let mut summary = make_0_7_28_summary_with_meteora();
summary.decoded_non_trade_useful_event_count = 5;
summary.liquidity_event_count = 2;
summary.pool_lifecycle_event_count = 1;
summary.fee_event_count = 1;
summary.reward_event_count = 1;
summary.pool_admin_event_count = 1;
let config = crate::LocalPipelineValidationConfig::v0_7_35_non_trade_fee_reward_admin();
let report = crate::validate_local_pipeline_diagnostics_summary(&summary, &config);
assert!(report.validation_passed);
assert_eq!(report.validation_profile_code, "0.7.35_non_trade_fee_reward_admin");
assert_eq!(report.fee_event_count, 1);
assert_eq!(report.reward_event_count, 1);
assert_eq!(report.pool_admin_event_count, 1);
}
#[test] #[test]
fn validation_rejects_0_7_33_pair_trading_readiness_mismatch() { fn validation_rejects_0_7_33_pair_trading_readiness_mismatch() {
let mut summary = make_0_7_28_summary_with_meteora(); let mut summary = make_0_7_28_summary_with_meteora();

View File

@@ -2,9 +2,9 @@
//! Materialization of useful non-trade DEX events. //! Materialization of useful non-trade DEX events.
//! //!
//! This service persists liquidity and pool lifecycle events from already //! This service persists liquidity, pool lifecycle, fee, reward and pool
//! decoded DEX events. It deliberately does not feed trade, metric or candle //! administration events from already decoded DEX events. It deliberately does
//! materialization. //! not feed trade, metric or candle materialization.
/// Result of non-trade event materialization for one transaction. /// Result of non-trade event materialization for one transaction.
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)] #[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
@@ -13,6 +13,12 @@ pub struct NonTradeEventMaterializationResult {
pub liquidity_event_count: usize, pub liquidity_event_count: usize,
/// Number of pool lifecycle events inserted or refreshed. /// Number of pool lifecycle events inserted or refreshed.
pub pool_lifecycle_event_count: usize, pub pool_lifecycle_event_count: usize,
/// Number of fee events inserted or refreshed.
pub fee_event_count: usize,
/// Number of reward events inserted or refreshed.
pub reward_event_count: usize,
/// Number of pool administration events inserted or refreshed.
pub pool_admin_event_count: usize,
} }
/// Materializes useful non-trade decoded DEX events. /// Materializes useful non-trade decoded DEX events.
@@ -127,6 +133,50 @@ impl NonTradeEventMaterializationService {
Err(error) => return Err(error), Err(error) => return Err(error),
} }
} }
if crate::is_dex_fee_event_kind(decoded_event.event_kind.as_str()) {
let materialized = self
.materialize_fee_event(&transaction, transaction_id, decoded_event, &payload)
.await;
match materialized {
Ok(was_materialized) => {
if was_materialized {
result.fee_event_count += 1;
}
},
Err(error) => return Err(error),
}
}
if crate::is_dex_reward_event_kind(decoded_event.event_kind.as_str()) {
let materialized = self
.materialize_reward_event(&transaction, transaction_id, decoded_event, &payload)
.await;
match materialized {
Ok(was_materialized) => {
if was_materialized {
result.reward_event_count += 1;
}
},
Err(error) => return Err(error),
}
}
if crate::is_dex_admin_event_kind(decoded_event.event_kind.as_str()) {
let materialized = self
.materialize_pool_admin_event(
&transaction,
transaction_id,
decoded_event,
&payload,
)
.await;
match materialized {
Ok(was_materialized) => {
if was_materialized {
result.pool_admin_event_count += 1;
}
},
Err(error) => return Err(error),
}
}
} }
return Ok(result); return Ok(result);
} }
@@ -170,6 +220,207 @@ impl NonTradeEventMaterializationService {
} }
} }
async fn materialize_fee_event(
&self,
transaction: &crate::ChainTransactionDto,
transaction_id: i64,
decoded_event: &crate::DexDecodedEventDto,
payload: &serde_json::Value,
) -> Result<bool, crate::Error> {
let decoded_event_id = match decoded_event.id {
Some(decoded_event_id) => decoded_event_id,
None => return Ok(false),
};
let context = self.resolve_decoded_event_context(decoded_event).await;
let context = match context {
Ok(context) => context,
Err(error) => return Err(error),
};
let actor_wallet = extract_first_string(
payload,
&[
"actorWallet",
"actor_wallet",
"receiver",
"recipient",
"owner",
"payer",
"authority",
"user",
],
);
let fee_token_mint = extract_first_string(
payload,
&[
"feeTokenMint",
"fee_token_mint",
"tokenMint",
"token_mint",
"mint",
"quoteMint",
"quote_mint",
],
);
let fee_amount_raw = extract_first_amount_string(
payload,
&[
"feeAmountRaw",
"fee_amount_raw",
"feeAmount",
"fee_amount",
"protocolFeeAmount",
"protocol_fee_amount",
"fundFeeAmount",
"fund_fee_amount",
"creatorFeeAmount",
"creator_fee_amount",
"amount",
],
);
let dto = crate::FeeEventDto::new(
transaction_id,
Some(decoded_event_id),
context.dex_id,
context.pool_id,
context.pair_id,
transaction.signature.clone(),
transaction.slot,
decoded_event.protocol_name.clone(),
decoded_event.program_id.clone(),
decoded_event.event_kind.clone(),
decoded_event.pool_account.clone(),
actor_wallet,
fee_token_mint,
fee_amount_raw,
decoded_event.payload_json.clone(),
);
let upsert_result = crate::query_fee_events_upsert(self.database.as_ref(), &dto).await;
match upsert_result {
Ok(_) => return Ok(true),
Err(error) => return Err(error),
}
}
async fn materialize_reward_event(
&self,
transaction: &crate::ChainTransactionDto,
transaction_id: i64,
decoded_event: &crate::DexDecodedEventDto,
payload: &serde_json::Value,
) -> Result<bool, crate::Error> {
let decoded_event_id = match decoded_event.id {
Some(decoded_event_id) => decoded_event_id,
None => return Ok(false),
};
let context = self.resolve_decoded_event_context(decoded_event).await;
let context = match context {
Ok(context) => context,
Err(error) => return Err(error),
};
let actor_wallet = extract_first_string(
payload,
&[
"actorWallet",
"actor_wallet",
"receiver",
"recipient",
"owner",
"payer",
"authority",
"user",
],
);
let reward_token_mint = extract_first_string(
payload,
&["rewardTokenMint", "reward_token_mint", "tokenMint", "token_mint", "mint"],
);
let reward_amount_raw = extract_first_amount_string(
payload,
&[
"rewardAmountRaw",
"reward_amount_raw",
"rewardAmount",
"reward_amount",
"emissionAmount",
"emission_amount",
"amount",
],
);
let dto = crate::RewardEventDto::new(
transaction_id,
Some(decoded_event_id),
context.dex_id,
context.pool_id,
context.pair_id,
transaction.signature.clone(),
transaction.slot,
decoded_event.protocol_name.clone(),
decoded_event.program_id.clone(),
decoded_event.event_kind.clone(),
decoded_event.pool_account.clone(),
actor_wallet,
reward_token_mint,
reward_amount_raw,
decoded_event.payload_json.clone(),
);
let upsert_result = crate::query_reward_events_upsert(self.database.as_ref(), &dto).await;
match upsert_result {
Ok(_) => return Ok(true),
Err(error) => return Err(error),
}
}
async fn materialize_pool_admin_event(
&self,
transaction: &crate::ChainTransactionDto,
transaction_id: i64,
decoded_event: &crate::DexDecodedEventDto,
payload: &serde_json::Value,
) -> Result<bool, crate::Error> {
let decoded_event_id = match decoded_event.id {
Some(decoded_event_id) => decoded_event_id,
None => return Ok(false),
};
let context = self.resolve_decoded_event_context(decoded_event).await;
let context = match context {
Ok(context) => context,
Err(error) => return Err(error),
};
let actor_wallet = extract_first_string(
payload,
&["actorWallet", "actor_wallet", "authority", "admin", "owner", "payer", "user"],
);
let admin_action = match extract_first_string(
payload,
&["adminAction", "admin_action", "action", "configAction", "config_action"],
) {
Some(admin_action) => Some(admin_action),
None => Some(decoded_event.event_kind.clone()),
};
let dto = crate::PoolAdminEventDto::new(
transaction_id,
Some(decoded_event_id),
context.dex_id,
context.pool_id,
context.pair_id,
transaction.signature.clone(),
transaction.slot,
decoded_event.protocol_name.clone(),
decoded_event.program_id.clone(),
decoded_event.event_kind.clone(),
decoded_event.pool_account.clone(),
actor_wallet,
admin_action,
decoded_event.payload_json.clone(),
);
let upsert_result =
crate::query_pool_admin_events_upsert(self.database.as_ref(), &dto).await;
match upsert_result {
Ok(_) => return Ok(true),
Err(error) => return Err(error),
}
}
async fn materialize_liquidity_event( async fn materialize_liquidity_event(
&self, &self,
transaction: &crate::ChainTransactionDto, transaction: &crate::ChainTransactionDto,
@@ -202,15 +453,16 @@ impl NonTradeEventMaterializationService {
Some(pair_id) => Some(pair_id), Some(pair_id) => Some(pair_id),
None => None, None => None,
}; };
let event_kind = if crate::is_dex_position_open_event_kind(decoded_event.event_kind.as_str()) { let event_kind =
crate::LiquidityEventKind::PositionOpen if crate::is_dex_position_open_event_kind(decoded_event.event_kind.as_str()) {
} else if crate::is_dex_position_close_event_kind(decoded_event.event_kind.as_str()) { crate::LiquidityEventKind::PositionOpen
crate::LiquidityEventKind::PositionClose } else if crate::is_dex_position_close_event_kind(decoded_event.event_kind.as_str()) {
} else if crate::is_dex_liquidity_remove_event_kind(decoded_event.event_kind.as_str()) { crate::LiquidityEventKind::PositionClose
crate::LiquidityEventKind::Remove } else if crate::is_dex_liquidity_remove_event_kind(decoded_event.event_kind.as_str()) {
} else { crate::LiquidityEventKind::Remove
crate::LiquidityEventKind::Add } else {
}; crate::LiquidityEventKind::Add
};
let actor_wallet = extract_first_string( let actor_wallet = extract_first_string(
payload, payload,
&[ &[

View File

@@ -35,6 +35,12 @@ pub struct TokenBackfillResult {
pub liquidity_event_count: usize, pub liquidity_event_count: usize,
/// Total number of pool lifecycle event materialization results produced during this run. /// Total number of pool lifecycle event materialization results produced during this run.
pub pool_lifecycle_event_count: usize, pub pool_lifecycle_event_count: usize,
/// Total number of fee event materialization results produced during this run.
pub fee_event_count: usize,
/// Total number of reward event materialization results produced during this run.
pub reward_event_count: usize,
/// Total number of pool administration event materialization results produced during this run.
pub pool_admin_event_count: usize,
/// Total number of pair-candle aggregation results produced during this run. /// Total number of pair-candle aggregation results produced during this run.
pub pair_candle_count: usize, pub pair_candle_count: usize,
} }
@@ -68,6 +74,12 @@ pub struct PoolBackfillResult {
pub liquidity_event_count: usize, pub liquidity_event_count: usize,
/// Total number of pool lifecycle event materialization results produced during this run. /// Total number of pool lifecycle event materialization results produced during this run.
pub pool_lifecycle_event_count: usize, pub pool_lifecycle_event_count: usize,
/// Total number of fee event materialization results produced during this run.
pub fee_event_count: usize,
/// Total number of reward event materialization results produced during this run.
pub reward_event_count: usize,
/// Total number of pool administration event materialization results produced during this run.
pub pool_admin_event_count: usize,
/// Total number of pair-candle aggregation results produced during this run. /// Total number of pair-candle aggregation results produced during this run.
pub pair_candle_count: usize, pub pair_candle_count: usize,
} }
@@ -163,6 +175,9 @@ impl TokenBackfillService {
trade_event_count: 0, trade_event_count: 0,
liquidity_event_count: 0, liquidity_event_count: 0,
pool_lifecycle_event_count: 0, pool_lifecycle_event_count: 0,
fee_event_count: 0,
reward_event_count: 0,
pool_admin_event_count: 0,
pair_candle_count: 0, pair_candle_count: 0,
}; };
let mut seen_signatures = std::collections::HashSet::<std::string::String>::new(); let mut seen_signatures = std::collections::HashSet::<std::string::String>::new();
@@ -237,6 +252,9 @@ impl TokenBackfillService {
"tradeEventCount": result.trade_event_count, "tradeEventCount": result.trade_event_count,
"liquidityEventCount": result.liquidity_event_count, "liquidityEventCount": result.liquidity_event_count,
"poolLifecycleEventCount": result.pool_lifecycle_event_count, "poolLifecycleEventCount": result.pool_lifecycle_event_count,
"feeEventCount": result.fee_event_count,
"rewardEventCount": result.reward_event_count,
"poolAdminEventCount": result.pool_admin_event_count,
"pairCandleCount": result.pair_candle_count "pairCandleCount": result.pair_candle_count
}); });
let observation_result = self let observation_result = self
@@ -377,6 +395,9 @@ impl TokenBackfillService {
trade_event_count: 0, trade_event_count: 0,
liquidity_event_count: 0, liquidity_event_count: 0,
pool_lifecycle_event_count: 0, pool_lifecycle_event_count: 0,
fee_event_count: 0,
reward_event_count: 0,
pool_admin_event_count: 0,
pair_candle_count: 0, pair_candle_count: 0,
}); });
} }
@@ -484,6 +505,9 @@ impl TokenBackfillService {
trade_event_count: trade_aggregations.len(), trade_event_count: trade_aggregations.len(),
liquidity_event_count: non_trade_materialization.liquidity_event_count, liquidity_event_count: non_trade_materialization.liquidity_event_count,
pool_lifecycle_event_count: non_trade_materialization.pool_lifecycle_event_count, pool_lifecycle_event_count: non_trade_materialization.pool_lifecycle_event_count,
fee_event_count: non_trade_materialization.fee_event_count,
reward_event_count: non_trade_materialization.reward_event_count,
pool_admin_event_count: non_trade_materialization.pool_admin_event_count,
pair_candle_count: pair_candle_aggregations.len(), pair_candle_count: pair_candle_aggregations.len(),
}); });
} }
@@ -509,6 +533,9 @@ impl TokenBackfillService {
trade_event_count: 0, trade_event_count: 0,
liquidity_event_count: 0, liquidity_event_count: 0,
pool_lifecycle_event_count: 0, pool_lifecycle_event_count: 0,
fee_event_count: 0,
reward_event_count: 0,
pool_admin_event_count: 0,
pair_candle_count: 0, pair_candle_count: 0,
}; };
let mut seen_addresses = std::collections::BTreeSet::<std::string::String>::new(); let mut seen_addresses = std::collections::BTreeSet::<std::string::String>::new();
@@ -594,6 +621,9 @@ impl TokenBackfillService {
result.trade_event_count += replay_result.trade_event_count; result.trade_event_count += replay_result.trade_event_count;
result.liquidity_event_count += replay_result.liquidity_event_count; result.liquidity_event_count += replay_result.liquidity_event_count;
result.pool_lifecycle_event_count += replay_result.pool_lifecycle_event_count; result.pool_lifecycle_event_count += replay_result.pool_lifecycle_event_count;
result.fee_event_count += replay_result.fee_event_count;
result.reward_event_count += replay_result.reward_event_count;
result.pool_admin_event_count += replay_result.pool_admin_event_count;
result.pair_candle_count += replay_result.pair_candle_count; result.pair_candle_count += replay_result.pair_candle_count;
} }
} }
@@ -612,6 +642,9 @@ impl TokenBackfillService {
"tradeEventCount": result.trade_event_count, "tradeEventCount": result.trade_event_count,
"liquidityEventCount": result.liquidity_event_count, "liquidityEventCount": result.liquidity_event_count,
"poolLifecycleEventCount": result.pool_lifecycle_event_count, "poolLifecycleEventCount": result.pool_lifecycle_event_count,
"feeEventCount": result.fee_event_count,
"rewardEventCount": result.reward_event_count,
"poolAdminEventCount": result.pool_admin_event_count,
"pairCandleCount": result.pair_candle_count, "pairCandleCount": result.pair_candle_count,
"scannedAddressCount": addresses_to_scan.len(), "scannedAddressCount": addresses_to_scan.len(),
"effectiveSignatureLimit": effective_limit "effectiveSignatureLimit": effective_limit
@@ -687,6 +720,9 @@ struct TokenBackfillSignatureResult {
trade_event_count: usize, trade_event_count: usize,
liquidity_event_count: usize, liquidity_event_count: usize,
pool_lifecycle_event_count: usize, pool_lifecycle_event_count: usize,
fee_event_count: usize,
reward_event_count: usize,
pool_admin_event_count: usize,
pair_candle_count: usize, pair_candle_count: usize,
} }
@@ -704,6 +740,9 @@ fn merge_token_backfill_signature_result(
aggregate.trade_event_count += value.trade_event_count; aggregate.trade_event_count += value.trade_event_count;
aggregate.liquidity_event_count += value.liquidity_event_count; aggregate.liquidity_event_count += value.liquidity_event_count;
aggregate.pool_lifecycle_event_count += value.pool_lifecycle_event_count; aggregate.pool_lifecycle_event_count += value.pool_lifecycle_event_count;
aggregate.fee_event_count += value.fee_event_count;
aggregate.reward_event_count += value.reward_event_count;
aggregate.pool_admin_event_count += value.pool_admin_event_count;
aggregate.pair_candle_count += value.pair_candle_count; aggregate.pair_candle_count += value.pair_candle_count;
} }

View File

@@ -391,6 +391,9 @@ impl TransactionResolutionService {
}; };
let liquidity_event_count = non_trade_materialization.liquidity_event_count; let liquidity_event_count = non_trade_materialization.liquidity_event_count;
let pool_lifecycle_event_count = non_trade_materialization.pool_lifecycle_event_count; let pool_lifecycle_event_count = non_trade_materialization.pool_lifecycle_event_count;
let fee_event_count = non_trade_materialization.fee_event_count;
let reward_event_count = non_trade_materialization.reward_event_count;
let pool_admin_event_count = non_trade_materialization.pool_admin_event_count;
let trade_aggregations_result = self let trade_aggregations_result = self
.trade_aggregation_service .trade_aggregation_service
.record_transaction_by_signature(request.signature.as_str()) .record_transaction_by_signature(request.signature.as_str())
@@ -445,6 +448,9 @@ impl TransactionResolutionService {
"walletHoldingCount": wallet_holding_count, "walletHoldingCount": wallet_holding_count,
"liquidityEventCount": liquidity_event_count, "liquidityEventCount": liquidity_event_count,
"poolLifecycleEventCount": pool_lifecycle_event_count, "poolLifecycleEventCount": pool_lifecycle_event_count,
"feeEventCount": fee_event_count,
"rewardEventCount": reward_event_count,
"poolAdminEventCount": pool_admin_event_count,
"tradeEventCount": trade_event_count, "tradeEventCount": trade_event_count,
"pairCandleCount": pair_candle_count, "pairCandleCount": pair_candle_count,
"pairAnalyticSignalCount": pair_analytic_signal_count, "pairAnalyticSignalCount": pair_analytic_signal_count,