Files
khadhroony-bot3/migration/khadhroony-bot2-reference/kb_rpc/src/standard_http_transactions.rs
2026-07-23 16:37:12 +02:00

156 lines
6.5 KiB
Rust

// file: kb_rpc/src/standard_http_transactions.rs
// version: 2
//! Configurable standard transaction-oriented Solana HTTP JSON-RPC requests.
/// Prioritization fee observed for one recent slot.
#[derive(Clone, Copy, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct RpcPrioritizationFee {
/// Slot from which the fee sample was retained.
pub slot: u64,
/// Minimum compute-unit price in micro-lamports for the requested writable set.
pub prioritization_fee: u64,
}
/// Typed `getRecentPrioritizationFees` request.
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct GetRecentPrioritizationFeesRequest {
/// Optional writable account set. `None` omits the parameter; `Some([])` sends an explicit empty set.
pub locked_writable_accounts: std::option::Option<std::vec::Vec<std::string::String>>,
}
impl crate::StandardHttpRequest for crate::GetRecentPrioritizationFeesRequest {
type Response = std::vec::Vec<crate::RpcPrioritizationFee>;
const METHOD: &'static str = "getRecentPrioritizationFees";
fn params(&self) -> kb_core::Result<std::vec::Vec<serde_json::Value>> {
if let std::option::Option::Some(accounts) = &self.locked_writable_accounts {
let validation_result = crate::standard_http::validate_pubkey_list(
accounts,
"getRecentPrioritizationFees writable account",
crate::constants::MAX_PRIORITIZATION_FEE_ACCOUNT_COUNT,
);
if let std::result::Result::Err(error) = validation_result {
return std::result::Result::Err(error);
}
let value = match crate::standard_http::serialize_parameter(Self::METHOD, accounts) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
return std::result::Result::Ok(std::vec![value]);
}
return std::result::Result::Ok(std::vec::Vec::new());
}
}
/// Typed `getTransactionCount` request.
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct GetTransactionCountRequest {
/// Optional commitment and minimum-context options.
pub config: std::option::Option<crate::RpcContextConfig>,
}
impl crate::StandardHttpRequest for crate::GetTransactionCountRequest {
type Response = u64;
const METHOD: &'static str = "getTransactionCount";
fn params(&self) -> kb_core::Result<std::vec::Vec<serde_json::Value>> {
if let std::option::Option::Some(config) = &self.config {
let value = match crate::standard_http::serialize_parameter(Self::METHOD, config) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
return std::result::Result::Ok(std::vec![value]);
}
return std::result::Result::Ok(std::vec::Vec::new());
}
}
/// Typed `isBlockhashValid` request.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct IsBlockhashValidRequest {
/// Base58 blockhash being checked.
pub blockhash: std::string::String,
/// Optional commitment and minimum-context options.
pub config: std::option::Option<crate::RpcContextConfig>,
}
impl crate::StandardHttpRequest for crate::IsBlockhashValidRequest {
type Response = crate::RpcResponse<bool>;
const METHOD: &'static str = "isBlockhashValid";
fn params(&self) -> kb_core::Result<std::vec::Vec<serde_json::Value>> {
let validation_result =
crate::validate_solana_hash_text(&self.blockhash, "isBlockhashValid blockhash");
if let std::result::Result::Err(error) = validation_result {
return std::result::Result::Err(error);
}
let mut params = std::vec![serde_json::Value::String(self.blockhash.clone())];
if let std::option::Option::Some(config) = &self.config {
let value = match crate::standard_http::serialize_parameter(Self::METHOD, config) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
params.push(value);
}
return std::result::Result::Ok(params);
}
}
#[cfg(test)]
mod tests {
fn pubkey(seed: u8) -> std::string::String {
return bs58::encode([seed; 32]).into_string();
}
#[test]
fn prioritization_fee_request_distinguishes_omitted_and_explicit_empty_sets() {
let omitted = crate::GetRecentPrioritizationFeesRequest {
locked_writable_accounts: std::option::Option::None,
};
let explicit = crate::GetRecentPrioritizationFeesRequest {
locked_writable_accounts: std::option::Option::Some(std::vec::Vec::new()),
};
let omitted_params = match crate::StandardHttpRequest::params(&omitted) {
std::result::Result::Ok(params) => params,
std::result::Result::Err(error) => panic!("unexpected omitted params error: {error}"),
};
let explicit_params = match crate::StandardHttpRequest::params(&explicit) {
std::result::Result::Ok(params) => params,
std::result::Result::Err(error) => panic!("unexpected explicit params error: {error}"),
};
assert_eq!(omitted_params, std::vec::Vec::<serde_json::Value>::new());
assert_eq!(explicit_params, std::vec![serde_json::json!([])]);
}
#[test]
fn prioritization_fee_request_enforces_official_account_bound() {
let request = crate::GetRecentPrioritizationFeesRequest {
locked_writable_accounts: std::option::Option::Some(
(0_u16..129_u16).map(|value| return pubkey(value as u8)).collect(),
),
};
assert!(crate::StandardHttpRequest::params(&request).is_err());
}
#[test]
fn blockhash_validity_preserves_minimum_context_slot() {
let request = crate::IsBlockhashValidRequest {
blockhash: pubkey(9),
config: std::option::Option::Some(crate::RpcContextConfig {
commitment: std::option::Option::Some(crate::RpcCommitmentLevel::Finalized),
min_context_slot: std::option::Option::Some(123),
}),
};
let params = match crate::StandardHttpRequest::params(&request) {
std::result::Result::Ok(params) => params,
std::result::Result::Err(error) => panic!("params failed: {error}"),
};
assert_eq!(params[1]["minContextSlot"], serde_json::Value::from(123_u64));
}
}