0.7.28 - final
This commit is contained in:
@@ -195,6 +195,37 @@ pub fn is_dex_admin_event_kind(event_kind: &str) -> bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Returns true when a decoded payload contains at least one direct amount or price field.
|
||||
///
|
||||
/// This is a conservative payload-level check. It does not inspect transaction
|
||||
/// token balance deltas and is intended for protocol decoders that cannot yet
|
||||
/// produce a deterministic materializable swap payload.
|
||||
pub(crate) fn decoded_payload_has_trade_amount_or_price_payload(
|
||||
payload: &serde_json::Value,
|
||||
) -> bool {
|
||||
return value_contains_any_non_null_key(
|
||||
payload,
|
||||
&[
|
||||
"baseAmountRaw",
|
||||
"base_amount_raw",
|
||||
"baseAmount",
|
||||
"amountBase",
|
||||
"amountInBase",
|
||||
"quoteAmountRaw",
|
||||
"quote_amount_raw",
|
||||
"quoteAmount",
|
||||
"amountQuote",
|
||||
"amountOutQuote",
|
||||
"amountIn",
|
||||
"amountOut",
|
||||
"priceQuotePerBase",
|
||||
"price_quote_per_base",
|
||||
"quotePerBase",
|
||||
"lastPriceQuotePerBase",
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
/// Returns true when a decoded payload is marked as a trade candidate.
|
||||
///
|
||||
/// Explicit payload metadata wins over event-kind inference. This allows
|
||||
@@ -332,6 +363,38 @@ fn json_insert_i64_if_missing(
|
||||
object.insert(key.to_owned(), serde_json::Value::Number(serde_json::Number::from(value)));
|
||||
}
|
||||
|
||||
fn value_contains_any_non_null_key(value: &serde_json::Value, candidate_keys: &[&str]) -> bool {
|
||||
if let Some(object) = value.as_object() {
|
||||
for candidate_key in candidate_keys {
|
||||
let candidate_value_option = object.get(*candidate_key);
|
||||
if let Some(candidate_value) = candidate_value_option {
|
||||
if !candidate_value.is_null() {
|
||||
if let Some(text) = candidate_value.as_str() {
|
||||
if text.trim().is_empty() {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
for nested_value in object.values() {
|
||||
if value_contains_any_non_null_key(nested_value, candidate_keys) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if let Some(array) = value.as_array() {
|
||||
for nested_value in array {
|
||||
if value_contains_any_non_null_key(nested_value, candidate_keys) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
fn extract_top_level_bool_by_candidate_keys(
|
||||
payload: &serde_json::Value,
|
||||
candidate_keys: &[&str],
|
||||
@@ -506,4 +569,20 @@ mod tests {
|
||||
assert!(!super::is_decoded_event_trade_candidate("pump_swap.buy", &payload_json));
|
||||
assert!(!super::is_decoded_event_candle_candidate("pump_swap.buy", &payload_json));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn detects_direct_amount_or_price_payload_recursively() {
|
||||
let payload_json = serde_json::json!({
|
||||
"nested": {
|
||||
"quoteAmountRaw": "2500"
|
||||
}
|
||||
});
|
||||
assert!(super::decoded_payload_has_trade_amount_or_price_payload(&payload_json));
|
||||
let empty_payload_json = serde_json::json!({
|
||||
"nested": {
|
||||
"quoteAmountRaw": ""
|
||||
}
|
||||
});
|
||||
assert!(!super::decoded_payload_has_trade_amount_or_price_payload(&empty_payload_json));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user