solana-client-wasm 1.14.11

Solana non-blocking WASM RPC client.
Documentation
use std::{collections::HashMap, fmt};

use solana_extra_wasm::{
    account_decoder::parse_token::UiTokenAmount, transaction_status::TransactionConfirmationStatus,
};
use solana_sdk::{
    clock::{Epoch, Slot, UnixTimestamp},
    inflation::Inflation,
    transaction::TransactionError,
};

// pub type RpcResult<T> = client_error::Result<Response<T>>;

// #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
// #[serde(rename_all = "camelCase")]
// pub struct RpcResponseContext {
//     pub slot: Slot,
//     #[serde(skip_serializing_if = "Option::is_none")]
//     pub api_version: Option<RpcApiVersion>,
// }

// #[derive(Debug, Clone, PartialEq, Eq)]
// pub struct RpcApiVersion(semver::Version);

// impl std::ops::Deref for RpcApiVersion {
//     type Target = semver::Version;
//     fn deref(&self) -> &Self::Target {
//         &self.0
//     }
// }

// impl Default for RpcApiVersion {
//     fn default() -> Self {
//         Self(solana_version::Version::default().as_semver_version())
//     }
// }

// impl Serialize for RpcApiVersion {
//     fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
//     where
//         S: Serializer,
//     {
//         serializer.serialize_str(&self.to_string())
//     }
// }

// impl<'de> Deserialize<'de> for RpcApiVersion {
//     fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
//     where
//         D: Deserializer<'de>,
//     {
//         let s: String = Deserialize::deserialize(deserializer)?;
//         Ok(RpcApiVersion(
//             semver::Version::from_str(&s).map_err(serde::de::Error::custom)?,
//         ))
//     }
// }

// impl RpcResponseContext {
//     pub fn new(slot: Slot) -> Self {
//         Self {
//             slot,
//             api_version: Some(RpcApiVersion::default()),
//         }
//     }
// }

// #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
// pub struct Response<T> {
//     pub context: RpcResponseContext,
//     pub value: T,
// }

// #[derive(Debug, PartialEq, Serialize, Deserialize)]
// #[serde(rename_all = "camelCase")]
// pub struct RpcBlockCommitment<T> {
//     pub commitment: Option<T>,
//     pub total_stake: u64,
// }

// #[derive(Serialize, Deserialize, Clone, Debug)]
// #[serde(rename_all = "camelCase")]
// pub struct RpcBlockhashFeeCalculator {
//     pub blockhash: String,
//     pub fee_calculator: FeeCalculator,
// }

#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(rename_all = "camelCase")]
pub struct RpcBlockhash {
    pub blockhash: String,
    pub last_valid_block_height: u64,
}

// #[derive(Serialize, Deserialize, Clone, Debug)]
// #[serde(rename_all = "camelCase")]
// pub struct RpcFees {
//     pub blockhash: String,
//     pub fee_calculator: FeeCalculator,
//     pub last_valid_slot: Slot,
//     pub last_valid_block_height: u64,
// }

// #[derive(Serialize, Deserialize, Clone, Debug)]
// #[serde(rename_all = "camelCase")]
// pub struct DeprecatedRpcFees {
//     pub blockhash: String,
//     pub fee_calculator: FeeCalculator,
//     pub last_valid_slot: Slot,
// }

// #[derive(Serialize, Deserialize, Clone, Debug)]
// #[serde(rename_all = "camelCase")]
// pub struct Fees {
//     pub blockhash: Hash,
//     pub fee_calculator: FeeCalculator,
//     pub last_valid_block_height: u64,
// }

// #[derive(Serialize, Deserialize, Clone, Debug)]
// #[serde(rename_all = "camelCase")]
// pub struct RpcFeeCalculator {
//     pub fee_calculator: FeeCalculator,
// }

// #[derive(Serialize, Deserialize, Clone, Debug)]
// #[serde(rename_all = "camelCase")]
// pub struct RpcFeeRateGovernor {
//     pub fee_rate_governor: FeeRateGovernor,
// }

