0.7.24-pre.2
This commit is contained in:
@@ -203,6 +203,31 @@ impl KbTradeAggregationService {
|
||||
price_quote_per_base = inferred.2;
|
||||
}
|
||||
}
|
||||
if decoded_event.event_kind.starts_with("pump_fun.")
|
||||
&& (base_amount_raw.is_none()
|
||||
|| quote_amount_raw.is_none()
|
||||
|| price_quote_per_base.is_none())
|
||||
{
|
||||
let inferred_result = kb_extract_pump_fun_amounts_from_transaction(
|
||||
transaction.transaction_json.as_str(),
|
||||
transaction.meta_json.as_deref(),
|
||||
base_vault_address.as_deref(),
|
||||
quote_vault_address.as_deref(),
|
||||
);
|
||||
let inferred = match inferred_result {
|
||||
Ok(inferred) => inferred,
|
||||
Err(error) => return Err(error),
|
||||
};
|
||||
if base_amount_raw.is_none() {
|
||||
base_amount_raw = inferred.0;
|
||||
}
|
||||
if quote_amount_raw.is_none() {
|
||||
quote_amount_raw = inferred.1;
|
||||
}
|
||||
if price_quote_per_base.is_none() {
|
||||
price_quote_per_base = inferred.2;
|
||||
}
|
||||
}
|
||||
if price_quote_per_base.is_none() {
|
||||
price_quote_per_base = kb_compute_price_quote_per_base_with_decimals(
|
||||
transaction.meta_json.as_deref(),
|
||||
@@ -211,6 +236,12 @@ impl KbTradeAggregationService {
|
||||
quote_vault_address.as_deref(),
|
||||
);
|
||||
}
|
||||
if price_quote_per_base.is_none() {
|
||||
price_quote_per_base = kb_compute_price_quote_per_base_from_raw_amounts(
|
||||
base_amount_raw.as_deref(),
|
||||
quote_amount_raw.as_deref(),
|
||||
);
|
||||
}
|
||||
let slot_i64 = kb_convert_slot_to_i64(transaction.slot);
|
||||
let created_trade_event = existing_trade_option.is_none();
|
||||
let trade_event_dto = crate::KbTradeEventDto::new(
|
||||
@@ -637,6 +668,146 @@ fn kb_extract_pump_swap_amounts_from_transaction(
|
||||
Ok((base_amount_raw, quote_amount_raw, price_quote_per_base))
|
||||
}
|
||||
|
||||
fn kb_extract_pump_fun_amounts_from_transaction(
|
||||
transaction_json: &str,
|
||||
meta_json: std::option::Option<&str>,
|
||||
base_vault_address: std::option::Option<&str>,
|
||||
quote_native_address: std::option::Option<&str>,
|
||||
) -> Result<
|
||||
(
|
||||
std::option::Option<std::string::String>,
|
||||
std::option::Option<std::string::String>,
|
||||
std::option::Option<f64>,
|
||||
),
|
||||
crate::KbError,
|
||||
> {
|
||||
let meta_json = match meta_json {
|
||||
Some(meta_json) => meta_json,
|
||||
None => return Ok((None, None, None)),
|
||||
};
|
||||
let transaction_value_result = serde_json::from_str::<serde_json::Value>(transaction_json);
|
||||
let transaction_value = match transaction_value_result {
|
||||
Ok(transaction_value) => transaction_value,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Json(format!(
|
||||
"cannot parse transaction_json for pump_fun amount extraction: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
};
|
||||
let meta_value_result = serde_json::from_str::<serde_json::Value>(meta_json);
|
||||
let meta_value = match meta_value_result {
|
||||
Ok(meta_value) => meta_value,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Json(format!(
|
||||
"cannot parse meta_json for pump_fun amount extraction: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
};
|
||||
let account_keys_result = kb_extract_transaction_account_keys(&transaction_value);
|
||||
let account_keys = match account_keys_result {
|
||||
Ok(account_keys) => account_keys,
|
||||
Err(error) => return Err(error),
|
||||
};
|
||||
let pre_balances_result =
|
||||
kb_extract_token_balance_map(&meta_value, &account_keys, "preTokenBalances");
|
||||
let pre_balances = match pre_balances_result {
|
||||
Ok(pre_balances) => pre_balances,
|
||||
Err(error) => return Err(error),
|
||||
};
|
||||
let post_balances_result =
|
||||
kb_extract_token_balance_map(&meta_value, &account_keys, "postTokenBalances");
|
||||
let post_balances = match post_balances_result {
|
||||
Ok(post_balances) => post_balances,
|
||||
Err(error) => return Err(error),
|
||||
};
|
||||
let mut base_amount_raw = None;
|
||||
let mut quote_amount_raw = None;
|
||||
let mut price_quote_per_base = None;
|
||||
let mut base_delta_ui = None;
|
||||
if let Some(base_vault_address) = base_vault_address {
|
||||
let base_pre = pre_balances.get(base_vault_address);
|
||||
let base_post = post_balances.get(base_vault_address);
|
||||
let base_pre_raw = base_pre.map(|value| value.0.clone());
|
||||
let base_post_raw = base_post.map(|value| value.0.clone());
|
||||
base_amount_raw = kb_compute_amount_delta_abs(base_pre_raw, base_post_raw);
|
||||
let base_pre_ui = base_pre.and_then(|value| value.1);
|
||||
let base_post_ui = base_post.and_then(|value| value.1);
|
||||
base_delta_ui = kb_compute_ui_delta_abs(base_pre_ui, base_post_ui);
|
||||
}
|
||||
if let Some(quote_native_address) = quote_native_address {
|
||||
let quote_delta_result = kb_extract_native_balance_delta_by_address(
|
||||
&meta_value,
|
||||
&account_keys,
|
||||
quote_native_address,
|
||||
);
|
||||
let quote_delta = match quote_delta_result {
|
||||
Ok(quote_delta) => quote_delta,
|
||||
Err(error) => return Err(error),
|
||||
};
|
||||
if let Some(quote_delta_lamports) = quote_delta {
|
||||
quote_amount_raw = Some(quote_delta_lamports.to_string());
|
||||
let quote_delta_ui = quote_delta_lamports as f64 / 1_000_000_000.0;
|
||||
if let Some(base_delta_ui) = base_delta_ui {
|
||||
if base_delta_ui > 0.0 {
|
||||
price_quote_per_base = Some(quote_delta_ui / base_delta_ui);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok((base_amount_raw, quote_amount_raw, price_quote_per_base))
|
||||
}
|
||||
|
||||
fn kb_extract_native_balance_delta_by_address(
|
||||
meta_value: &serde_json::Value,
|
||||
account_keys: &[std::string::String],
|
||||
address: &str,
|
||||
) -> Result<std::option::Option<u64>, crate::KbError> {
|
||||
let mut account_index = None;
|
||||
for (index, account_key) in account_keys.iter().enumerate() {
|
||||
if account_key.as_str() == address {
|
||||
account_index = Some(index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
let account_index = match account_index {
|
||||
Some(account_index) => account_index,
|
||||
None => return Ok(None),
|
||||
};
|
||||
let pre_balances_option = meta_value
|
||||
.get("preBalances")
|
||||
.and_then(|value| value.as_array());
|
||||
let post_balances_option = meta_value
|
||||
.get("postBalances")
|
||||
.and_then(|value| value.as_array());
|
||||
let pre_balances = match pre_balances_option {
|
||||
Some(pre_balances) => pre_balances,
|
||||
None => return Ok(None),
|
||||
};
|
||||
let post_balances = match post_balances_option {
|
||||
Some(post_balances) => post_balances,
|
||||
None => return Ok(None),
|
||||
};
|
||||
if account_index >= pre_balances.len() || account_index >= post_balances.len() {
|
||||
return Ok(None);
|
||||
}
|
||||
let pre_balance_option = pre_balances[account_index].as_u64();
|
||||
let post_balance_option = post_balances[account_index].as_u64();
|
||||
let pre_balance = match pre_balance_option {
|
||||
Some(pre_balance) => pre_balance,
|
||||
None => return Ok(None),
|
||||
};
|
||||
let post_balance = match post_balance_option {
|
||||
Some(post_balance) => post_balance,
|
||||
None => return Ok(None),
|
||||
};
|
||||
if post_balance >= pre_balance {
|
||||
return Ok(Some(post_balance - pre_balance));
|
||||
}
|
||||
Ok(Some(pre_balance - post_balance))
|
||||
}
|
||||
|
||||
fn kb_extract_transaction_account_keys(
|
||||
transaction_value: &serde_json::Value,
|
||||
) -> Result<std::vec::Vec<std::string::String>, crate::KbError> {
|
||||
@@ -792,6 +963,37 @@ fn kb_compute_ui_delta_abs(
|
||||
Some(delta)
|
||||
}
|
||||
|
||||
fn kb_compute_price_quote_per_base_from_raw_amounts(
|
||||
base_amount_raw: std::option::Option<&str>,
|
||||
quote_amount_raw: std::option::Option<&str>,
|
||||
) -> std::option::Option<f64> {
|
||||
let base_amount_raw = match base_amount_raw {
|
||||
Some(base_amount_raw) => base_amount_raw.trim(),
|
||||
None => return None,
|
||||
};
|
||||
let quote_amount_raw = match quote_amount_raw {
|
||||
Some(quote_amount_raw) => quote_amount_raw.trim(),
|
||||
None => return None,
|
||||
};
|
||||
if base_amount_raw.is_empty() || quote_amount_raw.is_empty() {
|
||||
return None;
|
||||
}
|
||||
let base_amount_result = base_amount_raw.parse::<f64>();
|
||||
let base_amount = match base_amount_result {
|
||||
Ok(base_amount) => base_amount,
|
||||
Err(_) => return None,
|
||||
};
|
||||
let quote_amount_result = quote_amount_raw.parse::<f64>();
|
||||
let quote_amount = match quote_amount_result {
|
||||
Ok(quote_amount) => quote_amount,
|
||||
Err(_) => return None,
|
||||
};
|
||||
if base_amount <= 0.0 {
|
||||
return None;
|
||||
}
|
||||
Some(quote_amount / base_amount)
|
||||
}
|
||||
|
||||
fn kb_compute_price_quote_per_base_with_decimals(
|
||||
meta_json: std::option::Option<&str>,
|
||||
transaction_json: &str,
|
||||
|
||||
Reference in New Issue
Block a user