use std::fmt;
use serde::{Deserialize, Serialize};
use validator::Validate;
use crate::validation::validate_transaction_data;
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, Validate)]
pub struct SendTransactionConfig {
#[serde(default)]
pub encoding: TransactionEncoding,
#[validate(range(min = 0, max = 100, message = "Max retries must be between 0 and 100"))]
#[serde(rename = "maxRetries")]
pub max_retries: Option<usize>,
#[validate(range(min = 0, message = "Min context slot must be non-negative"))]
#[serde(rename = "minContextSlot")]
pub min_context_slot: Option<u64>,
#[serde(rename = "skipPreflight", default)]
pub skip_preflight: bool,
#[serde(rename = "waitForExecution", default)]
pub wait_for_execution: bool,
}
impl SendTransactionConfig {
pub fn new(encoding: TransactionEncoding) -> Self {
Self {
encoding,
max_retries: None,
min_context_slot: None,
skip_preflight: false,
wait_for_execution: false,
}
}
}
impl Default for SendTransactionConfig {
fn default() -> Self {
Self::new(TransactionEncoding::Base64)
}
}
#[derive(Debug, Deserialize, Serialize, Clone, Validate)]
pub struct SendTransactionRequest {
#[serde(default)]
#[validate(custom(function = crate::validation::validate_protocol_version))]
pub version: u16,
#[validate(length(min = 1, message = "Transaction cannot be empty"))]
#[validate(custom(function = validate_transaction_data))]
pub transaction: String,
#[validate(nested)]
pub config: SendTransactionConfig,
}
impl SendTransactionRequest {
pub fn new(transaction: String, config: SendTransactionConfig) -> Self {
Self {
version: 0,
transaction,
config,
}
}
}
#[derive(Debug, Default, Clone, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum TransactionEncoding {
#[default]
Base64,
Base58,
}
impl fmt::Display for TransactionEncoding {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Base64 => f.write_str("base64"),
Self::Base58 => f.write_str("base58"),
}
}
}