#[derive(Serialize, Deserialize, PartialEq, Clone, Debug)]
#[serde(rename_all = "camelCase")]
pub struct RpcInflationGovernor {
    pub initial: f64,
    pub terminal: f64,
    pub taper: f64,
    pub foundation: f64,
    pub foundation_term: f64,
}

impl From<Inflation> for RpcInflationGovernor {
    fn from(inflation: Inflation) -> Self {
        Self {
            initial: inflation.initial,
            terminal: inflation.terminal,
            taper: inflation.taper,
            foundation: inflation.foundation,
            foundation_term: inflation.foundation_term,
        }
    }
}

#[derive(Serialize, Deserialize, PartialEq, Clone, Debug)]
#[serde(rename_all = "camelCase")]
pub struct RpcInflationRate {
    pub total: f64,
    pub validator: f64,
    pub foundation: f64,
    pub epoch: Epoch,
}

// #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
// #[serde(rename_all = "camelCase")]
// pub struct RpcKeyedAccount {
//     pub pubkey: String,
//     pub account: UiAccount,
// }

// #[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq)]
// pub struct SlotInfo {
//     pub slot: Slot,
//     pub parent: Slot,
//     pub root: Slot,
// }

// #[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq)]
// #[serde(rename_all = "camelCase")]
// pub struct SlotTransactionStats {
//     pub num_transaction_entries: u64,
//     pub num_successful_transactions: u64,
//     pub num_failed_transactions: u64,
//     pub max_transactions_per_entry: u64,
// }

// #[derive(Serialize, Deserialize, Debug)]
// #[serde(rename_all = "camelCase", tag = "type")]
// pub enum SlotUpdate {
//     FirstShredReceived {
//         slot: Slot,
//         timestamp: u64,
//     },
//     Completed {
//         slot: Slot,
//         timestamp: u64,
//     },
//     CreatedBank {
//         slot: Slot,
//         parent: Slot,
//         timestamp: u64,
//     },
//     Frozen {
//         slot: Slot,
//         timestamp: u64,
//         stats: SlotTransactionStats,
//     },
//     Dead {
//         slot: Slot,
//         timestamp: u64,
//         err: String,
//     },
//     OptimisticConfirmation {
//         slot: Slot,
//         timestamp: u64,
//     },
//     Root {
//         slot: Slot,
//         timestamp: u64,
//     },
// }

// impl SlotUpdate {
//     pub fn slot(&self) -> Slot {
//         match self {
//             Self::FirstShredReceived { slot, .. } => *slot,
//             Self::Completed { slot, .. } => *slot,
//             Self::CreatedBank { slot, .. } => *slot,
//             Self::Frozen { slot, .. } => *slot,
//             Self::Dead { slot, .. } => *slot,
//             Self::OptimisticConfirmation { slot, .. } => *slot,
//             Self::Root { slot, .. } => *slot,
//         }
//     }
// }

// #[derive(Serialize, Deserialize, Clone, Debug)]
// #[serde(rename_all = "camelCase", untagged)]
// pub enum RpcSignatureResult {
//     ProcessedSignature(ProcessedSignatureResult),
//     ReceivedSignature(ReceivedSignatureResult),
// }

// #[derive(Serialize, Deserialize, Clone, Debug)]
// #[serde(rename_all = "camelCase")]
// pub struct RpcLogsResponse {
//     pub signature: String, // Signature as base58 string
//     pub err: Option<TransactionError>,
//     pub logs: Vec<String>,
// }

// #[derive(Serialize, Deserialize, Clone, Debug)]
// #[serde(rename_all = "camelCase")]
// pub struct ProcessedSignatureResult {
//     pub err: Option<TransactionError>,
// }

// #[derive(Serialize, Deserialize, Clone, Debug)]
// #[serde(rename_all = "camelCase")]
// pub enum ReceivedSignatureResult {
//     ReceivedSignature,
// }

