Skip to main content

rialo_s_client_traits/
lib.rs

1//! Defines traits for blocking (synchronous) and non-blocking (asynchronous)
2//! communication with a Solana server as well as a trait that encompasses both.
3//!
4//! Synchronous implementations are expected to create transactions, sign them, and send
5//! them with multiple retries, updating valid_from and resigning as-needed.
6//!
7//! Asynchronous implementations are expected to create transactions, sign them, and send
8//! them but without waiting to see if the server accepted it.
9
10use rialo_hash::Hash;
11use rialo_s_account::Account;
12use rialo_s_commitment_config::CommitmentConfig;
13use rialo_s_epoch_info::EpochInfo;
14use rialo_s_instruction::Instruction;
15use rialo_s_keypair::Keypair;
16use rialo_s_message::Message;
17use rialo_s_pubkey::Pubkey;
18use rialo_s_signature::Signature;
19use rialo_s_signer::{signers::Signers, Signer};
20use rialo_s_system_interface::instruction::transfer;
21use rialo_s_transaction::{versioned::VersionedTransaction, Transaction};
22use rialo_s_transaction_error::{TransactionResult, TransportResult as Result};
23
24pub trait Client: SyncClient + AsyncClient {
25    fn tpu_addr(&self) -> String;
26}
27
28pub trait SyncClient {
29    /// Create a transaction from the given message, and send it to the
30    /// server, retrying as-needed.
31    fn send_and_confirm_message<T: Signers + ?Sized>(
32        &self,
33        keypairs: &T,
34        message: Message,
35    ) -> Result<Signature>;
36
37    /// Create a transaction from a single instruction that only requires
38    /// a single signer. Then send it to the server, retrying as-needed.
39    fn send_and_confirm_instruction(
40        &self,
41        keypair: &Keypair,
42        instruction: Instruction,
43    ) -> Result<Signature>;
44
45    /// Transfer kelvins from `keypair` to `pubkey`, retrying until the
46    /// transfer completes or produces and error.
47    fn transfer_and_confirm(
48        &self,
49        kelvins: u64,
50        keypair: &Keypair,
51        pubkey: &Pubkey,
52    ) -> Result<Signature>;
53
54    /// Get an account or None if not found.
55    fn get_account_data(&self, pubkey: &Pubkey) -> Result<Option<Vec<u8>>>;
56
57    /// Get an account or None if not found.
58    fn get_account(&self, pubkey: &Pubkey) -> Result<Option<Account>>;
59
60    /// Get an account or None if not found. Uses explicit commitment configuration.
61    fn get_account_with_commitment(
62        &self,
63        pubkey: &Pubkey,
64        commitment_config: CommitmentConfig,
65    ) -> Result<Option<Account>>;
66
67    /// Get account balance or 0 if not found.
68    fn get_balance(&self, pubkey: &Pubkey) -> Result<u64>;
69
70    /// Get account balance or 0 if not found. Uses explicit commitment configuration.
71    fn get_balance_with_commitment(
72        &self,
73        pubkey: &Pubkey,
74        commitment_config: CommitmentConfig,
75    ) -> Result<u64>;
76
77    fn get_minimum_balance_for_rent_exemption(&self, data_len: usize) -> Result<u64>;
78
79    /// Get signature status.
80    fn get_signature_status(&self, signature: &Signature) -> Result<Option<TransactionResult<()>>>;
81
82    /// Get signature status. Uses explicit commitment configuration.
83    fn get_signature_status_with_commitment(
84        &self,
85        signature: &Signature,
86        commitment_config: CommitmentConfig,
87    ) -> Result<Option<TransactionResult<()>>>;
88
89    /// Get last known slot
90    fn get_slot(&self) -> Result<u64>;
91
92    /// Get last known slot. Uses explicit commitment configuration.
93    fn get_slot_with_commitment(&self, commitment_config: CommitmentConfig) -> Result<u64>;
94
95    /// Get transaction count
96    fn get_transaction_count(&self) -> Result<u64>;
97
98    /// Get transaction count. Uses explicit commitment configuration.
99    fn get_transaction_count_with_commitment(
100        &self,
101        commitment_config: CommitmentConfig,
102    ) -> Result<u64>;
103
104    fn get_epoch_info(&self) -> Result<EpochInfo>;
105
106    /// Poll until the signature has been confirmed by at least `min_confirmed_blocks`
107    fn poll_for_signature_confirmation(
108        &self,
109        signature: &Signature,
110        min_confirmed_blocks: usize,
111    ) -> Result<usize>;
112
113    /// Poll to confirm a transaction.
114    fn poll_for_signature(&self, signature: &Signature) -> Result<()>;
115
116    /// Get the current bank time
117    fn get_bank_time(&self) -> Result<i64>;
118
119    /// Check if the blockhash is valid
120    fn is_blockhash_valid(&self, blockhash: &Hash, commitment: CommitmentConfig) -> Result<bool>;
121
122    /// Calculate the fee for a `Message`
123    fn get_fee_for_message(&self, message: &Message) -> Result<u64>;
124}
125
126pub trait AsyncClient {
127    /// Send a signed transaction, but don't wait to see if the server accepted it.
128    fn async_send_transaction(&self, transaction: Transaction) -> Result<Signature> {
129        self.async_send_versioned_transaction(transaction.into())
130    }
131
132    /// Send a batch of signed transactions without confirmation.
133    fn async_send_batch(&self, transactions: Vec<Transaction>) -> Result<()> {
134        let transactions = transactions.into_iter().map(Into::into).collect();
135        self.async_send_versioned_transaction_batch(transactions)
136    }
137
138    /// Send a signed versioned transaction, but don't wait to see if the server accepted it.
139    fn async_send_versioned_transaction(
140        &self,
141        transaction: VersionedTransaction,
142    ) -> Result<Signature>;
143
144    /// Send a batch of signed versioned transactions without confirmation.
145    fn async_send_versioned_transaction_batch(
146        &self,
147        transactions: Vec<VersionedTransaction>,
148    ) -> Result<()> {
149        for t in transactions {
150            self.async_send_versioned_transaction(t)?;
151        }
152        Ok(())
153    }
154
155    /// Create a transaction from the given message, and send it to the
156    /// server, but don't wait for to see if the server accepted it.
157    fn async_send_message<T: Signers + ?Sized>(
158        &self,
159        keypairs: &T,
160        message: Message,
161        valid_from: i64,
162    ) -> Result<Signature> {
163        let transaction = Transaction::new(keypairs, message, valid_from);
164        self.async_send_transaction(transaction)
165    }
166
167    /// Create a transaction from a single instruction that only requires
168    /// a single signer. Then send it to the server, but don't wait for a reply.
169    fn async_send_instruction(
170        &self,
171        keypair: &Keypair,
172        instruction: Instruction,
173        valid_from: i64,
174    ) -> Result<Signature> {
175        let message = Message::new(&[instruction], Some(&keypair.pubkey()));
176        self.async_send_message(&[keypair], message, valid_from)
177    }
178
179    /// Attempt to transfer kelvins from `keypair` to `pubkey`, but don't wait to confirm.
180    fn async_transfer(
181        &self,
182        kelvins: u64,
183        keypair: &Keypair,
184        pubkey: &Pubkey,
185        valid_from: i64,
186    ) -> Result<Signature> {
187        let transfer_instruction = transfer(&keypair.pubkey(), pubkey, kelvins);
188        self.async_send_instruction(keypair, transfer_instruction, valid_from)
189    }
190}