// #[derive(Serialize, Deserialize, Clone, Debug)]
// #[serde(rename_all = "camelCase")]
// pub struct RpcContactInfo {
//     /// Pubkey of the node as a base-58 string
//     pub pubkey: String,
//     /// Gossip port
//     pub gossip: Option<SocketAddr>,
//     /// Tpu port
//     pub tpu: Option<SocketAddr>,
//     /// JSON RPC port
//     pub rpc: Option<SocketAddr>,
//     /// Software version
//     pub version: Option<String>,
//     /// First 4 bytes of the FeatureSet identifier
//     pub feature_set: Option<u32>,
//     /// Shred version
//     pub shred_version: Option<u16>,
// }

/// Map of leader base58 identity pubkeys to the slot indices relative to the first epoch slot
pub type RpcLeaderSchedule = HashMap<String, Vec<usize>>;

#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RpcBlockProductionRange {
    pub first_slot: Slot,
    pub last_slot: Slot,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct RpcBlockProduction {
    /// Map of leader base58 identity pubkeys to a tuple of `(number of leader slots, number of blocks produced)`
    pub by_identity: HashMap<String, (usize, usize)>,
    pub range: RpcBlockProductionRange,
}

#[derive(Serialize, Deserialize, Clone)]
#[serde(rename_all = "kebab-case")]
pub struct RpcVersionInfo {
    /// The current version of solana-core
    pub solana_core: String,
    /// first 4 bytes of the FeatureSet identifier
    pub feature_set: Option<u32>,
}

impl fmt::Debug for RpcVersionInfo {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.solana_core)
    }
}

impl fmt::Display for RpcVersionInfo {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if let Some(version) = self.solana_core.split_whitespace().next() {
            // Display just the semver if possible
            write!(f, "{}", version)
        } else {
            write!(f, "{}", self.solana_core)
        }
    }
}

// #[derive(Serialize, Deserialize, Clone, Debug)]
// #[serde(rename_all = "kebab-case")]
// pub struct RpcIdentity {
//     /// The current node identity pubkey
//     pub identity: String,
// }

// #[derive(Serialize, Deserialize, Clone, Debug)]
// #[serde(rename_all = "camelCase")]
// pub struct RpcVote {
//     /// Vote account address, as base-58 encoded string
//     pub vote_pubkey: String,
//     pub slots: Vec<Slot>,
//     pub hash: String,
//     pub timestamp: Option<UnixTimestamp>,
//     pub signature: String,
// }

#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(rename_all = "camelCase")]
pub struct RpcVoteAccountStatus {
    pub current: Vec<RpcVoteAccountInfo>,
    pub delinquent: Vec<RpcVoteAccountInfo>,
}

#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(rename_all = "camelCase")]
pub struct RpcVoteAccountInfo {
    /// Vote account address, as base-58 encoded string
    pub vote_pubkey: String,

    /// The validator identity, as base-58 encoded string
    pub node_pubkey: String,

    /// The current stake, in lamports, delegated to this vote account
    pub activated_stake: u64,

    /// An 8-bit integer used as a fraction (commission/MAX_U8) for rewards payout
    pub commission: u8,

    /// Whether this account is staked for the current epoch
    pub epoch_vote_account: bool,

    /// History of how many credits earned by the end of each epoch
    ///   each tuple is (Epoch, credits, prev_credits)
    pub epoch_credits: Vec<(Epoch, u64, u64)>,

    /// Most recent slot voted on by this vote account (0 if no votes exist)
    pub last_vote: u64,

    /// Current root slot for this vote account (0 if not root slot exists)
    pub root_slot: Slot,
}

// #[derive(Serialize, Deserialize, Clone, Debug)]
// #[serde(rename_all = "camelCase")]
// pub struct RpcSignatureConfirmation {
//     pub confirmations: usize,
//     pub status: Result<()>,
// }

// #[derive(Serialize, Deserialize, Clone, Debug)]
// #[serde(rename_all = "camelCase")]
// pub struct RpcSimulateTransactionResult {
//     pub err: Option<TransactionError>,
//     pub logs: Option<Vec<String>>,
//     pub accounts: Option<Vec<Option<UiAccount>>>,
//     pub units_consumed: Option<u64>,
//     pub return_data: Option<RpcTransactionReturnData>,
// }

// #[derive(Serialize, Deserialize, Clone, Debug)]
// #[serde(rename_all = "camelCase")]
// pub struct RpcTransactionReturnData {
//     pub program_id: String,
//     pub data: (String, ReturnDataEncoding),
// }

// impl From<TransactionReturnData> for RpcTransactionReturnData {
//     fn from(return_data: TransactionReturnData) -> Self {
//         Self {
//             program_id: return_data.program_id.to_string(),
//             data: (base64::encode(return_data.data), ReturnDataEncoding::Base64),
//         }
//     }
// }

// #[derive(Serialize, Deserialize, Clone, Copy, Debug, Eq, Hash, PartialEq)]
// #[serde(rename_all = "camelCase")]
// pub enum ReturnDataEncoding {
//     Base64,
// }

// #[derive(Serialize, Deserialize, Clone, Debug)]
// #[serde(rename_all = "camelCase")]
// pub struct RpcStorageTurn {
//     pub blockhash: String,
//     pub slot: Slot,
// }

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct RpcAccountBalance {
    pub address: String,
    pub lamports: u64,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct RpcSupply {
    pub total: u64,
    pub circulating: u64,
    pub non_circulating: u64,
    pub non_circulating_accounts: Vec<String>,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub enum StakeActivationState {
    Activating,
    Active,
    Deactivating,
    Inactive,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct RpcStakeActivation {
    pub state: StakeActivationState,
    pub active: u64,
    pub inactive: u64,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct RpcTokenAccountBalance {
    pub address: String,
    #[serde(flatten)]
    pub amount: UiTokenAmount,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RpcConfirmedTransactionStatusWithSignature {
    pub signature: String,
    pub slot: Slot,
    pub err: Option<TransactionError>,
    pub memo: Option<String>,
    pub block_time: Option<UnixTimestamp>,
    pub confirmation_status: Option<TransactionConfirmationStatus>,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RpcPerfSample {
    pub slot: Slot,
    pub num_transactions: u64,
    pub num_slots: u64,
    pub sample_period_secs: u16,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RpcInflationReward {
    pub epoch: Epoch,
    pub effective_slot: Slot,
    pub amount: u64,            // lamports
    pub post_balance: u64,      // lamports
    pub commission: Option<u8>, // Vote account commission when the reward was credited
}

// #[derive(Clone, Deserialize, Serialize, Debug, Error, Eq, PartialEq)]
// pub enum RpcBlockUpdateError {
//     #[error("block store error")]
//     BlockStoreError,

//     #[error("unsupported transaction version ({0})")]
//     UnsupportedTransactionVersion(u8),
// }

// #[derive(Serialize, Deserialize, Debug)]
// #[serde(rename_all = "camelCase")]
// pub struct RpcBlockUpdate {
//     pub slot: Slot,
//     pub block: Option<UiConfirmedBlock>,
//     pub err: Option<RpcBlockUpdateError>,
// }

// impl From<ConfirmedTransactionStatusWithSignature> for RpcConfirmedTransactionStatusWithSignature {
//     fn from(value: ConfirmedTransactionStatusWithSignature) -> Self {
//         let ConfirmedTransactionStatusWithSignature {
//             signature,
//             slot,
//             err,
//             memo,
//             block_time,
//         } = value;
//         Self {
//             signature: signature.to_string(),
//             slot,
//             err,
//             memo,
//             block_time,
//             confirmation_status: None,
//         }
//     }
// }

// #[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq)]
// pub struct RpcSnapshotSlotInfo {
//     pub full: Slot,
//     pub incremental: Option<Slot>,
// }